aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristof Provost <kp@FreeBSD.org>2021-11-05 11:01:37 +0000
committerKristof Provost <kp@FreeBSD.org>2021-11-09 08:39:53 +0000
commit8e45fed3aefd00ff544efce8fedeba5e099d3d01 (patch)
tree55ecd5e0190f6dbfa4974dd637cbcfe7ebd5fadb
parent3576121c8b1fcaa31b3a45ea52ff83f7c5855266 (diff)
downloadsrc-8e45fed3aefd00ff544efce8fedeba5e099d3d01.tar.gz
src-8e45fed3aefd00ff544efce8fedeba5e099d3d01.zip
if_stf: enable use in vnet jails
The cloner must be per-vnet so that cloned interfaces get destroyed when the vnet goes away. Otherwise we fail assertions in vnet_if_uninit(): panic: vnet_if_uninit:475 tailq &V_ifnet=0xfffffe01665fe070 not empty cpuid = 19 time = 1636107064 KDB: stack backtrace: db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe015d0cac60 vpanic() at vpanic+0x187/frame 0xfffffe015d0cacc0 panic() at panic+0x43/frame 0xfffffe015d0cad20 vnet_if_uninit() at vnet_if_uninit+0x7b/frame 0xfffffe015d0cad30 vnet_destroy() at vnet_destroy+0x170/frame 0xfffffe015d0cad60 prison_deref() at prison_deref+0x9b0/frame 0xfffffe015d0cadd0 sys_jail_remove() at sys_jail_remove+0x119/frame 0xfffffe015d0cae00 amd64_syscall() at amd64_syscall+0x12e/frame 0xfffffe015d0caf30 fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe015d0caf30 --- syscall (508, FreeBSD ELF64, sys_jail_remove), rip = 0x8011e920a, rsp = 0x7fffffffe788, rbp = 0x7fffffffe810 --- KDB: enter: panic MFC after: 3 weeks Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D32849
-rw-r--r--sys/net/if_stf.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/sys/net/if_stf.c b/sys/net/if_stf.c
index a18cf058a6e2..f80ba96e2f59 100644
--- a/sys/net/if_stf.c
+++ b/sys/net/if_stf.c
@@ -169,7 +169,8 @@ static int stf_ioctl(struct ifnet *, u_long, caddr_t);
static int stf_clone_match(struct if_clone *, const char *);
static int stf_clone_create(struct if_clone *, char *, size_t, caddr_t);
static int stf_clone_destroy(struct if_clone *, struct ifnet *);
-static struct if_clone *stf_cloner;
+VNET_DEFINE_STATIC(struct if_clone *, stf_cloner);
+#define V_stf_cloner VNET(stf_cloner)
static const struct encap_config ipv4_encap_cfg = {
.proto = IPPROTO_IPV6,
@@ -281,17 +282,33 @@ stf_clone_destroy(struct if_clone *ifc, struct ifnet *ifp)
return (0);
}
+static void
+vnet_stf_init(const void *unused __unused)
+{
+ V_stf_cloner = if_clone_advanced(stfname, 0, stf_clone_match,
+ stf_clone_create, stf_clone_destroy);
+}
+VNET_SYSINIT(vnet_stf_init, SI_SUB_PSEUDO, SI_ORDER_ANY, vnet_stf_init, NULL);
+
+static void
+vnet_stf_uninit(const void *unused __unused)
+{
+ if_clone_detach(V_stf_cloner);
+ V_stf_cloner = NULL;
+}
+VNET_SYSUNINIT(vnet_stf_uninit, SI_SUB_PSEUDO, SI_ORDER_ANY, vnet_stf_uninit,
+ NULL);
+
static int
stfmodevent(module_t mod, int type, void *data)
{
switch (type) {
case MOD_LOAD:
- stf_cloner = if_clone_advanced(stfname, 0, stf_clone_match,
- stf_clone_create, stf_clone_destroy);
+ /* Done in vnet_stf_init() */
break;
case MOD_UNLOAD:
- if_clone_detach(stf_cloner);
+ /* Done in vnet_stf_uninit() */
break;
default:
return (EOPNOTSUPP);