]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
I was wrong about Linux allowing userland to mark addresses as temporary,
authorRoy Marples <roy@marples.name>
Mon, 7 Sep 2015 18:14:31 +0000 (18:14 +0000)
committerRoy Marples <roy@marples.name>
Mon, 7 Sep 2015 18:14:31 +0000 (18:14 +0000)
this just does not work.
Instead we can only mark addresses such that the kernel will generate and
manage temporary address from.
This means that that a large chunk of the temporary address management
code can be disabled on Linux, resulting in a smaller binary.
Fixes [8f4197ed4d] and [f40b0f329a].

if-linux.c
ipv6.h

index fbebac757112ce0d064bd3daabbbe76ace6876cb..a28f86eb1ba521601a962efb9610188ecef4c436 100644 (file)
@@ -1457,7 +1457,7 @@ if_addrflags(__unused const struct in_addr *addr,
 
 #ifdef INET6
 int
-if_address6(const struct ipv6_addr *ap, int action)
+if_address6(const struct ipv6_addr *ia, int action)
 {
        struct nlma nlm;
        struct ifa_cacheinfo cinfo;
@@ -1476,39 +1476,40 @@ if_address6(const struct ipv6_addr *ap, int action)
                nlm.hdr.nlmsg_type = RTM_NEWADDR;
        } else
                nlm.hdr.nlmsg_type = RTM_DELADDR;
-       nlm.ifa.ifa_index = ap->iface->index;
+       nlm.ifa.ifa_index = ia->iface->index;
        nlm.ifa.ifa_family = AF_INET6;
-       if (ap->addr_flags & IFA_F_TEMPORARY) {
+#ifdef IPV6_MANAGETEMPADDR
+       if (ia->flags & IPV6_AF_TEMPORARY) {
+               /* Currently the kernel filters out these flags */
 #ifdef IFA_F_NOPREFIXROUTE
                flags |= IFA_F_TEMPORARY;
 #else
                nlm.ifa.ifa_flags |= IFA_F_TEMPORARY;
 #endif
        }
-#ifdef IFA_F_MANAGETEMPADDR
-       else if (ap->flags & IPV6_AF_AUTOCONF &&
-           ip6_use_tempaddr(ap->iface->name))
+#elif IFA_F_MANAGETEMPADDR
+       if (ia->flags & IPV6_AF_AUTOCONF)
                flags |= IFA_F_MANAGETEMPADDR;
 #endif
 
        /* Add as /128 if no IFA_F_NOPREFIXROUTE ? */
-       nlm.ifa.ifa_prefixlen = ap->prefix_len;
+       nlm.ifa.ifa_prefixlen = ia->prefix_len;
        /* This creates the aliased interface */
        add_attr_l(&nlm.hdr, sizeof(nlm), IFA_LABEL,
-           ap->iface->alias, (unsigned short)(strlen(ap->iface->alias) + 1));
+           ia->iface->alias, (unsigned short)(strlen(ia->iface->alias) + 1));
        add_attr_l(&nlm.hdr, sizeof(nlm), IFA_LOCAL,
-           &ap->addr.s6_addr, sizeof(ap->addr.s6_addr));
+           &ia->addr.s6_addr, sizeof(ia->addr.s6_addr));
 
        if (action >= 0) {
                memset(&cinfo, 0, sizeof(cinfo));
-               cinfo.ifa_prefered = ap->prefix_pltime;
-               cinfo.ifa_valid = ap->prefix_vltime;
+               cinfo.ifa_prefered = ia->prefix_pltime;
+               cinfo.ifa_valid = ia->prefix_vltime;
                add_attr_l(&nlm.hdr, sizeof(nlm), IFA_CACHEINFO,
                    &cinfo, sizeof(cinfo));
        }
 
 #ifdef IFA_F_NOPREFIXROUTE
-       if (!IN6_IS_ADDR_LINKLOCAL(&ap->addr))
+       if (!IN6_IS_ADDR_LINKLOCAL(&ia->addr))
                flags |= IFA_F_NOPREFIXROUTE;
 #endif
 #if defined(IFA_F_NOPREFIXROUTE) || defined(IFA_F_MANAGETEMPADDR)
@@ -1516,7 +1517,7 @@ if_address6(const struct ipv6_addr *ap, int action)
                add_attr_32(&nlm.hdr, sizeof(nlm), IFA_FLAGS, flags);
 #endif
 
-       if (send_netlink(ap->iface->ctx, NULL, NETLINK_ROUTE, &nlm.hdr,
+       if (send_netlink(ia->iface->ctx, NULL, NETLINK_ROUTE, &nlm.hdr,
            NULL) == -1)
                retval = -1;
        return retval;
diff --git a/ipv6.h b/ipv6.h
index c7840ff2642934b19fd2359b4f677814020fdef9..3171735aef83a291460dda5faef46bc2d2c444eb 100644 (file)
--- a/ipv6.h
+++ b/ipv6.h
 #  undef IPV6_POLLADDRFLAG
 #endif
 
-/* Linux-3.18 can manage temporary addresses even with RA
- * processing disabled. */
-//#undef IFA_F_MANAGETEMPADDR
-#if defined(__linux__) && defined(IFA_F_MANAGETEMPADDR)
+/*
+ * If dhcpcd handles RA processing instead of the kernel, the kernel needs
+ * to either allow userland to set temporary addresses or mark an address
+ * for the kernel to manage temporary addresses from.
+ * If the kernel allows the former, a global #define is needed, otherwise
+ * the address marking will be handled in the platform specific address handler.
+ *
+ * Some BSDs do not allow userland to set temporary addresses.
+ * Linux-3.18 allows the marking of addresses from which to manage temp addrs.
+ */
+#if defined(BSD) && defined(IN6_IFF_TEMPORARY)
 #define IPV6_MANAGETEMPADDR
 #endif
 
-/* Some BSDs do not allow userland to set temporary addresses. */
-#if defined(BSD) && defined(IN6_IFF_TEMPORARY)
+/*
+ * You could enable IPV6_MANAGETEMPADDR anyway and disable the platform
+ * specific address marking to test dhcpcd's temporary address handling as well,
+ * but this will not affect source address selection so is of very limited use.
+ */
+#if 0
+/* Pretend we have an old Linux kernel. */
+#undef IFA_F_MANAGETEMPADDR
+/* Enable dhcpcd handling temporary addresses. */
 #define IPV6_MANAGETEMPADDR
 #endif