svn commit: r192669 - in head: . sys/kern sys/net sys/sys

Marko Zec zec at FreeBSD.org
Sat May 23 21:43:45 UTC 2009


Author: zec
Date: Sat May 23 21:43:44 2009
New Revision: 192669
URL: http://svn.freebsd.org/changeset/base/192669

Log:
  V_irtualize the if_clone framework, thus allowing for clonable ifnets
  to optionally have overlapping unit numbers if attached in different
  vnets.
  
  At this stage if_loop is the only clonable ifnet class that has been
  extended to allow for such overlapping allocation of unit numbers, i.e.
  in each vnet it is possible to have a lo0 interface.  Other clonable ifnet
  classes remain to operate with traditional semantics, i.e. each instance
  of a clonable ifnet will be assigned a globally unique unit number,
  regardless in which vnet such an ifnet becomes instantiated.
  
  While here, garbage collect unused _lo_list field in struct vnet_net,
  as well as improve indentation for #defines in sys/net/vnet.h.
  
  The layout of struct vnet_net has changed, therefore bump
  __FreeBSD_version.
  
  This change has no functional impact on nooptions VIMAGE kernel builds.
  
  Reviewed by:	bz, brooks
  Approved by:	julian (mentor)

Modified:
  head/UPDATING
  head/sys/kern/kern_vimage.c
  head/sys/net/if_clone.c
  head/sys/net/if_loop.c
  head/sys/net/vnet.h
  head/sys/sys/param.h
  head/sys/sys/vimage.h

Modified: head/UPDATING
==============================================================================
--- head/UPDATING	Sat May 23 20:33:53 2009	(r192668)
+++ head/UPDATING	Sat May 23 21:43:44 2009	(r192669)
@@ -23,6 +23,11 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.
 	ln -s aj /etc/malloc.conf.)
 
 20090523:
+	The layout of struct vnet_net has changed, therefore modules
+	need to be rebuilt.
+	Bump __FreeBSD_version to 800090.
+
+20090523:
 	The newly imported zic(8) produces a new format in the
 	output. Please run tzsetup(8) to install the newly created
 	data to /etc/localtime.

Modified: head/sys/kern/kern_vimage.c
==============================================================================
--- head/sys/kern/kern_vimage.c	Sat May 23 20:33:53 2009	(r192668)
+++ head/sys/kern/kern_vimage.c	Sat May 23 21:43:44 2009	(r192669)
@@ -66,6 +66,10 @@ struct vprocg vprocg_0;
 #endif
 #endif
 
+#ifdef VIMAGE
+struct vnet *vnet0;
+#endif
+
 void
 vnet_mod_register(const struct vnet_modinfo *vmi)
 {
@@ -331,6 +335,7 @@ vi_init(void *unused)
 	LIST_INSERT_HEAD(&vnet_head, vnet, vnet_le);
 	vnet->vnet_magic_n = VNET_MAGIC_N;
 	vip->v_net = vnet;
+	vnet0 = vnet;
 
 	/* We MUST clear curvnet in vi_init_done before going SMP. */
 	curvnet = LIST_FIRST(&vnet_head);

Modified: head/sys/net/if_clone.c
==============================================================================
--- head/sys/net/if_clone.c	Sat May 23 20:33:53 2009	(r192668)
+++ head/sys/net/if_clone.c	Sat May 23 21:43:44 2009	(r192669)
@@ -55,10 +55,13 @@
 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;
+#ifdef VIMAGE_GLOBALS
 static int		if_cloners_count;
-LIST_HEAD(, if_clone)	if_cloners = LIST_HEAD_INITIALIZER(if_cloners);
+LIST_HEAD(, if_clone)	if_cloners;
+#endif
 
 #define IF_CLONERS_LOCK_INIT()		\
     mtx_init(&if_cloners_mtx, "if_cloners lock", NULL, MTX_DEF)
@@ -112,10 +115,32 @@ LIST_HEAD(, if_clone)	if_cloners = LIST_
 
 static MALLOC_DEFINE(M_CLONE, "clone", "interface cloning framework");
 
+#ifndef VIMAGE_GLOBALS
+static const vnet_modinfo_t vnet_clone_modinfo = {
+	.vmi_id		= VNET_MOD_IF_CLONE,
+	.vmi_name	= "if_clone",
+	.vmi_iattach	= vnet_clone_iattach
+};
+#endif /* !VIMAGE_GLOBALS */
+
+static int vnet_clone_iattach(const void *unused __unused)
+{
+	INIT_VNET_NET(curvnet);
+
+	LIST_INIT(&V_if_cloners);
+	return (0);
+}
+
 void
 if_clone_init(void)
 {
+
 	IF_CLONERS_LOCK_INIT();
+#ifndef VIMAGE_GLOBALS
+	vnet_mod_register(&vnet_clone_modinfo);
+#else
+	vnet_clone_iattach(NULL);
+#endif
 }
 
 /*
@@ -124,15 +149,27 @@ if_clone_init(void)
 int
 if_clone_create(char *name, size_t len, caddr_t params)
 {
+	INIT_VNET_NET(curvnet);
 	struct if_clone *ifc;
 
 	/* Try to find an applicable cloner for this request */
 	IF_CLONERS_LOCK();
-	LIST_FOREACH(ifc, &if_cloners, ifc_list) {
+	LIST_FOREACH(ifc, &V_if_cloners, ifc_list) {
 		if (ifc->ifc_match(ifc, name)) {
 			break;
 		}
 	}
+#ifdef VIMAGE
+	if (ifc == NULL && !IS_DEFAULT_VNET(curvnet)) {
+		CURVNET_SET_QUIET(vnet0);
+		INIT_VNET_NET(vnet0);
+		LIST_FOREACH(ifc, &V_if_cloners, ifc_list) {
+			if (ifc->ifc_match(ifc, name))
+				break;
+		}
+		CURVNET_RESTORE();
+	}
+#endif
 	IF_CLONERS_UNLOCK();
 
 	if (ifc == NULL)
@@ -176,6 +213,7 @@ if_clone_createif(struct if_clone *ifc, 
 int
 if_clone_destroy(const char *name)
 {
+	INIT_VNET_NET(curvnet);
 	struct if_clone *ifc;
 	struct ifnet *ifp;
 
@@ -185,11 +223,22 @@ if_clone_destroy(const char *name)
 
 	/* Find the cloner for this interface */
 	IF_CLONERS_LOCK();
-	LIST_FOREACH(ifc, &if_cloners, ifc_list) {
+	LIST_FOREACH(ifc, &V_if_cloners, ifc_list) {
 		if (strcmp(ifc->ifc_name, ifp->if_dname) == 0) {
 			break;
 		}
 	}
+#ifdef VIMAGE
+	if (ifc == NULL && !IS_DEFAULT_VNET(curvnet)) {
+		CURVNET_SET_QUIET(vnet0);
+		INIT_VNET_NET(vnet0);
+		LIST_FOREACH(ifc, &V_if_cloners, ifc_list) {
+			if (ifc->ifc_match(ifc, name))
+				break;
+		}
+		CURVNET_RESTORE();
+	}
+#endif
 	IF_CLONERS_UNLOCK();
 	if (ifc == NULL)
 		return (EINVAL);
@@ -208,11 +257,17 @@ if_clone_destroyif(struct if_clone *ifc,
 	if (ifc->ifc_destroy == NULL)
 		return(EOPNOTSUPP);
 
+	/*
+	 * Given that the cloned ifnet might be attached to a different
+	 * vnet from where its cloner was registered, we have to
+	 * switch to the vnet context of the target vnet.
+	 */
+	CURVNET_SET_QUIET(ifp->if_vnet);
+
 	IF_CLONE_LOCK(ifc);
 	IFC_IFLIST_REMOVE(ifc, ifp);
 	IF_CLONE_UNLOCK(ifc);
 
-	CURVNET_SET_QUIET(ifp->if_vnet);
 	if_delgroup(ifp, ifc->ifc_name);
 
 	err =  (*ifc->ifc_destroy)(ifc, ifp);
@@ -234,6 +289,7 @@ if_clone_destroyif(struct if_clone *ifc,
 void
 if_clone_attach(struct if_clone *ifc)
 {
+	INIT_VNET_NET(curvnet);
 	int len, maxclone;
 
 	/*
@@ -249,8 +305,8 @@ if_clone_attach(struct if_clone *ifc)
 	IF_CLONE_ADDREF(ifc);
 
 	IF_CLONERS_LOCK();
-	LIST_INSERT_HEAD(&if_cloners, ifc, ifc_list);
-	if_cloners_count++;
+	LIST_INSERT_HEAD(&V_if_cloners, ifc, ifc_list);
+	V_if_cloners_count++;
 	IF_CLONERS_UNLOCK();
 
 	LIST_INIT(&ifc->ifc_iflist);
@@ -266,11 +322,12 @@ if_clone_attach(struct if_clone *ifc)
 void
 if_clone_detach(struct if_clone *ifc)
 {
+	INIT_VNET_NET(curvnet);
 	struct ifc_simple_data *ifcs = ifc->ifc_data;
 
 	IF_CLONERS_LOCK();
 	LIST_REMOVE(ifc, ifc_list);
-	if_cloners_count--;
+	V_if_cloners_count--;
 	IF_CLONERS_UNLOCK();
 
 	/* Allow all simples to be destroyed */
@@ -305,6 +362,7 @@ if_clone_free(struct if_clone *ifc)
 int
 if_clone_list(struct if_clonereq *ifcr)
 {
+	INIT_VNET_NET(curvnet);
 	char *buf, *dst, *outbuf = NULL;
 	struct if_clone *ifc;
 	int buf_count, count, err = 0;
@@ -321,23 +379,23 @@ if_clone_list(struct if_clonereq *ifcr)
 	 * could be because that would let arbitrary users cause us to
 	 * allocate abritrary amounts of kernel memory.
 	 */
-	buf_count = (if_cloners_count < ifcr->ifcr_count) ?
-	    if_cloners_count : ifcr->ifcr_count;
+	buf_count = (V_if_cloners_count < ifcr->ifcr_count) ?
+	    V_if_cloners_count : ifcr->ifcr_count;
 	IF_CLONERS_UNLOCK();
 
 	outbuf = malloc(IFNAMSIZ*buf_count, M_CLONE, M_WAITOK | M_ZERO);
 
 	IF_CLONERS_LOCK();
 
-	ifcr->ifcr_total = if_cloners_count;
+	ifcr->ifcr_total = V_if_cloners_count;
 	if ((dst = ifcr->ifcr_buffer) == NULL) {
 		/* Just asking how many there are. */
 		goto done;
 	}
-	count = (if_cloners_count < buf_count) ?
-	    if_cloners_count : buf_count;
+	count = (V_if_cloners_count < buf_count) ?
+	    V_if_cloners_count : buf_count;
 
-	for (ifc = LIST_FIRST(&if_cloners), buf = outbuf;
+	for (ifc = LIST_FIRST(&V_if_cloners), buf = outbuf;
 	    ifc != NULL && count != 0;
 	    ifc = LIST_NEXT(ifc, ifc_list), count--, buf += IFNAMSIZ) {
 		strlcpy(buf, ifc->ifc_name, IFNAMSIZ);

Modified: head/sys/net/if_loop.c
==============================================================================
--- head/sys/net/if_loop.c	Sat May 23 20:33:53 2009	(r192668)
+++ head/sys/net/if_loop.c	Sat May 23 21:43:44 2009	(r192669)
@@ -111,9 +111,14 @@ static int	vnet_loif_iattach(const void 
 struct ifnet *loif;			/* Used externally */
 #endif
 
+#ifdef VIMAGE
+MALLOC_DEFINE(M_LO_CLONER, "lo_cloner", "lo_cloner");
+#endif
+
 #ifndef VIMAGE_GLOBALS
 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
 };
@@ -167,7 +172,15 @@ static int vnet_loif_iattach(const void 
 	INIT_VNET_NET(curvnet);
 
 	V_loif = NULL;
+	
+#ifdef VIMAGE
+	V_lo_cloner = malloc(sizeof(*V_lo_cloner), M_LO_CLONER,
+	    M_WAITOK | M_ZERO);
+	bcopy(&lo_cloner, V_lo_cloner, sizeof(*V_lo_cloner));
+	if_clone_attach(V_lo_cloner);
+#else
 	if_clone_attach(&lo_cloner);
+#endif
 	return (0);
 }
 

Modified: head/sys/net/vnet.h
==============================================================================
--- head/sys/net/vnet.h	Sat May 23 20:33:53 2009	(r192668)
+++ head/sys/net/vnet.h	Sat May 23 21:43:44 2009	(r192669)
@@ -31,7 +31,7 @@
  */
 
 #ifndef _NET_VNET_H_
-#define _NET_VNET_H_
+#define	_NET_VNET_H_
 
 #include <net/if_var.h>
 
@@ -50,10 +50,13 @@ struct vnet_net {
 	uma_zone_t		_rtzone;
 
 	struct ifnet *		_loif;
-	LIST_HEAD(, lo_softc)	_lo_list;
+	struct if_clone *	_lo_cloner;
 
 	LIST_HEAD(, rawcb)	_rawcb_list;
 
+	LIST_HEAD(, if_clone)	_if_cloners;
+	int			_if_cloners_count;
+
 	int			_ether_ipfw;
 };
 
@@ -74,19 +77,21 @@ extern struct vnet_net vnet_net_0;
 
 #define	VNET_NET(sym)	VSYM(vnet_net, sym)
 
-#define	V_ether_ipfw	VNET_NET(ether_ipfw)
-#define	V_if_index	VNET_NET(if_index)
-#define	V_if_indexlim	VNET_NET(if_indexlim)
-#define	V_ifg_head	VNET_NET(ifg_head)
-#define	V_ifindex_table	VNET_NET(ifindex_table)
-#define	V_ifklist	VNET_NET(ifklist)
-#define	V_ifnet		VNET_NET(ifnet)
-#define	V_lo_list	VNET_NET(lo_list)
-#define	V_loif		VNET_NET(loif)
-#define	V_rawcb_list	VNET_NET(rawcb_list)
-#define	V_rt_tables	VNET_NET(rt_tables)
-#define	V_rtstat	VNET_NET(rtstat)
-#define	V_rttrash	VNET_NET(rttrash)
-#define	V_rtzone	VNET_NET(rtzone)
+#define	V_ether_ipfw		VNET_NET(ether_ipfw)
+#define	V_if_index		VNET_NET(if_index)
+#define	V_if_indexlim		VNET_NET(if_indexlim)
+#define	V_if_cloners		VNET_NET(if_cloners)
+#define	V_if_cloners_count	VNET_NET(if_cloners_count)
+#define	V_ifg_head		VNET_NET(ifg_head)
+#define	V_ifindex_table		VNET_NET(ifindex_table)
+#define	V_ifklist		VNET_NET(ifklist)
+#define	V_ifnet			VNET_NET(ifnet)
+#define	V_lo_cloner		VNET_NET(lo_cloner)
+#define	V_loif			VNET_NET(loif)
+#define	V_rawcb_list		VNET_NET(rawcb_list)
+#define	V_rt_tables		VNET_NET(rt_tables)
+#define	V_rtstat		VNET_NET(rtstat)
+#define	V_rttrash		VNET_NET(rttrash)
+#define	V_rtzone		VNET_NET(rtzone)
 
 #endif /* !_NET_VNET_H_ */

Modified: head/sys/sys/param.h
==============================================================================
--- head/sys/sys/param.h	Sat May 23 20:33:53 2009	(r192668)
+++ head/sys/sys/param.h	Sat May 23 21:43:44 2009	(r192669)
@@ -57,7 +57,7 @@
  *		is created, otherwise 1.
  */
 #undef __FreeBSD_version
-#define __FreeBSD_version 800089	/* Master, propagated to newvers */
+#define __FreeBSD_version 800090	/* Master, propagated to newvers */
 
 #ifndef LOCORE
 #include <sys/types.h>

Modified: head/sys/sys/vimage.h
==============================================================================
--- head/sys/sys/vimage.h	Sat May 23 20:33:53 2009	(r192668)
+++ head/sys/sys/vimage.h	Sat May 23 21:43:44 2009	(r192669)
@@ -95,6 +95,7 @@ struct vnet_modlink {
 #define	VNET_MOD_MLD		13
 
 /* 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
@@ -271,6 +272,7 @@ extern struct vprocg vprocg_0;
 #ifdef VIMAGE
 LIST_HEAD(vnet_list_head, vnet);
 extern struct vnet_list_head vnet_head;
+extern struct vnet *vnet0;
 #define	VNET_ITERATOR_DECL(arg) struct vnet *arg;
 #define	VNET_FOREACH(arg) LIST_FOREACH(arg, &vnet_head, vnet_le)
 #else


More information about the svn-src-all mailing list