Index: sys/net/if.c =================================================================== --- sys/net/if.c +++ sys/net/if.c @@ -472,11 +472,23 @@ { struct ifnet *ifp, *nifp; + /* We need to protect our access to the V_ifnet tailq. Ordinarily we'd + * enter NET_EPOCH, but that's not possible, because if_vmove() calls + * if_detach_internal(), which waits for NET_EPOCH callbacks to + * complete. We can't do that from within NET_EPOCH. + * + * However, we can also use the IFNET_xLOCK, which is the V_ifnet + * read/write lock. We take this lock from within if_vmove() as well, + * but it's a recursive lock, so that's safe. We do have to take the + * write lock, because we need the write lock in if_vmove(). + */ + IFNET_WLOCK(); /* Return all inherited interfaces to their parent vnets. */ CK_STAILQ_FOREACH_SAFE(ifp, &V_ifnet, if_link, nifp) { if (ifp->if_home_vnet != ifp->if_vnet) if_vmove(ifp, ifp->if_home_vnet); } + IFNET_WUNLOCK(); } VNET_SYSUNINIT(vnet_if_return, SI_SUB_VNET_DONE, SI_ORDER_ANY, vnet_if_return, NULL);