untrusted comment: signature from openbsd 5.6 base private key RWR0EANmo9nqhsr9jS8BgHhwsAYDH7hRTPEunrGAZJdzabwpNNlCMaRCqqsBZR4mdw7nABwj+qfibDasRWE1dTBZg9Rtbhrftg0= OpenBSD 5.6 errata 2, Oct 1, 2014: Redundant IPv6 autoconf addresses. Apply patch using: signify -Vep /etc/signify/openbsd-56-base.pub -x 002_nd6.patch.sig -m - | \ (cd /usr/src && patch -p0) Then build and install a new kernel: cd /usr/src/sys/arch/`machine`/conf KK=`sysctl -n kern.osversion | cut -d# -f1` config $KK cd ../compile/$KK make make install Index: sys/netinet6/nd6_rtr.c =================================================================== RCS file: /cvs/src/sys/netinet6/nd6_rtr.c,v retrieving revision 1.83 retrieving revision 1.83.4.1 diff -u -p -r1.83 -r1.83.4.1 --- sys/netinet6/nd6_rtr.c 12 Jul 2014 18:44:23 -0000 1.83 +++ sys/netinet6/nd6_rtr.c 8 Sep 2014 14:42:40 -0000 1.83.4.1 @@ -1296,13 +1296,51 @@ void nd6_addr_add(void *prptr, void *arg2) { struct nd_prefix *pr = (struct nd_prefix *)prptr; - struct in6_ifaddr *ia6 = NULL; - int autoconf, privacy, s; + struct in6_ifaddr *ia6; + struct ifaddr *ifa; + int ifa_plen, autoconf, privacy, s; s = splsoftnet(); autoconf = 1; privacy = (pr->ndpr_ifp->if_xflags & IFXF_INET6_NOPRIVACY) == 0; + + /* + * Check again if a non-deprecated address has already + * been autoconfigured for this prefix. + */ + TAILQ_FOREACH(ifa, &pr->ndpr_ifp->if_addrlist, ifa_list) { + if (ifa->ifa_addr->sa_family != AF_INET6) + continue; + + ia6 = ifatoia6(ifa); + + /* + * Spec is not clear here, but I believe we should concentrate + * on unicast (i.e. not anycast) addresses. + * XXX: other ia6_flags? detached or duplicated? + */ + if ((ia6->ia6_flags & IN6_IFF_ANYCAST) != 0) + continue; + + if ((ia6->ia6_flags & IN6_IFF_AUTOCONF) == 0) + continue; + + if ((ia6->ia6_flags & IN6_IFF_DEPRECATED) != 0) + continue; + + ifa_plen = in6_mask2len(&ia6->ia_prefixmask.sin6_addr, NULL); + if (ifa_plen == pr->ndpr_plen && + in6_are_prefix_equal(&ia6->ia_addr.sin6_addr, + &pr->ndpr_prefix.sin6_addr, ifa_plen)) { + if ((ia6->ia6_flags & IN6_IFF_PRIVACY) == 0) + autoconf = 0; + else + privacy = 0; + if (!autoconf && !privacy) + break; + } + } if (autoconf && (ia6 = in6_ifadd(pr, 0)) != NULL) { ia6->ia6_ndpr = pr;