diff options
author | Kristof Provost <kp@FreeBSD.org> | 2021-11-05 11:01:37 +0000 |
---|---|---|
committer | Kristof Provost <kp@FreeBSD.org> | 2021-11-09 08:39:53 +0000 |
commit | 8e45fed3aefd00ff544efce8fedeba5e099d3d01 (patch) | |
tree | 55ecd5e0190f6dbfa4974dd637cbcfe7ebd5fadb | |
parent | 3576121c8b1fcaa31b3a45ea52ff83f7c5855266 (diff) | |
download | src-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.c | 25 |
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); |