git: fd67a7587c1a - stable/14 - if_tuntap: make SIOCIFDESTROY interruptible
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 12 Apr 2026 13:44:08 UTC
The branch stable/14 has been updated by kevans:
URL: https://cgit.FreeBSD.org/src/commit/?id=fd67a7587c1a187cc162cf02ece94f4142874f35
commit fd67a7587c1a187cc162cf02ece94f4142874f35
Author: Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2025-08-21 14:21:41 +0000
Commit: Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2026-04-12 13:43:37 +0000
if_tuntap: make SIOCIFDESTROY interruptible
There's no good justification to permanently hang a thread until the
tunnel can be destroyed. Make it interruptible so that the admin can
^C it and remedy the situation if something erroneously has the tunnel
open, rather than forcing them to open another shell to resolve it.
Reviewed by: markj
(cherry picked from commit 274bf7c8ae7e7b51853cd541481985f0e687f10e)
---
sys/net/if_tuntap.c | 40 ++++++++++++++++++++++++++--------------
1 file changed, 26 insertions(+), 14 deletions(-)
diff --git a/sys/net/if_tuntap.c b/sys/net/if_tuntap.c
index 45d981de9fdb..f42daed4a68d 100644
--- a/sys/net/if_tuntap.c
+++ b/sys/net/if_tuntap.c
@@ -623,19 +623,34 @@ out:
CURVNET_RESTORE();
}
-static void
-tun_destroy(struct tuntap_softc *tp)
+static int
+tun_destroy(struct tuntap_softc *tp, bool may_intr)
{
+ int error;
TUN_LOCK(tp);
+ MPASS((tp->tun_flags & TUN_DYING) == 0);
tp->tun_flags |= TUN_DYING;
- if (tp->tun_busy != 0)
- cv_wait_unlock(&tp->tun_cv, &tp->tun_mtx);
- else
- TUN_UNLOCK(tp);
+ error = 0;
+ while (tp->tun_busy != 0) {
+ if (may_intr)
+ error = cv_wait_sig(&tp->tun_cv, &tp->tun_mtx);
+ else
+ cv_wait(&tp->tun_cv, &tp->tun_mtx);
+ if (error != 0) {
+ tp->tun_flags &= ~TUN_DYING;
+ TUN_UNLOCK(tp);
+ return (error);
+ }
+ }
+ TUN_UNLOCK(tp);
CURVNET_SET(TUN2IFP(tp)->if_vnet);
+ mtx_lock(&tunmtx);
+ TAILQ_REMOVE(&tunhead, tp, tun_list);
+ mtx_unlock(&tunmtx);
+
/* destroy_dev will take care of any alias. */
destroy_dev(tp->tun_dev);
seldrain(&tp->tun_rsel);
@@ -656,6 +671,8 @@ tun_destroy(struct tuntap_softc *tp)
cv_destroy(&tp->tun_cv);
free(tp, M_TUN);
CURVNET_RESTORE();
+
+ return (0);
}
static int
@@ -663,12 +680,7 @@ tun_clone_destroy(struct if_clone *ifc __unused, struct ifnet *ifp, uint32_t fla
{
struct tuntap_softc *tp = ifp->if_softc;
- mtx_lock(&tunmtx);
- TAILQ_REMOVE(&tunhead, tp, tun_list);
- mtx_unlock(&tunmtx);
- tun_destroy(tp);
-
- return (0);
+ return (tun_destroy(tp, true));
}
static void
@@ -723,9 +735,9 @@ tun_uninit(const void *unused __unused)
mtx_lock(&tunmtx);
while ((tp = TAILQ_FIRST(&tunhead)) != NULL) {
- TAILQ_REMOVE(&tunhead, tp, tun_list);
mtx_unlock(&tunmtx);
- tun_destroy(tp);
+ /* tun_destroy() will remove it from the tailq. */
+ tun_destroy(tp, false);
mtx_lock(&tunmtx);
}
mtx_unlock(&tunmtx);