Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 16 Oct 2012 13:37:55 +0000 (UTC)
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r241610 - in head: . sys/dev/usb sys/net sys/net80211 sys/netpfil/ipfw sys/netpfil/pf sys/sys
Message-ID:  <201210161337.q9GDbtr8049924@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: glebius
Date: Tue Oct 16 13:37:54 2012
New Revision: 241610
URL: http://svn.freebsd.org/changeset/base/241610

Log:
  Make the "struct if_clone" opaque to users of the cloning API. Users
  now use function calls:
  
    if_clone_simple()
    if_clone_advanced()
  
  to initialize a cloner, instead of macros that initialize if_clone
  structure.
  
  Discussed with:		brooks, bz, 1 year ago

Modified:
  head/UPDATING
  head/sys/dev/usb/usb_pf.c
  head/sys/net/if_bridge.c
  head/sys/net/if_clone.c
  head/sys/net/if_clone.h
  head/sys/net/if_disc.c
  head/sys/net/if_edsc.c
  head/sys/net/if_enc.c
  head/sys/net/if_epair.c
  head/sys/net/if_faith.c
  head/sys/net/if_gif.c
  head/sys/net/if_gre.c
  head/sys/net/if_lagg.c
  head/sys/net/if_loop.c
  head/sys/net/if_stf.c
  head/sys/net/if_tap.c
  head/sys/net/if_tun.c
  head/sys/net/if_vlan.c
  head/sys/net80211/ieee80211_freebsd.c
  head/sys/netpfil/ipfw/ip_fw_log.c
  head/sys/netpfil/pf/if_pflog.c
  head/sys/netpfil/pf/if_pfsync.c
  head/sys/sys/param.h

Modified: head/UPDATING
==============================================================================
--- head/UPDATING	Tue Oct 16 13:27:20 2012	(r241609)
+++ head/UPDATING	Tue Oct 16 13:37:54 2012	(r241610)
@@ -24,6 +24,13 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 10
 	disable the most expensive debugging functionality run
 	"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
 
+20121016:
+	The interface cloning API and ABI has changed. The following
+	modules need to be recompiled together with kernel:
+	ipfw(4), pfsync(4), pflog(4), usb(4), wlan(4), stf(4),
+	vlan(4), disc(4), edsc(4), if_bridge(4), gif(4), tap(4),
+	faith(4), epair(4), enc(4), tun(4), if_lagg(4), gre(4).
+
 20121015:
 	The sdhci driver was split in two parts: sdhci (generic SD Host
 	Controller logic) and sdhci_pci (actual hardware driver).

Modified: head/sys/dev/usb/usb_pf.c
==============================================================================
--- head/sys/dev/usb/usb_pf.c	Tue Oct 16 13:27:20 2012	(r241609)
+++ head/sys/dev/usb/usb_pf.c	Tue Oct 16 13:37:54 2012	(r241610)
@@ -60,8 +60,6 @@ __FBSDID("$FreeBSD$");
 #include <dev/usb/usb_pf.h>
 #include <dev/usb/usb_transfer.h>
 
-#define	USBUSNAME	"usbus"
-
 static void usbpf_init(void);
 static void usbpf_uninit(void);
 static int usbpf_ioctl(struct ifnet *, u_long, caddr_t);
@@ -74,9 +72,8 @@ static uint32_t usbpf_aggregate_status(s
 static int usbpf_xfer_frame_is_read(struct usb_xfer *, uint32_t);
 static uint32_t usbpf_xfer_precompute_size(struct usb_xfer *, int);
 
-static struct if_clone usbpf_cloner = IFC_CLONE_INITIALIZER(
-    USBUSNAME, NULL, IF_MAXUNIT,
-    NULL, usbpf_clone_match, usbpf_clone_create, usbpf_clone_destroy);
+static struct if_clone *usbpf_cloner;
+static const char usbusname[] = "usbus";
 
 SYSINIT(usbpf_init, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, usbpf_init, NULL);
 SYSUNINIT(usbpf_uninit, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, usbpf_uninit, NULL);
@@ -85,7 +82,8 @@ static void
 usbpf_init(void)
 {
 
-	if_clone_attach(&usbpf_cloner);
+	usbpf_cloner = if_clone_advanced(usbusname, 0, usbpf_clone_match,
+	    usbpf_clone_create, usbpf_clone_destroy);
 }
 
 static void
@@ -98,9 +96,9 @@ usbpf_uninit(void)
 	int error;
 	int i;
 	
-	if_clone_detach(&usbpf_cloner);
+	if_clone_detach(usbpf_cloner);
 
-	dc = devclass_find(USBUSNAME);
+	dc = devclass_find(usbusname);
 	if (dc == NULL)
 		return;
 	error = devclass_get_devices(dc, &devlp, &devlcnt);
@@ -109,7 +107,7 @@ usbpf_uninit(void)
 	for (i = 0; i < devlcnt; i++) {
 		ubus = device_get_softc(devlp[i]);
 		if (ubus != NULL && ubus->ifp != NULL)
-			usbpf_clone_destroy(&usbpf_cloner, ubus->ifp);
+			usbpf_clone_destroy(usbpf_cloner, ubus->ifp);
 	}
 	free(devlp, M_TEMP);
 }
@@ -130,12 +128,12 @@ usbpf_ifname2ubus(const char *ifname)
 	int unit;
 	int error;
 
-	if (strncmp(ifname, USBUSNAME, sizeof(USBUSNAME) - 1) != 0)
+	if (strncmp(ifname, usbusname, sizeof(usbusname) - 1) != 0)
 		return (NULL);
 	error = ifc_name2unit(ifname, &unit);
 	if (error || unit < 0)
 		return (NULL);
-	dc = devclass_find(USBUSNAME);
+	dc = devclass_find(usbusname);
 	if (dc == NULL)
 		return (NULL);
 	dev = devclass_get_device(dc, unit);
@@ -195,7 +193,7 @@ usbpf_clone_create(struct if_clone *ifc,
 	}
 	strlcpy(ifp->if_xname, name, sizeof(ifp->if_xname));
 	ifp->if_softc = ubus;
-	ifp->if_dname = ifc->ifc_name;
+	ifp->if_dname = usbusname;
 	ifp->if_dunit = unit;
 	ifp->if_ioctl = usbpf_ioctl;
 	if_attach(ifp);
@@ -242,7 +240,7 @@ usbpf_detach(struct usb_bus *ubus)
 {
 
 	if (ubus->ifp != NULL)
-		usbpf_clone_destroy(&usbpf_cloner, ubus->ifp);
+		usbpf_clone_destroy(usbpf_cloner, ubus->ifp);
 	if (bootverbose)
 		device_printf(ubus->parent, "usbpf: Detached\n");
 }

Modified: head/sys/net/if_bridge.c
==============================================================================
--- head/sys/net/if_bridge.c	Tue Oct 16 13:27:20 2012	(r241609)
+++ head/sys/net/if_bridge.c	Tue Oct 16 13:37:54 2012	(r241610)
@@ -481,7 +481,8 @@ const int bridge_control_table_size =
 
 LIST_HEAD(, bridge_softc) bridge_list;
 
-IFC_SIMPLE_DECLARE(bridge, 0);
+static struct if_clone *bridge_cloner;
+static const char bridge_name[] = "bridge";
 
 static int
 bridge_modevent(module_t mod, int type, void *data)
@@ -490,7 +491,8 @@ bridge_modevent(module_t mod, int type, 
 	switch (type) {
 	case MOD_LOAD:
 		mtx_init(&bridge_list_mtx, "if_bridge list", NULL, MTX_DEF);
-		if_clone_attach(&bridge_cloner);
+		bridge_cloner = if_clone_simple(bridge_name,
+		    bridge_clone_create, bridge_clone_destroy, 0);
 		bridge_rtnode_zone = uma_zcreate("bridge_rtnode",
 		    sizeof(struct bridge_rtnode), NULL, NULL, NULL, NULL,
 		    UMA_ALIGN_PTR, 0);
@@ -506,7 +508,7 @@ bridge_modevent(module_t mod, int type, 
 	case MOD_UNLOAD:
 		EVENTHANDLER_DEREGISTER(ifnet_departure_event,
 		    bridge_detach_cookie);
-		if_clone_detach(&bridge_cloner);
+		if_clone_detach(bridge_cloner);
 		uma_zdestroy(bridge_rtnode_zone);
 		bridge_input_p = NULL;
 		bridge_output_p = NULL;
@@ -595,7 +597,7 @@ bridge_clone_create(struct if_clone *ifc
 	LIST_INIT(&sc->sc_spanlist);
 
 	ifp->if_softc = sc;
-	if_initname(ifp, ifc->ifc_name, unit);
+	if_initname(ifp, bridge_name, unit);
 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
 	ifp->if_ioctl = bridge_ioctl;
 	ifp->if_transmit = bridge_transmit;

Modified: head/sys/net/if_clone.c
==============================================================================
--- head/sys/net/if_clone.c	Tue Oct 16 13:27:20 2012	(r241609)
+++ head/sys/net/if_clone.c	Tue Oct 16 13:37:54 2012	(r241610)
@@ -1,4 +1,5 @@
 /*-
+ * Copyright (c) 2012 Gleb Smirnoff <glebius@FreeBSD.org>
  * Copyright (c) 1980, 1986, 1993
  *	The Regents of the University of California.  All rights reserved.
  *
@@ -42,19 +43,65 @@
 
 #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 */
+	int ifc_maxunit;		/* (c) maximum unit number */
+	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 +185,25 @@ if_clone_create(char *name, size_t len, 
 
 	/* 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 +227,10 @@ if_clone_createif(struct if_clone *ifc, 
 	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 +271,14 @@ if_clone_destroy(const char *name)
 #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 +302,7 @@ if_clone_destroyif(struct if_clone *ifc,
 	int err;
 	struct ifnet *ifcifp;
 
-	if (ifc->ifc_destroy == NULL)
+	if (ifc->ifc_type == ADVANCED && ifc->ifc_destroy == NULL)
 		return(EOPNOTSUPP);
 
 	/*
@@ -266,7 +327,10 @@ if_clone_destroyif(struct if_clone *ifc,
 
 	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 +343,29 @@ if_clone_destroyif(struct if_clone *ifc,
 	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_maxunit = maxunit ? maxunit : IF_MAXUNIT;
 	ifc->ifc_unrhdr = new_unrhdr(0, ifc->ifc_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,11 +377,63 @@ if_clone_attach(struct if_clone *ifc)
 	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) {
+		if_clone_free(ifc);
+		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) {
+		if_clone_free(ifc);
+		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);
 }
 
 /*
@@ -318,7 +442,6 @@ if_clone_attach(struct if_clone *ifc)
 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 +449,8 @@ if_clone_detach(struct if_clone *ifc)
 	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 +468,7 @@ if_clone_free(struct if_clone *ifc)
 
 	IF_CLONE_LOCK_DESTROY(ifc);
 	delete_unrhdr(ifc->ifc_unrhdr);
+	free(ifc, M_CLONE);
 }
 
 /*
@@ -483,29 +607,7 @@ ifc_free_unit(struct if_clone *ifc, int 
 	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;
@@ -526,14 +628,13 @@ ifc_simple_match(struct if_clone *ifc, c
 	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)
@@ -545,7 +646,7 @@ ifc_simple_create(struct if_clone *ifc, 
 	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);
@@ -569,18 +670,17 @@ ifc_simple_create(struct if_clone *ifc, 
 	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);
 

Modified: head/sys/net/if_clone.h
==============================================================================
--- head/sys/net/if_clone.h	Tue Oct 16 13:27:20 2012	(r241609)
+++ head/sys/net/if_clone.h	Tue Oct 16 13:37:54 2012	(r241610)
@@ -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,						\
-    }
-
-/*
- * 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. */
-
-	/* (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 *);
-
-	long ifc_refcnt;		/* (i) Refrence count. */
-	struct mtx ifc_mtx;		/* Mutex to protect members. */
-	LIST_HEAD(, ifnet) ifc_iflist;	/* (i) List of cloned interfaces */
-};
+struct if_clone;
 
-void	if_clone_init(void);
-int	if_clone_attach(struct if_clone *);
+/* 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 *);
+
+typedef int	ifcs_create_t(struct if_clone *, int, caddr_t);
+typedef void	ifcs_destroy_t(struct ifnet *);
+
+/* 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)
-
-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 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 *);
 
-#endif /* _KERNEL */
+/* The below interface used only by epair(4). */
+int	if_clone_destroyif(struct if_clone *, struct ifnet *);
 
+#endif /* _KERNEL */
 #endif /* !_NET_IF_CLONE_H_ */

Modified: head/sys/net/if_disc.c
==============================================================================
--- head/sys/net/if_disc.c	Tue Oct 16 13:27:20 2012	(r241609)
+++ head/sys/net/if_disc.c	Tue Oct 16 13:37:54 2012	(r241610)
@@ -59,8 +59,6 @@
 #define DSMTU	65532
 #endif
 
-#define DISCNAME	"disc"
-
 struct disc_softc {
 	struct ifnet *sc_ifp;
 };
@@ -72,9 +70,10 @@ static int	discioctl(struct ifnet *, u_l
 static int	disc_clone_create(struct if_clone *, int, caddr_t);
 static void	disc_clone_destroy(struct ifnet *);
 
-static MALLOC_DEFINE(M_DISC, DISCNAME, "Discard interface");
+static const char discname[] = "disc";
+static MALLOC_DEFINE(M_DISC, discname, "Discard interface");
 
-IFC_SIMPLE_DECLARE(disc, 0);
+static struct if_clone *disc_cloner;
 
 static int
 disc_clone_create(struct if_clone *ifc, int unit, caddr_t params)
@@ -90,7 +89,7 @@ disc_clone_create(struct if_clone *ifc, 
 	}
 
 	ifp->if_softc = sc;
-	if_initname(ifp, ifc->ifc_name, unit);
+	if_initname(ifp, discname, unit);
 	ifp->if_mtu = DSMTU;
 	/*
 	 * IFF_LOOPBACK should not be removed from disc's flags because
@@ -135,10 +134,11 @@ disc_modevent(module_t mod, int type, vo
 
 	switch (type) {
 	case MOD_LOAD:
-		if_clone_attach(&disc_cloner);
+		disc_cloner = if_clone_simple(discname, disc_clone_create,
+		    disc_clone_destroy, 0);
 		break;
 	case MOD_UNLOAD:
-		if_clone_detach(&disc_cloner);
+		if_clone_detach(disc_cloner);
 		break;
 	default:
 		return (EOPNOTSUPP);

Modified: head/sys/net/if_edsc.c
==============================================================================
--- head/sys/net/if_edsc.c	Tue Oct 16 13:27:20 2012	(r241609)
+++ head/sys/net/if_edsc.c	Tue Oct 16 13:37:54 2012	(r241610)
@@ -51,6 +51,8 @@
 #include <net/if_types.h>	/* IFT_ETHER and friends */
 #include <net/if_var.h>		/* kernel-only part of ifnet(9) */
 
+static const char edscname[] = "edsc";
+
 /*
  * Software configuration of an interface specific to this device type.
  */
@@ -64,9 +66,9 @@ struct edsc_softc {
 };
 
 /*
- * Simple cloning methods.
- * IFC_SIMPLE_DECLARE() expects precisely these names.
+ * Attach to the interface cloning framework.
  */
+static struct if_clone *edsc_cloner;
 static int	edsc_clone_create(struct if_clone *, int, caddr_t);
 static void	edsc_clone_destroy(struct ifnet *);
 
@@ -81,15 +83,7 @@ static void	edsc_start(struct ifnet *ifp
 /*
  * We'll allocate softc instances from this.
  */
-static		MALLOC_DEFINE(M_EDSC, "edsc", "Ethernet discard interface");
-
-/*
- * Attach to the interface cloning framework under the name of "edsc".
- * The second argument is the number of units to be created from
- * the outset.  It's also the minimum number of units allowed.
- * We don't want any units created as soon as the driver is loaded.
- */
-IFC_SIMPLE_DECLARE(edsc, 0);
+static		MALLOC_DEFINE(M_EDSC, edscname, "Ethernet discard interface");
 
 /*
  * Create an interface instance.
@@ -116,7 +110,7 @@ edsc_clone_create(struct if_clone *ifc, 
 	/*
 	 * Get a name for this particular interface in its ifnet structure.
 	 */
-	if_initname(ifp, ifc->ifc_name, unit);
+	if_initname(ifp, edscname, unit);
 
 	/*
 	 * Typical Ethernet interface flags: we can do broadcast and
@@ -323,8 +317,13 @@ edsc_modevent(module_t mod, int type, vo
 	case MOD_LOAD:
 		/*
 		 * Connect to the network interface cloning framework.
+		 * The last argument is the number of units to be created
+		 * from the outset.  It's also the minimum number of units
+		 * allowed.  We don't want any units created as soon as the
+		 * driver is loaded.
 		 */
-		if_clone_attach(&edsc_cloner);
+		edsc_cloner = if_clone_simple(edscname, edsc_clone_create,
+		    edsc_clone_destroy, 0);
 		break;
 
 	case MOD_UNLOAD:
@@ -332,7 +331,7 @@ edsc_modevent(module_t mod, int type, vo
 		 * Disconnect from the cloning framework.
 		 * Existing interfaces will be disposed of properly.
 		 */
-		if_clone_detach(&edsc_cloner);
+		if_clone_detach(edsc_cloner);
 		break;
 
 	default:

Modified: head/sys/net/if_enc.c
==============================================================================
--- head/sys/net/if_enc.c	Tue Oct 16 13:27:20 2012	(r241609)
+++ head/sys/net/if_enc.c	Tue Oct 16 13:37:54 2012	(r241610)
@@ -91,8 +91,8 @@ static int	enc_output(struct ifnet *ifp,
 		    struct sockaddr *dst, struct route *ro);
 static int	enc_clone_create(struct if_clone *, int, caddr_t);
 static void	enc_clone_destroy(struct ifnet *);
-
-IFC_SIMPLE_DECLARE(enc, 1);
+static struct if_clone *enc_cloner;
+static const char encname[] = "enc";
 
 /*
  * Sysctls.
@@ -143,7 +143,7 @@ enc_clone_create(struct if_clone *ifc, i
 		return (ENOSPC);
 	}
 
-	if_initname(ifp, ifc->ifc_name, unit);
+	if_initname(ifp, encname, unit);
 	ifp->if_mtu = ENCMTU;
 	ifp->if_ioctl = enc_ioctl;
 	ifp->if_output = enc_output;
@@ -167,7 +167,8 @@ enc_modevent(module_t mod, int type, voi
 	switch (type) {
 	case MOD_LOAD:
 		mtx_init(&enc_mtx, "enc mtx", NULL, MTX_DEF);
-		if_clone_attach(&enc_cloner);
+		enc_cloner = if_clone_simple(encname, enc_clone_create,
+		    enc_clone_destroy, 0);
 		break;
 	case MOD_UNLOAD:
 		printf("enc module unload - not possible for this module\n");

Modified: head/sys/net/if_epair.c
==============================================================================
--- head/sys/net/if_epair.c	Tue Oct 16 13:27:20 2012	(r241609)
+++ head/sys/net/if_epair.c	Tue Oct 16 13:37:54 2012	(r241610)
@@ -72,8 +72,6 @@ __FBSDID("$FreeBSD$");
 #include <net/netisr.h>
 #include <net/vnet.h>
 
-#define	EPAIRNAME	"epair"
-
 SYSCTL_DECL(_net_link);
 static SYSCTL_NODE(_net_link, OID_AUTO, epair, CTLFLAG_RW, 0, "epair sysctl");
 
@@ -100,9 +98,11 @@ static int epair_clone_match(struct if_c
 static int epair_clone_create(struct if_clone *, char *, size_t, caddr_t);
 static int epair_clone_destroy(struct if_clone *, struct ifnet *);
 
+static const char epairname[] = "epair";
+
 /* Netisr realted definitions and sysctl. */
 static struct netisr_handler epair_nh = {
-	.nh_name	= EPAIRNAME,
+	.nh_name	= epairname,
 	.nh_proto	= NETISR_EPAIR,
 	.nh_policy	= NETISR_POLICY_CPU,
 	.nh_handler	= epair_nh_sintr,
@@ -168,12 +168,10 @@ STAILQ_HEAD(eid_list, epair_ifp_drain);
 #define	EPAIR_REFCOUNT_ASSERT(a, p)
 #endif
 
-static MALLOC_DEFINE(M_EPAIR, EPAIRNAME,
+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.
@@ -692,10 +690,10 @@ epair_clone_match(struct if_clone *ifc, 
 	 * - epair<n>
 	 * but not the epair<n>[ab] versions.
 	 */
-	if (strncmp(EPAIRNAME, name, sizeof(EPAIRNAME)-1) != 0)
+	if (strncmp(epairname, name, sizeof(epairname)-1) != 0)
 		return (0);
 
-	for (cp = name + sizeof(EPAIRNAME) - 1; *cp != '\0'; cp++) {
+	for (cp = name + sizeof(epairname) - 1; *cp != '\0'; cp++) {
 		if (*cp < '0' || *cp > '9')
 			return (0);
 	}
@@ -714,7 +712,7 @@ epair_clone_create(struct if_clone *ifc,
 
 	/*
 	 * 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 @@ epair_clone_create(struct if_clone *ifc,
 	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 @@ epair_clone_create(struct if_clone *ifc,
 	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;
@@ -843,10 +841,10 @@ epair_clone_create(struct if_clone *ifc,
 	ifp->if_init  = epair_init;
 	ifp->if_snd.ifq_maxlen = ifqmaxlen;
 	/* We need to play some tricks here for the second interface. */
-	strlcpy(name, EPAIRNAME, len);
+	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;
@@ -958,16 +956,17 @@ epair_modevent(module_t mod, int type, v
 		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);
+			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)
-			printf("%s unloaded.\n", EPAIRNAME);
+			printf("%s unloaded.\n", epairname);
 		break;
 	default:
 		return (EOPNOTSUPP);

Modified: head/sys/net/if_faith.c
==============================================================================
--- head/sys/net/if_faith.c	Tue Oct 16 13:27:20 2012	(r241609)
+++ head/sys/net/if_faith.c	Tue Oct 16 13:37:54 2012	(r241610)
@@ -79,8 +79,6 @@
 #include <netinet6/ip6_var.h>
 #endif
 
-#define FAITHNAME	"faith"
-
 struct faith_softc {
 	struct ifnet *sc_ifp;
 };
@@ -95,12 +93,12 @@ static int faithprefix(struct in6_addr *
 
 static int faithmodevent(module_t, int, void *);
 
-static MALLOC_DEFINE(M_FAITH, FAITHNAME, "Firewall Assisted Tunnel Interface");
+static const char faithname[] = "faith";
+static MALLOC_DEFINE(M_FAITH, faithname, "Firewall Assisted Tunnel Interface");
 
 static int	faith_clone_create(struct if_clone *, int, caddr_t);
 static void	faith_clone_destroy(struct ifnet *);
-
-IFC_SIMPLE_DECLARE(faith, 0);
+static struct if_clone *faith_cloner;
 
 #define	FAITHMTU	1500
 
@@ -113,8 +111,8 @@ faithmodevent(mod, type, data)
 
 	switch (type) {
 	case MOD_LOAD:
-		if_clone_attach(&faith_cloner);
-
+		faith_cloner = if_clone_simple(faithname, faith_clone_create,
+		    faith_clone_destroy, 0);
 #ifdef INET6
 		faithprefix_p = faithprefix;
 #endif
@@ -125,7 +123,7 @@ faithmodevent(mod, type, data)
 		faithprefix_p = NULL;
 #endif
 
-		if_clone_detach(&faith_cloner);
+		if_clone_detach(faith_cloner);
 		break;
 	default:
 		return EOPNOTSUPP;
@@ -159,7 +157,7 @@ faith_clone_create(ifc, unit, params)
 	}
 
 	ifp->if_softc = sc;
-	if_initname(sc->sc_ifp, ifc->ifc_name, unit);
+	if_initname(sc->sc_ifp, faithname, unit);
 
 	ifp->if_mtu = FAITHMTU;
 	/* Change to BROADCAST experimentaly to announce its prefix. */

Modified: head/sys/net/if_gif.c
==============================================================================
--- head/sys/net/if_gif.c	Tue Oct 16 13:27:20 2012	(r241609)
+++ head/sys/net/if_gif.c	Tue Oct 16 13:37:54 2012	(r241610)
@@ -88,7 +88,7 @@
 
 #include <security/mac/mac_framework.h>
 
-#define GIFNAME		"gif"
+static const char gifname[] = "gif";
 
 /*
  * gif_mtx protects the global gif_softc_list.
@@ -106,8 +106,7 @@ void	(*ng_gif_detach_p)(struct ifnet *if
 static void	gif_start(struct ifnet *);
 static int	gif_clone_create(struct if_clone *, int, caddr_t);
 static void	gif_clone_destroy(struct ifnet *);
-
-IFC_SIMPLE_DECLARE(gif, 0);
+static struct if_clone *gif_cloner;
 
 static int gifmodevent(module_t, int, void *);
 
@@ -171,7 +170,7 @@ gif_clone_create(ifc, unit, params)
 	GIF_LOCK_INIT(sc);
 
 	GIF2IFP(sc)->if_softc = sc;
-	if_initname(GIF2IFP(sc), ifc->ifc_name, unit);
+	if_initname(GIF2IFP(sc), gifname, unit);
 
 	sc->encap_cookie4 = sc->encap_cookie6 = NULL;
 	sc->gif_options = GIF_ACCEPT_REVETHIP;
@@ -256,11 +255,12 @@ gifmodevent(mod, type, data)
 	switch (type) {
 	case MOD_LOAD:
 		mtx_init(&gif_mtx, "gif_mtx", NULL, MTX_DEF);
-		if_clone_attach(&gif_cloner);
+		gif_cloner = if_clone_simple(gifname, gif_clone_create,
+		    gif_clone_destroy, 0);
 		break;
 
 	case MOD_UNLOAD:
-		if_clone_detach(&gif_cloner);
+		if_clone_detach(gif_cloner);
 		mtx_destroy(&gif_mtx);
 		break;
 	default:

Modified: head/sys/net/if_gre.c
==============================================================================
--- head/sys/net/if_gre.c	Tue Oct 16 13:27:20 2012	(r241609)

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



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