Recent NFS-related rtisvalid(9) regressions turns out to be related
to the use of DOWN RTF_CLONED route entries.  Such entries are DOWN
because they are cloned from a DOWN RTF_CLONING entry.

While investigating this race I figured out that we have different
code paths messing with link-state change.  Diff below unify them
all.  As a result two #ifdef chunks dies because dohook() is now
called.

ok?


Index: net/if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.385
diff -u -p -r1.385 if.c
--- net/if.c    5 Oct 2015 19:05:09 -0000       1.385
+++ net/if.c    8 Oct 2015 09:42:01 -0000
@@ -137,13 +137,14 @@ int       if_getgroupmembers(caddr_t);
 int    if_getgroupattribs(caddr_t);
 int    if_setgroupattribs(caddr_t);
 
+void   if_linkstate(void *);
+
 int    if_clone_list(struct if_clonereq *);
 struct if_clone        *if_clone_lookup(const char *, int *);
 
 int    if_group_egress_build(void);
 
 void   if_watchdog_task(void *);
-void   if_link_state_change_task(void *);
 
 void   if_input_process(void *);
 
@@ -408,7 +409,7 @@ if_attachsetup(struct ifnet *ifp)
        timeout_set(ifp->if_slowtimo, if_slowtimo, ifp);
        if_slowtimo(ifp);
 
-       task_set(ifp->if_linkstatetask, if_link_state_change_task, ifp);
+       task_set(ifp->if_linkstatetask, if_linkstate, ifp);
 
        if_idxmap_insert(ifp);
        KASSERT(if_get(0) == NULL);
@@ -1385,7 +1386,6 @@ if_downall(void)
 /*
  * Mark an interface down and notify protocols of
  * the transition.
- * NOTE: must be called at splsoftnet or equivalent.
  */
 void
 if_down(struct ifnet *ifp)
@@ -1400,24 +1400,13 @@ if_down(struct ifnet *ifp)
                pfctlinput(PRC_IFDOWN, ifa->ifa_addr);
        }
        IFQ_PURGE(&ifp->if_snd);
-#if NCARP > 0
-       if (ifp->if_carp)
-               carp_carpdev_state(ifp);
-#endif
-#if NBRIDGE > 0
-       if (ifp->if_bridgeport)
-               bstp_ifstate(ifp);
-#endif
-       rt_ifmsg(ifp);
-#ifndef SMALL_KERNEL
-       rt_if_track(ifp);
-#endif
+
+       if_linkstate(ifp);
 }
 
 /*
  * Mark an interface up and notify protocols of
  * the transition.
- * NOTE: must be called at splsoftnet or equivalent.
  */
 void
 if_up(struct ifnet *ifp)
@@ -1426,42 +1415,24 @@ if_up(struct ifnet *ifp)
 
        ifp->if_flags |= IFF_UP;
        microtime(&ifp->if_lastchange);
-#if NCARP > 0
-       if (ifp->if_carp)
-               carp_carpdev_state(ifp);
-#endif
-#if NBRIDGE > 0
-       if (ifp->if_bridgeport)
-               bstp_ifstate(ifp);
-#endif
-       rt_ifmsg(ifp);
+
 #ifdef INET6
        /* Userland expects the kernel to set ::1 on lo0. */
        if (ifp == lo0ifp)
                in6_ifattach(ifp);
 #endif
-#ifndef SMALL_KERNEL
-       rt_if_track(ifp);
-#endif
-}
 
-/*
- * Schedule a link state change task.
- */
-void
-if_link_state_change(struct ifnet *ifp)
-{
-       /* put the routing table update task on systq */
-       task_add(systq, ifp->if_linkstatetask);
+       if_linkstate(ifp);
 }
 
 /*
- * Process a link state change.
+ * Notify userland, the routing table and hooks owner of
+ * a link-state transition.
  */
 void
-if_link_state_change_task(void *arg)
+if_linkstate(void *xifp)
 {
-       struct ifnet *ifp = arg;
+       struct ifnet *ifp = xifp;
        int s;
 
        s = splsoftnet();
@@ -1471,6 +1442,15 @@ if_link_state_change_task(void *arg)
 #endif
        dohooks(ifp->if_linkstatehooks, 0);
        splx(s);
+}
+
+/*
+ * Schedule a link state change task.
+ */
+void
+if_link_state_change(struct ifnet *ifp)
+{
+       task_add(systq, ifp->if_linkstatetask);
 }
 
 /*

Reply via email to