Hi,

It looks like Mac OS X puts some IPv6 garbage on the wire and
our cheap consumer router starts happily advertising routes
like this:

 4006:16e1:ac17:189::/64 if=re0
 flags=LAO vltime=6401, pltime=0, expire=1h46m34s, ref=0
   advertised by
     fe80::9ec7:a6ff:fe86:a3f4%re0 (reachable)

This makes us generate autoconf and privacy addresses which
immediately become deprecated (pltime=0 translates to a zero
preferred lifetime for these addresses).  Within minutes on
an active network you end up with hundreds of dead IPv6
addresses.

RFC 4941 says in 3.3.5:

 "In particular, an implementation MUST NOT create a temporary
  address with a zero Preferred Lifetime."

Which means we have to strengthen the lifetime check.  OK?

This also raises the question whether we should memorize such
prefixes at all -- but I haven't found a straight answer just
yet.


diff --git sys/netinet6/nd6_rtr.c sys/netinet6/nd6_rtr.c
index de23248..d7f59de 100644
--- sys/netinet6/nd6_rtr.c
+++ sys/netinet6/nd6_rtr.c
@@ -1374,16 +1374,17 @@ prelist_update(struct nd_prefix *new, struct 
nd_defrouter *dr, struct mbuf *m)
                ia6->ia6_lifetime = lt6_tmp;
                ia6->ia6_updatetime = time_second;
        }
 
        if ((!autoconf || ((ifp->if_xflags & IFXF_INET6_NOPRIVACY) == 0 &&
-           !tempaddr_preferred)) && new->ndpr_vltime != 0 &&
+            !tempaddr_preferred)) &&
+           new->ndpr_vltime != 0 && new->ndpr_pltime != 0 &&
            !((ifp->if_xflags & IFXF_INET6_NOPRIVACY) && statique)) {
                /*
                 * There is no SLAAC address and/or there is no preferred RFC
-                * 4941 temporary address. And the valid prefix lifetime is
-                * non-zero. And there is no static address in the same prefix.
+                * 4941 temporary address. And prefix lifetimes are non-zero.
+                * And there is no static address in the same prefix.
                 * Create new addresses in process context.
                 * Increment prefix refcount to ensure the prefix is not
                 * removed before the task is done.
                 */
                pr->ndpr_refcnt++;

Reply via email to