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
This commit is contained in:
Kristof Provost 2021-11-05 12:01:37 +01:00
parent 3576121c8b
commit 8e45fed3ae

View file

@ -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);