提交 383ebc46 编写于 作者: P Pieter Hollants 提交者: Laine Stump

Add support for <option> tag in network config

This patch adds support for a new <option>-Tag in the <dhcp> block of
network configs, based on a subset of the fifth proposal by Laine
Stump in the mailing list discussion at
https://www.redhat.com/archives/libvir-list/2012-November/msg01054.html.
Any such defined option will result in a dhcp-option=<number>,"<value>"
statement in the generated dnsmasq configuration file.

Currently, DHCP options can be specified by number only and there is
no whitelisting or blacklisting of option numbers, which should
probably be added.
Signed-off-by: NPieter Hollants <pieter@hollants.com>
Signed-off-by: NLaine Stump <laine@laine.org>
上级 2795813c
...@@ -293,6 +293,12 @@ ...@@ -293,6 +293,12 @@
</optional> </optional>
</element> </element>
</optional> </optional>
<zeroOrMore>
<element name="option">
<attribute name="number"><ref name="uint8range"/></attribute>
<attribute name="value"><text/></attribute>
</element>
</zeroOrMore>
</element> </element>
</optional> </optional>
</element> </element>
......
...@@ -776,6 +776,37 @@ cleanup: ...@@ -776,6 +776,37 @@ cleanup:
return ret; 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 static int
virNetworkDHCPDefParseXML(const char *networkName, virNetworkDHCPDefParseXML(const char *networkName,
xmlNodePtr node, xmlNodePtr node,
...@@ -837,6 +868,17 @@ virNetworkDHCPDefParseXML(const char *networkName, ...@@ -837,6 +868,17 @@ virNetworkDHCPDefParseXML(const char *networkName,
def->bootfile = file; def->bootfile = file;
def->bootserver = inaddr; def->bootserver = inaddr;
VIR_FREE(server); 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; cur = cur->next;
...@@ -2171,6 +2213,12 @@ virNetworkIpDefFormat(virBufferPtr buf, ...@@ -2171,6 +2213,12 @@ virNetworkIpDefFormat(virBufferPtr buf,
virBufferAddLit(buf, "/>\n"); 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); virBufferAdjustIndent(buf, -2);
virBufferAddLit(buf, "</dhcp>\n"); virBufferAddLit(buf, "</dhcp>\n");
......
...@@ -70,6 +70,13 @@ struct _virNetworkDHCPHostDef { ...@@ -70,6 +70,13 @@ struct _virNetworkDHCPHostDef {
virSocketAddr ip; virSocketAddr ip;
}; };
typedef struct _virNetworkDHCPOptionDef virNetworkDHCPOptionDef;
typedef virNetworkDHCPOptionDef *virNetworkDHCPOptionDefPtr;
struct _virNetworkDHCPOptionDef {
unsigned int number;
char *value;
};
typedef struct _virNetworkDNSTxtDef virNetworkDNSTxtDef; typedef struct _virNetworkDNSTxtDef virNetworkDNSTxtDef;
typedef virNetworkDNSTxtDef *virNetworkDNSTxtDefPtr; typedef virNetworkDNSTxtDef *virNetworkDNSTxtDefPtr;
struct _virNetworkDNSTxtDef { struct _virNetworkDNSTxtDef {
...@@ -129,9 +136,13 @@ struct _virNetworkIpDef { ...@@ -129,9 +136,13 @@ struct _virNetworkIpDef {
size_t nhosts; /* Zero or more dhcp hosts */ size_t nhosts; /* Zero or more dhcp hosts */
virNetworkDHCPHostDefPtr hosts; virNetworkDHCPHostDefPtr hosts;
size_t noptions; /* Zero or more additional dhcp options */
virNetworkDHCPOptionDefPtr options;
char *tftproot; char *tftproot;
char *bootfile; char *bootfile;
virSocketAddr bootserver; virSocketAddr bootserver;
}; };
typedef struct _virNetworkForwardIfDef virNetworkForwardIfDef; typedef struct _virNetworkForwardIfDef virNetworkForwardIfDef;
......
...@@ -926,6 +926,23 @@ networkDnsmasqConfContents(virNetworkObjPtr network, ...@@ -926,6 +926,23 @@ networkDnsmasqConfContents(virNetworkObjPtr network,
virBufferAsprintf(&configbuf, "dhcp-boot=%s\n", ipdef->bootfile); 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; ipdef = (ipdef == ipv6def) ? NULL : ipv6def;
} }
......
...@@ -12,6 +12,11 @@ bind-dynamic ...@@ -12,6 +12,11 @@ bind-dynamic
interface=virbr0 interface=virbr0
dhcp-range=192.168.122.2,192.168.122.254 dhcp-range=192.168.122.2,192.168.122.254
dhcp-no-override 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-leasefile=/var/lib/libvirt/dnsmasq/default.leases
dhcp-lease-max=253 dhcp-lease-max=253
dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile
......
...@@ -8,6 +8,11 @@ ...@@ -8,6 +8,11 @@
<range start='192.168.122.2' end='192.168.122.254' /> <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: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' /> <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> </dhcp>
</ip> </ip>
<ip family='ipv4' address='192.168.123.1' netmask='255.255.255.0'> <ip family='ipv4' address='192.168.123.1' netmask='255.255.255.0'>
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
<dhcp> <dhcp>
<range start="192.168.122.2" end="192.168.122.254" /> <range start="192.168.122.2" end="192.168.122.254" />
<bootp file="pxeboot.img" /> <bootp file="pxeboot.img" />
<option number="252" value="\n"/>
</dhcp> </dhcp>
</ip> </ip>
</network> </network>
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
<dhcp> <dhcp>
<range start="192.168.122.2" end="192.168.122.254" /> <range start="192.168.122.2" end="192.168.122.254" />
<bootp file="pxeboot.img" server="10.20.30.40" /> <bootp file="pxeboot.img" server="10.20.30.40" />
<option number="252" value="\n"/>
</dhcp> </dhcp>
</ip> </ip>
</network> </network>
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
<dhcp> <dhcp>
<range start='192.168.122.2' end='192.168.122.254' /> <range start='192.168.122.2' end='192.168.122.254' />
<bootp file='pxeboot.img' /> <bootp file='pxeboot.img' />
<option number='252' value='\n'/>
</dhcp> </dhcp>
</ip> </ip>
</network> </network>
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
<dhcp> <dhcp>
<range start='192.168.122.2' end='192.168.122.254' /> <range start='192.168.122.2' end='192.168.122.254' />
<bootp file='pxeboot.img' server='10.20.30.40' /> <bootp file='pxeboot.img' server='10.20.30.40' />
<option number='252' value='\n'/>
</dhcp> </dhcp>
</ip> </ip>
</network> </network>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册