Index: sys/net/if.c =================================================================== --- sys/net/if.c +++ sys/net/if.c @@ -314,6 +314,9 @@ struct sx ifnet_sxlock; SX_SYSINIT_FLAGS(ifnet_sx, &ifnet_sxlock, "ifnet_sx", SX_RECURSE); +struct sx ifnet_detach_sxlock; +SX_SYSINIT(ifnet_detach, &ifnet_detach_sxlock, "ifnet_detach_sx"); + /* * The allocation of network interfaces is a rather non-atomic affair; we * need to select an index before we are ready to expose the interface for @@ -543,7 +546,9 @@ IFNET_WUNLOCK(); for (int j = 0; j < i; j++) { + sx_xlock(&ifnet_detach_sxlock); if_vmove(pending[j], pending[j]->if_home_vnet); + sx_xunlock(&ifnet_detach_sxlock); } free(pending, M_IFNET); @@ -1118,8 +1123,11 @@ CURVNET_SET_QUIET(ifp->if_vnet); found = if_unlink_ifnet(ifp, false); - if (found) + if (found) { + sx_slock(&ifnet_detach_sxlock); if_detach_internal(ifp, 0, NULL); + sx_sunlock(&ifnet_detach_sxlock); + } CURVNET_RESTORE(); } @@ -3010,8 +3018,12 @@ goto out_noref; case SIOCIFDESTROY: error = priv_check(td, PRIV_NET_IFDESTROY); - if (error == 0) + + if (error == 0) { + sx_slock(&ifnet_detach_sxlock); error = if_clone_destroy(ifr->ifr_name); + sx_sunlock(&ifnet_detach_sxlock); + } goto out_noref; case SIOCIFGCLONERS: