]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
dnsmasq: disable IPv6 default gateway in RA for isolated networks
authorMaxim Perevedentsev <mperevedentsev@virtuozzo.com>
Fri, 1 Jul 2016 11:50:18 +0000 (14:50 +0300)
committerMaxim Nestratov <mnestratov@virtuozzo.com>
Wed, 13 Jul 2016 10:49:03 +0000 (13:49 +0300)
IPv6 RA always contains an implicit default route via
the link-local address of the source of RA. This forces
the guest to install a route via isolated network, which
may disturb the guest's networking in case of multiple interfaces.
More info in 013427e6e733f7a662f4e8a9c11f7dad4cd65e3f.

The validity of this route is controlled by "default [route] lifetime"
field of RA. If the lifetime is set to 0 seconds, then no route
is installed by receiver.

dnsmasq 2.67+ supports "ra-param=<interface>,<RA interval>,<default
lifetime>" option. We pass "ra-param=*,0,0"
(here, RA_interval=0 means default) to disable default gateway in RA
for isolated networks.

src/network/bridge_driver.c
src/util/virdnsmasq.c
src/util/virdnsmasq.h

index 0221a3820b0a84f4ee7bf4f442cf383ebef17bc6..50202664e440e8b35fbf5e6bf5a564d298186e30 100644 (file)
@@ -1047,10 +1047,17 @@ networkDnsmasqConfContents(virNetworkObjPtr network,
      * requests are forwarded on to the dns server listed in the
      * host's /etc/resolv.conf (since this could be used as a channel
      * to build a connection to the outside).
+     * IPv6 RA always contains an implicit default route
+     * via the sender's link-local address. The only thing we can do
+     * is set the lifetime of this route to 0, i.e. disable it.
      */
     if (network->def->forward.type == VIR_NETWORK_FORWARD_NONE) {
         virBufferAddLit(&configbuf, "dhcp-option=3\n"
                         "no-resolv\n");
+        if (dnsmasqCapsGet(caps, DNSMASQ_CAPS_RA_PARAM)) {
+            /* interface=* (any), interval=0 (default), lifetime=0 (seconds) */
+            virBufferAddLit(&configbuf, "ra-param=*,0,0\n");
+        }
     }
 
     for (i = 0; i < dns->ntxts; i++) {
index cd986087a93ed2571853a765c2e2004be2e5cf74..1b78c1fadc53890f5770993be6eb940da9bb9692 100644 (file)
@@ -688,12 +688,16 @@ dnsmasqCapsSetFromBuffer(dnsmasqCapsPtr caps, const char *buf)
     if (strstr(buf, "--bind-interfaces with SO_BINDTODEVICE"))
         dnsmasqCapsSet(caps, DNSMASQ_CAPS_BINDTODEVICE);
 
+    if (strstr(buf, "--ra-param"))
+        dnsmasqCapsSet(caps, DNSMASQ_CAPS_RA_PARAM);
+
     VIR_INFO("dnsmasq version is %d.%d, --bind-dynamic is %spresent, "
-             "SO_BINDTODEVICE is %sin use",
+             "SO_BINDTODEVICE is %sin use, --ra-param is %spresent",
              (int)caps->version / 1000000,
              (int)(caps->version % 1000000) / 1000,
              dnsmasqCapsGet(caps, DNSMASQ_CAPS_BIND_DYNAMIC) ? "" : "NOT ",
-             dnsmasqCapsGet(caps, DNSMASQ_CAPS_BINDTODEVICE) ? "" : "NOT ");
+             dnsmasqCapsGet(caps, DNSMASQ_CAPS_BINDTODEVICE) ? "" : "NOT ",
+             dnsmasqCapsGet(caps, DNSMASQ_CAPS_RA_PARAM) ? "" : "NOT ");
     return 0;
 
  fail:
index ed560da45d56b2b5c9d04c7d8b7d8e5282b24b6e..f47bea3abe9b8117179969f3625801437661c2d6 100644 (file)
@@ -71,6 +71,7 @@ typedef struct
 typedef enum {
    DNSMASQ_CAPS_BIND_DYNAMIC = 0, /* support for --bind-dynamic */
    DNSMASQ_CAPS_BINDTODEVICE = 1, /* uses SO_BINDTODEVICE for --bind-interfaces */
+   DNSMASQ_CAPS_RA_PARAM = 2,     /* support for --ra-param */
 
    DNSMASQ_CAPS_LAST,             /* this must always be the last item */
 } dnsmasqCapsFlags;