aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2021-03-24 11:13:12 -0600
committerJason A. Donenfeld <Jason@zx2c4.com>2021-03-24 12:03:58 -0600
commit1f6818b7e4bab23b3ab471d752d6c481453e9622 (patch)
tree2e07d5e651a7bb6420fc2b12711491868128d4b7
parentif_wg: remove old link state check (diff)
downloadwireguard-freebsd-1f6818b7e4bab23b3ab471d752d6c481453e9622.tar.xz
wireguard-freebsd-1f6818b7e4bab23b3ab471d752d6c481453e9622.zip
if_wg: simplify jail exit logic
We already handle vnet stuff on wg_reassign, and handling it here means that everytime we toggle any jail that shares the vnet, we render the link useless. Reported-by: Matt Smith <matt.r.smith@bt.com> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r--src/if_wg.c39
1 files changed, 9 insertions, 30 deletions
diff --git a/src/if_wg.c b/src/if_wg.c
index 82f62c2..1434369 100644
--- a/src/if_wg.c
+++ b/src/if_wg.c
@@ -3328,6 +3328,9 @@ wg_clone_destroy(struct ifnet *ifp)
sx_xunlock(&wg_sx);
if_link_state_change(sc->sc_ifp, LINK_STATE_DOWN);
+ CURVNET_SET(sc->sc_ifp->if_vnet);
+ if_purgeaddrs(sc->sc_ifp);
+ CURVNET_RESTORE();
sx_xlock(&sc->sc_lock);
wg_socket_uninit(sc);
@@ -3426,8 +3429,6 @@ wg_prison_remove(void *obj, void *data __unused)
{
const struct prison *pr = obj;
struct wg_softc *sc;
- struct ucred *cred;
- bool dying;
/*
* Do a pass through all if_wg interfaces and release creds on any from
@@ -3436,39 +3437,17 @@ wg_prison_remove(void *obj, void *data __unused)
*/
sx_slock(&wg_sx);
LIST_FOREACH(sc, &wg_list, sc_entry) {
- cred = NULL;
-
sx_xlock(&sc->sc_lock);
- dying = (sc->sc_flags & WGF_DYING) != 0;
- if (!dying && sc->sc_ucred != NULL &&
- sc->sc_ucred->cr_prison == pr) {
- /* Home jail is going away. */
- cred = sc->sc_ucred;
- sc->sc_ucred = NULL;
-
- sc->sc_flags |= WGF_DYING;
- }
-
- /*
- * If this is our foreign vnet going away, we'll also down the
- * link and kill the socket because traffic needs to stop. Any
- * address will be revoked in the rehoming process.
- */
- if (cred != NULL || (!dying &&
- sc->sc_ifp->if_vnet == pr->pr_vnet)) {
+ if (!(sc->sc_flags & WGF_DYING) && sc->sc_ucred && sc->sc_ucred->cr_prison == pr) {
+ struct ucred *cred = sc->sc_ucred;
+ DPRINTF(sc, "Creating jail exiting\n");
if_link_state_change(sc->sc_ifp, LINK_STATE_DOWN);
- /* Have to kill the sockets, as they also hold refs. */
wg_socket_uninit(sc);
- }
-
- sx_xunlock(&sc->sc_lock);
-
- if (cred != NULL) {
- CURVNET_SET(sc->sc_ifp->if_vnet);
- if_purgeaddrs(sc->sc_ifp);
- CURVNET_RESTORE();
+ sc->sc_ucred = NULL;
crfree(cred);
+ sc->sc_flags |= WGF_DYING;
}
+ sx_xunlock(&sc->sc_lock);
}
sx_sunlock(&wg_sx);