Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 30 Apr 2009 13:36:26 +0000 (UTC)
From:      Marko Zec <zec@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r191688 - in head: . sys/kern sys/net sys/netinet sys/netinet6 sys/netipsec sys/sys
Message-ID:  <200904301336.n3UDaQYW013558@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: zec
Date: Thu Apr 30 13:36:26 2009
New Revision: 191688
URL: http://svn.freebsd.org/changeset/base/191688

Log:
  Permit buiding kernels with options VIMAGE, restricted to only a single
  active network stack instance.  Turning on options VIMAGE at compile
  time yields the following changes relative to default kernel build:
  
  1) V_ accessor macros for virtualized variables resolve to structure
  fields via base pointers, instead of being resolved as fields in global
  structs or plain global variables.  As an example, V_ifnet becomes:
  
      options VIMAGE:          ((struct vnet_net *) vnet_net)->_ifnet
      default build:           vnet_net_0._ifnet
      options VIMAGE_GLOBALS:  ifnet
  
  2) INIT_VNET_* macros will declare and set up base pointers to be used
  by V_ accessor macros, instead of resolving to whitespace:
  
      INIT_VNET_NET(ifp->if_vnet); becomes
  
      struct vnet_net *vnet_net = (ifp->if_vnet)->mod_data[VNET_MOD_NET];
  
  3) Memory for vnet modules registered via vnet_mod_register() is now
  allocated at run time in sys/kern/kern_vimage.c, instead of per vnet
  module structs being declared as globals.  If required, vnet modules
  can now request the framework to provide them with allocated bzeroed
  memory by filling in the vmi_size field in their vmi_modinfo structures.
  
  4) structs socket, ifnet, inpcbinfo, tcpcb and syncache_head are
  extended to hold a pointer to the parent vnet.  options VIMAGE builds
  will fill in those fields as required.
  
  5) curvnet is introduced as a new global variable in options VIMAGE
  builds, always pointing to the default and only struct vnet.
  
  6) struct sysctl_oid has been extended with additional two fields to
  store major and minor virtualization module identifiers, oid_v_subs and
  oid_v_mod.  SYSCTL_V_* family of macros will fill in those fields
  accordingly, and store the offset in the appropriate vnet container
  struct in oid_arg1.
  In sysctl handlers dealing with virtualized sysctls, the
  SYSCTL_RESOLVE_V_ARG1() macro will compute the address of the target
  variable and make it available in arg1 variable for further processing.
  
  Unused fields in structs vnet_inet, vnet_inet6 and vnet_ipfw have
  been deleted.
  
  Reviewed by:	bz, rwatson
  Approved by:	julian (mentor)

Modified:
  head/UPDATING
  head/sys/kern/kern_mib.c
  head/sys/kern/kern_sysctl.c
  head/sys/kern/kern_vimage.c
  head/sys/kern/uipc_socket.c
  head/sys/net/if.c
  head/sys/net/if_gif.c
  head/sys/net/if_mib.c
  head/sys/net/if_var.h
  head/sys/netinet/in_pcb.c
  head/sys/netinet/in_pcb.h
  head/sys/netinet/ip_divert.c
  head/sys/netinet/ip_fw.h
  head/sys/netinet/ip_fw_pfil.c
  head/sys/netinet/ip_input.c
  head/sys/netinet/raw_ip.c
  head/sys/netinet/tcp_subr.c
  head/sys/netinet/tcp_syncache.c
  head/sys/netinet/tcp_syncache.h
  head/sys/netinet/tcp_var.h
  head/sys/netinet/udp_usrreq.c
  head/sys/netinet/vinet.h
  head/sys/netinet6/in6_ifattach.c
  head/sys/netinet6/in6_mcast.c
  head/sys/netinet6/in6_proto.c
  head/sys/netinet6/ip6_input.c
  head/sys/netinet6/mld6.c
  head/sys/netinet6/nd6.c
  head/sys/netinet6/raw_ip6.c
  head/sys/netinet6/vinet6.h
  head/sys/netipsec/ipsec.c
  head/sys/sys/param.h
  head/sys/sys/socketvar.h
  head/sys/sys/sysctl.h
  head/sys/sys/vimage.h

Modified: head/UPDATING
==============================================================================
--- head/UPDATING	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/UPDATING	Thu Apr 30 13:36:26 2009	(r191688)
@@ -22,6 +22,14 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.
 	to maximize performance.  (To disable malloc debugging, run
 	ln -s aj /etc/malloc.conf.)
 
+20090430:
+	The layout of the following structs has changed: sysctl_oid,
+	socket, ifnet, inpcbinfo, tcpcb, syncache_head, vnet_inet,
+	vnet_inet6 and vnet_ipfw.  Most modules need to be rebuild or
+	panics may be experienced.  World rebuild is required for
+	correctly checking networking state from userland.
+	Bump __FreeBSD_version to 800085.
+
 20090429:
 	MLDv2 and Source-Specific Multicast (SSM) have been merged
 	to the IPv6 stack. VIMAGE hooks are in but not yet used.

Modified: head/sys/kern/kern_mib.c
==============================================================================
--- head/sys/kern/kern_mib.c	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/kern/kern_mib.c	Thu Apr 30 13:36:26 2009	(r191688)
@@ -208,9 +208,8 @@ static char	machine_arch[] = MACHINE_ARC
 SYSCTL_STRING(_hw, HW_MACHINE_ARCH, machine_arch, CTLFLAG_RD,
     machine_arch, 0, "System architecture");
 
-#ifndef VIMAGE
+/* should become #ifndef VIMAGE */
 char hostname[MAXHOSTNAMELEN];
-#endif
 
 /*
  * This mutex is used to protect the hostname and domainname variables, and
@@ -349,9 +348,8 @@ SYSCTL_PROC(_kern, OID_AUTO, conftxt, CT
     0, 0, sysctl_kern_config, "", "Kernel configuration file");
 #endif
 
-#ifndef VIMAGE
+/* should become #ifndef VIMAGE */
 char domainname[MAXHOSTNAMELEN];	/* Protected by hostname_mtx. */
-#endif
 
 static int
 sysctl_domainname(SYSCTL_HANDLER_ARGS)

Modified: head/sys/kern/kern_sysctl.c
==============================================================================
--- head/sys/kern/kern_sysctl.c	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/kern/kern_sysctl.c	Thu Apr 30 13:36:26 2009	(r191688)
@@ -934,6 +934,30 @@ sysctl_handle_int(SYSCTL_HANDLER_ARGS)
 	return (error);
 }
 
+#ifdef VIMAGE
+int
+sysctl_handle_v_int(SYSCTL_HANDLER_ARGS)
+{
+	int tmpout, error = 0;
+ 
+	SYSCTL_RESOLVE_V_ARG1();
+ 
+	/*
+	 * Attempt to get a coherent snapshot by making a copy of the data.
+	 */
+	tmpout = *(int *)arg1;
+	error = SYSCTL_OUT(req, &tmpout, sizeof(int));
+
+	if (error || !req->newptr)
+		return (error);
+
+	if (!arg1)
+		error = EPERM;
+	else
+		error = SYSCTL_IN(req, arg1, sizeof(int));
+	return (error);
+}
+#endif
 
 /*
  * Based on on sysctl_handle_int() convert milliseconds into ticks.
@@ -944,7 +968,9 @@ sysctl_msec_to_ticks(SYSCTL_HANDLER_ARGS
 {
 	int error, s, tt;
 
-	tt = *(int *)oidp->oid_arg1;
+	SYSCTL_RESOLVE_V_ARG1();
+
+	tt = *(int *)arg1;
 	s = (int)((int64_t)tt * 1000 / hz);
 
 	error = sysctl_handle_int(oidp, &s, 0, req);
@@ -955,7 +981,7 @@ sysctl_msec_to_ticks(SYSCTL_HANDLER_ARGS
 	if (tt < 1)
 		return (EINVAL);
 
-	*(int *)oidp->oid_arg1 = tt;
+	*(int *)arg1 = tt;
 	return (0);
 }
 
@@ -1069,6 +1095,47 @@ retry:
 	return (error);
 }
 
+#ifdef VIMAGE
+int
+sysctl_handle_v_string(SYSCTL_HANDLER_ARGS)
+{
+	int error=0;
+	char *tmparg;
+	size_t outlen;
+
+	SYSCTL_RESOLVE_V_ARG1();
+
+	/*
+	 * Attempt to get a coherent snapshot by copying to a
+	 * temporary kernel buffer.
+	 */
+retry:
+	outlen = strlen((char *)arg1)+1;
+	tmparg = malloc(outlen, M_SYSCTLTMP, M_WAITOK);
+
+	if (strlcpy(tmparg, (char *)arg1, outlen) >= outlen) {
+		free(tmparg, M_SYSCTLTMP);
+		goto retry;
+	}
+
+	error = SYSCTL_OUT(req, tmparg, outlen);
+	free(tmparg, M_SYSCTLTMP);
+
+	if (error || !req->newptr)
+		return (error);
+
+	if ((req->newlen - req->newidx) >= arg2) {
+		error = EINVAL;
+	} else {
+		arg2 = (req->newlen - req->newidx);
+		error = SYSCTL_IN(req, arg1, arg2);
+		((char *)arg1)[arg2] = '\0';
+	}
+
+	return (error);
+}
+#endif
+
 /*
  * Handle any kind of opaque data.
  * arg1 points to it, arg2 is the size.
@@ -1106,6 +1173,35 @@ retry:
 	return (error);
 }
 
+#ifdef VIMAGE
+int
+sysctl_handle_v_opaque(SYSCTL_HANDLER_ARGS)
+{
+	int error, tries;
+	u_int generation;
+	struct sysctl_req req2;
+
+	SYSCTL_RESOLVE_V_ARG1();
+
+	tries = 0;
+	req2 = *req;
+retry:
+	generation = curthread->td_generation;
+	error = SYSCTL_OUT(req, arg1, arg2);
+	if (error)
+		return (error);
+	tries++;
+	if (generation != curthread->td_generation && tries < 3) {
+		*req = req2;
+		goto retry;
+	}
+
+	error = SYSCTL_IN(req, arg1, arg2);
+
+	return (error);
+}
+#endif
+
 /*
  * Transfer functions to/from kernel space.
  * XXX: rather untested at this point

Modified: head/sys/kern/kern_vimage.c
==============================================================================
--- head/sys/kern/kern_vimage.c	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/kern/kern_vimage.c	Thu Apr 30 13:36:26 2009	(r191688)
@@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
 #ifndef VIMAGE_GLOBALS
 
 MALLOC_DEFINE(M_VIMAGE, "vimage", "vimage resource container");
+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;
@@ -49,6 +50,12 @@ static void vnet_mod_complete_registrati
 static int vnet_mod_constructor(struct vnet_modlink *);
 static int vnet_mod_destructor(struct vnet_modlink *);
 
+#ifdef VIMAGE
+/* curvnet should be thread-local - this is only a temporary step. */
+struct vnet *curvnet;
+struct vnet_list_head vnet_head;
+#endif
+
 void
 vnet_mod_register(const struct vnet_modinfo *vmi)
 {
@@ -263,7 +270,14 @@ vi_symlookup(struct kld_sym_lookup *look
 		for (mapentry = vml->vml_modinfo->vmi_symmap;
 		    mapentry->name != NULL; mapentry++) {
 			if (strcmp(symstr, mapentry->name) == 0) {
-				lookup->symvalue = (u_long) mapentry->base;
+#ifdef VIMAGE
+				lookup->symvalue =
+				    (u_long) curvnet->mod_data[
+				    vml->vml_modinfo->vmi_id];
+				lookup->symvalue += mapentry->offset;
+#else
+				lookup->symvalue = (u_long) mapentry->offset;
+#endif
 				lookup->symsize = mapentry->size;
 				return (0);
 			}
@@ -275,9 +289,23 @@ vi_symlookup(struct kld_sym_lookup *look
 static void
 vi_init(void *unused)
 {
+#ifdef VIMAGE
+	struct vnet *vnet;
+#endif
 
 	TAILQ_INIT(&vnet_modlink_head);
 	TAILQ_INIT(&vnet_modpending_head);
+
+#ifdef VIMAGE
+	LIST_INIT(&vnet_head);
+
+	vnet = malloc(sizeof(struct vnet), M_VNET, M_NOWAIT | M_ZERO);
+	if (vnet == NULL)
+		panic("vi_alloc: malloc failed");
+	LIST_INSERT_HEAD(&vnet_head, vnet, vnet_le);
+
+	curvnet = LIST_FIRST(&vnet_head);
+#endif
 }
 
 static void

Modified: head/sys/kern/uipc_socket.c
==============================================================================
--- head/sys/kern/uipc_socket.c	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/kern/uipc_socket.c	Thu Apr 30 13:36:26 2009	(r191688)
@@ -130,6 +130,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/sysctl.h>
 #include <sys/uio.h>
 #include <sys/jail.h>
+#include <sys/vimage.h>
 
 #include <security/mac/mac_framework.h>
 
@@ -284,6 +285,9 @@ soalloc(void)
 	mtx_lock(&so_global_mtx);
 	so->so_gencnt = ++so_gencnt;
 	++numopensockets;
+#ifdef VIMAGE
+	so->so_vnet = curvnet;
+#endif
 	mtx_unlock(&so_global_mtx);
 	return (so);
 }

Modified: head/sys/net/if.c
==============================================================================
--- head/sys/net/if.c	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/net/if.c	Thu Apr 30 13:36:26 2009	(r191688)
@@ -186,6 +186,7 @@ static struct vnet_symmap vnet_net_symma
 static const vnet_modinfo_t vnet_net_modinfo = {
 	.vmi_id		= VNET_MOD_NET,
 	.vmi_name	= "net",
+	.vmi_size	= sizeof(struct vnet_net),
 	.vmi_symmap	= vnet_net_symmap,
 	.vmi_iattach	= vnet_net_iattach
 };
@@ -545,6 +546,7 @@ if_alloc(u_char type)
 static void
 if_free_internal(struct ifnet *ifp)
 {
+	INIT_VNET_NET(ifp->if_vnet);
 
 	KASSERT((ifp->if_flags & IFF_DYING),
 	    ("if_free_internal: interface not dying"));
@@ -582,7 +584,6 @@ if_free_internal(struct ifnet *ifp)
 void
 if_free_type(struct ifnet *ifp, u_char type)
 {
-	INIT_VNET_NET(curvnet); /* ifp->if_vnet can be NULL here ! */
 
 	KASSERT(ifp->if_alloctype == type,
 	    ("if_free_type: type (%d) != alloctype (%d)", type,
@@ -673,6 +674,10 @@ if_attach(struct ifnet *ifp)
 		panic ("%s: BUG: if_attach called without if_alloc'd input()\n",
 		    ifp->if_xname);
 
+#ifdef VIMAGE
+	ifp->if_vnet = curvnet;
+#endif
+
 	if_addgroup(ifp, IFG_ALL);
 
 	getmicrotime(&ifp->if_lastchange);
@@ -978,6 +983,9 @@ if_detach(struct ifnet *ifp)
 	}
 	IF_AFDATA_UNLOCK(ifp);
 	ifq_detach(&ifp->if_snd);
+#ifdef VIMAGE
+	ifp->if_vnet = NULL;
+#endif
 	splx(s);
 }
 

Modified: head/sys/net/if_gif.c
==============================================================================
--- head/sys/net/if_gif.c	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/net/if_gif.c	Thu Apr 30 13:36:26 2009	(r191688)
@@ -127,6 +127,7 @@ static int	vnet_gif_iattach(const void *
 static const vnet_modinfo_t vnet_gif_modinfo = {
 	.vmi_id		= VNET_MOD_GIF,
 	.vmi_name	= "gif",
+	.vmi_size	= sizeof(struct vnet_gif),
 	.vmi_dependson	= VNET_MOD_NET,
 	.vmi_iattach	= vnet_gif_iattach
 };
@@ -303,8 +304,10 @@ gifmodevent(mod, type, data)
 		if_clone_detach(&gif_cloner);
 		mtx_destroy(&gif_mtx);
 #ifdef INET6
+#ifndef VIMAGE
 		V_ip6_gif_hlim = 0;	/* XXX -> vnet_gif_idetach() */
 #endif
+#endif
 		break;
 	default:
 		return EOPNOTSUPP;

Modified: head/sys/net/if_mib.c
==============================================================================
--- head/sys/net/if_mib.c	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/net/if_mib.c	Thu Apr 30 13:36:26 2009	(r191688)
@@ -77,7 +77,6 @@ SYSCTL_V_INT(V_NET, vnet_net, _net_link_
 static int
 sysctl_ifdata(SYSCTL_HANDLER_ARGS) /* XXX bad syntax! */
 {
-	INIT_VNET_NET(curvnet);
 	int *name = (int *)arg1;
 	int error;
 	u_int namelen = arg2;

Modified: head/sys/net/if_var.h
==============================================================================
--- head/sys/net/if_var.h	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/net/if_var.h	Thu Apr 30 13:36:26 2009	(r191688)
@@ -117,6 +117,7 @@ struct	ifqueue {
 struct ifnet {
 	void	*if_softc;		/* pointer to driver state */
 	void	*if_l2com;		/* pointer to protocol bits */
+	struct vnet *if_vnet;		/* pointer to network stack instance */
 	TAILQ_ENTRY(ifnet) if_link; 	/* all struct ifnets are chained */
 	char	if_xname[IFNAMSIZ];	/* external name (name + unit) */
 	const char *if_dname;		/* driver name */

Modified: head/sys/netinet/in_pcb.c
==============================================================================
--- head/sys/netinet/in_pcb.c	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/netinet/in_pcb.c	Thu Apr 30 13:36:26 2009	(r191688)
@@ -126,7 +126,9 @@ sysctl_net_ipport_check(SYSCTL_HANDLER_A
 	INIT_VNET_INET(curvnet);
 	int error;
 
-	error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req);
+	SYSCTL_RESOLVE_V_ARG1();
+
+	error = sysctl_handle_int(oidp, arg1, arg2, req);
 	if (error == 0) {
 		RANGECHK(V_ipport_lowfirstauto, 1, IPPORT_RESERVED - 1);
 		RANGECHK(V_ipport_lowlastauto, 1, IPPORT_RESERVED - 1);

Modified: head/sys/netinet/in_pcb.h
==============================================================================
--- head/sys/netinet/in_pcb.h	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/netinet/in_pcb.h	Thu Apr 30 13:36:26 2009	(r191688)
@@ -224,6 +224,8 @@ struct inpcb {
 #define	in6p_icmp6filt	inp_depend6.inp6_icmp6filt
 #define	in6p_cksum	inp_depend6.inp6_cksum
 
+#define	inp_vnet	inp_pcbinfo->ipi_vnet
+
 /*
  * The range of the generation count, as used in this implementation, is 9e19.
  * We would have to create 300 billion connections per second for this number
@@ -301,8 +303,12 @@ struct inpcbinfo {
 	struct rwlock		 ipi_lock;
 
 	/*
-	 * vimage 1
-	 * general use 1
+	 * Pointer to network stack instance
+	 */
+	struct vnet		*ipi_vnet;
+
+	/*
+	 * general use 2
 	 */
 	void 			*ipi_pspare[2];
 };

Modified: head/sys/netinet/ip_divert.c
==============================================================================
--- head/sys/netinet/ip_divert.c	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/netinet/ip_divert.c	Thu Apr 30 13:36:26 2009	(r191688)
@@ -162,6 +162,9 @@ div_init(void)
 	INP_INFO_LOCK_INIT(&V_divcbinfo, "div");
 	LIST_INIT(&V_divcb);
 	V_divcbinfo.ipi_listhead = &V_divcb;
+#ifdef VIMAGE
+	V_divcbinfo.ipi_vnet = curvnet;
+#endif
 	/*
 	 * XXX We don't use the hash list for divert IP, but it's easier
 	 * to allocate a one entry hash list than it is to check all

Modified: head/sys/netinet/ip_fw.h
==============================================================================
--- head/sys/netinet/ip_fw.h	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/netinet/ip_fw.h	Thu Apr 30 13:36:26 2009	(r191688)
@@ -695,7 +695,6 @@ struct vnet_ipfw {
 	int	_fw_deny_unknown_exthdrs;
 	int	_fw_verbose;
 	int	_verbose_limit;
-	int	_fw_debug;		/* actually unused */
 	int	_autoinc_step;
 	ipfw_dyn_rule **_ipfw_dyn_v;
 	uma_zone_t _ipfw_dyn_rule_zone;
@@ -740,7 +739,6 @@ extern struct vnet_ipfw vnet_ipfw_0;
 #define	V_fw_deny_unknown_exthdrs VNET_IPFW(fw_deny_unknown_exthdrs)
 #define	V_fw_verbose		VNET_IPFW(fw_verbose)
 #define	V_verbose_limit		VNET_IPFW(verbose_limit)
-#define	V_fw_debug		VNET_IPFW(fw_debug)
 #define	V_autoinc_step		VNET_IPFW(autoinc_step)
 #define	V_ipfw_dyn_v		VNET_IPFW(ipfw_dyn_v)
 #define	V_ipfw_dyn_rule_zone	VNET_IPFW(ipfw_dyn_rule_zone)

Modified: head/sys/netinet/ip_fw_pfil.c
==============================================================================
--- head/sys/netinet/ip_fw_pfil.c	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/netinet/ip_fw_pfil.c	Thu Apr 30 13:36:26 2009	(r191688)
@@ -95,6 +95,7 @@ int
 ipfw_check_in(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
     struct inpcb *inp)
 {
+	INIT_VNET_INET(curvnet);
 	struct ip_fw_args args;
 	struct ng_ipfw_tag *ng_tag;
 	struct m_tag *dn_tag;
@@ -224,6 +225,7 @@ int
 ipfw_check_out(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
     struct inpcb *inp)
 {
+	INIT_VNET_INET(curvnet);
 	struct ip_fw_args args;
 	struct ng_ipfw_tag *ng_tag;
 	struct m_tag *dn_tag;

Modified: head/sys/netinet/ip_input.c
==============================================================================
--- head/sys/netinet/ip_input.c	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/netinet/ip_input.c	Thu Apr 30 13:36:26 2009	(r191688)
@@ -237,6 +237,7 @@ static void vnet_inet_register(void);
 static const vnet_modinfo_t vnet_inet_modinfo = {
 	.vmi_id		= VNET_MOD_INET,
 	.vmi_name	= "inet",
+	.vmi_size	= sizeof(struct vnet_inet)
 };
  
 static void vnet_inet_register()

Modified: head/sys/netinet/raw_ip.c
==============================================================================
--- head/sys/netinet/raw_ip.c	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/netinet/raw_ip.c	Thu Apr 30 13:36:26 2009	(r191688)
@@ -187,6 +187,9 @@ rip_init(void)
 
 	INP_INFO_LOCK_INIT(&V_ripcbinfo, "rip");
 	LIST_INIT(&V_ripcb);
+#ifdef VIMAGE
+	V_ripcbinfo.ipi_vnet = curvnet;
+#endif
 	V_ripcbinfo.ipi_listhead = &V_ripcb;
 	V_ripcbinfo.ipi_hashbase =
 	    hashinit(INP_PCBHASH_RAW_SIZE, M_PCB, &V_ripcbinfo.ipi_hashmask);

Modified: head/sys/netinet/tcp_subr.c
==============================================================================
--- head/sys/netinet/tcp_subr.c	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/netinet/tcp_subr.c	Thu Apr 30 13:36:26 2009	(r191688)
@@ -359,6 +359,9 @@ tcp_init(void)
 
 	INP_INFO_LOCK_INIT(&V_tcbinfo, "tcp");
 	LIST_INIT(&V_tcb);
+#ifdef VIMAGE
+	V_tcbinfo.ipi_vnet = curvnet;
+#endif
 	V_tcbinfo.ipi_listhead = &V_tcb;
 	hashsize = TCBHASHSIZE;
 	TUNABLE_INT_FETCH("net.inet.tcp.tcbhashsize", &hashsize);
@@ -703,6 +706,9 @@ tcp_newtcpcb(struct inpcb *inp)
 	if (tm == NULL)
 		return (NULL);
 	tp = &tm->tcb;
+#ifdef VIMAGE
+	tp->t_vnet = inp->inp_vnet;
+#endif
 	tp->t_timers = &tm->tt;
 	/*	LIST_INIT(&tp->t_segq); */	/* XXX covered by M_ZERO */
 	tp->t_maxseg = tp->t_maxopd =

Modified: head/sys/netinet/tcp_syncache.c
==============================================================================
--- head/sys/netinet/tcp_syncache.c	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/netinet/tcp_syncache.c	Thu Apr 30 13:36:26 2009	(r191688)
@@ -259,6 +259,9 @@ syncache_init(void)
 
 	/* Initialize the hash buckets. */
 	for (i = 0; i < V_tcp_syncache.hashsize; i++) {
+#ifdef VIMAGE
+		V_tcp_syncache.hashbase[i].sch_vnet = curvnet;
+#endif
 		TAILQ_INIT(&V_tcp_syncache.hashbase[i].sch_bucket);
 		mtx_init(&V_tcp_syncache.hashbase[i].sch_mtx, "tcp_sc_head",
 			 NULL, MTX_DEF);

Modified: head/sys/netinet/tcp_syncache.h
==============================================================================
--- head/sys/netinet/tcp_syncache.h	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/netinet/tcp_syncache.h	Thu Apr 30 13:36:26 2009	(r191688)
@@ -96,6 +96,7 @@ struct syncache {
 #define	SYNCOOKIE_LIFETIME	16	/* seconds */
 
 struct syncache_head {
+	struct vnet	*sch_vnet;
 	struct mtx	sch_mtx;
 	TAILQ_HEAD(sch_head, syncache)	sch_bucket;
 	struct callout	sch_timer;

Modified: head/sys/netinet/tcp_var.h
==============================================================================
--- head/sys/netinet/tcp_var.h	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/netinet/tcp_var.h	Thu Apr 30 13:36:26 2009	(r191688)
@@ -35,6 +35,8 @@
 
 #include <netinet/tcp.h>
 
+struct vnet;
+
 /*
  * Kernel variables for tcp.
  */
@@ -106,6 +108,8 @@ struct tcpcb {
 	int	t_state;		/* state of this connection */
 	u_int	t_flags;
 
+	struct	vnet *t_vnet;		/* back pointer to parent vnet */
+
 	tcp_seq	snd_una;		/* send unacknowledged */
 	tcp_seq	snd_max;		/* highest sequence number sent;
 					 * used to recognize retransmits
@@ -186,8 +190,8 @@ struct tcpcb {
 	int	t_rttlow;		/* smallest observerved RTT */
 	u_int32_t	rfbuf_ts;	/* recv buffer autoscaling timestamp */
 	int	rfbuf_cnt;		/* recv buffer autoscaling byte count */
-	void	*t_pspare[3];		/* toe usrreqs / toepcb * / congestion algo / vimage / 1 general use */
-	struct toe_usrreqs *t_tu;       /* offload operations vector */
+	void	*t_pspare[3];		/* toe usrreqs / toepcb * / congestion algo / 1 general use */
+	struct toe_usrreqs *t_tu;	/* offload operations vector */
 	void	*t_toe;			/* TOE pcb pointer */
 	int	t_bytes_acked;		/* # bytes acked during current RTT */
 };

Modified: head/sys/netinet/udp_usrreq.c
==============================================================================
--- head/sys/netinet/udp_usrreq.c	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/netinet/udp_usrreq.c	Thu Apr 30 13:36:26 2009	(r191688)
@@ -179,6 +179,9 @@ udp_init(void)
 
 	INP_INFO_LOCK_INIT(&V_udbinfo, "udp");
 	LIST_INIT(&V_udb);
+#ifdef VIMAGE
+	V_udbinfo.ipi_vnet = curvnet;
+#endif
 	V_udbinfo.ipi_listhead = &V_udb;
 	V_udbinfo.ipi_hashbase = hashinit(UDBHASHSIZE, M_PCB,
 	    &V_udbinfo.ipi_hashmask);

Modified: head/sys/netinet/vinet.h
==============================================================================
--- head/sys/netinet/vinet.h	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/netinet/vinet.h	Thu Apr 30 13:36:26 2009	(r191688)
@@ -54,7 +54,6 @@ struct vnet_inet {
 	struct	in_ifaddrhashhead *_in_ifaddrhashtbl;
 	struct	in_ifaddrhead _in_ifaddrhead;
 	u_long	_in_ifaddrhmask;
-	struct	in_multihead _in_multihead;	/* XXX unused */
 
 	int	_arpt_keep;
 	int	_arp_maxtries;
@@ -269,7 +268,6 @@ extern struct vnet_inet vnet_inet_0;
 #define	V_in_ifaddrhashtbl	VNET_INET(in_ifaddrhashtbl)
 #define	V_in_ifaddrhead		VNET_INET(in_ifaddrhead)
 #define	V_in_ifaddrhmask	VNET_INET(in_ifaddrhmask)
-#define	V_in_multihead		VNET_INET(in_multihead)
 #define	V_ip_checkinterface	VNET_INET(ip_checkinterface)
 #define	V_ip_defttl		VNET_INET(ip_defttl)
 #define	V_ip_do_randomid	VNET_INET(ip_do_randomid)

Modified: head/sys/netinet6/in6_ifattach.c
==============================================================================
--- head/sys/netinet6/in6_ifattach.c	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/netinet6/in6_ifattach.c	Thu Apr 30 13:36:26 2009	(r191688)
@@ -888,8 +888,9 @@ in6_get_tmpifid(struct ifnet *ifp, u_int
 }
 
 void
-in6_tmpaddrtimer(void *ignored_arg)
+in6_tmpaddrtimer(void *arg)
 {
+	CURVNET_SET((struct vnet *) arg);
 	INIT_VNET_NET(curvnet);
 	INIT_VNET_INET6(curvnet);
 	struct nd_ifinfo *ndi;
@@ -898,7 +899,7 @@ in6_tmpaddrtimer(void *ignored_arg)
 
 	callout_reset(&V_in6_tmpaddrtimer_ch,
 	    (V_ip6_temp_preferred_lifetime - V_ip6_desync_factor -
-	    V_ip6_temp_regen_advance) * hz, in6_tmpaddrtimer, NULL);
+	    V_ip6_temp_regen_advance) * hz, in6_tmpaddrtimer, curvnet);
 
 	bzero(nullbuf, sizeof(nullbuf));
 	for (ifp = TAILQ_FIRST(&V_ifnet); ifp;
@@ -914,12 +915,12 @@ in6_tmpaddrtimer(void *ignored_arg)
 		}
 	}
 
+	CURVNET_RESTORE();
 }
 
 static void
 in6_purgemaddrs(struct ifnet *ifp)
 {
-	INIT_VNET_INET6(ifp->if_vnet);
 	LIST_HEAD(,in6_multi)	 purgeinms;
 	struct in6_multi	*inm, *tinm;
 	struct ifmultiaddr	*ifma;

Modified: head/sys/netinet6/in6_mcast.c
==============================================================================
--- head/sys/netinet6/in6_mcast.c	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/netinet6/in6_mcast.c	Thu Apr 30 13:36:26 2009	(r191688)
@@ -1302,7 +1302,6 @@ static int
 in6p_block_unblock_source(struct inpcb *inp, struct sockopt *sopt)
 {
 	INIT_VNET_NET(curvnet);
-	INIT_VNET_INET6(curvnet);
 	struct group_source_req		 gsr;
 	sockunion_t			*gsa, *ssa;
 	struct ifnet			*ifp;
@@ -1463,6 +1462,7 @@ out_in6p_locked:
 static struct ip6_moptions *
 in6p_findmoptions(struct inpcb *inp)
 {
+	INIT_VNET_INET6(curvnet);
 	struct ip6_moptions	 *imo;
 	struct in6_multi		**immp;
 	struct in6_mfilter	 *imfp;
@@ -1745,7 +1745,6 @@ static struct ifnet *
 in6p_lookup_mcast_ifp(const struct inpcb *in6p __unused,
     const struct sockaddr_in6 *gsin6)
 {
-	INIT_VNET_INET6(curvnet);
 	struct route_in6	 ro6;
 	struct ifnet		*ifp;
 
@@ -2032,7 +2031,6 @@ static int
 in6p_leave_group(struct inpcb *inp, struct sockopt *sopt)
 {
 	INIT_VNET_NET(curvnet);
-	INIT_VNET_INET(curvnet);
 	struct group_source_req		 gsr;
 	sockunion_t			*gsa, *ssa;
 	struct ifnet			*ifp;
@@ -2249,7 +2247,6 @@ static int
 in6p_set_multicast_if(struct inpcb *inp, struct sockopt *sopt)
 {
 	INIT_VNET_NET(curvnet);
-	INIT_VNET_INET6(curvnet);
 	struct ifnet		*ifp;
 	struct ip6_moptions	*imo;
 	u_int			 ifindex;
@@ -2454,6 +2451,7 @@ out_in6p_locked:
 int
 ip6_setmoptions(struct inpcb *inp, struct sockopt *sopt)
 {
+	INIT_VNET_INET6(curvnet);
 	struct ip6_moptions	*im6o;
 	int			 error;
 

Modified: head/sys/netinet6/in6_proto.c
==============================================================================
--- head/sys/netinet6/in6_proto.c	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/netinet6/in6_proto.c	Thu Apr 30 13:36:26 2009	(r191688)
@@ -447,6 +447,8 @@ sysctl_ip6_temppltime(SYSCTL_HANDLER_ARG
 	int error = 0;
 	int old;
 
+	SYSCTL_RESOLVE_V_ARG1();
+
 	error = SYSCTL_OUT(req, arg1, sizeof(int));
 	if (error || !req->newptr)
 		return (error);
@@ -467,6 +469,8 @@ sysctl_ip6_tempvltime(SYSCTL_HANDLER_ARG
 	int error = 0;
 	int old;
 
+	SYSCTL_RESOLVE_V_ARG1();
+
 	error = SYSCTL_OUT(req, arg1, sizeof(int));
 	if (error || !req->newptr)
 		return (error);

Modified: head/sys/netinet6/ip6_input.c
==============================================================================
--- head/sys/netinet6/ip6_input.c	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/netinet6/ip6_input.c	Thu Apr 30 13:36:26 2009	(r191688)
@@ -161,6 +161,7 @@ static void vnet_inet6_register(void);
 static const vnet_modinfo_t vnet_inet6_modinfo = {
 	.vmi_id		= VNET_MOD_INET6,
 	.vmi_name	= "inet6",
+	.vmi_size	= sizeof(struct vnet_inet6),
 	.vmi_dependson	= VNET_MOD_INET	/* XXX revisit - TCP/UDP needs this? */
 };
  
@@ -307,14 +308,14 @@ ip6_init2_vnet(const void *unused __unus
 
 	/* nd6_timer_init */
 	callout_init(&V_nd6_timer_ch, 0);
-	callout_reset(&V_nd6_timer_ch, hz, nd6_timer, NULL);
+	callout_reset(&V_nd6_timer_ch, hz, nd6_timer, curvnet);
 
 	/* timer for regeneranation of temporary addresses randomize ID */
 	callout_init(&V_in6_tmpaddrtimer_ch, 0);
 	callout_reset(&V_in6_tmpaddrtimer_ch,
 		      (V_ip6_temp_preferred_lifetime - V_ip6_desync_factor -
 		       V_ip6_temp_regen_advance) * hz,
-		      in6_tmpaddrtimer, NULL);
+		      in6_tmpaddrtimer, curvnet);
 
 	return (0);
 }

Modified: head/sys/netinet6/mld6.c
==============================================================================
--- head/sys/netinet6/mld6.c	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/netinet6/mld6.c	Thu Apr 30 13:36:26 2009	(r191688)
@@ -435,7 +435,6 @@ mld_dispatch_queue(struct ifqueue *ifq, 
 static __inline int
 mld_is_addr_reported(const struct in6_addr *addr)
 {
-	INIT_VNET_INET6(curvnet);
 
 	KASSERT(IN6_IS_ADDR_MULTICAST(addr), ("%s: not multicast", __func__));
 
@@ -639,7 +638,6 @@ static int
 mld_v1_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6,
     const struct mld_hdr *mld)
 {
-	INIT_VNET_INET6(ifp->if_vnet);
 	struct ifmultiaddr	*ifma;
 	struct mld_ifinfo	*mli;
 	struct in6_multi	*inm;
@@ -1034,7 +1032,6 @@ static int
 mld_v1_input_report(struct ifnet *ifp, const struct ip6_hdr *ip6,
     const struct mld_hdr *mld)
 {
-	INIT_VNET_INET6(curvnet);
 	struct in6_ifaddr	*ia;
 	struct in6_multi	*inm;
 #ifdef KTR
@@ -1646,7 +1643,6 @@ mld_slowtimo_vnet(void)
 static void
 mld_v1_process_querier_timers(struct mld_ifinfo *mli)
 {
-	INIT_VNET_INET6(curvnet);
 
 	MLD_LOCK_ASSERT();
 
@@ -3009,7 +3005,6 @@ out:
 static struct mbuf *
 mld_v2_encap_report(struct ifnet *ifp, struct mbuf *m)
 {
-	INIT_VNET_INET6(curvnet);
 	struct mbuf		*mh;
 	struct mldv2_report	*mld;
 	struct ip6_hdr		*ip6;

Modified: head/sys/netinet6/nd6.c
==============================================================================
--- head/sys/netinet6/nd6.c	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/netinet6/nd6.c	Thu Apr 30 13:36:26 2009	(r191688)
@@ -191,7 +191,7 @@ nd6_init(void)
 	/* start timer */
 	callout_init(&V_nd6_slowtimo_ch, 0);
 	callout_reset(&V_nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL * hz,
-	    nd6_slowtimo, NULL);
+	    nd6_slowtimo, curvnet);
 
 	nd6_init_done = 1;
 
@@ -593,7 +593,7 @@ void
 nd6_timer(void *arg)
 {
 	CURVNET_SET_QUIET((struct vnet *) arg);
-	INIT_VNET_INET6((struct vnet *) arg);
+	INIT_VNET_INET6(curvnet);
 	int s;
 	struct nd_defrouter *dr;
 	struct nd_prefix *pr;
@@ -601,7 +601,7 @@ nd6_timer(void *arg)
 	struct in6_addrlifetime *lt6;
 
 	callout_reset(&V_nd6_timer_ch, V_nd6_prune * hz,
-	    nd6_timer, NULL);
+	    nd6_timer, curvnet);
 
 	/* expire default router list */
 	s = splnet();
@@ -872,7 +872,6 @@ nd6_purge(struct ifnet *ifp)
 struct llentry *
 nd6_lookup(struct in6_addr *addr6, int flags, struct ifnet *ifp)
 {
-	INIT_VNET_INET6(curvnet);
 	struct sockaddr_in6 sin6;
 	struct llentry *ln;
 	int llflags = 0;
@@ -1669,7 +1668,7 @@ nd6_slowtimo(void *arg)
 	struct ifnet *ifp;
 
 	callout_reset(&V_nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL * hz,
-	    nd6_slowtimo, NULL);
+	    nd6_slowtimo, curvnet);
 	IFNET_RLOCK();
 	for (ifp = TAILQ_FIRST(&V_ifnet); ifp;
 	    ifp = TAILQ_NEXT(ifp, if_list)) {

Modified: head/sys/netinet6/raw_ip6.c
==============================================================================
--- head/sys/netinet6/raw_ip6.c	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/netinet6/raw_ip6.c	Thu Apr 30 13:36:26 2009	(r191688)
@@ -651,6 +651,7 @@ rip6_attach(struct socket *so, int proto
 static void
 rip6_detach(struct socket *so)
 {
+	INIT_VNET_INET(so->so_vnet);
 	INIT_VNET_INET6(so->so_vnet);
 	struct inpcb *inp;
 

Modified: head/sys/netinet6/vinet6.h
==============================================================================
--- head/sys/netinet6/vinet6.h	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/netinet6/vinet6.h	Thu Apr 30 13:36:26 2009	(r191688)
@@ -54,8 +54,6 @@ struct vnet_inet6 {
 	u_int				_frag6_nfrags;
 	struct ip6q			_ip6q;
 
-	struct route_in6 		_ip6_forward_rt;	/* XXX remove */
-
 	struct in6_addrpolicy 		_defaultaddrpolicy;
 	TAILQ_HEAD(, addrsel_policyent) _addrsel_policytab;
 	u_int				_in6_maxmtu;
@@ -122,10 +120,6 @@ struct vnet_inet6 {
 	int				_udp6_recvspace;
 	int				_ip6qmaxlen;
 	int				_ip6_prefer_tempaddr;
-	int				_ip6_forward_srcrt;	/* XXX remove */
-	int				_ip6_sourcecheck;	/* XXX remove */
-	int				_ip6_sourcecheck_interval; /* XXX remove */
-	int				_ip6_ours_check_algorithm; /* XXX remove */
 
 	int				_nd6_prune;
 	int				_nd6_delay;

Modified: head/sys/netipsec/ipsec.c
==============================================================================
--- head/sys/netipsec/ipsec.c	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/netipsec/ipsec.c	Thu Apr 30 13:36:26 2009	(r191688)
@@ -248,6 +248,7 @@ MALLOC_DEFINE(M_IPSEC_INPCB, "inpcbpolic
 static const vnet_modinfo_t vnet_ipsec_modinfo = {
 	.vmi_id		= VNET_MOD_IPSEC,
 	.vmi_name	= "ipsec",
+	.vmi_size	= sizeof(struct vnet_ipsec),
 	.vmi_dependson	= VNET_MOD_INET,	/* XXX revisit - INET6 ? */
 	.vmi_iattach	= ipsec_iattach
 };

Modified: head/sys/sys/param.h
==============================================================================
--- head/sys/sys/param.h	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/sys/param.h	Thu Apr 30 13:36:26 2009	(r191688)
@@ -57,7 +57,7 @@
  *		is created, otherwise 1.
  */
 #undef __FreeBSD_version
-#define __FreeBSD_version 800084	/* Master, propagated to newvers */
+#define __FreeBSD_version 800085	/* Master, propagated to newvers */
 
 #ifndef LOCORE
 #include <sys/types.h>

Modified: head/sys/sys/socketvar.h
==============================================================================
--- head/sys/sys/socketvar.h	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/sys/socketvar.h	Thu Apr 30 13:36:26 2009	(r191688)
@@ -45,6 +45,8 @@
 #include <sys/sockopt.h>
 #endif
 
+struct vnet;
+
 /*
  * Kernel structure per socket.
  * Contains send and receive buffer queues,
@@ -72,6 +74,7 @@ struct socket {
 	short	so_state;		/* (b) internal state flags SS_* */
 	int	so_qstate;		/* (e) internal state flags SQ_* */
 	void	*so_pcb;		/* protocol control block */
+	struct	vnet *so_vnet;		/* network stack instance */
 	struct	protosw *so_proto;	/* (a) protocol handle */
 /*
  * Variables for connection queuing.

Modified: head/sys/sys/sysctl.h
==============================================================================
--- head/sys/sys/sysctl.h	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/sys/sysctl.h	Thu Apr 30 13:36:26 2009	(r191688)
@@ -163,6 +163,8 @@ struct sysctl_oid {
 	const char	*oid_fmt;
 	int		oid_refcnt;
 	const char	*oid_descr;
+	short		oid_v_subs;
+	short		oid_v_mod;
 };
 
 #define SYSCTL_IN(r, p, l) (r->newfunc)(r, p, l)
@@ -292,7 +294,8 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_e
 
 #ifdef VIMAGE
 #define	SYSCTL_V_INT(subs, mod, parent, nbr, name, access, sym, val, descr) \
-	SYSCTL_V_OID(subs, mod, parent, nbr, name, CTLTYPE_INT|(access), \
+	SYSCTL_V_OID(subs, mod, parent, nbr, name,			    \
+		CTLTYPE_INT|CTLFLAG_MPSAFE|(access),			    \
 		sym, val, sysctl_handle_v_int, "I", descr)
 #else
 #ifdef VIMAGE_GLOBALS
@@ -317,7 +320,8 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_e
 
 #ifdef VIMAGE
 #define	SYSCTL_V_UINT(subs, mod, parent, nbr, name, access, sym, val, descr) \
-	SYSCTL_V_OID(subs, mod, parent, nbr, name, CTLTYPE_UINT|(access), \
+	SYSCTL_V_OID(subs, mod, parent, nbr, name, 			     \
+		CTLTYPE_UINT|CTLFLAG_MPSAFE|(access),			     \
 		sym, val, sysctl_handle_v_int, "IU", descr)
 #else
 #ifdef VIMAGE_GLOBALS
@@ -440,6 +444,29 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_e
 #define	FEATURE(name, desc)						\
 	SYSCTL_INT(_kern_features, OID_AUTO, name, CTLFLAG_RD, 0, 1, desc)
 	
+/*
+ * Resolve void *arg1 in a proper virtualization container.
+ */
+#ifdef VIMAGE
+#define SYSCTL_RESOLVE_V_ARG1() do {					\
+	char *cp;							\
+	switch (oidp->oid_v_subs) {					\
+	case V_GLOBAL:							\
+		/* do nothing - this is NOT a virtualized variable! */	\
+		break;							\
+	case V_NET:							\
+		cp = (char *)						\
+		    TD_TO_VNET(curthread)->mod_data[oidp->oid_v_mod];	\
+		arg1 = cp + (size_t) arg1;				\
+		break;							\
+	default:							\
+		panic("unsupported module id %d", oidp->oid_v_subs);	\
+	}								\
+} while (0)
+#else
+#define SYSCTL_RESOLVE_V_ARG1()
+#endif
+
 #endif /* _KERNEL */
 
 /*

Modified: head/sys/sys/vimage.h
==============================================================================
--- head/sys/sys/vimage.h	Thu Apr 30 13:30:27 2009	(r191687)
+++ head/sys/sys/vimage.h	Thu Apr 30 13:36:26 2009	(r191688)
@@ -39,6 +39,10 @@
 #error "You cannot have both option VIMAGE and option VIMAGE_GLOBALS!"
 #endif
 
+#ifdef INVARIANTS
+#define	VNET_DEBUG
+#endif
+
 typedef int vnet_attach_fn(const void *);
 typedef int vnet_detach_fn(const void *);
 
@@ -48,8 +52,8 @@ struct kld_sym_lookup;
 
 struct vnet_symmap {
 	char	*name;
-	void	*base;
-	size_t	size;
+	size_t	 offset;
+	size_t	 size;
 };
 typedef struct vnet_symmap vnet_symmap_t;
 
@@ -59,7 +63,7 @@ struct vnet_modinfo {
 	char				*vmi_name;
 	vnet_attach_fn			*vmi_iattach;
 	vnet_detach_fn			*vmi_idetach;
-	size_t				 vmi_struct_size;
+	size_t				 vmi_size;
 	struct vnet_symmap		*vmi_symmap;
 };
 typedef struct vnet_modinfo vnet_modinfo_t;
@@ -71,13 +75,7 @@ struct vnet_modlink {
 	const char			*vml_iname;
 };
 
-#define	VNET_SYMMAP(mod, name)						\
-	{ #name, &(vnet_ ## mod ## _0._ ## name),			\
-	sizeof(vnet_ ## mod ## _0._ ## name) }
-
-#define	VNET_SYMMAP_END		{ NULL, 0 }
-
-/* stateful modules */
+/* Stateful modules. */
 #define	VNET_MOD_NET		 0	/* MUST be 0 - implicit dependency */
 #define	VNET_MOD_NETGRAPH	 1
 #define	VNET_MOD_INET		 2
@@ -93,7 +91,7 @@ struct vnet_modlink {
 #define	VNET_MOD_IGMP		12
 #define	VNET_MOD_MLD		13
 
-/* stateless modules */
+/* Stateless modules. */
 #define	VNET_MOD_NG_ETHER	20
 #define	VNET_MOD_NG_IFACE	21
 #define	VNET_MOD_NG_EIFACE	22
@@ -109,7 +107,11 @@ struct vnet_modlink {
 #define	VNET_MOD_DYNAMIC_START	32
 #define	VNET_MOD_MAX		64
 
-/* Sysctl virtualization macros need these name mappings bellow */
+/* Major module IDs for vimage sysctl virtualization. */
+#define	V_GLOBAL		0	/* global variable - no indirection */
+#define	V_NET			1
+
+/* Name mappings for minor module IDs in vimage sysctl virtualization. */
 #define	V_MOD_vnet_net		VNET_MOD_NET
 #define	V_MOD_vnet_netgraph	VNET_MOD_NETGRAPH
 #define	V_MOD_vnet_inet		VNET_MOD_INET
@@ -131,27 +133,82 @@ void	vnet_mod_deregister_multi(const str
 #define	VSYM(base, sym) (sym)
 #else
 #ifdef VIMAGE
-#error "No option VIMAGE yet!"
+#define	VSYM(base, sym) ((base)->_ ## sym)
 #else
 #define	VSYM(base, sym) (base ## _0._ ## sym)
 #endif
 #endif
 
+#ifndef VIMAGE_GLOBALS
+#ifdef VIMAGE

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



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