diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in
index fd6843004a..e471385e25 100644
--- a/docs/formatnetwork.html.in
+++ b/docs/formatnetwork.html.in
@@ -113,9 +113,13 @@
address will be their default route. The netmask
attribute defines the significant bits of the network address,
again specified in dotted-decimal format. Since 0.3.0
-
-
dhcp
- Immediately within the ip
element there is an
+ tftp
Immediately within
+ the ip
element there is an optional tftp
+ element. The presence of this element and of its attribute
+ root
enables TFTP services. The attribute specifies
+ the path to the root directory served via TFTP.
+ Since 0.7.1
+ dhcp
Also within the ip
element there is an
optional dhcp
element. The presence of this element
enables DHCP services on the virtual network. It will further
contain one or more range
elements.
@@ -137,7 +141,12 @@
assigned to that host (via the ip
attribute), and the
name to be given that host by the DHCP server (via the
name
attribute). Since 0.4.5
-
+ bootp
The optional bootp
+ element specifies BOOTP options to be provided by the DHCP server.
+ Only one attribute is supported, file
, giving the file
+ to be used for the boot image). The BOOTP options currently have to
+ be the same for all address ranges and statically assigned addresses.Since 0.7.1.
diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
index a4281a52ff..042e013d85 100644
--- a/docs/schemas/network.rng
+++ b/docs/schemas/network.rng
@@ -60,6 +60,11 @@
+
+
+
+
+
@@ -76,6 +81,11 @@
+
+
+
+
+
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 3764bb409f..14eb5437be 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -115,6 +115,9 @@ void virNetworkDefFree(virNetworkDefPtr def)
}
VIR_FREE(def->hosts);
+ VIR_FREE(def->tftproot);
+ VIR_FREE(def->bootfile);
+
VIR_FREE(def);
}
@@ -299,6 +302,17 @@ virNetworkDHCPRangeDefParseXML(virConnectPtr conn,
def->hosts[def->nhosts].name = (char *)name;
def->hosts[def->nhosts].ip = (char *)ip;
def->nhosts++;
+
+ } else if (cur->type == XML_ELEMENT_NODE &&
+ xmlStrEqual(cur->name, BAD_CAST "bootp")) {
+ xmlChar *file;
+
+ if (!(file = xmlGetProp(cur, BAD_CAST "file"))) {
+ cur = cur->next;
+ continue;
+ }
+
+ def->bootfile = (char *)file;
}
cur = cur->next;
@@ -307,6 +321,37 @@ virNetworkDHCPRangeDefParseXML(virConnectPtr conn,
return 0;
}
+static int
+virNetworkIPParseXML(virConnectPtr conn,
+ virNetworkDefPtr def,
+ xmlNodePtr node) {
+ xmlNodePtr cur;
+
+ cur = node->children;
+ while (cur != NULL) {
+ if (cur->type == XML_ELEMENT_NODE &&
+ xmlStrEqual(cur->name, BAD_CAST "dhcp")) {
+ int result = virNetworkDHCPRangeDefParseXML(conn, def, cur);
+ if (result)
+ return result;
+
+ } else if (cur->type == XML_ELEMENT_NODE &&
+ xmlStrEqual(cur->name, BAD_CAST "tftp")) {
+ xmlChar *root;
+
+ if (!(root = xmlGetProp(cur, BAD_CAST "root"))) {
+ cur = cur->next;
+ continue;
+ }
+
+ def->tftproot = (char *)root;
+ }
+
+ cur = cur->next;
+ }
+ return 0;
+}
+
static virNetworkDefPtr
virNetworkDefParseXML(virConnectPtr conn,
xmlXPathContextPtr ctxt)
@@ -363,7 +408,7 @@ virNetworkDefParseXML(virConnectPtr conn,
/* XXX someday we want IPv6 too, so inet_aton won't work there */
struct in_addr inaddress, innetmask;
char *netaddr;
- xmlNodePtr dhcp;
+ xmlNodePtr ip;
if (inet_pton(AF_INET, def->ipAddress, &inaddress) <= 0) {
virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
@@ -386,8 +431,8 @@ virNetworkDefParseXML(virConnectPtr conn,
goto error;
}
- if ((dhcp = virXPathNode(conn, "./ip[1]/dhcp[1]", ctxt)) &&
- virNetworkDHCPRangeDefParseXML(conn, def, dhcp) < 0)
+ if ((ip = virXPathNode(conn, "./ip[1]", ctxt)) &&
+ virNetworkIPParseXML(conn, def, ip) < 0)
goto error;
}
@@ -605,6 +650,10 @@ char *virNetworkDefFormat(virConnectPtr conn,
virBufferAddLit(&buf, ">\n");
+ if (def->tftproot) {
+ virBufferEscapeString(&buf, " \n",
+ def->tftproot);
+ }
if ((def->nranges || def->nhosts)) {
int i;
virBufferAddLit(&buf, " \n");
@@ -621,6 +670,11 @@ char *virNetworkDefFormat(virConnectPtr conn,
virBufferVSprintf(&buf, "ip='%s' ", def->hosts[i].ip);
virBufferAddLit(&buf, "/>\n");
}
+ if (def->bootfile) {
+ virBufferEscapeString(&buf, " \n",
+ def->bootfile);
+ }
+
virBufferAddLit(&buf, " \n");
}
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index 4076f9a8b5..e983a015a1 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -78,6 +78,9 @@ struct _virNetworkDef {
unsigned int nhosts; /* Zero or more dhcp hosts */
virNetworkDHCPHostDefPtr hosts;
+
+ char *tftproot;
+ char *bootfile;
};
typedef struct _virNetworkObj virNetworkObj;
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index fd3d08f8a2..95bc810416 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -400,6 +400,10 @@ networkBuildDnsmasqArgv(virConnectPtr conn,
(2 * network->def->nranges) + /* --dhcp-range 10.0.0.2,10.0.0.254 */
/* --dhcp-host 01:23:45:67:89:0a,hostname,10.0.0.3 */
(2 * network->def->nhosts) +
+ /* --enable-tftp --tftp-root /srv/tftp */
+ (network->def->tftproot ? 3 : 0) +
+ /* --dhcp-boot pxeboot.img */
+ (network->def->bootfile ? 2 : 0) +
1; /* NULL */
if (VIR_ALLOC_N(*argv, len) < 0)
@@ -478,6 +482,16 @@ networkBuildDnsmasqArgv(virConnectPtr conn,
APPEND_ARG(*argv, i++, buf);
}
+ if (network->def->tftproot) {
+ APPEND_ARG(*argv, i++, "--enable-tftp");
+ APPEND_ARG(*argv, i++, "--tftp-root");
+ APPEND_ARG(*argv, i++, network->def->tftproot);
+ }
+ if (network->def->bootfile) {
+ APPEND_ARG(*argv, i++, "--dhcp-boot");
+ APPEND_ARG(*argv, i++, network->def->bootfile);
+ }
+
#undef APPEND_ARG
return 0;
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 4cc21c9a02..abda4ad790 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -53,6 +53,7 @@ EXTRA_DIST = \
capabilityschematest \
capabilityschemadata \
networkschematest \
+ networkschemadata \
domainschematest \
domainschemadata \
interfaceschemadata \
diff --git a/tests/networkschemadata/netboot-network.xml b/tests/networkschemadata/netboot-network.xml
new file mode 100644
index 0000000000..7274ee6b99
--- /dev/null
+++ b/tests/networkschemadata/netboot-network.xml
@@ -0,0 +1,12 @@
+
+ netboot
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/networkschematest b/tests/networkschematest
index ac22bc1557..3fc0f272af 100755
--- a/tests/networkschematest
+++ b/tests/networkschematest
@@ -3,7 +3,7 @@
test -z "$srcdir" && srcdir=`pwd`
test -z "$abs_srcdir" && abs_srcdir=`pwd`
-DIRS="../src/network"
+DIRS="../src/network networkschemadata"
n=0
f=0