Changeset View
Changeset View
Standalone View
Standalone View
sys/net/if.c
Show First 20 Lines • Show All 309 Lines • ▼ Show 20 Lines | |||||
* The global network interface list (V_ifnet) and related state (such as | * The global network interface list (V_ifnet) and related state (such as | ||||
* if_index, if_indexlim, and ifindex_table) are protected by an sxlock. | * if_index, if_indexlim, and ifindex_table) are protected by an sxlock. | ||||
* This may be acquired to stabilise the list, or we may rely on NET_EPOCH. | * This may be acquired to stabilise the list, or we may rely on NET_EPOCH. | ||||
*/ | */ | ||||
struct sx ifnet_sxlock; | struct sx ifnet_sxlock; | ||||
SX_SYSINIT_FLAGS(ifnet_sx, &ifnet_sxlock, "ifnet_sx", SX_RECURSE); | SX_SYSINIT_FLAGS(ifnet_sx, &ifnet_sxlock, "ifnet_sx", SX_RECURSE); | ||||
struct sx ifnet_detach_sxlock; | struct sx ifnet_detach_sxlock; | ||||
SX_SYSINIT(ifnet_detach, &ifnet_detach_sxlock, "ifnet_detach_sx"); | SX_SYSINIT_FLAGS(ifnet_detach, &ifnet_detach_sxlock, "ifnet_detach_sx", | ||||
SX_RECURSE); | |||||
/* | /* | ||||
* The allocation of network interfaces is a rather non-atomic affair; we | * 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 | * need to select an index before we are ready to expose the interface for | ||||
* use, so will use this pointer value to indicate reservation. | * use, so will use this pointer value to indicate reservation. | ||||
*/ | */ | ||||
#define IFNET_HOLD (void *)(uintptr_t)(-1) | #define IFNET_HOLD (void *)(uintptr_t)(-1) | ||||
▲ Show 20 Lines • Show All 214 Lines • ▼ Show 20 Lines | if (ifp->if_home_vnet != ifp->if_vnet) { | ||||
MPASS(found); | MPASS(found); | ||||
pending[i++] = ifp; | pending[i++] = ifp; | ||||
} | } | ||||
} | } | ||||
IFNET_WUNLOCK(); | IFNET_WUNLOCK(); | ||||
for (int j = 0; j < i; j++) { | for (int j = 0; j < i; j++) { | ||||
sx_xlock(&ifnet_detach_sxlock); | |||||
if_vmove(pending[j], pending[j]->if_home_vnet); | if_vmove(pending[j], pending[j]->if_home_vnet); | ||||
sx_xunlock(&ifnet_detach_sxlock); | |||||
} | } | ||||
free(pending, M_IFNET); | free(pending, M_IFNET); | ||||
} | } | ||||
VNET_SYSUNINIT(vnet_if_return, SI_SUB_VNET_DONE, SI_ORDER_ANY, | VNET_SYSUNINIT(vnet_if_return, SI_SUB_VNET_DONE, SI_ORDER_ANY, | ||||
vnet_if_return, NULL); | vnet_if_return, NULL); | ||||
#endif | #endif | ||||
▲ Show 20 Lines • Show All 559 Lines • ▼ Show 20 Lines | |||||
void | void | ||||
if_detach(struct ifnet *ifp) | if_detach(struct ifnet *ifp) | ||||
{ | { | ||||
bool found; | bool found; | ||||
CURVNET_SET_QUIET(ifp->if_vnet); | CURVNET_SET_QUIET(ifp->if_vnet); | ||||
found = if_unlink_ifnet(ifp, false); | found = if_unlink_ifnet(ifp, false); | ||||
if (found) { | if (found) { | ||||
sx_slock(&ifnet_detach_sxlock); | sx_xlock(&ifnet_detach_sxlock); | ||||
if_detach_internal(ifp, 0, NULL); | if_detach_internal(ifp, 0, NULL); | ||||
sx_sunlock(&ifnet_detach_sxlock); | sx_xunlock(&ifnet_detach_sxlock); | ||||
} | } | ||||
CURVNET_RESTORE(); | CURVNET_RESTORE(); | ||||
} | } | ||||
/* | /* | ||||
* The vmove flag, if set, indicates that we are called from a callpath | * The vmove flag, if set, indicates that we are called from a callpath | ||||
* that is moving an interface to a different vnet instance. | * that is moving an interface to a different vnet instance. | ||||
* | * | ||||
▲ Show 20 Lines • Show All 3,424 Lines • Show Last 20 Lines |