Changeset View
Changeset View
Standalone View
Standalone View
sys/net/if.c
Show First 20 Lines • Show All 507 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 782 Lines • ▼ Show 20 Lines | |||||
if_vmove_loan(struct thread *td, struct ifnet *ifp, char *ifname, int jid) | if_vmove_loan(struct thread *td, struct ifnet *ifp, char *ifname, int jid) | ||||
{ | { | ||||
struct prison *pr; | struct prison *pr; | ||||
struct ifnet *difp; | struct ifnet *difp; | ||||
int error; | int error; | ||||
bool found __diagused; | bool found __diagused; | ||||
bool shutdown; | bool shutdown; | ||||
MPASS(ifindex_table[ifp->if_index].ife_ifnet == ifp); | |||||
/* Try to find the prison within our visibility. */ | /* Try to find the prison within our visibility. */ | ||||
sx_slock(&allprison_lock); | sx_slock(&allprison_lock); | ||||
pr = prison_find_child(td->td_ucred->cr_prison, jid); | pr = prison_find_child(td->td_ucred->cr_prison, jid); | ||||
sx_sunlock(&allprison_lock); | sx_sunlock(&allprison_lock); | ||||
if (pr == NULL) | if (pr == NULL) | ||||
return (ENXIO); | return (ENXIO); | ||||
prison_hold_locked(pr); | prison_hold_locked(pr); | ||||
mtx_unlock(&pr->pr_mtx); | mtx_unlock(&pr->pr_mtx); | ||||
/* Do not try to move the iface from and to the same prison. */ | /* Do not try to move the iface from and to the same prison. */ | ||||
if (pr->pr_vnet == ifp->if_vnet) { | if (pr->pr_vnet == ifp->if_vnet) { | ||||
prison_free(pr); | prison_free(pr); | ||||
return (EEXIST); | return (EEXIST); | ||||
} | } | ||||
/* Make sure the named iface does not exists in the dst. prison/vnet. */ | /* Make sure the named iface does not exists in the dst. prison/vnet. */ | ||||
/* XXX Lock interfaces to avoid races. */ | /* XXX Lock interfaces to avoid races. */ | ||||
CURVNET_SET_QUIET(pr->pr_vnet); | CURVNET_SET_QUIET(pr->pr_vnet); | ||||
difp = ifunit(ifname); | difp = ifunit(ifname); | ||||
if (difp != NULL) { | if (difp != NULL) { | ||||
CURVNET_RESTORE(); | CURVNET_RESTORE(); | ||||
prison_free(pr); | prison_free(pr); | ||||
return (EEXIST); | return (EEXIST); | ||||
} | } | ||||
sx_xlock(&ifnet_detach_sxlock); | |||||
/* Make sure the VNET is stable. */ | /* Make sure the VNET is stable. */ | ||||
shutdown = VNET_IS_SHUTTING_DOWN(ifp->if_vnet); | shutdown = VNET_IS_SHUTTING_DOWN(ifp->if_vnet); | ||||
if (shutdown) { | if (shutdown) { | ||||
sx_xunlock(&ifnet_detach_sxlock); | |||||
CURVNET_RESTORE(); | CURVNET_RESTORE(); | ||||
prison_free(pr); | prison_free(pr); | ||||
return (EBUSY); | return (EBUSY); | ||||
} | } | ||||
CURVNET_RESTORE(); | CURVNET_RESTORE(); | ||||
found = if_unlink_ifnet(ifp, true); | found = if_unlink_ifnet(ifp, true); | ||||
MPASS(found); | if (! found) { | ||||
sx_xunlock(&ifnet_detach_sxlock); | |||||
CURVNET_RESTORE(); | |||||
prison_free(pr); | |||||
return (ENODEV); | |||||
} | |||||
/* Move the interface into the child jail/vnet. */ | /* Move the interface into the child jail/vnet. */ | ||||
error = if_vmove(ifp, pr->pr_vnet); | error = if_vmove(ifp, pr->pr_vnet); | ||||
/* Report the new if_xname back to the userland on success. */ | /* Report the new if_xname back to the userland on success. */ | ||||
if (error == 0) | if (error == 0) | ||||
sprintf(ifname, "%s", ifp->if_xname); | sprintf(ifname, "%s", ifp->if_xname); | ||||
sx_xunlock(&ifnet_detach_sxlock); | |||||
prison_free(pr); | prison_free(pr); | ||||
return (error); | return (error); | ||||
} | } | ||||
static int | static int | ||||
if_vmove_reclaim(struct thread *td, char *ifname, int jid) | if_vmove_reclaim(struct thread *td, char *ifname, int jid) | ||||
{ | { | ||||
struct prison *pr; | struct prison *pr; | ||||
Show All 34 Lines | if (shutdown) { | ||||
CURVNET_RESTORE(); | CURVNET_RESTORE(); | ||||
prison_free(pr); | prison_free(pr); | ||||
return (EBUSY); | return (EBUSY); | ||||
} | } | ||||
/* Get interface back from child jail/vnet. */ | /* Get interface back from child jail/vnet. */ | ||||
found = if_unlink_ifnet(ifp, true); | found = if_unlink_ifnet(ifp, true); | ||||
MPASS(found); | MPASS(found); | ||||
sx_xlock(&ifnet_detach_sxlock); | |||||
error = if_vmove(ifp, vnet_dst); | error = if_vmove(ifp, vnet_dst); | ||||
sx_xunlock(&ifnet_detach_sxlock); | |||||
CURVNET_RESTORE(); | CURVNET_RESTORE(); | ||||
/* Report the new if_xname back to the userland on success. */ | /* Report the new if_xname back to the userland on success. */ | ||||
if (error == 0) | if (error == 0) | ||||
sprintf(ifname, "%s", ifp->if_xname); | sprintf(ifname, "%s", ifp->if_xname); | ||||
prison_free(pr); | prison_free(pr); | ||||
return (error); | return (error); | ||||
▲ Show 20 Lines • Show All 860 Lines • ▼ Show 20 Lines | ifunit_ref(const char *name) | ||||
struct ifnet *ifp; | struct ifnet *ifp; | ||||
NET_EPOCH_ENTER(et); | NET_EPOCH_ENTER(et); | ||||
CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) { | CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) { | ||||
if (strncmp(name, ifp->if_xname, IFNAMSIZ) == 0 && | if (strncmp(name, ifp->if_xname, IFNAMSIZ) == 0 && | ||||
!(ifp->if_flags & IFF_DYING)) | !(ifp->if_flags & IFF_DYING)) | ||||
break; | break; | ||||
} | } | ||||
if (ifp != NULL) | if (ifp != NULL) { | ||||
if_ref(ifp); | if_ref(ifp); | ||||
MPASS(ifindex_table[ifp->if_index].ife_ifnet == ifp); | |||||
} | |||||
NET_EPOCH_EXIT(et); | NET_EPOCH_EXIT(et); | ||||
return (ifp); | return (ifp); | ||||
} | } | ||||
struct ifnet * | struct ifnet * | ||||
ifunit(const char *name) | ifunit(const char *name) | ||||
{ | { | ||||
struct epoch_tracker et; | struct epoch_tracker et; | ||||
▲ Show 20 Lines • Show All 2,289 Lines • Show Last 20 Lines |