提交 2d5cd1d7 编写于 作者: G Gene Czarcinski 提交者: Laine Stump

network: add support for DHCPv6

The DHCPv6 support includes IPV6 dhcp-range and dhcp-host for one
IPv6 subnetwork on one interface.  This support will only work
if dnsmasq version >= 2.64; otherwise an error occurs if
dhcp-range or dhcp-host is specified for an IPv6 address.

Essentially, this change provides the same DHCP support for IPv6
that has been available for IPv4.

With dnsmasq >= 2.64, support for the RA service is also now provided
by dnsmasq (radvd is no longer used/started). (Although at least one
version of dnsmasq prior to 2.64 "supported" IPv6 Router
Advertisement, there were bugs (fixed in 2.64) that rendered it
unusable.)

Documentation and the network schema has been updated
to reflect the new support.
上级 71e30eff
...@@ -583,8 +583,10 @@ ...@@ -583,8 +583,10 @@
dotted-decimal format, or an IPv6 address in standard dotted-decimal format, or an IPv6 address in standard
colon-separated hexadecimal format, that will be configured on colon-separated hexadecimal format, that will be configured on
the bridge the bridge
device associated with the virtual network. To the guests this device associated with the virtual network. To the guests this IPv4
address will be their default route. For IPv4 addresses, the <code>netmask</code> address will be their IPv4 default route. For IPv6, the default route is
established via Router Advertisement.
For IPv4 addresses, the <code>netmask</code>
attribute defines the significant bits of the network address, attribute defines the significant bits of the network address,
again specified in dotted-decimal format. For IPv6 addresses, again specified in dotted-decimal format. For IPv6 addresses,
and as an alternate method for IPv4 addresses, you can specify and as an alternate method for IPv4 addresses, you can specify
...@@ -593,10 +595,13 @@ ...@@ -593,10 +595,13 @@
could also be given as <code>prefix='24'</code>. The <code>family</code> could also be given as <code>prefix='24'</code>. The <code>family</code>
attribute is used to specify the type of address - 'ipv4' or 'ipv6'; if no attribute is used to specify the type of address - 'ipv4' or 'ipv6'; if no
<code>family</code> is given, 'ipv4' is assumed. A network can have more than <code>family</code> is given, 'ipv4' is assumed. A network can have more than
one of each family of address defined, but only a single address can have a one of each family of address defined, but only a single IPv4 address can have a
<code>dhcp</code> or <code>tftp</code> element. <span class="since">Since 0.3.0; <code>dhcp</code> or <code>tftp</code> element. <span class="since">Since 0.3.0 </span>
IPv6, multiple addresses on a single network, <code>family</code>, and IPv6, multiple addresses on a single network, <code>family</code>, and
<code>prefix</code> since 0.8.7</span> <code>prefix</code> are support <span class="since">Since 0.8.7</span>.
Similar to IPv4, one IPv6 address per network can also have
a <code>dhcp</code> definition. <span class="since">Since 1.0.1</span>
<dl> <dl>
<dt><code>tftp</code></dt> <dt><code>tftp</code></dt>
<dd>Immediately within <dd>Immediately within
...@@ -614,30 +619,44 @@ ...@@ -614,30 +619,44 @@
optional <code>dhcp</code> element. The presence of this element optional <code>dhcp</code> element. The presence of this element
enables DHCP services on the virtual network. It will further enables DHCP services on the virtual network. It will further
contain one or more <code>range</code> elements. The contain one or more <code>range</code> elements. The
<code>dhcp</code> element is not supported for IPv6, and <code>dhcp</code> element supported for both
is only supported on a single IP address per network for IPv4. IPv4 <span class="since">Since 0.3.0</span>
<span class="since">Since 0.3.0</span> and IPv6 <span class="since">Since 1.0.1</span>, but
only for one IP address of each type per network.
<dl> <dl>
<dt><code>range</code></dt> <dt><code>range</code></dt>
<dd>The <code>start</code> and <code>end</code> attributes on the <dd>The <code>start</code> and <code>end</code> attributes on the
<code>range</code> element specify the boundaries of a pool of <code>range</code> element specify the boundaries of a pool of
IPv4 addresses to be provided to DHCP clients. These two addresses addresses to be provided to DHCP clients. These two addresses
must lie within the scope of the network defined on the parent must lie within the scope of the network defined on the parent
<code>ip</code> element. <span class="since">Since 0.3.0</span> <code>ip</code> element. There may be zero or more
<code>range</code> elements specified.
<span class="since">Since 0.3.0</span>
<code>range</code> can be specified for one IPv4 address,
one IPv6 address, or both. <span class="since">Since 1.0.1</span>
</dd> </dd>
<dt><code>host</code></dt> <dt><code>host</code></dt>
<dd>Within the <code>dhcp</code> element there may be zero or more <dd>Within the <code>dhcp</code> element there may be zero or more
<code>host</code> elements; these specify hosts which will be given <code>host</code> elements. These specify hosts which will be given
names and predefined IP addresses by the built-in DHCP server. Any names and predefined IP addresses by the built-in DHCP server. Any
such element must specify the MAC address of the host to be assigned IPv4 <code>host</code> element must specify the MAC address of the host to be assigned
a given name (via the <code>mac</code> attribute), the IP to be a given name (via the <code>mac</code> attribute), the IP to be
assigned to that host (via the <code>ip</code> attribute), and the assigned to that host (via the <code>ip</code> attribute), and the
name to be given that host by the DHCP server (via 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> <code>name</code> attribute). <span class="since">Since 0.4.5</span>
An IPv6 <code>host</code> element differs slightly from that for IPv4:
there is no <code>mac</code> attribute since a MAC address has no
defined meaning in IPv6. Instead, the <code>name</code> attribute is
used to identify the host to be assigned the IPv6 address. For DHCPv6,
the name is the plain name of the client host sent by the
client to the server. Note that this method of assigning a
specific IP address can also be used instead of the <code>mac</code>
attribute for IPv4. <span class="since">Since 1.0.1</span>
</dd> </dd>
<dt><code>bootp</code></dt> <dt><code>bootp</code></dt>
<dd>The optional <code>bootp</code> <dd>The optional <code>bootp</code>
element specifies BOOTP options to be provided by the DHCP server. element specifies BOOTP options to be provided by the DHCP
server for IPv4 only.
Two attributes are supported: <code>file</code> is mandatory and Two attributes are supported: <code>file</code> is mandatory and
gives the file to be used for the boot image; <code>server</code> is gives the file to be used for the boot image; <code>server</code> is
optional and gives the address of the TFTP server from which the boot optional and gives the address of the TFTP server from which the boot
...@@ -680,6 +699,29 @@ ...@@ -680,6 +699,29 @@
&lt;ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64" /&gt; &lt;ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64" /&gt;
&lt;/network&gt;</pre> &lt;/network&gt;</pre>
<p>
Below is a variation of the above example which adds an IPv6
dhcp range definition.
</p>
<pre>
&lt;network&gt;
&lt;name&gt;default6&lt;/name&gt;
&lt;bridge name="virbr0" /&gt;
&lt;forward mode="nat"/&gt;
&lt;ip address="192.168.122.1" netmask="255.255.255.0"&gt;
&lt;dhcp&gt;
&lt;range start="192.168.122.2" end="192.168.122.254" /&gt;
&lt;/dhcp&gt;
&lt;/ip&gt;
&lt;ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64" &gt;
&lt;dhcp&gt;
&lt;range start="2001:db8:ca2:2:1::10" end="2001:db8:ca2:2:1::ff" /&gt;
&lt;/dhcp&gt;
&lt;/ip&gt;
&lt;/network&gt;</pre>
<h3><a name="examplesRoute">Routed network config</a></h3> <h3><a name="examplesRoute">Routed network config</a></h3>
<p> <p>
...@@ -704,6 +746,29 @@ ...@@ -704,6 +746,29 @@
&lt;ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64" /&gt; &lt;ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64" /&gt;
&lt;/network&gt;</pre> &lt;/network&gt;</pre>
<p>
Below is another IPv6 varition. Instead of a dhcp range being
specified, this example has a couple of IPv6 host definitions.
</p>
<pre>
&lt;network&gt;
&lt;name&gt;local6&lt;/name&gt;
&lt;bridge name="virbr1" /&gt;
&lt;forward mode="route" dev="eth1"/&gt;
&lt;ip address="192.168.122.1" netmask="255.255.255.0"&gt;
&lt;dhcp&gt;
&lt;range start="192.168.122.2" end="192.168.122.254" /&gt;
&lt;/dhcp&gt;
&lt;/ip&gt;
&lt;ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64" &gt;
&lt;dhcp&gt;
&lt;host name="paul" ip="2001:db8:ca2:2:3::1" /&gt;
&lt;host name="bob" ip="2001:db8:ca2:2:3::2" /&gt;
&lt;/dhcp&gt;
&lt;/ip&gt;
&lt;/network&gt;</pre>
<h3><a name="examplesPrivate">Isolated network config</a></h3> <h3><a name="examplesPrivate">Isolated network config</a></h3>
<p> <p>
...@@ -726,6 +791,24 @@ ...@@ -726,6 +791,24 @@
&lt;ip family="ipv6" address="2001:db8:ca2:3::1" prefix="64" /&gt; &lt;ip family="ipv6" address="2001:db8:ca2:3::1" prefix="64" /&gt;
&lt;/network&gt;</pre> &lt;/network&gt;</pre>
<h3><a name="examplesPrivate6">Isolated IPv6 network config</a></h3>
<p>
This variation of an isolated network defines only IPv6.
</p>
<pre>
&lt;network&gt;
&lt;name&gt;sixnet&lt;/name&gt;
&lt;bridge name="virbr6" /&gt;
&lt;ip family="ipv6" address="2001:db8:ca2:6::1" prefix="64" &gt;
&lt;dhcp&gt;
&lt;host name="peter" ip="2001:db8:ca2:6:6::1" /&gt;
&lt;host name="dariusz" ip="2001:db8:ca2:6:6::2" /&gt;
&lt;/dhcp&gt;
&lt;/ip&gt;
&lt;/network&gt;</pre>
<h3><a name="examplesBridge">Using an existing host bridge</a></h3> <h3><a name="examplesBridge">Using an existing host bridge</a></h3>
<p> <p>
......
...@@ -218,7 +218,7 @@ ...@@ -218,7 +218,7 @@
</zeroOrMore> </zeroOrMore>
<zeroOrMore> <zeroOrMore>
<element name="host"> <element name="host">
<attribute name="ip"><ref name="ipv4Addr"/></attribute> <attribute name="ip"><ref name="ipAddr"/></attribute>
<oneOrMore> <oneOrMore>
<element name="hostname"><ref name="dnsName"/></element> <element name="hostname"><ref name="dnsName"/></element>
</oneOrMore> </oneOrMore>
...@@ -272,15 +272,17 @@ ...@@ -272,15 +272,17 @@
<element name="dhcp"> <element name="dhcp">
<zeroOrMore> <zeroOrMore>
<element name="range"> <element name="range">
<attribute name="start"><ref name="ipv4Addr"/></attribute> <attribute name="start"><ref name="ipAddr"/></attribute>
<attribute name="end"><ref name="ipv4Addr"/></attribute> <attribute name="end"><ref name="ipAddr"/></attribute>
</element> </element>
</zeroOrMore> </zeroOrMore>
<zeroOrMore> <zeroOrMore>
<element name="host"> <element name="host">
<attribute name="mac"><ref name="uniMacAddr"/></attribute> <optional>
<attribute name="mac"><ref name="uniMacAddr"/></attribute>
</optional>
<attribute name="name"><text/></attribute> <attribute name="name"><text/></attribute>
<attribute name="ip"><ref name="ipv4Addr"/></attribute> <attribute name="ip"><ref name="ipAddr"/></attribute>
</element> </element>
</zeroOrMore> </zeroOrMore>
<optional> <optional>
......
...@@ -654,6 +654,7 @@ cleanup: ...@@ -654,6 +654,7 @@ cleanup:
static int static int
virNetworkDHCPHostDefParseXML(const char *networkName, virNetworkDHCPHostDefParseXML(const char *networkName,
const virNetworkIpDefPtr def,
xmlNodePtr node, xmlNodePtr node,
virNetworkDHCPHostDefPtr host, virNetworkDHCPHostDefPtr host,
bool partialOkay) bool partialOkay)
...@@ -665,6 +666,13 @@ virNetworkDHCPHostDefParseXML(const char *networkName, ...@@ -665,6 +666,13 @@ virNetworkDHCPHostDefParseXML(const char *networkName,
mac = virXMLPropString(node, "mac"); mac = virXMLPropString(node, "mac");
if (mac != NULL) { if (mac != NULL) {
if (VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET6)) {
virReportError(VIR_ERR_XML_ERROR,
_("Invalid to specify MAC address '%s' "
"in network '%s' IPv6 static host definition"),
mac, networkName);
goto cleanup;
}
if (virMacAddrParse(mac, &addr) < 0) { if (virMacAddrParse(mac, &addr) < 0) {
virReportError(VIR_ERR_XML_ERROR, virReportError(VIR_ERR_XML_ERROR,
_("Cannot parse MAC address '%s' in network '%s'"), _("Cannot parse MAC address '%s' in network '%s'"),
...@@ -707,10 +715,20 @@ virNetworkDHCPHostDefParseXML(const char *networkName, ...@@ -707,10 +715,20 @@ virNetworkDHCPHostDefParseXML(const char *networkName,
networkName); networkName);
} }
} else { } else {
/* normal usage - you need at least one MAC address or one host name */ /* normal usage - you need at least name (IPv6) or one of MAC
if (!(mac || name)) { * address or name (IPv4)
*/
if (VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET6)) {
if (!name) {
virReportError(VIR_ERR_XML_ERROR,
_("Static host definition in IPv6 network '%s' "
"must have name attribute"),
networkName);
goto cleanup;
}
} else if (!(mac || name)) {
virReportError(VIR_ERR_XML_ERROR, virReportError(VIR_ERR_XML_ERROR,
_("Static host definition in network '%s' " _("Static host definition in IPv4 network '%s' "
"must have mac or name attribute"), "must have mac or name attribute"),
networkName); networkName);
goto cleanup; goto cleanup;
...@@ -769,15 +787,16 @@ virNetworkDHCPDefParseXML(const char *networkName, ...@@ -769,15 +787,16 @@ virNetworkDHCPDefParseXML(const char *networkName,
virReportOOMError(); virReportOOMError();
return -1; return -1;
} }
if (virNetworkDHCPHostDefParseXML(networkName, cur, if (virNetworkDHCPHostDefParseXML(networkName, def, cur,
&def->hosts[def->nhosts], &def->hosts[def->nhosts],
false) < 0) { false) < 0) {
return -1; return -1;
} }
def->nhosts++; def->nhosts++;
} else if (cur->type == XML_ELEMENT_NODE && } else if (VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET) &&
xmlStrEqual(cur->name, BAD_CAST "bootp")) { cur->type == XML_ELEMENT_NODE &&
xmlStrEqual(cur->name, BAD_CAST "bootp")) {
char *file; char *file;
char *server; char *server;
virSocketAddr inaddr; virSocketAddr inaddr;
...@@ -1189,30 +1208,29 @@ virNetworkIPDefParseXML(const char *networkName, ...@@ -1189,30 +1208,29 @@ virNetworkIPDefParseXML(const char *networkName,
} }
} }
if (VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET)) { cur = node->children;
/* parse IPv4-related info */ while (cur != NULL) {
cur = node->children; if (cur->type == XML_ELEMENT_NODE &&
while (cur != NULL) { xmlStrEqual(cur->name, BAD_CAST "dhcp")) {
if (cur->type == XML_ELEMENT_NODE && if (virNetworkDHCPDefParseXML(networkName, cur, def) < 0)
xmlStrEqual(cur->name, BAD_CAST "dhcp")) { goto cleanup;
result = virNetworkDHCPDefParseXML(networkName, cur, def); } else if (cur->type == XML_ELEMENT_NODE &&
if (result) xmlStrEqual(cur->name, BAD_CAST "tftp")) {
goto cleanup; char *root;
} else if (cur->type == XML_ELEMENT_NODE &&
xmlStrEqual(cur->name, BAD_CAST "tftp")) {
char *root;
if (!(root = virXMLPropString(cur, "root"))) {
cur = cur->next;
continue;
}
def->tftproot = (char *)root; if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Unsupported <tftp> element in an IPv6 element in network '%s'"),
networkName);
goto cleanup;
} }
if (!(root = virXMLPropString(cur, "root"))) {
cur = cur->next; cur = cur->next;
continue;
}
def->tftproot = (char *)root;
} }
cur = cur->next;
} }
result = 0; result = 0;
...@@ -2494,11 +2512,9 @@ virNetworkIpDefByIndex(virNetworkDefPtr def, int parentIndex) ...@@ -2494,11 +2512,9 @@ virNetworkIpDefByIndex(virNetworkDefPtr def, int parentIndex)
/* first find which ip element's dhcp host list to work on */ /* first find which ip element's dhcp host list to work on */
if (parentIndex >= 0) { if (parentIndex >= 0) {
ipdef = virNetworkDefGetIpByIndex(def, AF_UNSPEC, parentIndex); ipdef = virNetworkDefGetIpByIndex(def, AF_UNSPEC, parentIndex);
if (!(ipdef && if (!(ipdef)) {
VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET))) {
virReportError(VIR_ERR_OPERATION_INVALID, virReportError(VIR_ERR_OPERATION_INVALID,
_("couldn't update dhcp host entry - " _("couldn't update dhcp host entry - no <ip> "
"no <ip family='ipv4'> "
"element found at index %d in network '%s'"), "element found at index %d in network '%s'"),
parentIndex, def->name); parentIndex, def->name);
} }
...@@ -2511,17 +2527,17 @@ virNetworkIpDefByIndex(virNetworkDefPtr def, int parentIndex) ...@@ -2511,17 +2527,17 @@ virNetworkIpDefByIndex(virNetworkDefPtr def, int parentIndex)
for (ii = 0; for (ii = 0;
(ipdef = virNetworkDefGetIpByIndex(def, AF_UNSPEC, ii)); (ipdef = virNetworkDefGetIpByIndex(def, AF_UNSPEC, ii));
ii++) { ii++) {
if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET) && if (ipdef->nranges || ipdef->nhosts)
(ipdef->nranges || ipdef->nhosts)) {
break; break;
}
} }
if (!ipdef) if (!ipdef) {
ipdef = virNetworkDefGetIpByIndex(def, AF_INET, 0); ipdef = virNetworkDefGetIpByIndex(def, AF_INET, 0);
if (!ipdef)
ipdef = virNetworkDefGetIpByIndex(def, AF_INET6, 0);
}
if (!ipdef) { if (!ipdef) {
virReportError(VIR_ERR_OPERATION_INVALID, virReportError(VIR_ERR_OPERATION_INVALID,
_("couldn't update dhcp host entry - " _("couldn't update dhcp host entry - no <ip> "
"no <ip family='ipv4'> "
"element found in network '%s'"), def->name); "element found in network '%s'"), def->name);
} }
return ipdef; return ipdef;
...@@ -2551,8 +2567,10 @@ virNetworkDefUpdateIPDHCPHost(virNetworkDefPtr def, ...@@ -2551,8 +2567,10 @@ virNetworkDefUpdateIPDHCPHost(virNetworkDefPtr def,
/* parse the xml into a virNetworkDHCPHostDef */ /* parse the xml into a virNetworkDHCPHostDef */
if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY) { if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY) {
if (virNetworkDHCPHostDefParseXML(def->name, ctxt->node, &host, false) < 0) if (virNetworkDHCPHostDefParseXML(def->name, ipdef,
ctxt->node, &host, false) < 0) {
goto cleanup; goto cleanup;
}
/* search for the entry with this (mac|name), /* search for the entry with this (mac|name),
* and update the IP+(mac|name) */ * and update the IP+(mac|name) */
...@@ -2584,8 +2602,10 @@ virNetworkDefUpdateIPDHCPHost(virNetworkDefPtr def, ...@@ -2584,8 +2602,10 @@ virNetworkDefUpdateIPDHCPHost(virNetworkDefPtr def,
} else if ((command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST) || } else if ((command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST) ||
(command == VIR_NETWORK_UPDATE_COMMAND_ADD_LAST)) { (command == VIR_NETWORK_UPDATE_COMMAND_ADD_LAST)) {
if (virNetworkDHCPHostDefParseXML(def->name, ctxt->node, &host, true) < 0) if (virNetworkDHCPHostDefParseXML(def->name, ipdef,
ctxt->node, &host, true) < 0) {
goto cleanup; goto cleanup;
}
/* log error if an entry with same name/address/ip already exists */ /* log error if an entry with same name/address/ip already exists */
for (ii = 0; ii < ipdef->nhosts; ii++) { for (ii = 0; ii < ipdef->nhosts; ii++) {
...@@ -2618,8 +2638,10 @@ virNetworkDefUpdateIPDHCPHost(virNetworkDefPtr def, ...@@ -2618,8 +2638,10 @@ virNetworkDefUpdateIPDHCPHost(virNetworkDefPtr def,
} }
} else if (command == VIR_NETWORK_UPDATE_COMMAND_DELETE) { } else if (command == VIR_NETWORK_UPDATE_COMMAND_DELETE) {
if (virNetworkDHCPHostDefParseXML(def->name, ctxt->node, &host, false) < 0) if (virNetworkDHCPHostDefParseXML(def->name, ipdef,
ctxt->node, &host, false) < 0) {
goto cleanup; goto cleanup;
}
/* find matching entry - all specified attributes must match */ /* find matching entry - all specified attributes must match */
for (ii = 0; ii < ipdef->nhosts; ii++) { for (ii = 0; ii < ipdef->nhosts; ii++) {
......
此差异已折叠。
...@@ -293,11 +293,15 @@ hostsfileFree(dnsmasqHostsfile *hostsfile) ...@@ -293,11 +293,15 @@ hostsfileFree(dnsmasqHostsfile *hostsfile)
VIR_FREE(hostsfile); VIR_FREE(hostsfile);
} }
/* Note: There are many additional dhcp-host specifications
* supported by dnsmasq. There are only the basic ones.
*/
static int static int
hostsfileAdd(dnsmasqHostsfile *hostsfile, hostsfileAdd(dnsmasqHostsfile *hostsfile,
const char *mac, const char *mac,
virSocketAddr *ip, virSocketAddr *ip,
const char *name) const char *name,
bool ipv6)
{ {
char *ipstr = NULL; char *ipstr = NULL;
if (VIR_REALLOC_N(hostsfile->hosts, hostsfile->nhosts + 1) < 0) if (VIR_REALLOC_N(hostsfile->hosts, hostsfile->nhosts + 1) < 0)
...@@ -306,16 +310,24 @@ hostsfileAdd(dnsmasqHostsfile *hostsfile, ...@@ -306,16 +310,24 @@ hostsfileAdd(dnsmasqHostsfile *hostsfile,
if (!(ipstr = virSocketAddrFormat(ip))) if (!(ipstr = virSocketAddrFormat(ip)))
return -1; return -1;
if (name) { /* the first test determines if it is a dhcpv6 host */
if (ipv6) {
if (virAsprintf(&hostsfile->hosts[hostsfile->nhosts].host, "%s,[%s]",
name, ipstr) < 0)
goto alloc_error;
}
else if (name && mac) {
if (virAsprintf(&hostsfile->hosts[hostsfile->nhosts].host, "%s,%s,%s", if (virAsprintf(&hostsfile->hosts[hostsfile->nhosts].host, "%s,%s,%s",
mac, ipstr, name) < 0) { mac, ipstr, name) < 0)
goto alloc_error;
} else if (name && !mac){
if (virAsprintf(&hostsfile->hosts[hostsfile->nhosts].host, "%s,%s",
name, ipstr) < 0)
goto alloc_error; goto alloc_error;
}
} else { } else {
if (virAsprintf(&hostsfile->hosts[hostsfile->nhosts].host, "%s,%s", if (virAsprintf(&hostsfile->hosts[hostsfile->nhosts].host, "%s,%s",
mac, ipstr) < 0) { mac, ipstr) < 0)
goto alloc_error; goto alloc_error;
}
} }
VIR_FREE(ipstr); VIR_FREE(ipstr);
...@@ -496,9 +508,10 @@ int ...@@ -496,9 +508,10 @@ int
dnsmasqAddDhcpHost(dnsmasqContext *ctx, dnsmasqAddDhcpHost(dnsmasqContext *ctx,
const char *mac, const char *mac,
virSocketAddr *ip, virSocketAddr *ip,
const char *name) const char *name,
bool ipv6)
{ {
return hostsfileAdd(ctx->hostsfile, mac, ip, name); return hostsfileAdd(ctx->hostsfile, mac, ip, name, ipv6);
} }
/* /*
......
...@@ -82,7 +82,8 @@ void dnsmasqContextFree(dnsmasqContext *ctx); ...@@ -82,7 +82,8 @@ void dnsmasqContextFree(dnsmasqContext *ctx);
int dnsmasqAddDhcpHost(dnsmasqContext *ctx, int dnsmasqAddDhcpHost(dnsmasqContext *ctx,
const char *mac, const char *mac,
virSocketAddr *ip, virSocketAddr *ip,
const char *name); const char *name,
bool ipv6);
int dnsmasqAddHost(dnsmasqContext *ctx, int dnsmasqAddHost(dnsmasqContext *ctx,
virSocketAddr *ip, virSocketAddr *ip,
const char *name); const char *name);
...@@ -99,4 +100,18 @@ int dnsmasqCapsRefresh(dnsmasqCapsPtr *caps, const char *binaryPath); ...@@ -99,4 +100,18 @@ int dnsmasqCapsRefresh(dnsmasqCapsPtr *caps, const char *binaryPath);
bool dnsmasqCapsGet(dnsmasqCapsPtr caps, dnsmasqCapsFlags flag); bool dnsmasqCapsGet(dnsmasqCapsPtr caps, dnsmasqCapsFlags flag);
const char *dnsmasqCapsGetBinaryPath(dnsmasqCapsPtr caps); const char *dnsmasqCapsGetBinaryPath(dnsmasqCapsPtr caps);
unsigned long dnsmasqCapsGetVersion(dnsmasqCapsPtr caps); unsigned long dnsmasqCapsGetVersion(dnsmasqCapsPtr caps);
# define DNSMASQ_DHCPv6_MAJOR_REQD 2
# define DNSMASQ_DHCPv6_MINOR_REQD 64
# define DNSMASQ_RA_MAJOR_REQD 2
# define DNSMASQ_RA_MINOR_REQD 64
# define DNSMASQ_DHCPv6_SUPPORT(CAPS) \
(dnsmasqCapsGetVersion(CAPS) >= \
(DNSMASQ_DHCPv6_MAJOR_REQD * 1000000) + \
(DNSMASQ_DHCPv6_MINOR_REQD * 1000))
# define DNSMASQ_RA_SUPPORT(CAPS) \
(dnsmasqCapsGetVersion(CAPS) >= \
(DNSMASQ_RA_MAJOR_REQD * 1000000) + \
(DNSMASQ_RA_MINOR_REQD * 1000))
#endif /* __DNSMASQ_H__ */ #endif /* __DNSMASQ_H__ */
@DNSMASQ@ \
--strict-order \
--domain-needed \
--local=// \
--conf-file= \
--bind-dynamic \
--interface virbr0 \
--dhcp-range 192.168.122.2,192.168.122.254 \
--dhcp-no-override \
--dhcp-range 2001:db8:ac10:fd01::1:10,2001:db8:ac10:fd01::1:ff \
--dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases \
--dhcp-lease-max=493 \
--dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile \
--addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts \
--enable-ra\
<network>
<name>default</name>
<uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
<forward dev='eth1' mode='nat'/>
<bridge name='virbr0' stp='on' delay='0' />
<ip address='192.168.122.1' netmask='255.255.255.0'>
<dhcp>
<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' />
</dhcp>
</ip>
<ip family='ipv4' address='192.168.123.1' netmask='255.255.255.0'>
</ip>
<ip family='ipv6' address='2001:db8:ac10:fd01::1' prefix='64'>
<dhcp>
<range start='2001:db8:ac10:fd01::1:10' end='2001:db8:ac10:fd01::1:ff' />
<host name='ralph' ip='2001:db8:ac10:fd01::1:20' />
<host name='paul' ip='2001:db8:ac10:fd01::1:21' />
</dhcp>
</ip>
<ip family='ipv4' address='10.24.10.1'>
</ip>
</network>
@DNSMASQ@ \
--strict-order \
--domain-needed \
--domain=mynet \
--expand-hosts \
--local=/mynet/ \
--conf-file= \
--bind-dynamic \
--interface virbr0 \
--dhcp-range 2001:db8:ac10:fd01::1:10,2001:db8:ac10:fd01::1:ff \
--dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases \
--dhcp-lease-max=240 \
--dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile \
--addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts \
--enable-ra\
<network>
<name>default</name>
<uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
<forward dev='eth1' mode='nat'/>
<bridge name='virbr0' stp='on' delay='0' />
<domain name='mynet'/>
<ip family='ipv6' address='2001:db8:ac10:fd01::1' prefix='64'>
<dhcp>
<range start='2001:db8:ac10:fd01::1:10' end='2001:db8:ac10:fd01::1:ff' />
<host name='ralph' ip='2001:db8:ac10:fd01::1:20' />
<host name='paul' ip='2001:db8:ac10:fd01::1:21' />
</dhcp>
</ip>
</network>
@DNSMASQ@ \
--strict-order \
--domain-needed \
--local=// \
--conf-file= \
--bind-dynamic \
--interface virbr1 \
--dhcp-range 192.168.122.1,static \
--dhcp-no-override \
--dhcp-range 2001:db8:ac10:fd01::1,static \
--dhcp-hostsfile=/var/lib/libvirt/dnsmasq/local.hostsfile \
--addn-hosts=/var/lib/libvirt/dnsmasq/local.addnhosts \
--enable-ra\
<network>
<name>local</name>
<uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
<forward dev='eth1' mode='route'/>
<bridge name='virbr1' stp='on' delay='0' />
<mac address='12:34:56:78:9A:BC'/>
<ip address='192.168.122.1' netmask='255.255.255.0'>
<dhcp>
<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' />
</dhcp>
</ip>
<ip family='ipv6' address='2001:db8:ac10:fd01::1' prefix='64'>
<dhcp>
<host name='ralph' ip='2001:db8:ac10:fd01::1:20' />
<host name='paul' ip='2001:db8:ac10:fd01::1:21' />
</dhcp>
</ip>
</network>
@DNSMASQ@ --strict-order \ @DNSMASQ@ \
--local=// --domain-needed --conf-file= \ --strict-order \
--bind-interfaces --except-interface lo \ --domain-needed \
--local=// \
--conf-file= \
--bind-interfaces \
--except-interface lo \
--listen-address 192.168.152.1 \ --listen-address 192.168.152.1 \
--dhcp-option=3 --no-resolv \ --dhcp-option=3 \
--no-resolv \
--dhcp-range 192.168.152.2,192.168.152.254 \ --dhcp-range 192.168.152.2,192.168.152.254 \
--dhcp-leasefile=/var/lib/libvirt/dnsmasq/private.leases --dhcp-lease-max=253 \
--dhcp-no-override \ --dhcp-no-override \
--dhcp-leasefile=/var/lib/libvirt/dnsmasq/private.leases \
--dhcp-lease-max=253 \
--dhcp-hostsfile=/var/lib/libvirt/dnsmasq/private.hostsfile \ --dhcp-hostsfile=/var/lib/libvirt/dnsmasq/private.hostsfile \
--addn-hosts=/var/lib/libvirt/dnsmasq/private.addnhosts\ --addn-hosts=/var/lib/libvirt/dnsmasq/private.addnhosts\
@DNSMASQ@ --strict-order --domain=example.com \ @DNSMASQ@ \
--local=/example.com/ --domain-needed \ --strict-order \
--domain-needed \
--domain=example.com \
--expand-hosts \
--local=/example.com/ \
--conf-file= \ --conf-file= \
--bind-dynamic --interface virbr0 \ --bind-dynamic \
--expand-hosts --addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts\ --interface virbr0 \
--addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts\
@DNSMASQ@ \ @DNSMASQ@ \
--strict-order \ --strict-order \
--local=// --domain-needed --conf-file= \ --domain-needed \
--bind-interfaces --except-interface lo \ --local=// \
--conf-file= \
--bind-interfaces \
--except-interface lo \
--listen-address 192.168.122.1 \ --listen-address 192.168.122.1 \
--listen-address 192.168.123.1 \ --listen-address 192.168.123.1 \
--listen-address fc00:db8:ac10:fe01::1 \ --listen-address fc00:db8:ac10:fe01::1 \
...@@ -9,8 +12,8 @@ ...@@ -9,8 +12,8 @@
--listen-address 10.24.10.1 \ --listen-address 10.24.10.1 \
--srv-host=name.tcp.,,,, \ --srv-host=name.tcp.,,,, \
--dhcp-range 192.168.122.2,192.168.122.254 \ --dhcp-range 192.168.122.2,192.168.122.254 \
--dhcp-no-override \
--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-no-override \
--dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile \ --dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile \
--addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts\ --addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts\
@DNSMASQ@ \ @DNSMASQ@ \
--strict-order \ --strict-order \
--local=// --domain-needed --conf-file= \ --domain-needed \
--bind-dynamic --interface virbr0 \ --local=// \
--conf-file= \
--bind-dynamic \
--interface virbr0 \
--srv-host=name.tcp.test-domain-name,.,1024,10,10 \ --srv-host=name.tcp.test-domain-name,.,1024,10,10 \
--dhcp-range 192.168.122.2,192.168.122.254 \ --dhcp-range 192.168.122.2,192.168.122.254 \
--dhcp-no-override \
--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-no-override \
--dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile \ --dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile \
--addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts\ --addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts\
@DNSMASQ@ --strict-order \ @DNSMASQ@ \
--local=// --domain-needed --conf-file= \ --strict-order \
--domain-needed \
--local=// \
--conf-file= \
--bind-dynamic --interface virbr0 \ --bind-dynamic --interface virbr0 \
'--txt-record=example,example value' \ '--txt-record=example,example value' \
--dhcp-range 192.168.122.2,192.168.122.254 \ --dhcp-range 192.168.122.2,192.168.122.254 \
--dhcp-no-override \
--dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases \ --dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases \
--dhcp-lease-max=253 --dhcp-no-override \ --dhcp-lease-max=253 \
--dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile \ --dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile \
--addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts\ --addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts\
@DNSMASQ@ --strict-order \ @DNSMASQ@ \
--local=// --domain-needed --conf-file= \ --strict-order \
--bind-dynamic --interface virbr0 \ --domain-needed \
--local=// \
--conf-file= \
--bind-dynamic \
--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-leasefile=/var/lib/libvirt/dnsmasq/default.leases \ --dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases \
--dhcp-lease-max=253 --dhcp-no-override \ --dhcp-lease-max=253 \
--dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile \ --dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile \
--addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts\ --addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts \
--dhcp-range=2001:db8:ac10:fe01::1,ra-only \
--dhcp-range=2001:db8:ac10:fd01::1,ra-only\
@DNSMASQ@ --strict-order --domain=example.com \ @DNSMASQ@ \
--local=/example.com/ --domain-needed --conf-file= \ --strict-order \
--bind-interfaces --except-interface lo --listen-address 192.168.122.1 \ --domain-needed \
--domain=example.com \
--expand-hosts \
--local=/example.com/ \
--conf-file= \
--bind-interfaces \
--except-interface lo \
--listen-address 192.168.122.1 \
--dhcp-range 192.168.122.2,192.168.122.254 \ --dhcp-range 192.168.122.2,192.168.122.254 \
--dhcp-no-override \
--enable-tftp \
--tftp-root /var/lib/tftproot \
--dhcp-boot pxeboot.img \
--dhcp-leasefile=/var/lib/libvirt/dnsmasq/netboot.leases \ --dhcp-leasefile=/var/lib/libvirt/dnsmasq/netboot.leases \
--dhcp-lease-max=253 --dhcp-no-override --expand-hosts \ --dhcp-lease-max=253 \
--dhcp-hostsfile=/var/lib/libvirt/dnsmasq/netboot.hostsfile \ --dhcp-hostsfile=/var/lib/libvirt/dnsmasq/netboot.hostsfile \
--addn-hosts=/var/lib/libvirt/dnsmasq/netboot.addnhosts \ --addn-hosts=/var/lib/libvirt/dnsmasq/netboot.addnhosts\
--enable-tftp \
--tftp-root /var/lib/tftproot --dhcp-boot pxeboot.img\
@DNSMASQ@ --strict-order --domain=example.com \ @DNSMASQ@ \
--local=/example.com/ --domain-needed --conf-file= \ --strict-order \
--bind-interfaces --except-interface lo \ --domain-needed \
--domain=example.com \
--expand-hosts \
--local=/example.com/ \
--conf-file= \
--bind-interfaces \
--except-interface lo \
--listen-address 192.168.122.1 \ --listen-address 192.168.122.1 \
--dhcp-range 192.168.122.2,192.168.122.254 \ --dhcp-range 192.168.122.2,192.168.122.254 \
--dhcp-no-override \
--dhcp-boot pxeboot.img,,10.20.30.40 \
--dhcp-leasefile=/var/lib/libvirt/dnsmasq/netboot.leases \ --dhcp-leasefile=/var/lib/libvirt/dnsmasq/netboot.leases \
--dhcp-lease-max=253 --dhcp-no-override --expand-hosts \ --dhcp-lease-max=253 \
--dhcp-hostsfile=/var/lib/libvirt/dnsmasq/netboot.hostsfile \ --dhcp-hostsfile=/var/lib/libvirt/dnsmasq/netboot.hostsfile \
--addn-hosts=/var/lib/libvirt/dnsmasq/netboot.addnhosts \ --addn-hosts=/var/lib/libvirt/dnsmasq/netboot.addnhosts\
--dhcp-boot pxeboot.img,,10.20.30.40\
@DNSMASQ@ --strict-order \ @DNSMASQ@ \
--local=// --domain-needed --conf-file= \ --strict-order \
--bind-dynamic --interface virbr1 \ --domain-needed \
--local=// \
--conf-file= \
--bind-dynamic \
--interface virbr1 \
--addn-hosts=/var/lib/libvirt/dnsmasq/local.addnhosts\ --addn-hosts=/var/lib/libvirt/dnsmasq/local.addnhosts\
...@@ -152,6 +152,8 @@ mymain(void) ...@@ -152,6 +152,8 @@ mymain(void)
= dnsmasqCapsNewFromBuffer("Dnsmasq version 2.48", DNSMASQ); = dnsmasqCapsNewFromBuffer("Dnsmasq version 2.48", DNSMASQ);
dnsmasqCapsPtr full dnsmasqCapsPtr full
= dnsmasqCapsNewFromBuffer("Dnsmasq version 2.63\n--bind-dynamic", DNSMASQ); = dnsmasqCapsNewFromBuffer("Dnsmasq version 2.63\n--bind-dynamic", DNSMASQ);
dnsmasqCapsPtr dhcpv6
= dnsmasqCapsNewFromBuffer("Dnsmasq version 2.64\n--bind-dynamic", DNSMASQ);
networkDnsmasqLeaseFileName = testDnsmasqLeaseFileName; networkDnsmasqLeaseFileName = testDnsmasqLeaseFileName;
...@@ -172,10 +174,13 @@ mymain(void) ...@@ -172,10 +174,13 @@ mymain(void)
DO_TEST("netboot-proxy-network", restricted); DO_TEST("netboot-proxy-network", restricted);
DO_TEST("nat-network-dns-srv-record-minimal", restricted); DO_TEST("nat-network-dns-srv-record-minimal", restricted);
DO_TEST("routed-network", full); DO_TEST("routed-network", full);
DO_TEST("nat-network", full); DO_TEST("nat-network", dhcpv6);
DO_TEST("nat-network-dns-txt-record", full); DO_TEST("nat-network-dns-txt-record", full);
DO_TEST("nat-network-dns-srv-record", full); DO_TEST("nat-network-dns-srv-record", full);
DO_TEST("nat-network-dns-hosts", full); DO_TEST("nat-network-dns-hosts", full);
DO_TEST("dhcp6-network", dhcpv6);
DO_TEST("dhcp6-nat-network", dhcpv6);
DO_TEST("dhcp6host-routed-network", dhcpv6);
return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE; return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册