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:
Approved by:		re (VIMAGE blanket)

--- //depot/vendor/freebsd/src/sys/kern/kern_vimage.c	2009/07/19 17:46:07
+++ //depot/user/rwatson/vimage/src/sys/kern/kern_vimage.c	2009/07/21 21:16:35
@@ -52,12 +52,6 @@
 
 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 @@
 	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 @@
 
 	/* 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 @@
 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 @@
 			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 @@
 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 @@
 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,
--- //depot/vendor/freebsd/src/sys/kern/uipc_domain.c	2009/07/14 22:50:17
+++ //depot/user/rwatson/vimage/src/sys/kern/uipc_domain.c	2009/07/22 10:33:05
@@ -59,17 +59,12 @@
  */
 
 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 @@
 	.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 @@
  * 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 @@
 	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 @@
 			(*pr->pr_destroy)();
 	if (dp->dom_destroy)
 		(*dp->dom_destroy)();
-
-	return (0);
 }
 #endif
 
@@ -220,7 +208,7 @@
  * XXX can't fail at this time.
  */
 void
-net_add_domain(void *data)
+domain_add(void *data)
 {
 	struct domain *dp;
 
@@ -247,11 +235,6 @@
 		    "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
--- //depot/vendor/freebsd/src/sys/net/flowtable.c	2009/07/20 14:00:14
+++ //depot/user/rwatson/vimage/src/sys/net/flowtable.c	2009/07/22 22:26:35
@@ -55,6 +55,7 @@
 #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 @@
 #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 @@
 }
 
 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,22 +800,24 @@
 	    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);
 }
+
+VNET_SYSUNINIT(flowtable_uninit, SI_SUB_KTHREAD_INIT, SI_ORDER_ANY,
+    flowtable_uninit, NULL);
 #endif
 
-SYSINIT(flowtable_setup, SI_SUB_KTHREAD_INIT, SI_ORDER_ANY, flowtable_setup, NULL);
-
 /*
  * The rest of the code is devoted to garbage collection of expired entries.
  * It is a new additon made necessary by the switch to dynamically allocating
--- //depot/vendor/freebsd/src/sys/net/if.c	2009/07/19 17:46:07
+++ //depot/user/rwatson/vimage/src/sys/net/if.c	2009/07/21 21:16:35
@@ -150,11 +150,6 @@
 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 @@
 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 @@
  * 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();
 }
-
-static int
-vnet_net_iattach(const void *unused __unused)
-{
-
-	TAILQ_INIT(&V_ifnet);
-	TAILQ_INIT(&V_ifg_head);
-	if_grow();				/* create initial table */
+SYSINIT(interfaces, SI_SUB_INIT_IF, SI_ORDER_SECOND, if_init, NULL);
 
-	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
--- //depot/vendor/freebsd/src/sys/net/if_clone.c	2009/07/16 21:15:15
+++ //depot/user/rwatson/vimage/src/sys/net/if_clone.c	2009/07/21 21:16:35
@@ -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 @@
 
 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_CLONERS_LOCK_INIT();
-#ifdef VIMAGE
-	vnet_mod_register(&vnet_clone_modinfo);
-#else
-	vnet_clone_iattach(NULL);
-#endif
 }
 
 /*
--- //depot/vendor/freebsd/src/sys/net/if_clone.h	2008/09/20 19:45:13
+++ //depot/user/rwatson/vimage/src/sys/net/if_clone.h	2009/07/21 21:16:35
@@ -72,6 +72,7 @@
 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 *);
--- //depot/vendor/freebsd/src/sys/net/if_gif.c	2009/07/16 21:15:15
+++ //depot/user/rwatson/vimage/src/sys/net/if_gif.c	2009/07/21 08:40:15
@@ -96,19 +96,15 @@
 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 @@
 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 @@
  */
 #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 @@
  * 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 @@
 	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 @@
 	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;
 
-		break;
 	case MOD_UNLOAD:
 		if_clone_detach(&gif_cloner);
-#ifdef VIMAGE
-		vnet_mod_deregister(&vnet_gif_modinfo);
-#endif
 		mtx_destroy(&gif_mtx);
 		break;
 	default:
--- //depot/vendor/freebsd/src/sys/net/if_loop.c	2009/07/16 21:15:15
+++ //depot/user/rwatson/vimage/src/sys/net/if_loop.c	2009/07/21 21:16:35
@@ -103,30 +103,14 @@
 		    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 @@
 	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 @@
 
 	switch (type) {
 	case MOD_LOAD:
-#ifdef VIMAGE
-		vnet_mod_register(&vnet_loif_modinfo);
-#else
-		vnet_loif_iattach(NULL);
-#endif
 		break;
 
 	case MOD_UNLOAD:
--- //depot/vendor/freebsd/src/sys/net/route.c	2009/07/16 21:15:15
+++ //depot/user/rwatson/vimage/src/sys/net/route.c	2009/07/21 21:16:35
@@ -99,17 +99,6 @@
 
 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 @@
 	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 @@
 	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 @@
 			}
 		}
 	}
-
-	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 @@
 			}
 		}
 	}
-	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 @@
 		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);
--- //depot/vendor/freebsd/src/sys/net/rtsock.c	2009/07/14 22:50:17
+++ //depot/user/rwatson/vimage/src/sys/net/rtsock.c	2009/07/22 10:33:05
@@ -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 @@
 	.dom_protoswNPROTOSW =	&routesw[sizeof(routesw)/sizeof(routesw[0])]
 };
 
-DOMAIN_SET(route);
+VNET_DOMAIN_SET(route);
--- //depot/vendor/freebsd/src/sys/net/vnet.c	2009/07/14 22:50:17
+++ //depot/user/rwatson/vimage/src/sys/net/vnet.c	2009/07/21 11:38:58
@@ -126,6 +126,16 @@
  */
 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 @@
 		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);
+	}
+}
--- //depot/vendor/freebsd/src/sys/net/vnet.h	2009/07/21 22:00:14
+++ //depot/user/rwatson/vimage/src/sys/net/vnet.h	2009/07/22 22:06:54
@@ -46,7 +46,44 @@
 
 #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");
 #else
@@ -121,7 +158,17 @@
 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 @@
 #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)	\
--- //depot/vendor/freebsd/src/sys/netgraph/bluetooth/socket/ng_btsocket.c	2008/07/30 22:45:13
+++ //depot/user/rwatson/vimage/src/sys/netgraph/bluetooth/socket/ng_btsocket.c	2009/07/22 22:24:45
@@ -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 @@
  * 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 @@
         
 	switch (event) {
 	case MOD_LOAD:
-		net_add_domain(&ng_btsocket_domain);
 		break;
 
 	case MOD_UNLOAD:
@@ -285,3 +285,4 @@
 	return (error);
 } /* ng_btsocket_modevent */
 
+DOMAIN_SET(ng_btsocket_);
--- //depot/vendor/freebsd/src/sys/netgraph/netgraph.h	2009/07/14 22:50:17
+++ //depot/user/rwatson/vimage/src/sys/netgraph/netgraph.h	2009/07/21 14:08:52
@@ -1113,7 +1113,7 @@
 					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 */
--- //depot/vendor/freebsd/src/sys/netgraph/ng_base.c	2009/07/16 21:15:15
+++ //depot/user/rwatson/vimage/src/sys/netgraph/ng_base.c	2009/07/21 21:16:35
@@ -79,10 +79,6 @@
 /* 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 @@
 	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 @@
 		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 @@
 	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);
--- //depot/vendor/freebsd/src/sys/netgraph/ng_eiface.c	2009/07/16 21:15:15
+++ //depot/user/rwatson/vimage/src/sys/netgraph/ng_eiface.c	2009/07/22 08:59:45
@@ -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 @@
 };
 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 @@
 
 	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 @@
 	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);
--- //depot/vendor/freebsd/src/sys/netgraph/ng_ether.c	2009/07/14 22:50:17
+++ //depot/user/rwatson/vimage/src/sys/netgraph/ng_ether.c	2009/07/22 09:01:47
@@ -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_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 @@
 		 * 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 @@
 	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 @@
 			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);
--- //depot/vendor/freebsd/src/sys/netgraph/ng_iface.c	2009/07/16 21:15:15
+++ //depot/user/rwatson/vimage/src/sys/netgraph/ng_iface.c	2009/07/22 09:00:34
@@ -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 @@
 };
 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 @@
 
 	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 @@
 	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);
--- //depot/vendor/freebsd/src/sys/netgraph/ng_socket.c	2008/11/22 17:00:14
+++ //depot/user/rwatson/vimage/src/sys/netgraph/ng_socket.c	2009/07/22 10:33:05
@@ -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 @@
 
 	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 @@
 	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, "");
--- //depot/vendor/freebsd/src/sys/netinet/igmp.c	2009/07/20 14:00:14
+++ //depot/user/rwatson/vimage/src/sys/netinet/igmp.c	2009/07/21 21:16:35
@@ -114,7 +114,6 @@
 #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_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 @@
 #endif
 
 static void
-igmp_sysinit(void)
+igmp_init(void *unused __unused)
 {
 
 	CTR1(KTR_IGMPV3, "%s: initializing", __func__);
@@ -3591,9 +3587,10 @@
 
 	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_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 @@
 
     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);
--- //depot/vendor/freebsd/src/sys/netinet/in_proto.c	2009/06/17 12:50:15
+++ //depot/user/rwatson/vimage/src/sys/netinet/in_proto.c	2009/07/22 10:33:05
@@ -383,7 +383,7 @@
 	.dom_ifdetach =		in_domifdetach
 };
 
-DOMAIN_SET(inet);
+VNET_DOMAIN_SET(inet);
 
 SYSCTL_NODE(_net,      PF_INET,		inet,	CTLFLAG_RW, 0,
 	"Internet Family");
--- //depot/vendor/freebsd/src/sys/netinet6/in6_proto.c	2009/07/21 22:00:14
+++ //depot/user/rwatson/vimage/src/sys/netinet6/in6_proto.c	2009/07/22 22:06:54
@@ -375,7 +375,7 @@
 	.dom_ifdetach =		in6_domifdetach
 };
 
-DOMAIN_SET(inet6);
+VNET_DOMAIN_SET(inet6);
 
 /*
  * Internet configuration info
--- //depot/vendor/freebsd/src/sys/netinet6/mld6.c	2009/07/20 14:00:14
+++ //depot/user/rwatson/vimage/src/sys/netinet6/mld6.c	2009/07/22 09:03:31
@@ -117,8 +117,6 @@
 #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	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 @@
 #endif
 
 static void
-mld_sysinit(void)
+mld_init(void *unused __unused)
 {
 
 	CTR1(KTR_MLD, "%s: initializing", __func__);
@@ -3213,50 +3208,39 @@
 	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 @@
 
     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);
--- //depot/vendor/freebsd/src/sys/netipsec/ipsec.c	2009/07/20 14:00:14
+++ //depot/user/rwatson/vimage/src/sys/netipsec/ipsec.c	2009/07/21 21:16:35
@@ -240,15 +240,6 @@
 
 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 @@
 }
 
 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... */
--- //depot/vendor/freebsd/src/sys/netipsec/keysock.c	2009/07/16 21:15:15
+++ //depot/user/rwatson/vimage/src/sys/netipsec/keysock.c	2009/07/22 10:33:05
@@ -580,4 +580,4 @@
 	.dom_protoswNPROTOSW =	&keysw[sizeof(keysw)/sizeof(keysw[0])]
 };
 
-DOMAIN_SET(key);
+VNET_DOMAIN_SET(key);
--- //depot/vendor/freebsd/src/sys/sys/domain.h	2009/06/08 17:20:14
+++ //depot/user/rwatson/vimage/src/sys/sys/domain.h	2009/07/22 10:33:05
@@ -76,11 +76,31 @@
 #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_ */
--- //depot/vendor/freebsd/src/sys/sys/kernel.h	2009/07/19 14:25:14
+++ //depot/user/rwatson/vimage/src/sys/sys/kernel.h	2009/07/21 21:16:35
@@ -147,6 +147,7 @@
 	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 @@
 	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*/
 };
--- //depot/vendor/freebsd/src/sys/sys/vimage.h	2009/07/19 17:46:07
+++ //depot/user/rwatson/vimage/src/sys/sys/vimage.h	2009/07/22 22:04:32
@@ -63,69 +63,11 @@
 #define	VNET_DEBUG
 #endif
 
+#ifdef VIMAGE
+
 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
-
 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 *),
