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;