[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [libvirt] [PATCHv4] bridge_driver: handle DNS over IPv6



On 01/31/2011 03:31 PM, Paweł Krześniak wrote:
* dnsmasq listens on all defined IPv[46] addresses for network
* Add ip6tables rules to allow DNS traffic to host
---
  src/network/bridge_driver.c |   51 ++++++++++++++++++++++++++++++++++--------
  1 files changed, 41 insertions(+), 10 deletions(-)

diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index c098ab5..24be0b7 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -432,6 +432,8 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network,
      int r, ret = -1;
      int nbleases = 0;
      char *bridgeaddr;
+    int ii;
+    virNetworkIpDefPtr tmpipdef;

      if (!(bridgeaddr = virSocketFormatAddr(&ipdef->address)))
          goto cleanup;
@@ -468,20 +470,28 @@ 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
+     */
+    for (ii = 0;
+         (tmpipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, ii));
+         ii++) {
+    	char *ipaddr = virSocketFormatAddr(&tmpipdef->address);
+        if (!ipaddr)
+            goto cleanup;
+        virCommandAddArgList(cmd, "--listen-address", ipaddr, NULL);
+        VIR_FREE(ipaddr);
+    }
+
      for (r = 0 ; r<  ipdef->nranges ; r++) {
          char *saddr = virSocketFormatAddr(&ipdef->ranges[r].start);
          if (!saddr)
@@ -1027,9 +1037,30 @@ 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:

This looks good, builds, passes make syntax-check (after I squashed out one errant tab character), and appears to function properly.

ACK, and pushed. Thanks!

As I mentioned in earlier mails, sometime in the future a good followup to this for someone would be to eliminate the "ipdef" arg to networkBuildDnsmasqArgv, and figure out how to make dnsmasq serve multiple dhcp segments on the same interface. But that's a separate issue for another day...


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]