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);
}
/*