Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 29 Nov 2011 17:55:06 +0400
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        "Bjoern A. Zeeb" <bz@FreeBSD.org>
Cc:        svn-src-head@FreeBSD.org, svn-src-all@FreeBSD.org, src-committers@FreeBSD.org
Subject:   Re: svn commit: r228071 - head/sys/net
Message-ID:  <20111129135506.GB44498@FreeBSD.org>
In-Reply-To: <alpine.BSF.2.00.1111290942500.4603@ai.fobar.qr>
References:  <201111281444.pASEixdO095604@svn.freebsd.org> <E15FE643-3360-4D42-8736-827104FDD128@FreeBSD.org> <20111129093550.GZ44498@FreeBSD.org> <alpine.BSF.2.00.1111290942500.4603@ai.fobar.qr>

next in thread | previous in thread | raw e-mail | index | archive | help

--KN5l+BnMqAQyZLvT
Content-Type: text/plain; charset=koi8-r
Content-Disposition: inline

On Tue, Nov 29, 2011 at 09:43:37AM +0000, Bjoern A. Zeeb wrote:
B> On Tue, 29 Nov 2011, Gleb Smirnoff wrote:
B> > btw, I don't like the static initializer of cloners, since it require re-compile of
B> > dependencies.
B> >
B> > What about making an API change: remove the static initializer and make an initializer
B> > function. Modules should have only a pointer to opaque structure. We will bump
B> > __FreeBSD_version for that. But later with any change to the if_clone struct, we
B> > won't have ABI change. If everyone agrees, I can go for that.
B> 
B> I have some fairly intrusive changes to cloners sitting in p4 for the
B> V_irtualization but it could make my life easier;  I'll be happy to
B> look at the patch.

Okay, here is what I am suggesting:

- make struct if_clone opaque, and remove if from if_clone.h
- IF_CLONE_INITIALIZER and IFC_SIMPLE_DECLARE substituted with
  if_clone_advanced() and if_clone_simple()

Now, with all our guts obscure to the callers, we can simplify things:

- kill ifc_data, that was an old attempt to support simple & advanced cloners
  w/o changes to the struct ifclone
- make union that stores either simple or advanced methods and data
- kill ifc_attach, that was used only for simple callers, embed it into
  if_clone_simple()

Modifications to the callers are quite simple:

- substitute static initializer to 'static struct if_clone *fooclone;';
- substitite if_clone_attach() to either if_clone_advanced() or
  if_clone_simple()
- fix argument for if_clone_detach()
- if module reads ifc_name, substitute it to some locally stored name

Attached patch includes the core changes, changes to lo(4) - a simple
cloner, vlan(4) - advanced one, and epair(4) - API abuser :) All three
work, so I think converting others won't be a problem.

I am only not 100% sure that I've put correct code under VIMAGE ifdefs.
Can you review this part thoroughly?

If you agree with suggested changes, I can proceed to converting other
callers and commit.

-- 
Totus tuus, Glebius.

--KN5l+BnMqAQyZLvT
Content-Type: text/x-diff; charset=koi8-r
Content-Disposition: attachment; filename="if_clone.diff"

Index: if_clone.c
===================================================================
--- if_clone.c	(revision 228129)
+++ if_clone.c	(working copy)
@@ -1,4 +1,5 @@
 /*-
+ * Copyright (c) 2011 Gleb Smirnoff <glebius@FreeBSD.org>
  * Copyright (c) 1980, 1986, 1993
  *	The Regents of the University of California.  All rights reserved.
  *
@@ -42,19 +43,64 @@
 
 #include <net/if.h>
 #include <net/if_clone.h>
-#if 0
-#include <net/if_dl.h>
-#endif
-#include <net/if_types.h>
 #include <net/if_var.h>
 #include <net/radix.h>
 #include <net/route.h>
 #include <net/vnet.h>
 
+/* Current IF_MAXUNIT expands maximum to 5 characters. */
+#define	IFCLOSIZ	(IFNAMSIZ - 5)
+
+/*
+ * Structure describing a `cloning' interface.
+ *
+ * List of locks
+ * (c)		const until freeing
+ * (d)		driver specific data, may need external protection.
+ * (e)		locked by if_cloners_mtx
+ * (i)		locked by ifc_mtx mtx
+ */
+struct if_clone {
+	char ifc_name[IFCLOSIZ];	/* (c) Name of device, e.g. `gif' */
+	struct unrhdr *ifc_unrhdr;	/* (c) alloc_unr(9) header */
+	long ifc_refcnt;		/* (i) Reference count. */
+	LIST_HEAD(, ifnet) ifc_iflist;	/* (i) List of cloned interfaces */
+	struct mtx ifc_mtx;		/* Mutex to protect members. */
+
+	enum { SIMPLE, ADVANCED } ifc_type; /* (c) */
+
+	/* (c) Driver specific cloning functions.  Called with no locks held. */
+	union {
+		struct {	/* advanced cloner */
+			ifc_match_t	*_ifc_match;
+			ifc_create_t	*_ifc_create;
+			ifc_destroy_t	*_ifc_destroy;
+		} A;
+		struct {	/* simple cloner */
+			ifcs_create_t	*_ifcs_create;
+			ifcs_destroy_t	*_ifcs_destroy;
+			int		_ifcs_minifs;	/* minimum ifs */
+
+		} S;
+	} U;
+#define	ifc_match	U.A._ifc_match
+#define	ifc_create	U.A._ifc_create
+#define	ifc_destroy	U.A._ifc_destroy
+#define	ifcs_create	U.S._ifcs_create
+#define	ifcs_destroy	U.S._ifcs_destroy
+#define	ifcs_minifs	U.S._ifcs_minifs
+
+	LIST_ENTRY(if_clone) ifc_list;	/* (e) On list of cloners */
+};
+
 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     ifc_simple_match(struct if_clone *, const char *);
+static int     ifc_simple_create(struct if_clone *, char *, size_t, caddr_t);
+static int     ifc_simple_destroy(struct if_clone *, struct ifnet *);
+
 static struct mtx	if_cloners_mtx;
 static VNET_DEFINE(int, if_cloners_count);
 VNET_DEFINE(LIST_HEAD(, if_clone), if_cloners);
@@ -138,18 +184,25 @@
 
 	/* Try to find an applicable cloner for this request */
 	IF_CLONERS_LOCK();
-	LIST_FOREACH(ifc, &V_if_cloners, ifc_list) {
-		if (ifc->ifc_match(ifc, name)) {
-			break;
+	LIST_FOREACH(ifc, &V_if_cloners, ifc_list)
+		if (ifc->ifc_type == SIMPLE) {
+			if (ifc_simple_match(ifc, name))
+				break;
+		} else {
+			if (ifc->ifc_match(ifc, name))
+				break;
 		}
-	}
 #ifdef VIMAGE
 	if (ifc == NULL && !IS_DEFAULT_VNET(curvnet)) {
 		CURVNET_SET_QUIET(vnet0);
-		LIST_FOREACH(ifc, &V_if_cloners, ifc_list) {
-			if (ifc->ifc_match(ifc, name))
-				break;
-		}
+		LIST_FOREACH(ifc, &V_if_cloners, ifc_list)
+			if (ifc->ifc_type == SIMPLE) {
+				if (ifc_simple_match(ifc, name))
+					break;
+			} else {
+				if (ifc->ifc_match(ifc, name))
+					break;
+			}
 		CURVNET_RESTORE();
 	}
 #endif
@@ -173,7 +226,10 @@
 	if (ifunit(name) != NULL)
 		return (EEXIST);
 
-	err = (*ifc->ifc_create)(ifc, name, len, params);
+	if (ifc->ifc_type == SIMPLE)
+		err = ifc_simple_create(ifc, name, len, params);
+	else
+		err = (*ifc->ifc_create)(ifc, name, len, params);
 	
 	if (!err) {
 		ifp = ifunit(name);
@@ -214,10 +270,14 @@
 #ifdef VIMAGE
 	if (ifc == NULL && !IS_DEFAULT_VNET(curvnet)) {
 		CURVNET_SET_QUIET(vnet0);
-		LIST_FOREACH(ifc, &V_if_cloners, ifc_list) {
-			if (ifc->ifc_match(ifc, name))
-				break;
-		}
+		LIST_FOREACH(ifc, &V_if_cloners, ifc_list)
+			if (ifc->type == SIMPLE) {
+				if (ifc_simple_match(ifc, name))
+					break;
+			} else {
+				if (ifc->ifc_match(ifc, name))
+					break;
+			}
 		CURVNET_RESTORE();
 	}
 #endif
@@ -241,7 +301,7 @@
 	int err;
 	struct ifnet *ifcifp;
 
-	if (ifc->ifc_destroy == NULL)
+	if (ifc->ifc_type == ADVANCED && ifc->ifc_destroy == NULL)
 		return(EOPNOTSUPP);
 
 	/*
@@ -266,7 +326,10 @@
 
 	if_delgroup(ifp, ifc->ifc_name);
 
-	err =  (*ifc->ifc_destroy)(ifc, ifp);
+	if (ifc->ifc_type == SIMPLE)
+		err = ifc_simple_destroy(ifc, ifp);
+	else
+		err = (*ifc->ifc_destroy)(ifc, ifp);
 
 	if (err != 0) {
 		if_addgroup(ifp, ifc->ifc_name);
@@ -279,21 +342,29 @@
 	return (err);
 }
 
-/*
- * Register a network interface cloner.
- */
-int
-if_clone_attach(struct if_clone *ifc)
+static struct if_clone *
+if_clone_alloc(const char *name, int maxunit)
 {
-	struct if_clone *ifc1;
+	struct if_clone *ifc;
 
-	KASSERT(ifc->ifc_name != NULL, ("%s: no name\n", __func__));
+	KASSERT(name != NULL, ("%s: no name\n", __func__));
 
+	ifc = malloc(sizeof(struct if_clone), M_CLONE, M_WAITOK | M_ZERO);
+	strncpy(ifc->ifc_name, name, IFCLOSIZ-1);
 	IF_CLONE_LOCK_INIT(ifc);
 	IF_CLONE_ADDREF(ifc);
-	ifc->ifc_unrhdr = new_unrhdr(0, ifc->ifc_maxunit, &ifc->ifc_mtx);
+	ifc->ifc_unrhdr = new_unrhdr(0, (maxunit ? maxunit : IF_MAXUNIT),
+	    &ifc->ifc_mtx);
 	LIST_INIT(&ifc->ifc_iflist);
 
+	return (ifc);
+}
+	
+static int
+if_clone_attach(struct if_clone *ifc)
+{
+	struct if_clone *ifc1;
+
 	IF_CLONERS_LOCK();
 	LIST_FOREACH(ifc1, &V_if_cloners, ifc_list)
 		if (strcmp(ifc->ifc_name, ifc1->ifc_name) == 0) {
@@ -305,20 +376,67 @@
 	V_if_cloners_count++;
 	IF_CLONERS_UNLOCK();
 
-	if (ifc->ifc_attach != NULL)
-		(*ifc->ifc_attach)(ifc);
+	return (0);
+}
+
+struct if_clone *
+if_clone_advanced(const char *name, u_int maxunit, ifc_match_t match,
+	ifc_create_t create, ifc_destroy_t destroy)
+{
+	struct if_clone *ifc;
+
+	ifc = if_clone_alloc(name, maxunit);
+	ifc->ifc_type = ADVANCED;
+	ifc->ifc_match = match;
+	ifc->ifc_create = create;
+	ifc->ifc_destroy = destroy;
+
+	if (if_clone_attach(ifc) != 0)
+		return (NULL);
+
 	EVENTHANDLER_INVOKE(if_clone_event, ifc);
 
-	return (0);
+	return (ifc);
 }
 
+struct if_clone *
+if_clone_simple(const char *name, ifcs_create_t create, ifcs_destroy_t destroy,
+	u_int minifs)
+{
+	struct if_clone *ifc;
+	u_int unit;
+
+	ifc = if_clone_alloc(name, 0);
+	ifc->ifc_type = SIMPLE;
+	ifc->ifcs_create = create;
+	ifc->ifcs_destroy = destroy;
+	ifc->ifcs_minifs = minifs;
+
+	if (if_clone_attach(ifc) != 0)
+		return (NULL);
+
+	for (unit = 0; unit < minifs; unit++) {
+		char name[IFNAMSIZ];
+		int error;
+
+		snprintf(name, IFNAMSIZ, "%s%d", ifc->ifc_name, unit);
+		error = if_clone_createif(ifc, name, IFNAMSIZ, NULL);
+		KASSERT(error == 0,
+		    ("%s: failed to create required interface %s",
+		    __func__, name));
+	}
+
+	EVENTHANDLER_INVOKE(if_clone_event, ifc);
+
+	return (ifc);
+}
+
 /*
  * Unregister a network interface cloner.
  */
 void
 if_clone_detach(struct if_clone *ifc)
 {
-	struct ifc_simple_data *ifcs = ifc->ifc_data;
 
 	IF_CLONERS_LOCK();
 	LIST_REMOVE(ifc, ifc_list);
@@ -326,8 +444,8 @@
 	IF_CLONERS_UNLOCK();
 
 	/* Allow all simples to be destroyed */
-	if (ifc->ifc_attach == ifc_simple_attach)
-		ifcs->ifcs_minifs = 0;
+	if (ifc->ifc_type == SIMPLE)
+		ifc->ifcs_minifs = 0;
 
 	/* destroy all interfaces for this cloner */
 	while (!LIST_EMPTY(&ifc->ifc_iflist))
@@ -345,6 +463,7 @@
 
 	IF_CLONE_LOCK_DESTROY(ifc);
 	delete_unrhdr(ifc->ifc_unrhdr);
+	free(ifc, M_CLONE);
 }
 
 /*
@@ -474,29 +593,7 @@
 	IF_CLONE_REMREF(ifc);
 }
 
-void
-ifc_simple_attach(struct if_clone *ifc)
-{
-	int err;
-	int unit;
-	char name[IFNAMSIZ];
-	struct ifc_simple_data *ifcs = ifc->ifc_data;
-
-	KASSERT(ifcs->ifcs_minifs - 1 <= ifc->ifc_maxunit,
-	    ("%s: %s requested more units than allowed (%d > %d)",
-	    __func__, ifc->ifc_name, ifcs->ifcs_minifs,
-	    ifc->ifc_maxunit + 1));
-
-	for (unit = 0; unit < ifcs->ifcs_minifs; unit++) {
-		snprintf(name, IFNAMSIZ, "%s%d", ifc->ifc_name, unit);
-		err = if_clone_createif(ifc, name, IFNAMSIZ, NULL);
-		KASSERT(err == 0,
-		    ("%s: failed to create required interface %s",
-		    __func__, name));
-	}
-}
-
-int
+static int
 ifc_simple_match(struct if_clone *ifc, const char *name)
 {
 	const char *cp;
@@ -517,14 +614,13 @@
 	return (1);
 }
 
-int
+static int
 ifc_simple_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
 {
 	char *dp;
 	int wildcard;
 	int unit;
 	int err;
-	struct ifc_simple_data *ifcs = ifc->ifc_data;
 
 	err = ifc_name2unit(name, &unit);
 	if (err != 0)
@@ -536,7 +632,7 @@
 	if (err != 0)
 		return (err);
 
-	err = ifcs->ifcs_create(ifc, unit, params);
+	err = ifc->ifcs_create(ifc, unit, params);
 	if (err != 0) {
 		ifc_free_unit(ifc, unit);
 		return (err);
@@ -560,18 +656,17 @@
 	return (0);
 }
 
-int
+static int
 ifc_simple_destroy(struct if_clone *ifc, struct ifnet *ifp)
 {
 	int unit;
-	struct ifc_simple_data *ifcs = ifc->ifc_data;
 
 	unit = ifp->if_dunit;
 
-	if (unit < ifcs->ifcs_minifs) 
+	if (unit < ifc->ifcs_minifs) 
 		return (EINVAL);
 
-	ifcs->ifcs_destroy(ifp);
+	ifc->ifcs_destroy(ifp);
 
 	ifc_free_unit(ifc, unit);
 
Index: if_clone.h
===================================================================
--- if_clone.h	(revision 228129)
+++ if_clone.h	(working copy)
@@ -35,87 +35,42 @@
 
 #ifdef _KERNEL
 
-#define IFC_CLONE_INITIALIZER(name, data, maxunit,			\
-    attach, match, create, destroy)					\
-    {									\
-	.ifc_name = name,						\
-	.ifc_maxunit = maxunit,						\
-	.ifc_data = data,						\
-	.ifc_attach = attach,						\
-	.ifc_match = match,						\
-	.ifc_create = create,						\
-	.ifc_destroy = destroy,						\
-    }
+struct if_clone;
 
-/*
- * Structure describing a `cloning' interface.
- *
- * List of locks
- * (c)		const until freeing
- * (d)		driver specific data, may need external protection.
- * (e)		locked by if_cloners_mtx
- * (i)		locked by ifc_mtx mtx
- */
-struct if_clone {
-	LIST_ENTRY(if_clone) ifc_list;	/* (e) On list of cloners */
-	const char *ifc_name;		/* (c) Name of device, e.g. `gif' */
-	int ifc_maxunit;		/* (c) Maximum unit number */
-	struct unrhdr *ifc_unrhdr;	/* (c) alloc_unr(9) header */
-	void *ifc_data;			/* (*) Data for ifc_* functions. */
+/* Methods. */
+typedef int	ifc_match_t(struct if_clone *, const char *);
+typedef int	ifc_create_t(struct if_clone *, char *, size_t, caddr_t);
+typedef int	ifc_destroy_t(struct if_clone *, struct ifnet *);
 
-	/* (c) Driver specific cloning functions.  Called with no locks held. */
-	void	(*ifc_attach)(struct if_clone *);
-	int	(*ifc_match)(struct if_clone *, const char *);
-	int	(*ifc_create)(struct if_clone *, char *, size_t, caddr_t);
-	int	(*ifc_destroy)(struct if_clone *, struct ifnet *);
+typedef int	ifcs_create_t(struct if_clone *, int, caddr_t);
+typedef void	ifcs_destroy_t(struct ifnet *);
 
-	long ifc_refcnt;		/* (i) Refrence count. */
-	struct mtx ifc_mtx;		/* Mutex to protect members. */
-	LIST_HEAD(, ifnet) ifc_iflist;	/* (i) List of cloned interfaces */
-};
-
-void	if_clone_init(void);
-int	if_clone_attach(struct if_clone *);
+/* Interface cloner (de)allocating functions. */
+struct if_clone *
+	if_clone_advanced(const char *, u_int, ifc_match_t, ifc_create_t,
+		      ifc_destroy_t);
+struct if_clone *
+	if_clone_simple(const char *, ifcs_create_t, ifcs_destroy_t, u_int);
 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 *);
-int	if_clone_destroyif(struct if_clone *, struct ifnet *);
-int	if_clone_list(struct if_clonereq *);
-
+/* Unit (de)allocating fucntions. */
 int	ifc_name2unit(const char *name, int *unit);
 int	ifc_alloc_unit(struct if_clone *, int *);
 void	ifc_free_unit(struct if_clone *, int);
 
-/*
- * The ifc_simple functions, structures, and macros implement basic
- * cloning as in 5.[012].
- */
-
-struct ifc_simple_data {
-	int ifcs_minifs;		/* minimum number of interfaces */
-
-	int	(*ifcs_create)(struct if_clone *, int, caddr_t);
-	void	(*ifcs_destroy)(struct ifnet *);
-};
-
-/* interface clone event */
+/* Interface clone event. */
 typedef void (*if_clone_event_handler_t)(void *, struct if_clone *);
 EVENTHANDLER_DECLARE(if_clone_event, if_clone_event_handler_t);
 
-#define IFC_SIMPLE_DECLARE(name, minifs)				\
-struct ifc_simple_data name##_cloner_data =				\
-    {minifs, name##_clone_create, name##_clone_destroy};		\
-struct if_clone name##_cloner =						\
-    IFC_CLONE_INITIALIZER(#name, &name##_cloner_data, IF_MAXUNIT,	\
-    ifc_simple_attach, ifc_simple_match, ifc_simple_create, ifc_simple_destroy)
+/* The below interfaces used only by net/if.c. */
+void	if_clone_init(void);
+void	vnet_if_clone_init(void);
+int	if_clone_create(char *, size_t, caddr_t);
+int	if_clone_destroy(const char *);
+int	if_clone_list(struct if_clonereq *);
 
-void	ifc_simple_attach(struct if_clone *);
-int	ifc_simple_match(struct if_clone *, const char *);
-int	ifc_simple_create(struct if_clone *, char *, size_t, caddr_t);
-int	ifc_simple_destroy(struct if_clone *, struct ifnet *);
+/* The below interface used only by epair(4). */
+int	if_clone_destroyif(struct if_clone *, struct ifnet *);
 
 #endif /* _KERNEL */
-
 #endif /* !_NET_IF_CLONE_H_ */
Index: if_vlan.c
===================================================================
--- if_vlan.c	(revision 228129)
+++ if_vlan.c	(working copy)
@@ -207,11 +207,10 @@
 static	void vlan_ifdetach(void *arg, struct ifnet *ifp);
 static  void vlan_iflladdr(void *arg, struct ifnet *ifp);
 
-static	struct if_clone vlan_cloner = IFC_CLONE_INITIALIZER(VLANNAME, NULL,
-    IF_MAXUNIT, NULL, vlan_clone_match, vlan_clone_create, vlan_clone_destroy);
+static	struct if_clone *vlan_cloner;
 
 #ifdef VIMAGE
-static VNET_DEFINE(struct if_clone, vlan_cloner);
+static VNET_DEFINE(struct if_clone *, vlan_cloner);
 #define	V_vlan_cloner	VNET(vlan_cloner)
 #endif
 
@@ -719,7 +718,8 @@
 		vlan_tag_p = vlan_tag;
 		vlan_devat_p = vlan_devat;
 #ifndef VIMAGE
-		if_clone_attach(&vlan_cloner);
+		vlan_cloner = if_clone_advanced(VLANNAME, 0, vlan_clone_match,
+		    vlan_clone_create, vlan_clone_destroy);
 #endif
 		if (bootverbose)
 			printf("vlan: initialized, using "
@@ -733,7 +733,7 @@
 		break;
 	case MOD_UNLOAD:
 #ifndef VIMAGE
-		if_clone_detach(&vlan_cloner);
+		if_clone_detach(vlan_cloner);
 #endif
 		EVENTHANDLER_DEREGISTER(ifnet_departure_event, ifdetach_tag);
 		EVENTHANDLER_DEREGISTER(iflladdr_event, iflladdr_tag);
@@ -769,8 +769,9 @@
 vnet_vlan_init(const void *unused __unused)
 {
 
+	vlan_cloner = if_clone_advanced(VLANNAME, 0, vlan_clone_match,
+		    vlan_clone_create, vlan_clone_destroy);
 	V_vlan_cloner = vlan_cloner;
-	if_clone_attach(&V_vlan_cloner);
 }
 VNET_SYSINIT(vnet_vlan_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
     vnet_vlan_init, NULL);
@@ -779,7 +780,7 @@
 vnet_vlan_uninit(const void *unused __unused)
 {
 
-	if_clone_detach(&V_vlan_cloner);
+	if_clone_detach(V_vlan_cloner);
 }
 VNET_SYSUNINIT(vnet_vlan_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_FIRST,
     vnet_vlan_uninit, NULL);
@@ -936,7 +937,7 @@
 	 * we don't conform to the default naming convention for interfaces.
 	 */
 	strlcpy(ifp->if_xname, name, IFNAMSIZ);
-	ifp->if_dname = ifc->ifc_name;
+	ifp->if_dname = VLANNAME;
 	ifp->if_dunit = unit;
 	/* NB: flags are not set here */
 	ifp->if_linkmib = &ifv->ifv_mib;
Index: if_loop.c
===================================================================
--- if_loop.c	(revision 228129)
+++ if_loop.c	(working copy)
@@ -106,13 +106,12 @@
 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);
-#define	V_lo_cloner_data	VNET(lo_cloner_data)
+static VNET_DEFINE(struct if_clone *, lo_cloner);
 #define	V_lo_cloner		VNET(lo_cloner)
 #endif
 
-IFC_SIMPLE_DECLARE(lo, 1);
+static struct if_clone *lo_cloner;
+static const char *loname = "lo";
 
 static void
 lo_clone_destroy(struct ifnet *ifp)
@@ -137,7 +136,7 @@
 	if (ifp == NULL)
 		return (ENOSPC);
 
-	if_initname(ifp, ifc->ifc_name, unit);
+	if_initname(ifp, loname, unit);
 	ifp->if_mtu = LOMTU;
 	ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST;
 	ifp->if_ioctl = loioctl;
@@ -158,12 +157,12 @@
 {
 
 #ifdef VIMAGE
+	lo_cloner = if_clone_simple(loname, lo_clone_create, lo_clone_destroy,
+	    1);
 	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);
+	lo_cloner = if_clone_simple(loname, lo_clone_create, lo_clone_destroy,
+	    1);
 #endif
 }
 VNET_SYSINIT(vnet_loif_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
@@ -174,7 +173,7 @@
 vnet_loif_uninit(const void *unused __unused)
 {
 
-	if_clone_detach(&V_lo_cloner);
+	if_clone_detach(V_lo_cloner);
 	V_loif = NULL;
 }
 VNET_SYSUNINIT(vnet_loif_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
Index: if_epair.c
===================================================================
--- if_epair.c	(revision 228129)
+++ if_epair.c	(working copy)
@@ -171,9 +171,7 @@
 static MALLOC_DEFINE(M_EPAIR, EPAIRNAME,
     "Pair of virtual cross-over connected Ethernet-like interfaces");
 
-static struct if_clone epair_cloner = IFC_CLONE_INITIALIZER(
-    EPAIRNAME, NULL, IF_MAXUNIT,
-    NULL, epair_clone_match, epair_clone_create, epair_clone_destroy);
+static struct if_clone *epair_cloner;
 
 /*
  * DPCPU area and functions.
@@ -714,7 +712,7 @@
 
 	/*
 	 * We are abusing params to create our second interface.
-	 * Actually we already created it and called if_clone_createif()
+	 * Actually we already created it and called if_clone_create()
 	 * for it to do the official insertion procedure the moment we knew
 	 * it cannot fail anymore. So just do attach it here.
 	 */
@@ -807,7 +805,7 @@
 	ifp = sca->ifp;
 	ifp->if_softc = sca;
 	strlcpy(ifp->if_xname, name, IFNAMSIZ);
-	ifp->if_dname = ifc->ifc_name;
+	ifp->if_dname = EPAIRNAME;
 	ifp->if_dunit = unit;
 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
 	ifp->if_capabilities = IFCAP_VLAN_MTU;
@@ -833,7 +831,7 @@
 	ifp = scb->ifp;
 	ifp->if_softc = scb;
 	strlcpy(ifp->if_xname, name, IFNAMSIZ);
-	ifp->if_dname = ifc->ifc_name;
+	ifp->if_dname = EPAIRNAME;
 	ifp->if_dunit = unit;
 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
 	ifp->if_capabilities = IFCAP_VLAN_MTU;
@@ -846,7 +844,7 @@
 	strlcpy(name, EPAIRNAME, len);
 	error = if_clone_create(name, len, (caddr_t)scb);
 	if (error)
-		panic("%s: if_clone_createif() for our 2nd iface failed: %d",
+		panic("%s: if_clone_create() for our 2nd iface failed: %d",
 		    __func__, error);
 	scb->if_qflush = ifp->if_qflush;
 	ifp->if_qflush = epair_qflush;
@@ -956,12 +954,13 @@
 		if (TUNABLE_INT_FETCH("net.link.epair.netisr_maxqlen", &qlimit))
 		    epair_nh.nh_qlimit = qlimit;
 		netisr_register(&epair_nh);
-		if_clone_attach(&epair_cloner);
+		epair_cloner = if_clone_advanced(EPAIRNAME, 0,
+		    epair_clone_match, epair_clone_create, epair_clone_destroy);
 		if (bootverbose)
 			printf("%s initialized.\n", EPAIRNAME);
 		break;
 	case MOD_UNLOAD:
-		if_clone_detach(&epair_cloner);
+		if_clone_detach(epair_cloner);
 		netisr_unregister(&epair_nh);
 		epair_dpcpu_detach();
 		if (bootverbose)

--KN5l+BnMqAQyZLvT--



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