dhcpv6: assign all viable DHCPv6 addresses by default (FS#402, FS#524)
authorHans Dedecker <dedeckeh@gmail.com>
Wed, 2 Aug 2017 20:32:08 +0000 (22:32 +0200)
committerHans Dedecker <dedeckeh@gmail.com>
Thu, 3 Aug 2017 16:37:47 +0000 (18:37 +0200)
Some client implementations expect DHCPv6 addresses to be assigned for
every prefix present in a RA as reported in FS#524; if not done the
client implementations spam the DHCPv6 server with SOLICIT messages
trying to get an DHCPv6 address for every prefix.
When ra_managed is set to 1 and an ULA prefix is configured; the DHCPv6
server will only assign an ULA DHCPv6 addresses which possibly leads to
DNS issues.

Fix these problems by providing dhcpv6_assignall config option which
assigns all viable DHCPv6 addresses to a client by default.
This is a trade off as it means client implementations will be assigned
more IPv6 addresses and lose the ability to quickly renumber clients
which don't support reconfigure accept in case of wan prefix change

Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
README
src/config.c
src/dhcpv6-ia.c
src/odhcpd.h

diff --git a/README b/README
index fbcd99394f609d5512ee6a2f22d169bd7204c2e4..f4945ce7a32dd26cdac153fcc66a24752730b5cf 100644 (file)
--- a/README
+++ b/README
@@ -90,6 +90,10 @@ ndp                  string  disabled                Neighbor Discovery Proxy
 
 dynamicdhcp            bool    1                       Dynamically create leases
                                                        for DHCPv4 and DHCPv6
+dhcpv6_assignall       bool    1                       Assign all viable DHCPv6 addresses
+                                                       in statefull mode; if disabled
+                                                       only the DHCPv6 address having the
+                                                       longest preferred lifetime is assigned
 router                 list    <local address>         Routers to announce
                                                        accepts IPv4 only
 dns                    list    <local address>         DNS servers to announce
index 8670efc316d943a74fe26b23e5422d8b94f44b06..19b901c87cd41c19911f54d0077bc33d476e2cd5 100644 (file)
@@ -43,6 +43,7 @@ enum {
        IFACE_ATTR_DOMAIN,
        IFACE_ATTR_FILTER_CLASS,
        IFACE_ATTR_DHCPV6_RAW,
+       IFACE_ATTR_DHCPV6_ASSIGNALL,
        IFACE_ATTR_RA_DEFAULT,
        IFACE_ATTR_RA_MANAGEMENT,
        IFACE_ATTR_RA_OFFLINK,
@@ -83,6 +84,7 @@ static const struct blobmsg_policy iface_attrs[IFACE_ATTR_MAX] = {
        [IFACE_ATTR_DOMAIN] = { .name = "domain", .type = BLOBMSG_TYPE_ARRAY },
        [IFACE_ATTR_FILTER_CLASS] = { .name = "filter_class", .type = BLOBMSG_TYPE_STRING },
        [IFACE_ATTR_DHCPV6_RAW] = { .name = "dhcpv6_raw", .type = BLOBMSG_TYPE_STRING },
+       [IFACE_ATTR_DHCPV6_ASSIGNALL] = { .name ="dhcpv6_assignall", .type = BLOBMSG_TYPE_BOOL },
        [IFACE_ATTR_PD_MANAGER] = { .name = "pd_manager", .type = BLOBMSG_TYPE_STRING },
        [IFACE_ATTR_PD_CER] = { .name = "pd_cer", .type = BLOBMSG_TYPE_STRING },
        [IFACE_ATTR_RA_DEFAULT] = { .name = "ra_default", .type = BLOBMSG_TYPE_INT32 },
@@ -205,9 +207,10 @@ static struct interface* get_interface(const char *name)
 
 static void set_interface_defaults(struct interface *iface)
 {
-       iface->ra_managed = RA_MANAGED_MFLAG;
        iface->learn_routes = 1;
        iface->dhcpv4_leasetime = 43200;
+       iface->dhcpv6_assignall = true;
+       iface->ra_managed = RA_MANAGED_MFLAG;
        iface->ra_maxinterval = 600;
        iface->ra_mininterval = iface->ra_maxinterval/3;
        iface->ra_lifetime = -1;
@@ -617,6 +620,9 @@ int config_parse_interface(void *data, size_t len, const char *name, bool overwr
                odhcpd_unhexlify(iface->dhcpv6_raw, iface->dhcpv6_raw_len, blobmsg_get_string(c));
        }
 
+       if ((c = tb[IFACE_ATTR_DHCPV6_ASSIGNALL]))
+               iface->dhcpv6_assignall = blobmsg_get_bool(c);
+
        if ((c = tb[IFACE_ATTR_RA_DEFAULT]))
                iface->default_router = blobmsg_get_u32(c);
 
index 8bf42c8876c4fa454823931fbb6f658647194bd3..847ede4329c62211fb90b8f25510e0da622d4b9b 100644 (file)
@@ -36,7 +36,7 @@
 #include <libubox/usock.h>
 
 #define ADDR_ENTRY_VALID_IA_ADDR(iface, i, m, addrs) \
-    ((iface)->ra_managed == RA_MANAGED_NO_AFLAG || (i) == (m) || \
+    ((iface)->dhcpv6_assignall || (i) == (m) || \
      (addrs)[(i)].prefix > 64)
 
 static void free_dhcpv6_assignment(struct dhcpv6_assignment *c);
index 10f0edbe80bae725f98dced345f411097910bc9a..a03baf06a4232898ea511081a1cafa2c4d58ddb9 100644 (file)
@@ -185,8 +185,10 @@ struct interface {
        uint8_t *search;
        size_t search_len;
 
+       // DHCPV6
        void *dhcpv6_raw;
        size_t dhcpv6_raw_len;
+       bool dhcpv6_assignall;
 
        char *upstream;
        size_t upstream_len;