diff options
-rw-r--r-- | sys/kern/kern_vimage.c | 212 | ||||
-rw-r--r-- | sys/kern/uipc_domain.c | 55 | ||||
-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 | ||||
-rw-r--r-- | sys/netgraph/bluetooth/socket/ng_btsocket.c | 7 | ||||
-rw-r--r-- | sys/netgraph/netgraph.h | 2 | ||||
-rw-r--r-- | sys/netgraph/ng_base.c | 24 | ||||
-rw-r--r-- | sys/netgraph/ng_eiface.c | 39 | ||||
-rw-r--r-- | sys/netgraph/ng_ether.c | 31 | ||||
-rw-r--r-- | sys/netgraph/ng_iface.c | 39 | ||||
-rw-r--r-- | sys/netgraph/ng_socket.c | 12 | ||||
-rw-r--r-- | sys/netinet/igmp.c | 52 | ||||
-rw-r--r-- | sys/netinet/in_proto.c | 2 | ||||
-rw-r--r-- | sys/netinet6/in6_proto.c | 2 | ||||
-rw-r--r-- | sys/netinet6/mld6.c | 53 | ||||
-rw-r--r-- | sys/netipsec/ipsec.c | 28 | ||||
-rw-r--r-- | sys/netipsec/keysock.c | 2 | ||||
-rw-r--r-- | sys/sys/domain.h | 30 | ||||
-rw-r--r-- | sys/sys/kernel.h | 2 | ||||
-rw-r--r-- | sys/sys/vimage.h | 62 |
28 files changed, 397 insertions, 721 deletions
diff --git a/sys/kern/kern_vimage.c b/sys/kern/kern_vimage.c index b5742df..fa2d1f4 100644 --- a/sys/kern/kern_vimage.c +++ b/sys/kern/kern_vimage.c @@ -52,12 +52,6 @@ __FBSDID("$FreeBSD$"); MALLOC_DEFINE(M_VNET, "vnet", "network stack control block"); -static TAILQ_HEAD(vnet_modlink_head, vnet_modlink) vnet_modlink_head; -static TAILQ_HEAD(vnet_modpending_head, vnet_modlink) vnet_modpending_head; -static void vnet_mod_complete_registration(struct vnet_modlink *); -static int vnet_mod_constructor(struct vnet_modlink *); -static int vnet_mod_destructor(struct vnet_modlink *); - struct rwlock vnet_rwlock; struct sx vnet_sxlock; @@ -130,185 +124,10 @@ vi_if_move(struct thread *td, struct ifnet *ifp, char *ifname, int jid) return (error); } - -/* - * Kernel interfaces and handlers. - */ - -void -vnet_mod_register(const struct vnet_modinfo *vmi) -{ - - vnet_mod_register_multi(vmi, NULL, NULL); -} - -void -vnet_mod_register_multi(const struct vnet_modinfo *vmi, void *iarg, - char *iname) -{ - struct vnet_modlink *vml, *vml_iter; - - /* Do not register the same {module, iarg} pair more than once. */ - TAILQ_FOREACH(vml_iter, &vnet_modlink_head, vml_mod_le) - if (vml_iter->vml_modinfo == vmi && vml_iter->vml_iarg == iarg) - break; - if (vml_iter != NULL) - panic("registering an already registered vnet module: %s", - vml_iter->vml_modinfo->vmi_name); - vml = malloc(sizeof(struct vnet_modlink), M_VNET, M_NOWAIT); - - /* - * XXX we support only statically assigned module IDs at the time. - * In principle modules should be able to get a dynamically - * assigned ID at registration time. - * - * If a module is registered in multiple instances, then each - * instance must have both iarg and iname set. - */ - if (vmi->vmi_id >= VNET_MOD_MAX) - panic("invalid vnet module ID: %d", vmi->vmi_id); - if (vmi->vmi_name == NULL) - panic("vnet module with no name: %d", vmi->vmi_id); - if ((iarg == NULL) ^ (iname == NULL)) - panic("invalid vnet module instance: %s", vmi->vmi_name); - - vml->vml_modinfo = vmi; - vml->vml_iarg = iarg; - vml->vml_iname = iname; - - /* Check whether the module we depend on is already registered. */ - if (vmi->vmi_dependson != vmi->vmi_id) { - TAILQ_FOREACH(vml_iter, &vnet_modlink_head, vml_mod_le) - if (vml_iter->vml_modinfo->vmi_id == - vmi->vmi_dependson) - break; /* Depencency found, we are done. */ - if (vml_iter == NULL) { -#ifdef DEBUG_ORDERING - printf("dependency %d missing for vnet mod %s," - "postponing registration\n", - vmi->vmi_dependson, vmi->vmi_name); -#endif /* DEBUG_ORDERING */ - TAILQ_INSERT_TAIL(&vnet_modpending_head, vml, - vml_mod_le); - return; - } - } - - vnet_mod_complete_registration(vml); -} - -void -vnet_mod_complete_registration(struct vnet_modlink *vml) -{ - VNET_ITERATOR_DECL(vnet_iter); - struct vnet_modlink *vml_iter; - - TAILQ_INSERT_TAIL(&vnet_modlink_head, vml, vml_mod_le); - - VNET_FOREACH(vnet_iter) { - CURVNET_SET_QUIET(vnet_iter); - vnet_mod_constructor(vml); - CURVNET_RESTORE(); - } - - /* Check for pending modules depending on us. */ - do { - TAILQ_FOREACH(vml_iter, &vnet_modpending_head, vml_mod_le) - if (vml_iter->vml_modinfo->vmi_dependson == - vml->vml_modinfo->vmi_id) - break; - if (vml_iter != NULL) { -#ifdef DEBUG_ORDERING - printf("vnet mod %s now registering," - "dependency %d loaded\n", - vml_iter->vml_modinfo->vmi_name, - vml->vml_modinfo->vmi_id); -#endif /* DEBUG_ORDERING */ - TAILQ_REMOVE(&vnet_modpending_head, vml_iter, - vml_mod_le); - vnet_mod_complete_registration(vml_iter); - } - } while (vml_iter != NULL); -} - -void -vnet_mod_deregister(const struct vnet_modinfo *vmi) -{ - - vnet_mod_deregister_multi(vmi, NULL, NULL); -} - -void -vnet_mod_deregister_multi(const struct vnet_modinfo *vmi, void *iarg, - char *iname) -{ - VNET_ITERATOR_DECL(vnet_iter); - struct vnet_modlink *vml; - - TAILQ_FOREACH(vml, &vnet_modlink_head, vml_mod_le) - if (vml->vml_modinfo == vmi && vml->vml_iarg == iarg) - break; - if (vml == NULL) - panic("cannot deregister unregistered vnet module %s", - vmi->vmi_name); - - VNET_FOREACH(vnet_iter) { - CURVNET_SET_QUIET(vnet_iter); - vnet_mod_destructor(vml); - CURVNET_RESTORE(); - } - - TAILQ_REMOVE(&vnet_modlink_head, vml, vml_mod_le); - free(vml, M_VNET); -} - -static int -vnet_mod_constructor(struct vnet_modlink *vml) -{ - const struct vnet_modinfo *vmi = vml->vml_modinfo; - -#ifdef DEBUG_ORDERING - printf("instantiating vnet_%s", vmi->vmi_name); - if (vml->vml_iarg) - printf("/%s", vml->vml_iname); - printf(": "); - if (vmi->vmi_iattach != NULL) - printf("iattach()"); - printf("\n"); -#endif - - if (vmi->vmi_iattach != NULL) - vmi->vmi_iattach(vml->vml_iarg); - - return (0); -} - -static int -vnet_mod_destructor(struct vnet_modlink *vml) -{ - const struct vnet_modinfo *vmi = vml->vml_modinfo; - -#ifdef DEBUG_ORDERING - printf("destroying vnet_%s", vmi->vmi_name); - if (vml->vml_iarg) - printf("/%s", vml->vml_iname); - printf(": "); - if (vmi->vmi_idetach != NULL) - printf("idetach(); "); - printf("\n"); -#endif - - if (vmi->vmi_idetach) - vmi->vmi_idetach(vml->vml_iarg); - - return (0); -} - struct vnet * vnet_alloc(void) { struct vnet *vnet; - struct vnet_modlink *vml; vnet = malloc(sizeof(struct vnet), M_VNET, M_WAITOK | M_ZERO); vnet->vnet_magic_n = VNET_MAGIC_N; @@ -316,11 +135,12 @@ vnet_alloc(void) /* Initialize / attach vnet module instances. */ CURVNET_SET_QUIET(vnet); - TAILQ_FOREACH(vml, &vnet_modlink_head, vml_mod_le) - vnet_mod_constructor(vml); + + sx_xlock(&vnet_sxlock); + vnet_sysinit(); CURVNET_RESTORE(); - VNET_LIST_WLOCK(); + rw_wlock(&vnet_rwlock); LIST_INSERT_HEAD(&vnet_head, vnet, vnet_le); VNET_LIST_WUNLOCK(); @@ -331,14 +151,13 @@ void vnet_destroy(struct vnet *vnet) { struct ifnet *ifp, *nifp; - struct vnet_modlink *vml; KASSERT(vnet->vnet_sockcnt == 0, ("%s: vnet still has sockets", __func__)); VNET_LIST_WLOCK(); LIST_REMOVE(vnet, vnet_le); - VNET_LIST_WUNLOCK(); + rw_wunlock(&vnet_rwlock); CURVNET_SET_QUIET(vnet); @@ -348,10 +167,8 @@ vnet_destroy(struct vnet *vnet) if_vmove(ifp, ifp->if_home_vnet); } - /* Detach / free per-module state instances. */ - TAILQ_FOREACH_REVERSE(vml, &vnet_modlink_head, - vnet_modlink_head, vml_mod_le) - vnet_mod_destructor(vml); + vnet_sysuninit(); + sx_xunlock(&vnet_sxlock); CURVNET_RESTORE(); @@ -387,9 +204,6 @@ static void vnet0_init(void *arg) { - TAILQ_INIT(&vnet_modlink_head); - TAILQ_INIT(&vnet_modpending_head); - /* * We MUST clear curvnet in vi_init_done() before going SMP, * otherwise CURVNET_SET() macros would scream about unnecessary @@ -402,20 +216,8 @@ SYSINIT(vnet0_init, SI_SUB_VNET, SI_ORDER_FIRST, vnet0_init, NULL); static void vnet_init_done(void *unused) { - struct vnet_modlink *vml_iter; curvnet = NULL; - - if (TAILQ_EMPTY(&vnet_modpending_head)) - return; - - printf("vnet modules with unresolved dependencies:\n"); - TAILQ_FOREACH(vml_iter, &vnet_modpending_head, vml_mod_le) - printf(" %d:%s depending on %d\n", - vml_iter->vml_modinfo->vmi_id, - vml_iter->vml_modinfo->vmi_name, - vml_iter->vml_modinfo->vmi_dependson); - panic("going nowhere without my vnet modules!"); } SYSINIT(vnet_init_done, SI_SUB_VNET_DONE, SI_ORDER_FIRST, vnet_init_done, diff --git a/sys/kern/uipc_domain.c b/sys/kern/uipc_domain.c index 88322d5..dd0602e 100644 --- a/sys/kern/uipc_domain.c +++ b/sys/kern/uipc_domain.c @@ -59,17 +59,12 @@ __FBSDID("$FreeBSD$"); */ static void domaininit(void *); -SYSINIT(domain, SI_SUB_PROTO_DOMAIN, SI_ORDER_FIRST, domaininit, NULL); +SYSINIT(domain, SI_SUB_PROTO_DOMAININIT, SI_ORDER_ANY, domaininit, NULL); static void domainfinalize(void *); SYSINIT(domainfin, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_FIRST, domainfinalize, NULL); -static vnet_attach_fn net_init_domain; -#ifdef VIMAGE -static vnet_detach_fn net_detach_domain; -#endif - static struct callout pffast_callout; static struct callout pfslow_callout; @@ -106,15 +101,6 @@ struct pr_usrreqs nousrreqs = { .pru_sopoll = pru_sopoll_notsupp, }; -#ifdef VIMAGE -vnet_modinfo_t vnet_domain_modinfo = { - .vmi_id = VNET_MOD_DOMAIN, - .vmi_name = "domain", - .vmi_iattach = net_init_domain, - .vmi_idetach = net_detach_domain, -}; -#endif - static void protosw_init(struct protosw *pr) { @@ -174,10 +160,10 @@ protosw_init(struct protosw *pr) * Note: you cant unload it again because a socket may be using it. * XXX can't fail at this time. */ -static int -net_init_domain(const void *arg) +void +domain_init(void *arg) { - const struct domain *dp = arg; + struct domain *dp = arg; struct protosw *pr; if (dp->dom_init) @@ -191,17 +177,21 @@ net_init_domain(const void *arg) max_datalen = MHLEN - max_hdr; if (max_datalen < 1) panic("%s: max_datalen < 1", __func__); - return (0); } #ifdef VIMAGE -/* - * Detach / free a domain instance. - */ -static int -net_detach_domain(const void *arg) +void +vnet_domain_init(void *arg) +{ + + /* Virtualized case is no different -- call init functions. */ + domain_init(arg); +} + +void +vnet_domain_uninit(void *arg) { - const struct domain *dp = arg; + struct domain *dp = arg; struct protosw *pr; for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) @@ -209,8 +199,6 @@ net_detach_domain(const void *arg) (*pr->pr_destroy)(); if (dp->dom_destroy) (*dp->dom_destroy)(); - - return (0); } #endif @@ -220,7 +208,7 @@ net_detach_domain(const void *arg) * XXX can't fail at this time. */ void -net_add_domain(void *data) +domain_add(void *data) { struct domain *dp; @@ -234,24 +222,19 @@ net_add_domain(void *data) dp->dom_name)); #ifndef INVARIANTS if (domain_init_status < 1) - printf("WARNING: attempt to net_add_domain(%s) before " + printf("WARNING: attempt to domain_add(%s) before " "domaininit()\n", dp->dom_name); #endif #ifdef notyet KASSERT(domain_init_status < 2, - ("attempt to net_add_domain(%s) after domainfinalize()", + ("attempt to domain_add(%s) after domainfinalize()", dp->dom_name)); #else if (domain_init_status >= 2) - printf("WARNING: attempt to net_add_domain(%s) after " + printf("WARNING: attempt to domain_add(%s) after " "domainfinalize()\n", dp->dom_name); #endif mtx_unlock(&dom_mtx); -#ifdef VIMAGE - vnet_mod_register_multi(&vnet_domain_modinfo, dp, dp->dom_name); -#else - net_init_domain(dp); -#endif } static void 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) \ diff --git a/sys/netgraph/bluetooth/socket/ng_btsocket.c b/sys/netgraph/bluetooth/socket/ng_btsocket.c index 6c6b1f3..f1620bc 100644 --- a/sys/netgraph/bluetooth/socket/ng_btsocket.c +++ b/sys/netgraph/bluetooth/socket/ng_btsocket.c @@ -45,6 +45,7 @@ #include <sys/socketvar.h> #include <sys/sysctl.h> #include <sys/taskqueue.h> + #include <netgraph/ng_message.h> #include <netgraph/netgraph.h> #include <netgraph/bluetooth/include/ng_bluetooth.h> @@ -57,7 +58,7 @@ #include <netgraph/bluetooth/include/ng_btsocket_sco.h> static int ng_btsocket_modevent (module_t, int, void *); -extern struct domain ng_btsocket_domain; +static struct domain ng_btsocket_domain; /* * Bluetooth raw HCI sockets @@ -219,7 +220,7 @@ static struct protosw ng_btsocket_protosw[] = { * BLUETOOTH domain */ -struct domain ng_btsocket_domain = { +static struct domain ng_btsocket_domain = { .dom_family = AF_BLUETOOTH, .dom_name = "bluetooth", .dom_protosw = ng_btsocket_protosw, @@ -269,7 +270,6 @@ ng_btsocket_modevent(module_t mod, int event, void *data) switch (event) { case MOD_LOAD: - net_add_domain(&ng_btsocket_domain); break; case MOD_UNLOAD: @@ -285,3 +285,4 @@ ng_btsocket_modevent(module_t mod, int event, void *data) return (error); } /* ng_btsocket_modevent */ +DOMAIN_SET(ng_btsocket_); diff --git a/sys/netgraph/netgraph.h b/sys/netgraph/netgraph.h index 37ef833..8dbf0b5 100644 --- a/sys/netgraph/netgraph.h +++ b/sys/netgraph/netgraph.h @@ -1113,7 +1113,7 @@ MODULE_DEPEND(ng_##typename, netgraph, NG_ABI_VERSION, \ NG_ABI_VERSION) #define NETGRAPH_INIT(tn, tp) \ - NETGRAPH_INIT_ORDERED(tn, tp, SI_SUB_PSEUDO, SI_ORDER_ANY) + NETGRAPH_INIT_ORDERED(tn, tp, SI_SUB_PSEUDO, SI_ORDER_MIDDLE) /* Special malloc() type for netgraph structs and ctrl messages */ /* Only these two types should be visible to nodes */ diff --git a/sys/netgraph/ng_base.c b/sys/netgraph/ng_base.c index 084c676..b618bb4 100644 --- a/sys/netgraph/ng_base.c +++ b/sys/netgraph/ng_base.c @@ -79,10 +79,6 @@ MODULE_VERSION(netgraph, NG_ABI_VERSION); /* Mutex to protect topology events. */ static struct mtx ng_topo_mtx; -#ifdef VIMAGE -static vnet_detach_fn vnet_netgraph_idetach; -#endif - #ifdef NETGRAPH_DEBUG static struct mtx ng_nodelist_mtx; /* protects global node/hook lists */ static struct mtx ngq_mtx; /* protects the queue item list */ @@ -3068,18 +3064,9 @@ ng_mod_event(module_t mod, int event, void *data) return (error); } -#ifdef VIMAGE -static const vnet_modinfo_t vnet_netgraph_modinfo = { - .vmi_id = VNET_MOD_NETGRAPH, - .vmi_name = "netgraph", - .vmi_dependson = VNET_MOD_LOIF, - .vmi_idetach = vnet_netgraph_idetach -}; -#endif - #ifdef VIMAGE -static int -vnet_netgraph_idetach(const void *unused __unused) +static void +vnet_netgraph_uninit(const void *unused __unused) { #if 0 node_p node, last_killed = NULL; @@ -3101,9 +3088,9 @@ vnet_netgraph_idetach(const void *unused __unused) last_killed = node; } #endif - - return (0); } +VNET_SYSUNINIT(vnet_netgraph_uninit, SI_SUB_NETGRAPH, SI_ORDER_ANY, + vnet_netgraph_uninit, NULL); #endif /* VIMAGE */ /* @@ -3120,9 +3107,6 @@ ngb_mod_event(module_t mod, int event, void *data) switch (event) { case MOD_LOAD: /* Initialize everything. */ -#ifdef VIMAGE - vnet_mod_register(&vnet_netgraph_modinfo); -#endif NG_WORKLIST_LOCK_INIT(); mtx_init(&ng_typelist_mtx, "netgraph types mutex", NULL, MTX_DEF); diff --git a/sys/netgraph/ng_eiface.c b/sys/netgraph/ng_eiface.c index fb43eef..ad9668e 100644 --- a/sys/netgraph/ng_eiface.c +++ b/sys/netgraph/ng_eiface.c @@ -44,6 +44,7 @@ #include <net/if_types.h> #include <net/netisr.h> #include <net/route.h> +#include <net/vnet.h> #include <netgraph/ng_message.h> #include <netgraph/netgraph.h> @@ -113,22 +114,9 @@ static struct ng_type typestruct = { }; NETGRAPH_INIT(eiface, &typestruct); -static vnet_attach_fn ng_eiface_iattach; -static vnet_detach_fn ng_eiface_idetach; - static VNET_DEFINE(struct unrhdr *, ng_eiface_unit); #define V_ng_eiface_unit VNET(ng_eiface_unit) -#ifdef VIMAGE -static vnet_modinfo_t vnet_ng_eiface_modinfo = { - .vmi_id = VNET_MOD_NG_EIFACE, - .vmi_name = "ng_eiface", - .vmi_dependson = VNET_MOD_NETGRAPH, - .vmi_iattach = ng_eiface_iattach, - .vmi_idetach = ng_eiface_idetach -}; -#endif - /************************************************************************ INTERFACE STUFF ************************************************************************/ @@ -601,18 +589,7 @@ ng_eiface_mod_event(module_t mod, int event, void *data) switch (event) { case MOD_LOAD: -#ifdef VIMAGE - vnet_mod_register(&vnet_ng_eiface_modinfo); -#else - ng_eiface_iattach(NULL); -#endif - break; case MOD_UNLOAD: -#ifdef VIMAGE - vnet_mod_deregister(&vnet_ng_eiface_modinfo); -#else - ng_eiface_idetach(NULL); -#endif break; default: error = EOPNOTSUPP; @@ -621,18 +598,20 @@ ng_eiface_mod_event(module_t mod, int event, void *data) return (error); } -static int ng_eiface_iattach(const void *unused) +static void +vnet_ng_eiface_init(const void *unused) { V_ng_eiface_unit = new_unrhdr(0, 0xffff, NULL); - - return (0); } +VNET_SYSINIT(vnet_ng_eiface_init, SI_SUB_PSEUDO, SI_ORDER_ANY, + vnet_ng_eiface_init, NULL); -static int ng_eiface_idetach(const void *unused) +static void +vnet_ng_eiface_uninit(const void *unused) { delete_unrhdr(V_ng_eiface_unit); - - return (0); } +VNET_SYSUNINIT(vnet_ng_eiface_uninit, SI_SUB_PSEUDO, SI_ORDER_ANY, + vnet_ng_eiface_uninit, NULL); diff --git a/sys/netgraph/ng_ether.c b/sys/netgraph/ng_ether.c index 09a8615..85fc7fc 100644 --- a/sys/netgraph/ng_ether.c +++ b/sys/netgraph/ng_ether.c @@ -72,17 +72,6 @@ #define IFP2NG(ifp) (IFP2AC((ifp))->ac_netgraph) -static vnet_attach_fn ng_ether_iattach; - -#ifdef VIMAGE -static vnet_modinfo_t vnet_ng_ether_modinfo = { - .vmi_id = VNET_MOD_NG_ETHER, - .vmi_name = "ng_ether", - .vmi_dependson = VNET_MOD_NETGRAPH, - .vmi_iattach = ng_ether_iattach, -}; -#endif - /* Per-node private data */ struct private { struct ifnet *ifp; /* associated interface */ @@ -783,11 +772,6 @@ ng_ether_mod_event(module_t mod, int event, void *data) ng_ether_input_orphan_p = ng_ether_input_orphan; ng_ether_link_state_p = ng_ether_link_state; -#ifdef VIMAGE - vnet_mod_register(&vnet_ng_ether_modinfo); -#else - error = ng_ether_iattach(NULL); -#endif break; case MOD_UNLOAD: @@ -800,10 +784,6 @@ ng_ether_mod_event(module_t mod, int event, void *data) * is MOD_UNLOAD, so there's no need to detach any nodes. */ -#ifdef VIMAGE - vnet_mod_deregister(&vnet_ng_ether_modinfo); -#endif - /* Unregister function hooks */ ng_ether_attach_p = NULL; ng_ether_detach_p = NULL; @@ -821,10 +801,15 @@ ng_ether_mod_event(module_t mod, int event, void *data) return (error); } -static int ng_ether_iattach(const void *unused) +static void +vnet_ng_ether_init(const void *unused) { struct ifnet *ifp; + /* If module load was rejected, don't attach to vnets. */ + if (ng_ether_attach_p != ng_ether_attach) + return; + /* Create nodes for any already-existing Ethernet interfaces. */ IFNET_RLOCK(); TAILQ_FOREACH(ifp, &V_ifnet, if_link) { @@ -833,6 +818,6 @@ static int ng_ether_iattach(const void *unused) ng_ether_attach(ifp); } IFNET_RUNLOCK(); - - return (0); } +VNET_SYSINIT(vnet_ng_ether_init, SI_SUB_PSEUDO, SI_ORDER_ANY, + vnet_ng_ether_init, NULL); diff --git a/sys/netgraph/ng_iface.c b/sys/netgraph/ng_iface.c index 6ed1daf6..49cba25 100644 --- a/sys/netgraph/ng_iface.c +++ b/sys/netgraph/ng_iface.c @@ -76,6 +76,7 @@ #include <net/bpf.h> #include <net/netisr.h> #include <net/route.h> +#include <net/vnet.h> #include <netinet/in.h> @@ -209,22 +210,9 @@ static struct ng_type typestruct = { }; NETGRAPH_INIT(iface, &typestruct); -static vnet_attach_fn ng_iface_iattach; -static vnet_detach_fn ng_iface_idetach; - static VNET_DEFINE(struct unrhdr *, ng_iface_unit); #define V_ng_iface_unit VNET(ng_iface_unit) -#ifdef VIMAGE -static vnet_modinfo_t vnet_ng_iface_modinfo = { - .vmi_id = VNET_MOD_NG_IFACE, - .vmi_name = "ng_iface", - .vmi_dependson = VNET_MOD_NETGRAPH, - .vmi_iattach = ng_iface_iattach, - .vmi_idetach = ng_iface_idetach -}; -#endif - /************************************************************************ HELPER STUFF ************************************************************************/ @@ -849,18 +837,7 @@ ng_iface_mod_event(module_t mod, int event, void *data) switch (event) { case MOD_LOAD: -#ifdef VIMAGE - vnet_mod_register(&vnet_ng_iface_modinfo); -#else - ng_iface_iattach(NULL); -#endif - break; case MOD_UNLOAD: -#ifdef VIMAGE - vnet_mod_deregister(&vnet_ng_iface_modinfo); -#else - ng_iface_idetach(NULL); -#endif break; default: error = EOPNOTSUPP; @@ -869,18 +846,20 @@ ng_iface_mod_event(module_t mod, int event, void *data) return (error); } -static int ng_iface_iattach(const void *unused) +static void +vnet_ng_iface_init(const void *unused) { V_ng_iface_unit = new_unrhdr(0, 0xffff, NULL); - - return (0); } +VNET_SYSINIT(vnet_ng_iface_init, SI_SUB_PSEUDO, SI_ORDER_ANY, + vnet_ng_iface_init, NULL); -static int ng_iface_idetach(const void *unused) +static void +vnet_ng_iface_uninit(const void *unused) { delete_unrhdr(V_ng_iface_unit); - - return (0); } +VNET_SYSUNINIT(vnet_ng_iface_uninit, SI_SUB_PSEUDO, SI_ORDER_ANY, + vnet_ng_iface_uninit, NULL); diff --git a/sys/netgraph/ng_socket.c b/sys/netgraph/ng_socket.c index 0d59979..af68c63 100644 --- a/sys/netgraph/ng_socket.c +++ b/sys/netgraph/ng_socket.c @@ -67,6 +67,9 @@ #ifdef NOTYET #include <sys/vnode.h> #endif + +#include <net/vnet.h> + #include <netgraph/ng_message.h> #include <netgraph/netgraph.h> #include <netgraph/ng_socketvar.h> @@ -1112,17 +1115,12 @@ ngs_mod_event(module_t mod, int event, void *data) switch (event) { case MOD_LOAD: - /* Register protocol domain. */ - net_add_domain(&ngdomain); break; case MOD_UNLOAD: #ifdef NOTYET /* Unregister protocol domain XXX can't do this yet.. */ - if ((error = net_rm_domain(&ngdomain)) != 0) - break; - else #endif - error = EBUSY; + error = EBUSY; break; default: error = EOPNOTSUPP; @@ -1131,6 +1129,8 @@ ngs_mod_event(module_t mod, int event, void *data) return (error); } +VNET_DOMAIN_SET(ng); + SYSCTL_INT(_net_graph, OID_AUTO, family, CTLFLAG_RD, 0, AF_NETGRAPH, ""); SYSCTL_NODE(_net_graph, OID_AUTO, data, CTLFLAG_RW, 0, "DATA"); SYSCTL_INT(_net_graph_data, OID_AUTO, proto, CTLFLAG_RD, 0, NG_DATA, ""); diff --git a/sys/netinet/igmp.c b/sys/netinet/igmp.c index 2c7ed2e..44796de 100644 --- a/sys/netinet/igmp.c +++ b/sys/netinet/igmp.c @@ -114,7 +114,6 @@ static char * igmp_rec_type_to_str(const int); #endif static void igmp_set_version(struct igmp_ifinfo *, const int); static void igmp_slowtimo_vnet(void); -static void igmp_sysinit(void); static int igmp_v1v2_queue_report(struct in_multi *, const int); static void igmp_v1v2_process_group_timer(struct in_multi *, const int); static void igmp_v1v2_process_querier_timers(struct igmp_ifinfo *); @@ -137,9 +136,6 @@ static int sysctl_igmp_default_version(SYSCTL_HANDLER_ARGS); static int sysctl_igmp_gsr(SYSCTL_HANDLER_ARGS); static int sysctl_igmp_ifinfo(SYSCTL_HANDLER_ARGS); -static vnet_attach_fn vnet_igmp_iattach; -static vnet_detach_fn vnet_igmp_idetach; - static const struct netisr_handler igmp_nh = { .nh_name = "igmp", .nh_handler = igmp_intr, @@ -3580,7 +3576,7 @@ igmp_rec_type_to_str(const int type) #endif static void -igmp_sysinit(void) +igmp_init(void *unused __unused) { CTR1(KTR_IGMPV3, "%s: initializing", __func__); @@ -3591,9 +3587,10 @@ igmp_sysinit(void) netisr_register(&igmp_nh); } +SYSINIT(igmp_init, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, igmp_init, NULL); static void -igmp_sysuninit(void) +igmp_uninit(void *unused __unused) { CTR1(KTR_IGMPV3, "%s: tearing down", __func__); @@ -3605,42 +3602,30 @@ igmp_sysuninit(void) IGMP_LOCK_DESTROY(); } +SYSUNINIT(igmp_uninit, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, igmp_uninit, NULL); -/* - * Initialize an IGMPv3 instance. - * VIMAGE: Assumes curvnet set by caller and called per vimage. - */ -static int -vnet_igmp_iattach(const void *unused __unused) +static void +vnet_igmp_init(const void *unused __unused) { CTR1(KTR_IGMPV3, "%s: initializing", __func__); LIST_INIT(&V_igi_head); - - return (0); } +VNET_SYSINIT(vnet_igmp_init, SI_SUB_PSEUDO, SI_ORDER_ANY, vnet_igmp_init, + NULL); -static int -vnet_igmp_idetach(const void *unused __unused) +static void +vnet_igmp_uninit(const void *unused __unused) { CTR1(KTR_IGMPV3, "%s: tearing down", __func__); KASSERT(LIST_EMPTY(&V_igi_head), ("%s: igi list not empty; ifnets not detached?", __func__)); - - return (0); } - -#ifdef VIMAGE -static vnet_modinfo_t vnet_igmp_modinfo = { - .vmi_id = VNET_MOD_IGMP, - .vmi_name = "igmp", - .vmi_iattach = vnet_igmp_iattach, - .vmi_idetach = vnet_igmp_idetach -}; -#endif +VNET_SYSUNINIT(vnet_igmp_uninit, SI_SUB_PSEUDO, SI_ORDER_ANY, + vnet_igmp_uninit, NULL); static int igmp_modevent(module_t mod, int type, void *unused __unused) @@ -3648,20 +3633,7 @@ igmp_modevent(module_t mod, int type, void *unused __unused) switch (type) { case MOD_LOAD: - igmp_sysinit(); -#ifdef VIMAGE - vnet_mod_register(&vnet_igmp_modinfo); -#else - vnet_igmp_iattach(NULL); -#endif - break; case MOD_UNLOAD: -#ifdef VIMAGE - vnet_mod_deregister(&vnet_igmp_modinfo); -#else - vnet_igmp_idetach(NULL); -#endif - igmp_sysuninit(); break; default: return (EOPNOTSUPP); diff --git a/sys/netinet/in_proto.c b/sys/netinet/in_proto.c index 8384600..bf3c713 100644 --- a/sys/netinet/in_proto.c +++ b/sys/netinet/in_proto.c @@ -383,7 +383,7 @@ struct domain inetdomain = { .dom_ifdetach = in_domifdetach }; -DOMAIN_SET(inet); +VNET_DOMAIN_SET(inet); SYSCTL_NODE(_net, PF_INET, inet, CTLFLAG_RW, 0, "Internet Family"); diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c index 57253f7..8c4094d 100644 --- a/sys/netinet6/in6_proto.c +++ b/sys/netinet6/in6_proto.c @@ -375,7 +375,7 @@ struct domain inet6domain = { .dom_ifdetach = in6_domifdetach }; -DOMAIN_SET(inet6); +VNET_DOMAIN_SET(inet6); /* * Internet configuration info diff --git a/sys/netinet6/mld6.c b/sys/netinet6/mld6.c index f47671e..e23dea3 100644 --- a/sys/netinet6/mld6.c +++ b/sys/netinet6/mld6.c @@ -117,8 +117,6 @@ static char * mld_rec_type_to_str(const int); #endif static void mld_set_version(struct mld_ifinfo *, const int); static void mld_slowtimo_vnet(void); -static void mld_sysinit(void); -static void mld_sysuninit(void); static int mld_v1_input_query(struct ifnet *, const struct ip6_hdr *, /*const*/ struct mld_hdr *); static int mld_v1_input_report(struct ifnet *, const struct ip6_hdr *, @@ -147,9 +145,6 @@ static int mld_v2_process_group_query(struct in6_multi *, static int sysctl_mld_gsr(SYSCTL_HANDLER_ARGS); static int sysctl_mld_ifinfo(SYSCTL_HANDLER_ARGS); -static vnet_attach_fn vnet_mld_iattach; -static vnet_detach_fn vnet_mld_idetach; - /* * Normative references: RFC 2710, RFC 3590, RFC 3810. * @@ -3201,7 +3196,7 @@ mld_rec_type_to_str(const int type) #endif static void -mld_sysinit(void) +mld_init(void *unused __unused) { CTR1(KTR_MLD, "%s: initializing", __func__); @@ -3213,50 +3208,39 @@ mld_sysinit(void) mld_po.ip6po_prefer_tempaddr = IP6PO_TEMPADDR_NOTPREFER; mld_po.ip6po_flags = IP6PO_DONTFRAG; } +SYSINIT(mld_init, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, mld_init, NULL); static void -mld_sysuninit(void) +mld_uninit(void *unused __unused) { CTR1(KTR_MLD, "%s: tearing down", __func__); MLD_LOCK_DESTROY(); } +SYSUNINIT(mld_uninit, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, mld_uninit, NULL); -/* - * Initialize an MLDv2 instance. - * VIMAGE: Assumes curvnet set by caller and called per vimage. - */ -static int -vnet_mld_iattach(const void *unused __unused) +static void +vnet_mld_init(const void *unused __unused) { CTR1(KTR_MLD, "%s: initializing", __func__); LIST_INIT(&V_mli_head); - - return (0); } +VNET_SYSINIT(vnet_mld_init, SI_SUB_PSEUDO, SI_ORDER_ANY, vnet_mld_init, + NULL); -static int -vnet_mld_idetach(const void *unused __unused) +static void +vnet_mld_uninit(const void *unused __unused) { CTR1(KTR_MLD, "%s: tearing down", __func__); KASSERT(LIST_EMPTY(&V_mli_head), ("%s: mli list not empty; ifnets not detached?", __func__)); - - return (0); } - -#ifdef VIMAGE -static vnet_modinfo_t vnet_mld_modinfo = { - .vmi_id = VNET_MOD_MLD, - .vmi_name = "mld", - .vmi_iattach = vnet_mld_iattach, - .vmi_idetach = vnet_mld_idetach -}; -#endif +VNET_SYSUNINIT(vnet_mld_uninit, SI_SUB_PSEUDO, SI_ORDER_ANY, vnet_mld_uninit, + NULL); static int mld_modevent(module_t mod, int type, void *unused __unused) @@ -3264,20 +3248,7 @@ mld_modevent(module_t mod, int type, void *unused __unused) switch (type) { case MOD_LOAD: - mld_sysinit(); -#ifdef VIMAGE - vnet_mod_register(&vnet_mld_modinfo); -#else - vnet_mld_iattach(NULL); -#endif - break; case MOD_UNLOAD: -#ifdef VIMAGE - vnet_mod_deregister(&vnet_mld_modinfo); -#else - vnet_mld_idetach(NULL); -#endif - mld_sysuninit(); break; default: return (EOPNOTSUPP); diff --git a/sys/netipsec/ipsec.c b/sys/netipsec/ipsec.c index c393dce..07ae90e 100644 --- a/sys/netipsec/ipsec.c +++ b/sys/netipsec/ipsec.c @@ -240,15 +240,6 @@ static void vshiftl __P((unsigned char *, int, int)); MALLOC_DEFINE(M_IPSEC_INPCB, "inpcbpolicy", "inpcb-resident ipsec policy"); -static int ipsec_iattach(const void *); -#ifdef VIMAGE -static const vnet_modinfo_t vnet_ipsec_modinfo = { - .vmi_id = VNET_MOD_IPSEC, - .vmi_name = "ipsec", - .vmi_iattach = ipsec_iattach, -}; -#endif - /* * Return a held reference to the default SP. */ @@ -1711,27 +1702,14 @@ ipsec_dumpmbuf(struct mbuf *m) } static void -ipsec_attach(const void *unused __unused) -{ - -#ifdef VIMAGE - vnet_mod_register(&vnet_ipsec_modinfo); -#else - ipsec_iattach(NULL); -#endif -} - -static int -ipsec_iattach(const void *unused __unused) +ipsec_init(const void *unused __unused) { SECPOLICY_LOCK_INIT(&V_ip4_def_policy); V_ip4_def_policy.refcnt = 1; /* NB: disallow free. */ - - return (0); } - -SYSINIT(ipsec, SI_SUB_PROTO_DOMAIN, SI_ORDER_FIRST, ipsec_attach, NULL); +VNET_SYSINIT(ipsec_init, SI_SUB_PROTO_DOMAININIT, SI_ORDER_ANY, ipsec_init, + NULL); /* XXX This stuff doesn't belong here... */ diff --git a/sys/netipsec/keysock.c b/sys/netipsec/keysock.c index c35a3bd..a8fbd5e 100644 --- a/sys/netipsec/keysock.c +++ b/sys/netipsec/keysock.c @@ -580,4 +580,4 @@ struct domain keydomain = { .dom_protoswNPROTOSW = &keysw[sizeof(keysw)/sizeof(keysw[0])] }; -DOMAIN_SET(key); +VNET_DOMAIN_SET(key); diff --git a/sys/sys/domain.h b/sys/sys/domain.h index 431429e..2563cb6 100644 --- a/sys/sys/domain.h +++ b/sys/sys/domain.h @@ -76,11 +76,31 @@ struct domain { #ifdef _KERNEL extern int domain_init_status; extern struct domain *domains; -extern void net_add_domain(void *); +void domain_add(void *); +void domain_init(void *); +#ifdef VIMAGE +void vnet_domain_init(void *); +void vnet_domain_uninit(void *); +#endif -#define DOMAIN_SET(name) \ - SYSINIT(domain_ ## name, SI_SUB_PROTO_DOMAIN, SI_ORDER_SECOND, net_add_domain, & name ## domain) +#define DOMAIN_SET(name) \ + SYSINIT(domain_add_ ## name, SI_SUB_PROTO_DOMAIN, \ + SI_ORDER_FIRST, domain_add, & name ## domain); \ + SYSINIT(domain_init_ ## name, SI_SUB_PROTO_DOMAIN, \ + SI_ORDER_SECOND, domain_init, & name ## domain); +#ifdef VIMAGE +#define VNET_DOMAIN_SET(name) \ + SYSINIT(domain_add_ ## name, SI_SUB_PROTO_DOMAIN, \ + SI_ORDER_FIRST, domain_add, & name ## domain); \ + VNET_SYSINIT(vnet_domain_init_ ## name, SI_SUB_PROTO_DOMAIN, \ + SI_ORDER_SECOND, vnet_domain_init, & name ## domain); \ + VNET_SYSUNINIT(vnet_domain_uninit_ ## name, \ + SI_SUB_PROTO_DOMAIN, SI_ORDER_SECOND, vnet_domain_uninit, \ + & name ## domain) +#else /* !VIMAGE */ +#define VNET_DOMAIN_SET(name) DOMAIN_SET(name) +#endif /* VIMAGE */ -#endif +#endif /* _KERNEL */ -#endif +#endif /* !_SYS_DOMAIN_H_ */ diff --git a/sys/sys/kernel.h b/sys/sys/kernel.h index 87a4bfe..5461dfd 100644 --- a/sys/sys/kernel.h +++ b/sys/sys/kernel.h @@ -147,6 +147,7 @@ enum sysinit_sub_id { SI_SUB_EXEC = 0x7400000, /* execve() handlers */ SI_SUB_PROTO_BEGIN = 0x8000000, /* XXX: set splimp (kludge)*/ SI_SUB_PROTO_IF = 0x8400000, /* interfaces*/ + SI_SUB_PROTO_DOMAININIT = 0x8600000, /* domain registration system */ SI_SUB_PROTO_DOMAIN = 0x8800000, /* domains (address families?)*/ SI_SUB_PROTO_IFATTACHDOMAIN = 0x8800001, /* domain dependent data init*/ SI_SUB_PROTO_END = 0x8ffffff, /* XXX: set splx (kludge)*/ @@ -178,6 +179,7 @@ enum sysinit_elem_order { SI_ORDER_FIRST = 0x0000000, /* first*/ SI_ORDER_SECOND = 0x0000001, /* second*/ SI_ORDER_THIRD = 0x0000002, /* third*/ + SI_ORDER_FOURTH = 0x0000003, /* fourth*/ SI_ORDER_MIDDLE = 0x1000000, /* somewhere in the middle */ SI_ORDER_ANY = 0xfffffff /* last*/ }; diff --git a/sys/sys/vimage.h b/sys/sys/vimage.h index 41a7d9c..9dd0e5f 100644 --- a/sys/sys/vimage.h +++ b/sys/sys/vimage.h @@ -63,69 +63,11 @@ struct vnet { #define VNET_DEBUG #endif -struct vnet; -struct ifnet; - -typedef int vnet_attach_fn(const void *); -typedef int vnet_detach_fn(const void *); - #ifdef VIMAGE -struct vnet_modinfo { - u_int vmi_id; - u_int vmi_dependson; - char *vmi_name; - vnet_attach_fn *vmi_iattach; - vnet_detach_fn *vmi_idetach; -}; -typedef struct vnet_modinfo vnet_modinfo_t; - -struct vnet_modlink { - TAILQ_ENTRY(vnet_modlink) vml_mod_le; - const struct vnet_modinfo *vml_modinfo; - const void *vml_iarg; - const char *vml_iname; -}; - -/* Stateful modules. */ -#define VNET_MOD_NET 0 /* MUST be 0 - implicit dependency */ -#define VNET_MOD_NETGRAPH 1 -#define VNET_MOD_INET 2 -#define VNET_MOD_INET6 3 -#define VNET_MOD_IPSEC 4 -#define VNET_MOD_IPFW 5 -#define VNET_MOD_DUMMYNET 6 -#define VNET_MOD_PF 7 -#define VNET_MOD_ALTQ 8 -#define VNET_MOD_IPX 9 -#define VNET_MOD_ATALK 10 -#define VNET_MOD_ACCF_HTTP 11 -#define VNET_MOD_IGMP 12 -#define VNET_MOD_MLD 13 -#define VNET_MOD_RTABLE 14 - -/* Stateless modules. */ -#define VNET_MOD_IF_CLONE 19 -#define VNET_MOD_NG_ETHER 20 -#define VNET_MOD_NG_IFACE 21 -#define VNET_MOD_NG_EIFACE 22 -#define VNET_MOD_ESP 23 -#define VNET_MOD_IPIP 24 -#define VNET_MOD_AH 25 -#define VNET_MOD_IPCOMP 26 -#define VNET_MOD_GIF 27 - /* 28 */ -#define VNET_MOD_FLOWTABLE 29 -#define VNET_MOD_LOIF 30 -#define VNET_MOD_DOMAIN 31 -#define VNET_MOD_DYNAMIC_START 32 -#define VNET_MOD_MAX 64 - +struct vnet; +struct ifnet; int vi_if_move(struct thread *, struct ifnet *, char *, int); -void vnet_mod_register(const struct vnet_modinfo *); -void vnet_mod_register_multi(const struct vnet_modinfo *, void *, char *); -void vnet_mod_deregister(const struct vnet_modinfo *); -void vnet_mod_deregister_multi(const struct vnet_modinfo *, void *, char *); struct vnet *vnet_alloc(void); void vnet_destroy(struct vnet *); void vnet_foreach(void (*vnet_foreach_fn)(struct vnet *, void *), |