Changeset View
Changeset View
Standalone View
Standalone View
sys/net/if.c
| Show First 20 Lines • Show All 1,185 Lines • ▼ Show 20 Lines | #endif | ||||
| bpf_vmove(ifp->if_bpf); | bpf_vmove(ifp->if_bpf); | ||||
| CURVNET_RESTORE(); | CURVNET_RESTORE(); | ||||
| } | } | ||||
| /* | /* | ||||
| * Move an ifnet to or from another child prison/vnet, specified by the jail id. | * Move an ifnet to or from another child prison/vnet, specified by the jail id. | ||||
| */ | */ | ||||
| static int | static int | ||||
| if_vmove_loan(struct thread *td, struct ifnet *ifp, char *ifname, int jid) | if_vmove_loan(struct thread *td, char *ifname, int jid) | ||||
| { | { | ||||
| struct prison *pr; | struct prison *pr; | ||||
| struct ifnet *difp; | struct ifnet *ifp, *difp; | ||||
| bool found; | bool found; | ||||
| MPASS(curthread == td); | |||||
| MPASS(curvnet == TD_TO_VNET(td)); | |||||
| /* | |||||
| * We check the existence of the interface, and will later try to | |||||
| * unlink it from the "active" list, so it is sufficient to only | |||||
| * hold a weak reference to it. | |||||
| * Be aware that it is unsafe to access any member of it, until it | |||||
| * is proven to be safe to ( say it was on the "active" list ). | |||||
| */ | |||||
| ifp = ifunit(ifname); | |||||
| if (ifp == NULL) | |||||
| return (ENXIO); | |||||
| /* Try to find the prison within our visibility. */ | /* Try to find the prison within our visibility. */ | ||||
zlei: This revision is based on latest main, so this removal is competing with D55875 .
I'd… | |||||
| 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); | ||||
Not Done Inline ActionsThe error ENXIO means the interface does not exists. Should choose a better error to distinguish that with the case not found child prison / vnet. zlei: The error `ENXIO` means the interface does not exists. Should choose a better error to… | |||||
| prison_hold_locked(pr); | /* Do not try to move the iface from and to the same vnet. */ | ||||
| if (pr->pr_vnet == TD_TO_VNET(td)) { | |||||
| mtx_unlock(&pr->pr_mtx); | mtx_unlock(&pr->pr_mtx); | ||||
| /* Do not try to move the iface from and to the same prison. */ | |||||
| if (pr->pr_vnet == ifp->if_vnet) { | |||||
| prison_free(pr); | |||||
| return (EEXIST); | return (EEXIST); | ||||
| } | } | ||||
| prison_hold_locked(pr); | |||||
| mtx_unlock(&pr->pr_mtx); | |||||
| /* 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); | ||||
| CURVNET_RESTORE(); | CURVNET_RESTORE(); | ||||
| if (difp != NULL) { | if (difp != NULL) { | ||||
| prison_free(pr); | prison_free(pr); | ||||
| ▲ Show 20 Lines • Show All 1,353 Lines • ▼ Show 20 Lines | if (error) | ||||
| return (error); | return (error); | ||||
| error = copyinstr(ifr_data_get_ptr(ifr), new_name, IFNAMSIZ, | error = copyinstr(ifr_data_get_ptr(ifr), new_name, IFNAMSIZ, | ||||
| NULL); | NULL); | ||||
| if (error != 0) | if (error != 0) | ||||
| return (error); | return (error); | ||||
| error = if_rename(ifp, new_name); | error = if_rename(ifp, new_name); | ||||
| break; | break; | ||||
| #ifdef VIMAGE | |||||
| case SIOCSIFVNET: | |||||
| error = priv_check(td, PRIV_NET_SETIFVNET); | |||||
| if (error) | |||||
| return (error); | |||||
| error = if_vmove_loan(td, ifp, ifr->ifr_name, ifr->ifr_jid); | |||||
| break; | |||||
| #endif | |||||
| case SIOCSIFMETRIC: | case SIOCSIFMETRIC: | ||||
| error = priv_check(td, PRIV_NET_SETIFMETRIC); | error = priv_check(td, PRIV_NET_SETIFMETRIC); | ||||
| if (error) | if (error) | ||||
| return (error); | return (error); | ||||
| ifp->if_metric = ifr->ifr_metric; | ifp->if_metric = ifr->ifr_metric; | ||||
| getmicrotime(&ifp->if_lastchange); | getmicrotime(&ifp->if_lastchange); | ||||
| break; | break; | ||||
| ▲ Show 20 Lines • Show All 271 Lines • ▼ Show 20 Lines | #endif | ||||
| case SIOCGIFCONF: | case SIOCGIFCONF: | ||||
| error = ifconf(cmd, data); | error = ifconf(cmd, data); | ||||
| goto out_noref; | goto out_noref; | ||||
| } | } | ||||
| ifr = (struct ifreq *)data; | ifr = (struct ifreq *)data; | ||||
| switch (cmd) { | switch (cmd) { | ||||
| #ifdef VIMAGE | #ifdef VIMAGE | ||||
| case SIOCSIFVNET: | |||||
| error = priv_check(td, PRIV_NET_SETIFVNET); | |||||
| if (error == 0) | |||||
| error = if_vmove_loan(td, ifr->ifr_name, ifr->ifr_jid); | |||||
| goto out_noref; | |||||
| case SIOCSIFRVNET: | case SIOCSIFRVNET: | ||||
| error = priv_check(td, PRIV_NET_SETIFVNET); | error = priv_check(td, PRIV_NET_SETIFVNET); | ||||
| if (error == 0) | if (error == 0) | ||||
| error = if_vmove_reclaim(td, ifr->ifr_name, | error = if_vmove_reclaim(td, ifr->ifr_name, | ||||
| ifr->ifr_jid); | ifr->ifr_jid); | ||||
| goto out_noref; | goto out_noref; | ||||
| #endif | #endif | ||||
| case SIOCIFCREATE: | case SIOCIFCREATE: | ||||
| ▲ Show 20 Lines • Show All 2,226 Lines • Show Last 20 Lines | |||||
This revision is based on latest main, so this removal is competing with D55875 .
I'd personally prefer to land this first. With this change it is more robust to check "the moving between the same vnet".