[libvirt] [PATCH] handle DNS over IPv6

Firstly: Add ip6tables rules to allow DNS over IPv6 in network. Secondly: start dnsmasq with --interface option instead of --listen-address. Dnsmasq currently uses "--listen-address IPv4_address" option, which restricts DNS service to one IPv4 address only. We could append --listen-address for every IPv[46] address defined on interface, but it's cleaner to use "--interface brname". There were some problems in the past with --interface option. Dnsmasq version 2.46 and earlier exited with error when tired to bind() to IPv6 addresses on just brought up interfaces, because DAD (Duplicate Address Detection) takes some time to finish and bind() returns EADDRNOTAVAIL which caused dnsmasq to exit. Dnsmasq version 2.47 (released on 05-Feb-2009) fixed this issue by retrying bind() after getting EADDRNOTAVAIL error (as described in http://www.thekelleys.org.uk/dnsmasq/CHANGELOG; loop itself is defined in dnsmasq-2.47/src/network.c:404) * Using --interface option causes longer network startup: $ time virsh -c qemu:///system net-start isolated1 Network isolated1 started real 0m0.112s user 0m0.013s sys 0m0.009s $ time virsh -c qemu:///system net-start isolated1 Network isolated1 started real 0m2.101s user 0m0.011s sys 0m0.011s * Dnsmasq exits after DAD complets which guarantees that radvd will no more produces following warnings: Dec 28 19:42:11 nemo radvd[14652]: sendmsg: Invalid argument --- src/network/bridge_driver.c | 32 +++++++++++++++++++++++++------- 1 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 7d43ef5..a689c9f 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -469,16 +469,13 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network, virCommandAddArgList(cmd, "--conf-file=", "", NULL); /* - * XXX does not actually work, due to some kind of - * race condition setting up ipv6 addresses on the - * interface. A sleep(10) makes it work, but that's - * clearly not practical + * It's safe to use --interface option for dnsmasq 2.47 and later. + * With earlier versions we had to use --listen-address option. * - * virCommandAddArg(cmd, "--interface"); - * virCommandAddArg(cmd, ipdef->bridge); + * virCommandAddArgList(cmd, "--listen-address", bridgeaddr); */ virCommandAddArgList(cmd, - "--listen-address", bridgeaddr, + "--interface", network->def->bridge, "--except-interface", "lo", NULL); @@ -1157,9 +1154,30 @@ networkAddGeneralIptablesRules(struct network_driver *driver, goto err9; } + /* allow DNS over IPv6 requests through to dnsmasq */ + if (iptablesAddTcpInput(driver->iptables, AF_INET6, + network->def->bridge, 53) < 0) { + networkReportError(VIR_ERR_SYSTEM_ERROR, + _("failed to add ip6tables rule to allow DNS requests from '%s'"), + network->def->bridge); + goto err10; + } + + if (iptablesAddUdpInput(driver->iptables, AF_INET6, + network->def->bridge, 53) < 0) { + networkReportError(VIR_ERR_SYSTEM_ERROR, + _("failed to add ip6tables rule to allow DNS requests from '%s'"), + network->def->bridge); + goto err11; + } + return 0; /* unwind in reverse order from the point of failure */ +err11: + iptablesRemoveTcpInput(driver->iptables, AF_INET6, network->def->bridge, 53); +err10: + networkRemoveGeneralIp6tablesRules(driver, network); err9: iptablesRemoveForwardAllowCross(driver->iptables, AF_INET, network->def->bridge); err8:

On 12/29/2010 10:00 AM, Paweł Krześniak wrote:
Firstly: Add ip6tables rules to allow DNS over IPv6 in network.
Secondly: start dnsmasq with --interface option instead of --listen-address.
Dnsmasq currently uses "--listen-address IPv4_address" option, which restricts DNS service to one IPv4 address only. We could append --listen-address for every IPv[46] address defined on interface, but it's cleaner to use "--interface brname".
There were some problems in the past with --interface option. Dnsmasq version 2.46 and earlier exited with error when tired to bind() to IPv6 addresses on just brought up interfaces, because DAD (Duplicate Address Detection) takes some time to finish and bind() returns EADDRNOTAVAIL which caused dnsmasq to exit. Dnsmasq version 2.47 (released on 05-Feb-2009) fixed this issue by retrying bind() after getting EADDRNOTAVAIL error (as described in http://www.thekelleys.org.uk/dnsmasq/CHANGELOG; loop itself is defined in dnsmasq-2.47/src/network.c:404)
In general this would be a good change to have. I'm not certain how careful we need to be about preserving compatibility with any platform that is still using dnsmasq older than 2.47, though. Dan or Dan, would you like to weigh in on that?
* Using --interface option causes longer network startup: $ time virsh -c qemu:///system net-start isolated1 Network isolated1 started
real 0m0.112s user 0m0.013s sys 0m0.009s
$ time virsh -c qemu:///system net-start isolated1 Network isolated1 started
real 0m2.101s user 0m0.011s sys 0m0.011s
Not ideal, but not a big deal in the larger scheme of things...
* Dnsmasq exits after DAD complets which guarantees that radvd will no more produces following warnings: Dec 28 19:42:11 nemo radvd[14652]: sendmsg: Invalid argument
That's a good argument for putting in the change.
--- src/network/bridge_driver.c | 32 +++++++++++++++++++++++++------- 1 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 7d43ef5..a689c9f 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -469,16 +469,13 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network, virCommandAddArgList(cmd, "--conf-file=", "", NULL);
/* - * XXX does not actually work, due to some kind of - * race condition setting up ipv6 addresses on the - * interface. A sleep(10) makes it work, but that's - * clearly not practical + * It's safe to use --interface option for dnsmasq 2.47 and later. + * With earlier versions we had to use --listen-address option. * - * virCommandAddArg(cmd, "--interface"); - * virCommandAddArg(cmd, ipdef->bridge); + * virCommandAddArgList(cmd, "--listen-address", bridgeaddr);
This is just a comment, but still might as well be correct - virCommandArgList needs to end with a NULL arg ;-)
*/ virCommandAddArgList(cmd, - "--listen-address", bridgeaddr, + "--interface", network->def->bridge, "--except-interface", "lo", NULL);
@@ -1157,9 +1154,30 @@ networkAddGeneralIptablesRules(struct network_driver *driver, goto err9; }
+ /* allow DNS over IPv6 requests through to dnsmasq */ + if (iptablesAddTcpInput(driver->iptables, AF_INET6, + network->def->bridge, 53)< 0) { + networkReportError(VIR_ERR_SYSTEM_ERROR, + _("failed to add ip6tables rule to allow DNS requests from '%s'"), + network->def->bridge); + goto err10; + } + + if (iptablesAddUdpInput(driver->iptables, AF_INET6, + network->def->bridge, 53)< 0) { + networkReportError(VIR_ERR_SYSTEM_ERROR, + _("failed to add ip6tables rule to allow DNS requests from '%s'"), + network->def->bridge); + goto err11; + } +
These rules should be added in networkAddGeneralIp6tablesRules() rather then in networkAddGeneralIptablesRules.
return 0;
/* unwind in reverse order from the point of failure */ +err11: + iptablesRemoveTcpInput(driver->iptables, AF_INET6, network->def->bridge, 53); +err10: + networkRemoveGeneralIp6tablesRules(driver, network); err9: iptablesRemoveForwardAllowCross(driver->iptables, AF_INET, network->def->bridge); err8:
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list

Thanks for comments. v2 attached. Sorry, but my two previous patches don't apply because of line-wrapping issues. -- Pawel

On Mon, Jan 03, 2011 at 04:57:52PM +0100, Paweł Krześniak wrote:
handle DNS over IPv6
Firstly: Add ip6tables rules to allow DNS over IPv6 in network.
Secondly: start dnsmasq with --interface option instead of --listen-address.
Dnsmasq currently uses "--listen-address IPv4_address" option, which restricts DNS service to one IPv4 address only. We could append --listen-address for every IPv[46] address defined on interface, but it's cleaner to use "--interface brname".
While it is shorter to just use '--interface brname' this comes at the price of loosing compatibility with older dnsmasq which we still wish to support. If we used '--listen-address $IPV4ADDR --listen-address $IPV6ADDR' then people with dnsmasq < 2.48 can still use the virtual network capability in a IPv4 only context without problems. Only those people who actually needed IPv6 DNS would have to upgrade to newer dnsmasq.
There were some problems in the past with --interface option. Dnsmasq version 2.46 and earlier exited with error when tired to bind() to IPv6 addresses on just brought up interfaces, because DAD (Duplicate Address Detection) takes some time to finish and bind() returns EADDRNOTAVAIL which caused dnsmasq to exit. Dnsmasq version 2.47 (released on 05-Feb-2009) fixed this issue by retrying bind() after getting EADDRNOTAVAIL error (as described in http://www.thekelleys.org.uk/dnsmasq/CHANGELOG; loop itself is defined in dnsmasq-2.47/src/network.c:404)
* Using --interface option causes longer network startup: $ time virsh -c qemu:///system net-start isolated1 Network isolated1 started
real 0m0.112s user 0m0.013s sys 0m0.009s
$ time virsh -c qemu:///system net-start isolated1 Network isolated1 started
real 0m2.101s user 0m0.011s sys 0m0.011s
Do you have any idea what causes the delay ? In particular is the delay caused by the use of --listen-interface, or caused by the addition of IPv6 addrs ? Based on your descriptions here it sounds like going for multiple --listen-address parameters offers the same level of overall functionality, but with better compatibility for people on older dnsmasq. So I'm not seeing a compelling reason to switch over to using --listen-interface Regards, Daniel

2011/1/6 Daniel P. Berrange <berrange@redhat.com>:
While it is shorter to just use '--interface brname' this comes at the price of loosing compatibility with older dnsmasq which we still wish to support.
sure. RHEL5 is important target :)
If we used '--listen-address $IPV4ADDR --listen-address $IPV6ADDR' then people with dnsmasq < 2.48 can still use the virtual network capability in a IPv4 only context without problems. Only those people who actually needed IPv6 DNS would have to upgrade to newer dnsmasq.
hack for users of old dnsmasq and ipv6 needs is nodad option for /sbin/ip tool - read below.
Do you have any idea what causes the delay ? In particular is the delay caused by the use of --listen-interface, or caused by the addition of IPv6 addrs ?
Delay is caused by DAD. http://en.wikipedia.org/wiki/IPv6_address#Duplicate_address_detection It's caused by IPv6 address, not by --listen-interface option: # killall dnsmasq ; ip a del 2001:db8::1 dev wlan0 ; ip a add 2001:db8::1 dev wlan0 ; time dnsmasq --strict-order --bind-interfaces --conf-file= --except-interface lo --listen-address 2001:db8::1 dnsmasq: no process killed real 0m2.008s user 0m0.000s sys 0m0.006s # killall dnsmasq ; ip a del 2001:db8::1 dev wlan0 ; ip a add 2001:db8::1 dev wlan0 ; time dnsmasq --strict-order --bind-interfaces --conf-file= --except-interface lo --interface wlan0 real 0m2.006s user 0m0.000s sys 0m0.003s We can add v6 address to interface with skipping DAD (nodad option for /sbin/ip tool), but we can end up with duplicate v6 hosts on the same network. Without DAD dnsmasq doesn't need to wait: # killall dnsmasq ; ip a del 2001:db8::1 dev wlan0 ; ip a add 2001:db8::1 dev wlan0 nodad ; time dnsmasq --strict-order --bind-interfaces --conf-file= --except-interface lo --interface wlan0 dnsmasq: no process killed real 0m0.017s user 0m0.000s sys 0m0.005s
Based on your descriptions here it sounds like going for multiple --listen-address parameters offers the same level of overall functionality, but with better compatibility for people on older dnsmasq. So I'm not seeing a compelling reason to switch over to using --listen-interface
OK, I understand. Final question: what about link-local ipv6 addresses (fe80::/10). Should we --listen-address on them? (I think we should) -- Pawel

On Thu, Jan 06, 2011 at 09:45:04PM +0100, Paweł Krześniak wrote:
2011/1/6 Daniel P. Berrange <berrange@redhat.com>:
While it is shorter to just use '--interface brname' this comes at the price of loosing compatibility with older dnsmasq which we still wish to support.
sure. RHEL5 is important target :)
If we used '--listen-address $IPV4ADDR --listen-address $IPV6ADDR' then people with dnsmasq < 2.48 can still use the virtual network capability in a IPv4 only context without problems. Only those people who actually needed IPv6 DNS would have to upgrade to newer dnsmasq.
hack for users of old dnsmasq and ipv6 needs is nodad option for /sbin/ip tool - read below.
Do you have any idea what causes the delay ? In particular is the delay caused by the use of --listen-interface, or caused by the addition of IPv6 addrs ?
Delay is caused by DAD. http://en.wikipedia.org/wiki/IPv6_address#Duplicate_address_detection
It's caused by IPv6 address, not by --listen-interface option: # killall dnsmasq ; ip a del 2001:db8::1 dev wlan0 ; ip a add 2001:db8::1 dev wlan0 ; time dnsmasq --strict-order --bind-interfaces --conf-file= --except-interface lo --listen-address 2001:db8::1 dnsmasq: no process killed
real 0m2.008s user 0m0.000s sys 0m0.006s
# killall dnsmasq ; ip a del 2001:db8::1 dev wlan0 ; ip a add 2001:db8::1 dev wlan0 ; time dnsmasq --strict-order --bind-interfaces --conf-file= --except-interface lo --interface wlan0
real 0m2.006s user 0m0.000s sys 0m0.003s
We can add v6 address to interface with skipping DAD (nodad option for /sbin/ip tool), but we can end up with duplicate v6 hosts on the same network. Without DAD dnsmasq doesn't need to wait:
# killall dnsmasq ; ip a del 2001:db8::1 dev wlan0 ; ip a add 2001:db8::1 dev wlan0 nodad ; time dnsmasq --strict-order --bind-interfaces --conf-file= --except-interface lo --interface wlan0 dnsmasq: no process killed
real 0m0.017s user 0m0.000s sys 0m0.005s
Based on your descriptions here it sounds like going for multiple --listen-address parameters offers the same level of overall functionality, but with better compatibility for people on older dnsmasq. So I'm not seeing a compelling reason to switch over to using --listen-interface
OK, I understand. Final question: what about link-local ipv6 addresses (fe80::/10). Should we --listen-address on them? (I think we should)
Will DNS actually work over link-local addrs? IIUC, since link-local addrs are scoped to a specific interface, apps wanting to send traffic via a link local address need to explicitly specify the interface name. Practically no apps will be do this and so they typically can't make use of the link-local address. Mostly a link-local address is just there for the purpose of allowing ipv6 autoconf to take place at which point the real address is used. So I'm not sure that we need/want to use --listen-address on the link local addr. Regards, Daniel

On 01/12/2011 02:24 PM, Paweł Krześniak wrote:
2011/1/7 Daniel P. Berrange <berrange@redhat.com>:
Practically no apps will be do this and so they typically can't make use of the link-local address.
I agree. v2 of patch attached.
Can you convince your mailer to send patches with mime type text/plain, rather than base64 encoded as application/octet-stream? Inline review is a lot nicer. That said:
commit ce44728e232a39ff42bf87f5eb102bc76b71241d Author: Pawel Krzesniak <pawel.krzesniak@gmail.com> Date: Tue Jan 11 23:36:19 2011 +0100
bridge_driver: handle DNS over IPv6 * dnsmasq listens on all defined IPv[46] addresses for network * Add ip6tables rules to allow DNS traffic to host --- src/network/bridge_driver.c | 59 ++++++++++++++++++++++++++++++++++-------- 1 files changed, 47 insertions(+), 12 deletions(-)
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 4c64a74..d5524db 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -423,7 +423,7 @@ networkSaveDnsmasqHostsfile(virNetworkIpDefPtr ipdef, return 0; }
- +#define FAMILIES_COUNT 2
Rather than defining this,
static int networkBuildDnsmasqArgv(virNetworkObjPtr network, virNetworkIpDefPtr ipdef, @@ -431,7 +431,11 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network, virCommandPtr cmd) { int r, ret = -1; int nbleases = 0; - char *bridgeaddr; + char *bridgeaddr = NULL; + char *ipaddr = NULL; + int ii, jj; + virNetworkIpDefPtr tmpipdef; + int families[FAMILIES_COUNT] = { AF_INET, AF_INET6 };
just declare this as int families[] = { ... };
+ /* + * --interface does not actually work with dnsmasq < 2.47, + * due to DAD for ipv6 addresses on the interface. + * + * virCommandAddArgList(cmd, "--interface", ipdef->bridge, NULL); + * + * So listen on all defined IPv[46] addresses + */ + for (ii = 0; ii < FAMILIES_COUNT; ii++) {
and iterate while ii < ARRAY_CARDINALITY(families). One less thing to screw up if we ever add a third family.
@@ -1027,9 +1040,31 @@ networkAddGeneralIp6tablesRules(struct network_driver *driver, goto err3; }
+ /* allow DNS over IPv6 */ + if (iptablesAddTcpInput(driver->iptables, AF_INET6, + network->def->bridge, 53) < 0) { + networkReportError(VIR_ERR_SYSTEM_ERROR, + _("failed to add ip6tables rule to allow DNS requests from '%s'"), + network->def->bridge); + goto err4; + } + + if (iptablesAddUdpInput(driver->iptables, AF_INET6, + network->def->bridge, 53) < 0) { + networkReportError(VIR_ERR_SYSTEM_ERROR, + _("failed to add ip6tables rule to allow DNS requests from '%s'"), + network->def->bridge); + goto err5; + }
Is it worth a (separate) clean-up patch that provides iptablesAddTcpUdpInput, which adds a rules for both protocol types in one shot, rather than requiring every call site to duplicate the calls for tcp and udp? The patch looks reasonable to me from the coding standpoint, but is probably worth a v4 for my nits, and you may want feedback from someone more familiar with the networking standpoint. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

(Sorry for the delay in responding. We're in a bit of a crunch ;-) On 01/12/2011 04:24 PM, Paweł Krześniak wrote:
2011/1/7 Daniel P. Berrange<berrange@redhat.com>:
Practically no apps will be do this and so they typically can't make use of the link-local address. I agree. v2 of patch attached.
As Eric indicated, it would be more convenient if your mailer attached the patch as an ASCII file rather than base64-encoded (I'm guessing possibly it did that automatically because of the accented characters in your name - perhaps there's a config parameter that would cause it to use some other encoding when it encounters things outside basic 7bit ASCII?)
commit ce44728e232a39ff42bf87f5eb102bc76b71241d Author: Pawel Krzesniak<pawel.krzesniak@gmail.com> Date: Tue Jan 11 23:36:19 2011 +0100
bridge_driver: handle DNS over IPv6 * dnsmasq listens on all defined IPv[46] addresses for network * Add ip6tables rules to allow DNS traffic to host --- src/network/bridge_driver.c | 59 ++++++++++++++++++++++++++++++++++-------- 1 files changed, 47 insertions(+), 12 deletions(-)
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 4c64a74..d5524db 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -423,7 +423,7 @@ networkSaveDnsmasqHostsfile(virNetworkIpDefPtr ipdef, return 0; }
- +#define FAMILIES_COUNT 2 static int networkBuildDnsmasqArgv(virNetworkObjPtr network, virNetworkIpDefPtr ipdef,
I'd been thinking that, if we were going to add this capability, we may as well eliminate the virNetworkIpDefPtr arg from the function call - we're already iterating over all the IPs anyway, so we may as well look for the IP that has the ranges and static hosts as we go through the list. (As a matter of fact, doing this would make it easier to (in a future patch, not here and now! :-) add in the ranges and static hosts from *all* IPs on an interface, not just the first found to have them. I'm not a dnsmasq expert, but it looks like this would require using the "network-id" detailed in the dnsmasq man page, along with multiple --dhcp-option arguments (and probably some other things).
@@ -431,7 +431,11 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network, virCommandPtr cmd) { int r, ret = -1; int nbleases = 0; - char *bridgeaddr; + char *bridgeaddr = NULL; + char *ipaddr = NULL; + int ii, jj; + virNetworkIpDefPtr tmpipdef; + int families[FAMILIES_COUNT] = { AF_INET, AF_INET6 };
I actually think it's a bit of overkill to do this. At this point, we only have AF_INET and AF_INET6 addresses, and we want to do the same thing with all of them, so we don't even need to look at family.
if (!(bridgeaddr = virSocketFormatAddr(&ipdef->address))) goto cleanup; @@ -468,20 +472,29 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network, /* *no* conf file */ virCommandAddArgList(cmd, "--conf-file=", "", NULL);
- /* - * XXX does not actually work, due to some kind of - * race condition setting up ipv6 addresses on the - * interface. A sleep(10) makes it work, but that's - * clearly not practical - * - * virCommandAddArg(cmd, "--interface"); - * virCommandAddArg(cmd, ipdef->bridge); - */ virCommandAddArgList(cmd, - "--listen-address", bridgeaddr, "--except-interface", "lo", NULL);
+ /* + * --interface does not actually work with dnsmasq< 2.47, + * due to DAD for ipv6 addresses on the interface. + * + * virCommandAddArgList(cmd, "--interface", ipdef->bridge, NULL); + * + * So listen on all defined IPv[46] addresses + */
As mentioned above - just make the following a single loop with family "AF_UNSPEC" so it gets all the ip addresses. By definition, every item on the list will have either an AF_INET or an AF_INET6 address.
+ for (ii = 0; ii< FAMILIES_COUNT; ii++) { + for (jj = 0; + (tmpipdef = virNetworkDefGetIpByIndex(network->def, families[ii], jj)); + jj++) { + if (!(ipaddr = virSocketFormatAddr(&tmpipdef->address))) + goto cleanup; + virCommandAddArgList(cmd, "--listen-address", ipaddr, NULL); + VIR_FREE(ipaddr); + } + } +
As part of the "future patch" mentioned above to support ranges/static hosts for all IP addresses, this next bit (about nranges) could be moved inside the above loop. For now, if you remove the virDomainNetIpDefPtr arg from the call to this function, you would want to check for the presences of hosts or ranges at each iteration through the loop.
for (r = 0 ; r< ipdef->nranges ; r++) { char *saddr = virSocketFormatAddr(&ipdef->ranges[r].start); if (!saddr) @@ -1027,9 +1040,31 @@ networkAddGeneralIp6tablesRules(struct network_driver *driver, goto err3; }
+ /* allow DNS over IPv6 */ + if (iptablesAddTcpInput(driver->iptables, AF_INET6, + network->def->bridge, 53)< 0) { + networkReportError(VIR_ERR_SYSTEM_ERROR, + _("failed to add ip6tables rule to allow DNS requests from '%s'"), + network->def->bridge); + goto err4; + } + + if (iptablesAddUdpInput(driver->iptables, AF_INET6, + network->def->bridge, 53)< 0) { + networkReportError(VIR_ERR_SYSTEM_ERROR, + _("failed to add ip6tables rule to allow DNS requests from '%s'"), + network->def->bridge); + goto err5; + } + + return 0;
/* unwind in reverse order from the point of failure */ +err5: + iptablesRemoveTcpInput(driver->iptables, AF_INET6, network->def->bridge, 53); +err4: + iptablesRemoveForwardAllowCross(driver->iptables, AF_INET6, network->def->bridge); err3: iptablesRemoveForwardRejectIn(driver->iptables, AF_INET6, network->def->bridge); err2:
I'm fine with this 2nd part of the patch. (I don't think there's a need for a single function to add both tcp and udp rules (as Eric suggested); I'd rather each call correspond to a single rule.)

On Fri, Dec 31, 2010 at 02:57:16PM -0500, Laine Stump wrote:
On 12/29/2010 10:00 AM, Paweł Krześniak wrote:
Firstly: Add ip6tables rules to allow DNS over IPv6 in network.
Secondly: start dnsmasq with --interface option instead of --listen-address.
Dnsmasq currently uses "--listen-address IPv4_address" option, which restricts DNS service to one IPv4 address only. We could append --listen-address for every IPv[46] address defined on interface, but it's cleaner to use "--interface brname".
There were some problems in the past with --interface option. Dnsmasq version 2.46 and earlier exited with error when tired to bind() to IPv6 addresses on just brought up interfaces, because DAD (Duplicate Address Detection) takes some time to finish and bind() returns EADDRNOTAVAIL which caused dnsmasq to exit. Dnsmasq version 2.47 (released on 05-Feb-2009) fixed this issue by retrying bind() after getting EADDRNOTAVAIL error (as described in http://www.thekelleys.org.uk/dnsmasq/CHANGELOG; loop itself is defined in dnsmasq-2.47/src/network.c:404)
In general this would be a good change to have. I'm not certain how careful we need to be about preserving compatibility with any platform that is still using dnsmasq older than 2.47, though. Dan or Dan, would you like to weigh in on that?
RHEL5 is still a primary platform targetted for libvirt releases and that has dnsmasq 2.45. Thus I'd prefer that we found a way to support the IPv6 DNS feature if dnsmasq is new enough, without preventing people using IPv4 only DNS on older dnsmasq. Daniel
participants (4)
-
Daniel P. Berrange
-
Eric Blake
-
Laine Stump
-
Paweł Krześniak