From: Roy Marples Date: Mon, 7 Sep 2015 18:14:31 +0000 (+0000) Subject: I was wrong about Linux allowing userland to mark addresses as temporary, X-Git-Tag: v6.9.4~67 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2f08ed0ff37b6ee980abee72da6a6da3dce2809d;p=thirdparty%2Fdhcpcd.git I was wrong about Linux allowing userland to mark addresses as temporary, 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]. --- diff --git a/if-linux.c b/if-linux.c index fbebac75..a28f86eb 100644 --- a/if-linux.c +++ b/if-linux.c @@ -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 c7840ff2..3171735a 100644 --- a/ipv6.h +++ b/ipv6.h @@ -92,15 +92,29 @@ # 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