address will be their default route. The <code>netmask</code>
attribute defines the significant bits of the network address,
again specified in dotted-decimal format. <span class="since">Since 0.3.0</span>
- </dd>
- <dt><code>dhcp</code></dt>
- <dd>Immediately within the <code>ip</code> element there is an
+ </dd><dt><code>tftp</code></dt><dd>Immediately within
+ the <code>ip</code> element there is an optional <code>tftp</code>
+ element. The presence of this element and of its attribute
+ <code>root</code> enables TFTP services. The attribute specifies
+ the path to the root directory served via TFTP.
+ <span class="since">Since 0.7.1</span>
+ </dd><dt><code>dhcp</code></dt><dd>Also within the <code>ip</code> element there is an
optional <code>dhcp</code> element. The presence of this element
enables DHCP services on the virtual network. It will further
contain one or more <code>range</code> elements.
assigned to that host (via the <code>ip</code> attribute), and the
name to be given that host by the DHCP server (via the
<code>name</code> attribute). <span class="since">Since 0.4.5</span>
- </dd>
+ </dd><dt><code>bootp</code></dt><dd>The optional <code>bootp</code>
+ element specifies BOOTP options to be provided by the DHCP server.
+ Only one attribute is supported, <code>file</code>, 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.<span
+ class="since">Since 0.7.1.</span>
</dl>
<h2><a name="examples">Example configuration</a></h2>
<optional>
<attribute name="netmask"><text/></attribute>
</optional>
+ <optional>
+ <element name="tftp">
+ <attribute name="root"><text/></attribute>
+ </element>
+ </optional>
<!-- Define the range(s) of IP addresses that the DHCP
server should hand out -->
<element name="dhcp">
<attribute name="ip"><text/></attribute>
</element>
</zeroOrMore>
+ <optional>
+ <element name="bootp">
+ <attribute name="file"><text/></attribute>
+ </element>
+ </optional>
</element>
</element>
</optional>
}
VIR_FREE(def->hosts);
+ VIR_FREE(def->tftproot);
+ VIR_FREE(def->bootfile);
+
VIR_FREE(def);
}
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;
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)
/* 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,
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;
}
virBufferAddLit(&buf, ">\n");
+ if (def->tftproot) {
+ virBufferEscapeString(&buf, " <tftp root='%s' />\n",
+ def->tftproot);
+ }
if ((def->nranges || def->nhosts)) {
int i;
virBufferAddLit(&buf, " <dhcp>\n");
virBufferVSprintf(&buf, "ip='%s' ", def->hosts[i].ip);
virBufferAddLit(&buf, "/>\n");
}
+ if (def->bootfile) {
+ virBufferEscapeString(&buf, " <bootp file='%s' />\n",
+ def->bootfile);
+ }
+
virBufferAddLit(&buf, " </dhcp>\n");
}
unsigned int nhosts; /* Zero or more dhcp hosts */
virNetworkDHCPHostDefPtr hosts;
+
+ char *tftproot;
+ char *bootfile;
};
typedef struct _virNetworkObj virNetworkObj;
(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)
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;
capabilityschematest \
capabilityschemadata \
networkschematest \
+ networkschemadata \
domainschematest \
domainschemadata \
interfaceschemadata \
--- /dev/null
+<network>
+ <name>netboot</name>
+ <bridge name="virbr1" />
+ <forward/>
+ <ip address="192.168.122.1" netmask="255.255.255.0">
+ <tftp root="/var/lib/tftproot" />
+ <dhcp>
+ <range start="192.168.122.2" end="192.168.122.254" />
+ <bootp file="pxeboot.img" />
+ </dhcp>
+ </ip>
+</network>
test -z "$srcdir" && srcdir=`pwd`
test -z "$abs_srcdir" && abs_srcdir=`pwd`
-DIRS="../src/network"
+DIRS="../src/network networkschemadata"
n=0
f=0