diff options
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/flowtable.c | 40 | ||||
-rw-r--r-- | sys/net/if.c | 52 | ||||
-rw-r--r-- | sys/net/if_clone.c | 18 | ||||
-rw-r--r-- | sys/net/if_clone.h | 1 | ||||
-rw-r--r-- | sys/net/if_gif.c | 60 | ||||
-rw-r--r-- | sys/net/if_loop.c | 56 | ||||
-rw-r--r-- | sys/net/route.c | 40 | ||||
-rw-r--r-- | sys/net/rtsock.c | 4 | ||||
-rw-r--r-- | sys/net/vnet.c | 142 | ||||
-rw-r--r-- | sys/net/vnet.h | 51 |
10 files changed, 271 insertions, 193 deletions
diff --git a/sys/net/flowtable.c b/sys/net/flowtable.c index d16ffa3..1fe2bbe 100644 --- a/sys/net/flowtable.c +++ b/sys/net/flowtable.c @@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$"); #include <net/if_var.h> #include <net/route.h> #include <net/flowtable.h> +#include <net/vnet.h> #include <netinet/in.h> #include <netinet/in_systm.h> @@ -173,18 +174,6 @@ static VNET_DEFINE(uma_zone_t, flow_ipv6_zone); #define V_flow_ipv4_zone VNET(flow_ipv4_zone) #define V_flow_ipv6_zone VNET(flow_ipv6_zone) -static int flowtable_iattach(const void *); -#ifdef VIMAGE -static int flowtable_idetach(const void *); - -static const vnet_modinfo_t flowtable_modinfo = { - .vmi_id = VNET_MOD_FLOWTABLE, - .vmi_name = "flowtable", - .vmi_iattach = flowtable_iattach, - .vmi_idetach = flowtable_idetach -}; -#endif - /* * TODO: * - Make flowtable stats per-cpu, aggregated at sysctl call time, @@ -802,18 +791,7 @@ flowtable_alloc(int nentry, int flags) } static void -flowtable_setup(void *arg) -{ - -#ifdef VIMAGE - vnet_mod_register(&flowtable_modinfo); -#else - flowtable_iattach(NULL); -#endif -} - -static int -flowtable_iattach(const void *unused __unused) +flowtable_init(const void *unused __unused) { V_flow_ipv4_zone = uma_zcreate("ip4flow", sizeof(struct flentry_v4), @@ -822,21 +800,23 @@ flowtable_iattach(const void *unused __unused) NULL, NULL, NULL, NULL, 64, UMA_ZONE_MAXBUCKET); uma_zone_set_max(V_flow_ipv4_zone, V_flowtable_nmbflows); uma_zone_set_max(V_flow_ipv6_zone, V_flowtable_nmbflows); - return (0); } +VNET_SYSINIT(flowtable_init, SI_SUB_KTHREAD_INIT, SI_ORDER_ANY, + flowtable_init, NULL); + #ifdef VIMAGE -static int -flowtable_idetach(const void *unused __unused) +static void +flowtable_uninit(const void *unused __unused) { uma_zdestroy(V_flow_ipv4_zone); uma_zdestroy(V_flow_ipv6_zone); - return (0); } -#endif -SYSINIT(flowtable_setup, SI_SUB_KTHREAD_INIT, SI_ORDER_ANY, flowtable_setup, NULL); +VNET_SYSUNINIT(flowtable_uninit, SI_SUB_KTHREAD_INIT, SI_ORDER_ANY, + flowtable_uninit, NULL); +#endif /* * The rest of the code is devoted to garbage collection of expired entries. diff --git a/sys/net/if.c b/sys/net/if.c index 608eb08..3916675 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -150,11 +150,6 @@ static void if_detach_internal(struct ifnet *, int); extern void nd6_setmtu(struct ifnet *); #endif -static int vnet_net_iattach(const void *); -#ifdef VIMAGE -static int vnet_net_idetach(const void *); -#endif - VNET_DEFINE(struct ifnethead, ifnet); /* depend on static init XXX */ VNET_DEFINE(struct ifgrouphead, ifg_head); VNET_DEFINE(int, if_index); @@ -171,19 +166,9 @@ struct rwlock ifnet_lock; static if_com_alloc_t *if_com_alloc[256]; static if_com_free_t *if_com_free[256]; -#ifdef VIMAGE -static const vnet_modinfo_t vnet_net_modinfo = { - .vmi_id = VNET_MOD_NET, - .vmi_name = "net", - .vmi_iattach = vnet_net_iattach, - .vmi_idetach = vnet_net_idetach -}; -#endif - /* * System initialization */ -SYSINIT(interfaces, SI_SUB_INIT_IF, SI_ORDER_FIRST, if_init, NULL); SYSINIT(interface_check, SI_SUB_PROTO_IF, SI_ORDER_FIRST, if_check, NULL); MALLOC_DEFINE(M_IFNET, "ifnet", "interface internals"); @@ -255,44 +240,41 @@ ifaddr_byindex(u_short idx) * parameters. */ +static void +vnet_if_init(const void *unused __unused) +{ + + TAILQ_INIT(&V_ifnet); + TAILQ_INIT(&V_ifg_head); + if_grow(); /* create initial table */ + vnet_if_clone_init(); +} +VNET_SYSINIT(vnet_if_init, SI_SUB_INIT_IF, SI_ORDER_FIRST, vnet_if_init, + NULL); + /* ARGSUSED*/ static void if_init(void *dummy __unused) { -#ifdef VIMAGE - vnet_mod_register(&vnet_net_modinfo); -#else - vnet_net_iattach(NULL); -#endif - IFNET_LOCK_INIT(); if_clone_init(); } +SYSINIT(interfaces, SI_SUB_INIT_IF, SI_ORDER_SECOND, if_init, NULL); -static int -vnet_net_iattach(const void *unused __unused) -{ - - TAILQ_INIT(&V_ifnet); - TAILQ_INIT(&V_ifg_head); - if_grow(); /* create initial table */ - - return (0); -} #ifdef VIMAGE -static int -vnet_net_idetach(const void *unused __unused) +static void +vnet_if_uninit(const void *unused __unused) { VNET_ASSERT(TAILQ_EMPTY(&V_ifnet)); VNET_ASSERT(TAILQ_EMPTY(&V_ifg_head)); free((caddr_t)V_ifindex_table, M_IFNET); - - return (0); } +VNET_SYSUNINIT(vnet_if_uninit, SI_SUB_INIT_IF, SI_ORDER_FIRST, + vnet_if_uninit, NULL); #endif void diff --git a/sys/net/if_clone.c b/sys/net/if_clone.c index 4e3f787..95c07b7 100644 --- a/sys/net/if_clone.c +++ b/sys/net/if_clone.c @@ -55,7 +55,6 @@ static void if_clone_free(struct if_clone *ifc); static int if_clone_createif(struct if_clone *ifc, char *name, size_t len, caddr_t params); -static int vnet_clone_iattach(const void *); static struct mtx if_cloners_mtx; static VNET_DEFINE(int, if_cloners_count); @@ -116,19 +115,11 @@ VNET_DEFINE(LIST_HEAD(, if_clone), if_cloners); static MALLOC_DEFINE(M_CLONE, "clone", "interface cloning framework"); -#ifdef VIMAGE -static const vnet_modinfo_t vnet_clone_modinfo = { - .vmi_id = VNET_MOD_IF_CLONE, - .vmi_name = "if_clone", - .vmi_iattach = vnet_clone_iattach -}; -#endif - -static int vnet_clone_iattach(const void *unused __unused) +void +vnet_if_clone_init(void) { LIST_INIT(&V_if_cloners); - return (0); } void @@ -136,11 +127,6 @@ if_clone_init(void) { IF_CLONERS_LOCK_INIT(); -#ifdef VIMAGE - vnet_mod_register(&vnet_clone_modinfo); -#else - vnet_clone_iattach(NULL); -#endif } /* diff --git a/sys/net/if_clone.h b/sys/net/if_clone.h index 280a545..f125f8b 100644 --- a/sys/net/if_clone.h +++ b/sys/net/if_clone.h @@ -72,6 +72,7 @@ struct if_clone { void if_clone_init(void); void if_clone_attach(struct if_clone *); void if_clone_detach(struct if_clone *); +void vnet_if_clone_init(void); int if_clone_create(char *, size_t, caddr_t); int if_clone_destroy(const char *); diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c index f663283..3d75dd4 100644 --- a/sys/net/if_gif.c +++ b/sys/net/if_gif.c @@ -96,19 +96,15 @@ static struct mtx gif_mtx; static MALLOC_DEFINE(M_GIF, "gif", "Generic Tunnel Interface"); static VNET_DEFINE(LIST_HEAD(, gif_softc), gif_softc_list); -static VNET_DEFINE(int, max_gif_nesting); -static VNET_DEFINE(int, parallel_tunnels); #define V_gif_softc_list VNET(gif_softc_list) -#define V_max_gif_nesting VNET(max_gif_nesting) -#define V_parallel_tunnels VNET(parallel_tunnels) #ifdef INET -VNET_DEFINE(int, ip_gif_ttl); +VNET_DEFINE(int, ip_gif_ttl) = GIF_TTL; #define V_ip_gif_ttl VNET(ip_gif_ttl) #endif #ifdef INET6 -VNET_DEFINE(int, ip6_gif_hlim); +VNET_DEFINE(int, ip6_gif_hlim) = GIF_HLIM; #define V_ip6_gif_hlim VNET(ip6_gif_hlim) #endif @@ -120,16 +116,6 @@ void (*ng_gif_detach_p)(struct ifnet *ifp); static void gif_start(struct ifnet *); static int gif_clone_create(struct if_clone *, int, caddr_t); static void gif_clone_destroy(struct ifnet *); -static int vnet_gif_iattach(const void *); - -#ifdef VIMAGE -static const vnet_modinfo_t vnet_gif_modinfo = { - .vmi_id = VNET_MOD_GIF, - .vmi_name = "gif", - .vmi_dependson = VNET_MOD_NET, - .vmi_iattach = vnet_gif_iattach -}; -#endif IFC_SIMPLE_DECLARE(gif, 0); @@ -149,6 +135,10 @@ SYSCTL_NODE(_net_link, IFT_GIF, gif, CTLFLAG_RW, 0, */ #define MAX_GIF_NEST 1 #endif + +static VNET_DEFINE(int, max_gif_nesting) = MAX_GIF_NEST; +#define V_max_gif_nesting VNET(max_gif_nesting) + SYSCTL_VNET_INT(_net_link_gif, OID_AUTO, max_nesting, CTLFLAG_RW, &VNET_NAME(max_gif_nesting), 0, "Max nested tunnels"); @@ -163,6 +153,13 @@ SYSCTL_VNET_INT(_net_inet6_ip6, IPV6CTL_GIF_HLIM, gifhlim, CTLFLAG_RW, * pair of addresses. Some applications require this functionality so * we allow control over this check here. */ +#ifdef XBONEHACK +static VNET_DEFINE(int, parallel_tunnels) = 1; +#else +static VNET_DEFINE(int, parallel_tunnels) = 0; +#endif +#define V_parallel_tunnels VNET(parallel_tunnels) + SYSCTL_VNET_INT(_net_link_gif, OID_AUTO, parallel_tunnels, CTLFLAG_RW, &VNET_NAME(parallel_tunnels), 0, "Allow parallel tunnels?"); @@ -259,26 +256,14 @@ gif_clone_destroy(ifp) free(sc, M_GIF); } -static int -vnet_gif_iattach(const void *unused __unused) +static void +vnet_gif_init(const void *unused __unused) { LIST_INIT(&V_gif_softc_list); - V_max_gif_nesting = MAX_GIF_NEST; -#ifdef XBONEHACK - V_parallel_tunnels = 1; -#else - V_parallel_tunnels = 0; -#endif -#ifdef INET - V_ip_gif_ttl = GIF_TTL; -#endif -#ifdef INET6 - V_ip6_gif_hlim = GIF_HLIM; -#endif - - return (0); } +VNET_SYSINIT(vnet_gif_init, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, vnet_gif_init, + NULL); static int gifmodevent(mod, type, data) @@ -290,20 +275,11 @@ gifmodevent(mod, type, data) switch (type) { case MOD_LOAD: mtx_init(&gif_mtx, "gif_mtx", NULL, MTX_DEF); - -#ifdef VIMAGE - vnet_mod_register(&vnet_gif_modinfo); -#else - vnet_gif_iattach(NULL); -#endif if_clone_attach(&gif_cloner); - break; + case MOD_UNLOAD: if_clone_detach(&gif_cloner); -#ifdef VIMAGE - vnet_mod_deregister(&vnet_gif_modinfo); -#endif mtx_destroy(&gif_mtx); break; default: diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c index 7889570..043c808 100644 --- a/sys/net/if_loop.c +++ b/sys/net/if_loop.c @@ -103,30 +103,14 @@ int looutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, struct route *ro); static int lo_clone_create(struct if_clone *, int, caddr_t); static void lo_clone_destroy(struct ifnet *); -static int vnet_loif_iattach(const void *); -#ifdef VIMAGE -static int vnet_loif_idetach(const void *); -#endif VNET_DEFINE(struct ifnet *, loif); /* Used externally */ #ifdef VIMAGE -static VNET_DEFINE(struct ifc_simple_data *, lo_cloner_data); -static VNET_DEFINE(struct if_clone *, lo_cloner); +static VNET_DEFINE(struct ifc_simple_data, lo_cloner_data); +static VNET_DEFINE(struct if_clone, lo_cloner); #define V_lo_cloner_data VNET(lo_cloner_data) #define V_lo_cloner VNET(lo_cloner) - -MALLOC_DEFINE(M_LO_CLONER, "lo_cloner", "lo_cloner"); -#endif - -#ifdef VIMAGE -static const vnet_modinfo_t vnet_loif_modinfo = { - .vmi_id = VNET_MOD_LOIF, - .vmi_dependson = VNET_MOD_IF_CLONE, - .vmi_name = "loif", - .vmi_iattach = vnet_loif_iattach, - .vmi_idetach = vnet_loif_idetach -}; #endif IFC_SIMPLE_DECLARE(lo, 1); @@ -170,37 +154,32 @@ lo_clone_create(struct if_clone *ifc, int unit, caddr_t params) return (0); } -static int -vnet_loif_iattach(const void *unused __unused) +static void +vnet_loif_init(const void *unused __unused) { #ifdef VIMAGE - V_lo_cloner = malloc(sizeof(*V_lo_cloner), M_LO_CLONER, - M_WAITOK | M_ZERO); - V_lo_cloner_data = malloc(sizeof(*V_lo_cloner_data), M_LO_CLONER, - M_WAITOK | M_ZERO); - bcopy(&lo_cloner, V_lo_cloner, sizeof(*V_lo_cloner)); - bcopy(lo_cloner.ifc_data, V_lo_cloner_data, sizeof(*V_lo_cloner_data)); - V_lo_cloner->ifc_data = V_lo_cloner_data; - if_clone_attach(V_lo_cloner); + V_lo_cloner = lo_cloner; + V_lo_cloner_data = lo_cloner_data; + V_lo_cloner.ifc_data = &V_lo_cloner_data; + if_clone_attach(&V_lo_cloner); #else if_clone_attach(&lo_cloner); #endif - return (0); } +VNET_SYSINIT(vnet_loif_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY, + vnet_loif_init, NULL); #ifdef VIMAGE -static int -vnet_loif_idetach(const void *unused __unused) +static void +vnet_loif_uninit(const void *unused __unused) { - if_clone_detach(V_lo_cloner); - free(V_lo_cloner, M_LO_CLONER); - free(V_lo_cloner_data, M_LO_CLONER); + if_clone_detach(&V_lo_cloner); V_loif = NULL; - - return (0); } +VNET_SYSUNINIT(vnet_loif_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY, + vnet_loif_uninit, NULL); #endif static int @@ -209,11 +188,6 @@ loop_modevent(module_t mod, int type, void *data) switch (type) { case MOD_LOAD: -#ifdef VIMAGE - vnet_mod_register(&vnet_loif_modinfo); -#else - vnet_loif_iattach(NULL); -#endif break; case MOD_UNLOAD: diff --git a/sys/net/route.c b/sys/net/route.c index de677bc..544c3b6 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -99,17 +99,6 @@ VNET_DEFINE(struct rtstat, rtstat); static void rt_maskedcopy(struct sockaddr *, struct sockaddr *, struct sockaddr *); -static int vnet_route_iattach(const void *); -#ifdef VIMAGE -static int vnet_route_idetach(const void *); - -static const vnet_modinfo_t vnet_rtable_modinfo = { - .vmi_id = VNET_MOD_RTABLE, - .vmi_name = "rtable", - .vmi_iattach = vnet_route_iattach, - .vmi_idetach = vnet_route_idetach -}; -#endif /* compare two sockaddr structures */ #define sa_equal(a1, a2) (bcmp((a1), (a2), (a1)->sa_len) == 0) @@ -174,6 +163,10 @@ rt_tables_get_rnh(int table, int fam) return (*rt_tables_get_rnh_ptr(table, fam)); } +/* + * route initialization must occur before ip6_init2(), which happenas at + * SI_ORDER_MIDDLE. + */ static void route_init(void) { @@ -184,16 +177,11 @@ route_init(void) if (rt_numfibs == 0) rt_numfibs = 1; rn_init(); /* initialize all zeroes, all ones, mask table */ - -#ifdef VIMAGE - vnet_mod_register(&vnet_rtable_modinfo); -#else - vnet_route_iattach(NULL); -#endif } +SYSINIT(route_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, route_init, 0); -static int -vnet_route_iattach(const void *unused __unused) +static void +vnet_route_init(const void *unused __unused) { struct domain *dom; struct radix_node_head **rnh; @@ -229,13 +217,13 @@ vnet_route_iattach(const void *unused __unused) } } } - - return (0); } +VNET_SYSINIT(vnet_route_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_FOURTH, + vnet_route_init, 0); #ifdef VIMAGE -static int -vnet_route_idetach(const void *unused __unused) +static void +vnet_route_uninit(const void *unused __unused) { int table; int fam; @@ -259,8 +247,9 @@ vnet_route_idetach(const void *unused __unused) } } } - return (0); } +VNET_SYSUNINIT(vnet_route_uninit, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, + vnet_route_uninit, 0); #endif #ifndef _SYS_SYSPROTO_H_ @@ -1510,6 +1499,3 @@ rtinit(struct ifaddr *ifa, int cmd, int flags) fib = -1; return (rtinit1(ifa, cmd, flags, fib)); } - -/* This must be before ip6_init2(), which is now SI_ORDER_MIDDLE */ -SYSINIT(route, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, route_init, 0); diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index bdea325..88c9807 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -35,9 +35,9 @@ #include "opt_inet6.h" #include <sys/param.h> -#include <sys/domain.h> #include <sys/jail.h> #include <sys/kernel.h> +#include <sys/domain.h> #include <sys/lock.h> #include <sys/malloc.h> #include <sys/mbuf.h> @@ -1525,4 +1525,4 @@ static struct domain routedomain = { .dom_protoswNPROTOSW = &routesw[sizeof(routesw)/sizeof(routesw[0])] }; -DOMAIN_SET(route); +VNET_DOMAIN_SET(route); diff --git a/sys/net/vnet.c b/sys/net/vnet.c index a314886..cd5b2b3 100644 --- a/sys/net/vnet.c +++ b/sys/net/vnet.c @@ -126,6 +126,16 @@ MALLOC_DEFINE(M_VNET_DATA, "vnet_data", "VNET data"); */ static VNET_DEFINE(char, modspace[VNET_MODMIN]); +/* + * Global lists of subsystem constructor and destructors for vnets. + * They are registered via VNET_SYSINIT() and VNET_SYSUNINIT(). The + * lists are protected by the vnet_sxlock global lock. + */ +static TAILQ_HEAD(vnet_sysinit_head, vnet_sysinit) vnet_constructors = + TAILQ_HEAD_INITIALIZER(vnet_constructors); +static TAILQ_HEAD(vnet_sysuninit_head, vnet_sysinit) vnet_destructors = + TAILQ_HEAD_INITIALIZER(vnet_destructors); + struct vnet_data_free { uintptr_t vnd_start; int vnd_len; @@ -339,3 +349,135 @@ vnet_sysctl_handle_uint(SYSCTL_HANDLER_ARGS) arg1 = (void *)(curvnet->vnet_data_base + (uintptr_t)arg1); return (sysctl_handle_int(oidp, arg1, arg2, req)); } + +/* + * Support for special SYSINIT handlers registered via VNET_SYSINIT() + * and VNET_SYSUNINIT(). + */ +void +vnet_register_sysinit(void *arg) +{ + struct vnet_sysinit *vs, *vs2; + struct vnet *vnet; + + vs = arg; + KASSERT(vs->subsystem > SI_SUB_VNET, ("vnet sysinit too early")); + + /* Add the constructor to the global list of vnet constructors. */ + sx_xlock(&vnet_sxlock); + TAILQ_FOREACH(vs2, &vnet_constructors, link) { + if (vs2->subsystem > vs->subsystem) + break; + if (vs2->subsystem == vs->subsystem && vs2->order > vs->order) + break; + } + if (vs2 != NULL) + TAILQ_INSERT_BEFORE(vs2, vs, link); + else + TAILQ_INSERT_TAIL(&vnet_constructors, vs, link); + + /* + * Invoke the constructor on all the existing vnets when it is + * registered. + */ + VNET_FOREACH(vnet) { + CURVNET_SET_QUIET(vnet); + vs->func(vs->arg); + CURVNET_RESTORE(); + } + sx_xunlock(&vnet_sxlock); +} + +void +vnet_deregister_sysinit(void *arg) +{ + struct vnet_sysinit *vs; + + vs = arg; + + /* Remove the constructor from the global list of vnet constructors. */ + sx_xlock(&vnet_sxlock); + TAILQ_REMOVE(&vnet_constructors, vs, link); + sx_xunlock(&vnet_sxlock); +} + +void +vnet_register_sysuninit(void *arg) +{ + struct vnet_sysinit *vs, *vs2; + + vs = arg; + + /* Add the destructor to the global list of vnet destructors. */ + sx_xlock(&vnet_sxlock); + TAILQ_FOREACH(vs2, &vnet_destructors, link) { + if (vs2->subsystem > vs->subsystem) + break; + if (vs2->subsystem == vs->subsystem && vs2->order > vs->order) + break; + } + if (vs2 != NULL) + TAILQ_INSERT_BEFORE(vs2, vs, link); + else + TAILQ_INSERT_TAIL(&vnet_destructors, vs, link); + sx_xunlock(&vnet_sxlock); +} + +void +vnet_deregister_sysuninit(void *arg) +{ + struct vnet_sysinit *vs; + struct vnet *vnet; + + vs = arg; + + /* + * Invoke the destructor on all the existing vnets when it is + * deregistered. + */ + sx_xlock(&vnet_sxlock); + VNET_FOREACH(vnet) { + CURVNET_SET_QUIET(vnet); + vs->func(vs->arg); + CURVNET_RESTORE(); + } + + /* Remove the destructor from the global list of vnet destructors. */ + TAILQ_REMOVE(&vnet_destructors, vs, link); + sx_xunlock(&vnet_sxlock); +} + +/* + * Invoke all registered vnet constructors on the current vnet. Used + * during vnet construction. The caller is responsible for ensuring + * the new vnet is the current vnet and that the vnet_sxlock lock is + * locked. + */ +void +vnet_sysinit(void) +{ + struct vnet_sysinit *vs; + + sx_assert(&vnet_sxlock, SA_LOCKED); + TAILQ_FOREACH(vs, &vnet_constructors, link) { + vs->func(vs->arg); + } +} + +/* + * Invoke all registered vnet destructors on the current vnet. Used + * during vnet destruction. The caller is responsible for ensuring + * the dying vnet is the current vnet and that the vnet_sxlock lock is + * locked. + */ +void +vnet_sysuninit(void) +{ + struct vnet_sysinit *vs; + + sx_assert(&vnet_sxlock, SA_LOCKED); + TAILQ_FOREACH_REVERSE(vs, &vnet_destructors, vnet_sysuninit_head, + link) { + vs->func(vs->arg); + } +} diff --git a/sys/net/vnet.h b/sys/net/vnet.h index aec448a..8877bab 100644 --- a/sys/net/vnet.h +++ b/sys/net/vnet.h @@ -46,6 +46,43 @@ #ifdef _KERNEL #ifdef VIMAGE +#include <sys/kernel.h> + +/* + * SYSINIT/SYSUNINIT variants that provide per-vnet constructors and + * destructors. + */ +struct vnet_sysinit { + enum sysinit_sub_id subsystem; + enum sysinit_elem_order order; + sysinit_cfunc_t func; + const void *arg; + TAILQ_ENTRY(vnet_sysinit) link; +}; + +#define VNET_SYSINIT(ident, subsystem, order, func, arg) \ + static struct vnet_sysinit ident ## _vnet_init = { \ + subsystem, \ + order, \ + (sysinit_cfunc_t)(sysinit_nfunc_t)func, \ + (arg) \ + }; \ + SYSINIT(vnet_init_ ## ident, subsystem, order, \ + vnet_register_sysinit, &ident ## _vnet_init); \ + SYSUNINIT(vnet_init_ ## ident, subsystem, order, \ + vnet_deregister_sysinit, &ident ## _vnet_init) + +#define VNET_SYSUNINIT(ident, subsystem, order, func, arg) \ + static struct vnet_sysinit ident ## _vnet_uninit = { \ + subsystem, \ + order, \ + (sysinit_cfunc_t)(sysinit_nfunc_t)func, \ + (arg) \ + }; \ + SYSINIT(vnet_uninit_ ## ident, subsystem, order, \ + vnet_register_sysuninit, &ident ## _vnet_uninit); \ + SYSUNINIT(vnet_uninit_ ## ident, subsystem, order, \ + vnet_deregister_sysuninit, &ident ## _vnet_uninit) #if defined(__arm__) __asm__(".section " VNET_SETNAME ", \"aw\", %progbits"); @@ -121,6 +158,16 @@ void vnet_data_free(void *start_arg, int size); struct vnet; void vnet_data_init(struct vnet *vnet); void vnet_data_destroy(struct vnet *vnet); +void vnet_sysinit(void); +void vnet_sysuninit(void); + +/* + * Interfaces for managing per-vnet constructors and destructors. + */ +void vnet_register_sysinit(void *arg); +void vnet_register_sysuninit(void *arg); +void vnet_deregister_sysinit(void *arg); +void vnet_deregister_sysuninit(void *arg); #else /* !VIMAGE */ @@ -132,6 +179,10 @@ void vnet_data_destroy(struct vnet *vnet); #define VNET_DECLARE(t, n) extern t n #define VNET_DEFINE(t, n) t n #define _VNET_PTR(b, n) &VNET_NAME(n) +#define VNET_SYSINIT(ident, subsystem, order, func, arg) \ + SYSINIT(ident, subsystem, order, func, arg) +#define VNET_SYSUNINIT(ident, subsystem, order, func, arg) \ + SYSUNINIT(ident, subsystem, order, func, arg) #ifdef SYSCTL_OID #define SYSCTL_VNET_INT(parent, nbr, name, access, ptr, val, descr) \ |