</optional>
</element>
</optional>
+ <zeroOrMore>
+ <element name="option">
+ <attribute name="number"><ref name="uint8range"/></attribute>
+ <attribute name="value"><text/></attribute>
+ </element>
+ </zeroOrMore>
</element>
</optional>
</element>
return ret;
}
+static int
+virNetworkDHCPOptionDefParseXML(const char *networkName,
+ xmlNodePtr node,
+ virNetworkDHCPOptionDefPtr option)
+{
+ char *number = NULL;
+ int ret = -1;
+
+ if (!(number = virXMLPropString(node, "number"))) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Option definition in IPv4 network '%s' "
+ "must have number attribute"),
+ networkName);
+ goto cleanup;
+ }
+ if (virStrToLong_ui(number, NULL, 10, &option->number) < 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Malformed <option> number attribute: %s"),
+ number);
+ goto cleanup;
+ }
+ option->value = virXMLPropString(node, "value");
+
+ ret = 0;
+
+cleanup:
+ VIR_FREE(number);
+ return ret;
+}
+
+
static int
virNetworkDHCPDefParseXML(const char *networkName,
xmlNodePtr node,
def->bootfile = file;
def->bootserver = inaddr;
VIR_FREE(server);
+ } else if (cur->type == XML_ELEMENT_NODE &&
+ xmlStrEqual(cur->name, BAD_CAST "option")) {
+ if (VIR_REALLOC_N(def->options, def->noptions + 1) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+ if (virNetworkDHCPOptionDefParseXML(networkName, cur,
+ &def->options[def->noptions])) {
+ return -1;
+ }
+ def->noptions++;
}
cur = cur->next;
virBufferAddLit(buf, "/>\n");
}
+ for (ii = 0 ; ii < def->noptions ; ii++) {
+ virBufferAsprintf(buf, "<option number='%u'",
+ def->options[ii].number);
+ virBufferEscapeString(buf, " value='%s'", def->options[ii].value);
+ virBufferAddLit(buf, "/>\n");
+ }
virBufferAdjustIndent(buf, -2);
virBufferAddLit(buf, "</dhcp>\n");
virSocketAddr ip;
};
+typedef struct _virNetworkDHCPOptionDef virNetworkDHCPOptionDef;
+typedef virNetworkDHCPOptionDef *virNetworkDHCPOptionDefPtr;
+struct _virNetworkDHCPOptionDef {
+ unsigned int number;
+ char *value;
+};
+
typedef struct _virNetworkDNSTxtDef virNetworkDNSTxtDef;
typedef virNetworkDNSTxtDef *virNetworkDNSTxtDefPtr;
struct _virNetworkDNSTxtDef {
size_t nhosts; /* Zero or more dhcp hosts */
virNetworkDHCPHostDefPtr hosts;
+ size_t noptions; /* Zero or more additional dhcp options */
+ virNetworkDHCPOptionDefPtr options;
+
char *tftproot;
char *bootfile;
virSocketAddr bootserver;
+
};
typedef struct _virNetworkForwardIfDef virNetworkForwardIfDef;
virBufferAsprintf(&configbuf, "dhcp-boot=%s\n", ipdef->bootfile);
}
}
+
+ for (r = 0 ; r < ipdef->noptions ; r++) {
+ virBufferAsprintf(&configbuf, "dhcp-option=%u",
+ ipdef->options[r].number);
+ /* value is optional, and only needs quoting if it contains spaces */
+ if (ipdef->options[r].value) {
+ const char *quote = "";
+
+ if (strchr(ipdef->options[r].value, ' ') ||
+ strchr(ipdef->options[r].value, '\\')) {
+ quote = "\"";
+ }
+ virBufferAsprintf(&configbuf, ",%s%s%s",
+ quote, ipdef->options[r].value, quote);
+ }
+ virBufferAddLit(&configbuf, "\n");
+ }
}
ipdef = (ipdef == ipv6def) ? NULL : ipv6def;
}
interface=virbr0
dhcp-range=192.168.122.2,192.168.122.254
dhcp-no-override
+dhcp-option=42,192.168.122.20
+dhcp-option=23,50
+dhcp-option=40,libvirt
+dhcp-option=252,"\n"
+dhcp-option=253," leading and trailing spaces "
dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases
dhcp-lease-max=253
dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile
<range start='192.168.122.2' end='192.168.122.254' />
<host mac='00:16:3e:77:e2:ed' name='a.example.com' ip='192.168.122.10' />
<host mac='00:16:3e:3e:a9:1a' name='b.example.com' ip='192.168.122.11' />
+ <option number='42' value='192.168.122.20'/>
+ <option number='23' value='50'/>
+ <option number='40' value='libvirt'/>
+ <option number='252' value='\n'/>
+ <option number='253' value=' leading and trailing spaces '/>
</dhcp>
</ip>
<ip family='ipv4' address='192.168.123.1' netmask='255.255.255.0'>
<dhcp>
<range start="192.168.122.2" end="192.168.122.254" />
<bootp file="pxeboot.img" />
+ <option number="252" value="\n"/>
</dhcp>
</ip>
</network>
<dhcp>
<range start="192.168.122.2" end="192.168.122.254" />
<bootp file="pxeboot.img" server="10.20.30.40" />
+ <option number="252" value="\n"/>
</dhcp>
</ip>
</network>
<dhcp>
<range start='192.168.122.2' end='192.168.122.254' />
<bootp file='pxeboot.img' />
+ <option number='252' value='\n'/>
</dhcp>
</ip>
</network>
<dhcp>
<range start='192.168.122.2' end='192.168.122.254' />
<bootp file='pxeboot.img' server='10.20.30.40' />
+ <option number='252' value='\n'/>
</dhcp>
</ip>
</network>