diff --git a/sys/net/if.c b/sys/net/if.c --- a/sys/net/if.c +++ b/sys/net/if.c @@ -273,6 +273,7 @@ */ static void if_attachdomain(void *); static void if_attachdomain1(struct ifnet *); +static void if_detachdomain1(struct ifnet *); static int ifconf(u_long, caddr_t); static void if_input_default(struct ifnet *, struct mbuf *); static int if_requestencap_default(struct ifnet *, struct if_encap_req *); @@ -1003,6 +1004,32 @@ } } +static void +if_detachdomain1(struct ifnet *ifp) +{ + int i; + struct domain *dp; + + /* + * We cannot hold the lock over dom_ifdetach calls as they might + * sleep, for example trying to drain a callout, thus open up the + * theoretical race with re-attaching. + */ + IF_AFDATA_LOCK(ifp); + i = ifp->if_afdata_initialized; + ifp->if_afdata_initialized = 0; + IF_AFDATA_UNLOCK(ifp); + if (i == 0) + return; + SLIST_FOREACH(dp, &domains, dom_next) { + if (dp->dom_ifdetach && ifp->if_afdata[dp->dom_family]) { + (*dp->dom_ifdetach)(ifp, + ifp->if_afdata[dp->dom_family]); + ifp->if_afdata[dp->dom_family] = NULL; + } + } +} + /* * Remove any unicast or broadcast network addresses from an interface. */ @@ -1115,8 +1142,6 @@ if_detach_internal(struct ifnet *ifp, bool vmove) { struct ifaddr *ifa; - int i; - struct domain *dp; #ifdef VIMAGE bool shutdown; @@ -1259,24 +1284,7 @@ #ifdef VIMAGE finish_vnet_shutdown: #endif - /* - * We cannot hold the lock over dom_ifdetach calls as they might - * sleep, for example trying to drain a callout, thus open up the - * theoretical race with re-attaching. - */ - IF_AFDATA_LOCK(ifp); - i = ifp->if_afdata_initialized; - ifp->if_afdata_initialized = 0; - IF_AFDATA_UNLOCK(ifp); - if (i == 0) - return; - SLIST_FOREACH(dp, &domains, dom_next) { - if (dp->dom_ifdetach && ifp->if_afdata[dp->dom_family]) { - (*dp->dom_ifdetach)(ifp, - ifp->if_afdata[dp->dom_family]); - ifp->if_afdata[dp->dom_family] = NULL; - } - } + if_detachdomain1(ifp); } #ifdef VIMAGE