Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Move the detaching and making tentative addresses out if...



details:   https://anonhg.NetBSD.org/src/rev/975dfbbe224b
branches:  trunk
changeset: 787488:975dfbbe224b
user:      roy <roy%NetBSD.org@localhost>
date:      Thu Jun 20 13:56:29 2013 +0000

description:
Move the detaching and making tentative addresses out if in6_if_up
and into in6_if_link_up.

This fixes a possible panic where link is up but not the interface.
Note that a better solution would be to listen to the routing socket
in the kernel, but I don't know how to do that.

Reachable Router tests for IFF_UP as well.

diffstat:

 sys/dev/mii/mii_physubr.c |   7 ++-----
 sys/net/if.c              |  23 +++++++++++++++--------
 sys/netinet6/in6.c        |  32 +++++++++++++++++++++++---------
 sys/netinet6/in6.h        |   4 +++-
 sys/netinet6/nd6_rtr.c    |  11 ++++++-----
 5 files changed, 49 insertions(+), 28 deletions(-)

diffs (243 lines):

diff -r 8a7e5d0a04e5 -r 975dfbbe224b sys/dev/mii/mii_physubr.c
--- a/sys/dev/mii/mii_physubr.c Thu Jun 20 13:42:02 2013 +0000
+++ b/sys/dev/mii/mii_physubr.c Thu Jun 20 13:56:29 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mii_physubr.c,v 1.79 2013/06/16 06:29:08 msaitoh Exp $ */
+/*     $NetBSD: mii_physubr.c,v 1.80 2013/06/20 13:56:29 roy Exp $     */
 
 /*-
  * Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mii_physubr.c,v 1.79 2013/06/16 06:29:08 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mii_physubr.c,v 1.80 2013/06/20 13:56:29 roy Exp $");
 
 #include <sys/param.h>
 #include <sys/device.h>
@@ -436,9 +436,7 @@
 {
        struct mii_data *mii = sc->mii_pdata;
        struct ifnet *ifp = mii->mii_ifp;
-       int s;
 
-       s = splnet();
        if (mii->mii_media_status & IFM_AVALID) {
                if (mii->mii_media_status & IFM_ACTIVE)
                        if_link_state_change(ifp, LINK_STATE_UP);
@@ -446,7 +444,6 @@
                        if_link_state_change(ifp, LINK_STATE_DOWN);
        } else
                if_link_state_change(ifp, LINK_STATE_UNKNOWN);
-       splx(s);
 
        ifp->if_baudrate = ifmedia_baudrate(mii->mii_media_active);
 }
diff -r 8a7e5d0a04e5 -r 975dfbbe224b sys/net/if.c
--- a/sys/net/if.c      Thu Jun 20 13:42:02 2013 +0000
+++ b/sys/net/if.c      Thu Jun 20 13:56:29 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if.c,v 1.263 2013/06/11 12:08:29 roy Exp $     */
+/*     $NetBSD: if.c,v 1.264 2013/06/20 13:56:29 roy Exp $     */
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
@@ -90,7 +90,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.263 2013/06/11 12:08:29 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.264 2013/06/20 13:56:29 roy Exp $");
 
 #include "opt_inet.h"
 
@@ -1333,14 +1333,19 @@
 
 /*
  * Handle a change in the interface link state.
+ * XXX: We should listen to the routing socket in-kernel rather
+ * than calling in6_if_link_* functions directly from here.
  */
 void
 if_link_state_change(struct ifnet *ifp, int link_state)
 {
-       int old_link_state;
+       int old_link_state, s;
 
-       if (ifp->if_link_state == link_state)
+       s = splnet();
+       if (ifp->if_link_state == link_state) {
+               splx(s);
                return;
+       }
 
        old_link_state = ifp->if_link_state;
        ifp->if_link_state = link_state;
@@ -1349,7 +1354,7 @@
                link_state == LINK_STATE_UP ? "UP" :
                link_state == LINK_STATE_DOWN ? "DOWN" :
                "UNKNOWN",
-               old_link_state == LINK_STATE_UP ? "UP" :
+                old_link_state == LINK_STATE_UP ? "UP" :
                old_link_state == LINK_STATE_DOWN ? "DOWN" :
                "UNKNOWN");
 #endif
@@ -1366,7 +1371,7 @@
         */
        if (link_state == LINK_STATE_UP &&
            old_link_state == LINK_STATE_UNKNOWN)
-               in6_if_down(ifp);
+               in6_if_link_down(ifp);
 #endif
 
        /* Notify that the link state has changed. */
@@ -1379,10 +1384,12 @@
 
 #ifdef INET6
        if (link_state == LINK_STATE_DOWN)
-               in6_if_down(ifp);
+               in6_if_link_down(ifp);
        else if (link_state == LINK_STATE_UP)
-               in6_if_up(ifp);
+               in6_if_link_up(ifp);
 #endif
+
+       splx(s);
 }
 
 /*
diff -r 8a7e5d0a04e5 -r 975dfbbe224b sys/netinet6/in6.c
--- a/sys/netinet6/in6.c        Thu Jun 20 13:42:02 2013 +0000
+++ b/sys/netinet6/in6.c        Thu Jun 20 13:56:29 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in6.c,v 1.164 2013/06/11 12:08:29 roy Exp $    */
+/*     $NetBSD: in6.c,v 1.165 2013/06/20 13:56:29 roy Exp $    */
 /*     $KAME: in6.c,v 1.198 2001/07/18 09:12:38 itojun Exp $   */
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.164 2013/06/11 12:08:29 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.165 2013/06/20 13:56:29 roy Exp $");
 
 #include "opt_inet.h"
 #include "opt_pfil_hooks.h"
@@ -2165,7 +2165,7 @@
  * perform DAD when interface becomes IFF_UP.
  */
 void
-in6_if_up(struct ifnet *ifp)
+in6_if_link_up(struct ifnet *ifp)
 {
        struct ifaddr *ifa;
        struct in6_ifaddr *ia;
@@ -2206,24 +2206,34 @@
                }
        }
 
+       /* Restore any detached prefixes */
+       pfxlist_onlink_check();
+}
+
+void
+in6_if_up(struct ifnet *ifp)
+{
+
        /*
         * special cases, like 6to4, are handled in in6_ifattach
         */
        in6_ifattach(ifp, NULL);
 
-       /* Restore any detached prefixes */
-       pfxlist_onlink_check();
+       /* interface may not support link state, so bring it up also */
+       in6_if_link_up(ifp);
 }
-
 /*
  * Mark all addresses as detached.
  */
 void
-in6_if_down(struct ifnet *ifp)
+in6_if_link_down(struct ifnet *ifp)
 {
        struct ifaddr *ifa;
        struct in6_ifaddr *ia;
 
+       /* Any prefixes on this interface should be detached as well */
+       pfxlist_onlink_check();
+
        IFADDR_FOREACH(ifa, ifp) {
                if (ifa->ifa_addr->sa_family != AF_INET6)
                        continue;
@@ -2249,9 +2259,13 @@
                        nd6_newaddrmsg(ifa);
                }
        }
+}
 
-       /* Any prefixes on this interface should be detached as well */
-       pfxlist_onlink_check();
+void
+in6_if_down(struct ifnet *ifp)
+{
+
+       in6_if_link_down(ifp);
 }
 
 int
diff -r 8a7e5d0a04e5 -r 975dfbbe224b sys/netinet6/in6.h
--- a/sys/netinet6/in6.h        Thu Jun 20 13:42:02 2013 +0000
+++ b/sys/netinet6/in6.h        Thu Jun 20 13:56:29 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in6.h,v 1.72 2013/06/11 12:08:29 roy Exp $     */
+/*     $NetBSD: in6.h,v 1.73 2013/06/20 13:56:29 roy Exp $     */
 /*     $KAME: in6.h,v 1.83 2001/03/29 02:55:07 jinmei Exp $    */
 
 /*
@@ -700,6 +700,8 @@
 int    in6_localaddr(const struct in6_addr *);
 int    in6_addrscope(const struct in6_addr *);
 struct in6_ifaddr *in6_ifawithifp(struct ifnet *, struct in6_addr *);
+extern void in6_if_link_up(struct ifnet *);
+extern void in6_if_link_down(struct ifnet *);
 extern void in6_if_up(struct ifnet *);
 extern void in6_if_down(struct ifnet *);
 #ifndef __FreeBSD__
diff -r 8a7e5d0a04e5 -r 975dfbbe224b sys/netinet6/nd6_rtr.c
--- a/sys/netinet6/nd6_rtr.c    Thu Jun 20 13:42:02 2013 +0000
+++ b/sys/netinet6/nd6_rtr.c    Thu Jun 20 13:56:29 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nd6_rtr.c,v 1.88 2013/06/11 12:08:29 roy Exp $ */
+/*     $NetBSD: nd6_rtr.c,v 1.89 2013/06/20 13:56:29 roy Exp $ */
 /*     $KAME: nd6_rtr.c,v 1.95 2001/02/07 08:09:47 itojun Exp $        */
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nd6_rtr.c,v 1.88 2013/06/11 12:08:29 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6_rtr.c,v 1.89 2013/06/20 13:56:29 roy Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -1404,11 +1404,12 @@
 
        for (pfxrtr = LIST_FIRST(&pr->ndpr_advrtrs); pfxrtr;
             pfxrtr = LIST_NEXT(pfxrtr, pfr_entry)) {
-               if ((rt = nd6_lookup(&pfxrtr->router->rtaddr, 0,
+               if (pfxrtr->router->ifp->if_flags & IFF_UP &&
+                   pfxrtr->router->ifp->if_link_state != LINK_STATE_DOWN &&
+                   (rt = nd6_lookup(&pfxrtr->router->rtaddr, 0,
                    pfxrtr->router->ifp)) &&
                    (ln = (struct llinfo_nd6 *)rt->rt_llinfo) &&
-                   ND6_IS_LLINFO_PROBREACH(ln) &&
-                   pfxrtr->router->ifp->if_link_state != LINK_STATE_DOWN)
+                   ND6_IS_LLINFO_PROBREACH(ln))
                        break;  /* found */
        }
 



Home | Main Index | Thread Index | Old Index