Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 23 Jul 2009 20:46:49 +0000 (UTC)
From:      Robert Watson <rwatson@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r195837 - in head/sys: kern net netgraph netgraph/bluetooth/socket netinet netinet6 netipsec sys
Message-ID:  <200907232046.n6NKkntU088803@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rwatson
Date: Thu Jul 23 20:46:49 2009
New Revision: 195837
URL: http://svn.freebsd.org/changeset/base/195837

Log:
  Introduce and use a sysinit-based initialization scheme for virtual
  network stacks, VNET_SYSINIT:
  
  - Add VNET_SYSINIT and VNET_SYSUNINIT macros to declare events that will
    occur each time a network stack is instantiated and destroyed.  In the
    !VIMAGE case, these are simply mapped into regular SYSINIT/SYSUNINIT.
    For the VIMAGE case, we instead use SYSINIT's to track their order and
    properties on registration, using them for each vnet when created/
    destroyed, or immediately on module load for already-started vnets.
  - Remove vnet_modinfo mechanism that existed to serve this purpose
    previously, as well as its dependency scheme: we now just use the
    SYSINIT ordering scheme.
  - Implement VNET_DOMAIN_SET() to allow protocol domains to declare that
    they want init functions to be called for each virtual network stack
    rather than just once at boot, compiling down to DOMAIN_SET() in the
    non-VIMAGE case.
  - Walk all virtualized kernel subsystems and make use of these instead
    of modinfo or DOMAIN_SET() for init/uninit events.  In some cases,
    convert modular components from using modevent to using sysinit (where
    appropriate).  In some cases, do minor rejuggling of SYSINIT ordering
    to make room for or better manage events.
  
  Portions submitted by:	jhb (VNET_SYSINIT), bz (cleanup)
  Discussed with:		jhb, bz, julian, zec
  Reviewed by:		bz
  Approved by:		re (VIMAGE blanket)

Modified:
  head/sys/kern/kern_vimage.c
  head/sys/kern/uipc_domain.c
  head/sys/net/flowtable.c
  head/sys/net/if.c
  head/sys/net/if_clone.c
  head/sys/net/if_clone.h
  head/sys/net/if_gif.c
  head/sys/net/if_loop.c
  head/sys/net/route.c
  head/sys/net/rtsock.c
  head/sys/net/vnet.c
  head/sys/net/vnet.h
  head/sys/netgraph/bluetooth/socket/ng_btsocket.c
  head/sys/netgraph/netgraph.h
  head/sys/netgraph/ng_base.c
  head/sys/netgraph/ng_eiface.c
  head/sys/netgraph/ng_ether.c
  head/sys/netgraph/ng_iface.c
  head/sys/netgraph/ng_socket.c
  head/sys/netinet/igmp.c
  head/sys/netinet/in_proto.c
  head/sys/netinet6/in6_proto.c
  head/sys/netinet6/mld6.c
  head/sys/netipsec/ipsec.c
  head/sys/netipsec/keysock.c
  head/sys/sys/domain.h
  head/sys/sys/kernel.h
  head/sys/sys/vimage.h

Modified: head/sys/kern/kern_vimage.c
==============================================================================
--- head/sys/kern/kern_vimage.c	Thu Jul 23 19:43:23 2009	(r195836)
+++ head/sys/kern/kern_vimage.c	Thu Jul 23 20:46:49 2009	(r195837)
@@ -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 ifn
 	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_ORDE
 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,

Modified: head/sys/kern/uipc_domain.c
==============================================================================
--- head/sys/kern/uipc_domain.c	Thu Jul 23 19:43:23 2009	(r195836)
+++ head/sys/kern/uipc_domain.c	Thu Jul 23 20:46:49 2009	(r195837)
@@ -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

Modified: head/sys/net/flowtable.c
==============================================================================
--- head/sys/net/flowtable.c	Thu Jul 23 19:43:23 2009	(r195836)
+++ head/sys/net/flowtable.c	Thu Jul 23 20:46:49 2009	(r195837)
@@ -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
 #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 __u
 	    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.

Modified: head/sys/net/if.c
==============================================================================
--- head/sys/net/if.c	Thu Jul 23 19:43:23 2009	(r195836)
+++ head/sys/net/if.c	Thu Jul 23 20:46:49 2009	(r195837)
@@ -150,11 +150,6 @@ static void	if_detach_internal(struct if
 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

Modified: head/sys/net/if_clone.c
==============================================================================
--- head/sys/net/if_clone.c	Thu Jul 23 19:43:23 2009	(r195836)
+++ head/sys/net/if_clone.c	Thu Jul 23 20:46:49 2009	(r195837)
@@ -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_cl
 
 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
 }
 
 /*

Modified: head/sys/net/if_clone.h
==============================================================================
--- head/sys/net/if_clone.h	Thu Jul 23 19:43:23 2009	(r195836)
+++ head/sys/net/if_clone.h	Thu Jul 23 20:46:49 2009	(r195837)
@@ -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 *);

Modified: head/sys/net/if_gif.c
==============================================================================
--- head/sys/net/if_gif.c	Thu Jul 23 19:43:23 2009	(r195836)
+++ head/sys/net/if_gif.c	Thu Jul 23 20:46:49 2009	(r195837)
@@ -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 *if
 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, CTL
  */
 #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_
  * 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:

Modified: head/sys/net/if_loop.c
==============================================================================
--- head/sys/net/if_loop.c	Thu Jul 23 19:43:23 2009	(r195836)
+++ head/sys/net/if_loop.c	Thu Jul 23 20:46:49 2009	(r195837)
@@ -103,30 +103,14 @@ int		looutput(struct ifnet *ifp, struct 
 		    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, in
 	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, vo
 
 	switch (type) {
 	case MOD_LOAD:
-#ifdef VIMAGE
-		vnet_mod_register(&vnet_loif_modinfo);
-#else
-		vnet_loif_iattach(NULL);
-#endif
 		break;
 
 	case MOD_UNLOAD:

Modified: head/sys/net/route.c
==============================================================================
--- head/sys/net/route.c	Thu Jul 23 19:43:23 2009	(r195836)
+++ head/sys/net/route.c	Thu Jul 23 20:46:49 2009	(r195837)
@@ -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 __
 			}
 		}
 	}
-
-	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 __
 			}
 		}
 	}
-	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 
 		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);

Modified: head/sys/net/rtsock.c
==============================================================================
--- head/sys/net/rtsock.c	Thu Jul 23 19:43:23 2009	(r195836)
+++ head/sys/net/rtsock.c	Thu Jul 23 20:46:49 2009	(r195837)
@@ -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);

Modified: head/sys/net/vnet.c
==============================================================================
--- head/sys/net/vnet.c	Thu Jul 23 19:43:23 2009	(r195836)
+++ head/sys/net/vnet.c	Thu Jul 23 20:46:49 2009	(r195837)
@@ -126,6 +126,16 @@ MALLOC_DEFINE(M_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_A
 		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;
+	}

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200907232046.n6NKkntU088803>