Diff below makes sure that no connected route is created for
loopback/p2p interfaces for linklocal *and* non-linklocal addrs.

route(8)'s output will change:

-fe80::%lo10001/64                  fe80::1%lo10001                U          0 
       0 32768     4 lo10001
 fe80::1%lo10001                    fe80::1%lo10001                UHl        0 
       0 32768     1 lo10001


This makes IPv6 automagically created routes coherent with IPv4
ones.

I'm unsure about the hack for DAD w/ p2p interfaces, so I left it.

Ok?

Index: netinet6/in6.c
===================================================================
RCS file: /cvs/src/sys/netinet6/in6.c,v
retrieving revision 1.168
diff -u -p -r1.168 in6.c
--- netinet6/in6.c      24 Aug 2015 23:26:43 -0000      1.168
+++ netinet6/in6.c      26 Aug 2015 10:43:33 -0000
@@ -462,7 +462,7 @@ in6_control(struct socket *so, u_long cm
 
        case SIOCAIFADDR_IN6:
        {
-               int plen, error = 0;
+               int error = 0;
 
                /* reject read-only flags */
                if ((ifra->ifra_flags & IN6_IFF_DUPLICATED) != 0 ||
@@ -508,10 +508,9 @@ in6_control(struct socket *so, u_long cm
                if (ia6->ia6_flags & IN6_IFF_TENTATIVE)
                        nd6_dad_start(&ia6->ia_ifa);
 
-               plen = in6_mask2len(&ifra->ifra_prefixmask.sin6_addr, NULL);
-               if (plen == 128) {
+               if (ifp->if_flags & (IFF_POINTOPOINT|IFF_LOOPBACK)) {
                        dohooks(ifp->if_addrhooks, 0);
-                       break;  /* we don't need to install a host route. */
+                       break;  /* No need to install a connected route. */
                }
 
                s = splsoftnet();
@@ -966,7 +965,10 @@ in6_unlink_ifa(struct in6_ifaddr *ia6, s
 
        /* Release the reference to the base prefix. */
        if (ia6->ia6_ndpr == NULL) {
-               rt_ifa_del(ifa, RTF_CLONING | RTF_CONNECTED, ifa->ifa_addr);
+               if ((ifp->if_flags & (IFF_POINTOPOINT|IFF_LOOPBACK)) == 0) {
+                       rt_ifa_del(ifa, RTF_CLONING | RTF_CONNECTED,
+                           ifa->ifa_addr);
+               }
        } else {
                KASSERT(ia6->ia6_flags & IN6_IFF_AUTOCONF);
                ia6->ia6_flags &= ~IN6_IFF_AUTOCONF;
Index: netinet6/in6_ifattach.c
===================================================================
RCS file: /cvs/src/sys/netinet6/in6_ifattach.c,v
retrieving revision 1.93
diff -u -p -r1.93 in6_ifattach.c
--- netinet6/in6_ifattach.c     24 Aug 2015 23:26:43 -0000      1.93
+++ netinet6/in6_ifattach.c     26 Aug 2015 10:43:18 -0000
@@ -332,47 +332,41 @@ in6_ifattach_linklocal(struct ifnet *ifp
        ifra.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
 
        /*
-        * Now call in6_update_ifa() to do a bunch of procedures to configure
-        * a link-local address. In the case of CARP, we may be called after
-        * one has already been configured, so check if it's already there
-        * with in6ifa_ifpforlinklocal() and clobber it if it exists.
+        * XXX: Some P2P interfaces seem not to send packets just after
+        * becoming up, so we skip p2p interfaces for safety.
         */
+       if (in6if_do_dad(ifp) && ((ifp->if_flags & IFF_POINTOPOINT) == 0))
+               ifra.ifra_flags |= IN6_IFF_TENTATIVE;
+
        s = splsoftnet();
        error = in6_update_ifa(ifp, &ifra, in6ifa_ifpforlinklocal(ifp, 0));
        splx(s);
-
-       if (error != 0) {
-               /*
-                * XXX: When the interface does not support IPv6, this call
-                * would fail in the SIOCSIFADDR ioctl.  I believe the
-                * notification is rather confusing in this case, so just
-                * suppress it.  ([email protected] 20010130)
-                */
-               if (error != EAFNOSUPPORT)
-                       nd6log((LOG_NOTICE, "in6_ifattach_linklocal: failed to "
-                           "configure a link-local address on %s "
-                           "(errno=%d)\n",
-                           ifp->if_xname, error));
-               return (-1);
-       }
+       if (error != 0)
+               return (error);
 
        ia6 = in6ifa_ifpforlinklocal(ifp, 0);
 
-       /*
-        * Perform DAD.
-        *
-        * XXX: Some P2P interfaces seem not to send packets just after
-        * becoming up, so we skip p2p interfaces for safety.
-        */
-       if (in6if_do_dad(ifp) && ((ifp->if_flags & IFF_POINTOPOINT) == 0)) {
-               ia6->ia6_flags |= IN6_IFF_TENTATIVE;
+       /* Perform DAD, if needed. */
+       if (ia6->ia6_flags & IN6_IFF_TENTATIVE)
                nd6_dad_start(&ia6->ia_ifa);
+
+       if (ifp->if_flags & (IFF_POINTOPOINT|IFF_LOOPBACK)) {
+               dohooks(ifp->if_addrhooks, 0);
+               return (0); /* No need to install a connected route. */
        }
 
+       s = splsoftnet();
        error = rt_ifa_add(&ia6->ia_ifa, RTF_UP|RTF_CLONING|RTF_CONNECTED,
            ia6->ia_ifa.ifa_addr);
+       if (error) {
+               in6_purgeaddr(&ia6->ia_ifa);
+               splx(s);
+               return (error);
+       }
+       dohooks(ifp->if_addrhooks, 0);
+       splx(s);
 
-       return (error);
+       return (0);
 }
 
 int

Reply via email to