[libvirt] [PATCHv2] handle DNS over IPv6

Paweł Krześniak pawel.krzesniak at gmail.com
Mon Jan 3 15:57:52 UTC 2011


Thanks for comments. v2 attached.

Sorry, but my two previous patches don't apply because of line-wrapping issues.

-- 
Pawel
-------------- next part --------------
commit 41aedffa7bb30ba4e4357e220f071dab35c8e36c
Author: Pawel Krzesniak <pawel.krzesniak at gmail.com>
Date:   Mon Jan 3 09:46:02 2011 +0100

    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 |   33 ++++++++++++++++++++++++++-------
 1 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 7d43ef5..5b17c9e 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, NULL);
      */
     virCommandAddArgList(cmd,
-                         "--listen-address", bridgeaddr,
+                         "--interface", network->def->bridge,
                          "--except-interface", "lo",
                          NULL);
 
@@ -1027,9 +1024,31 @@ networkAddGeneralIp6tablesRules(struct network_driver *driver,
         goto err3;
     }
 
+    /* allow DNS over IPv6 requests */
+    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:


More information about the libvir-list mailing list