Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

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


git-svn-id: svn+ssh://svn.freebsd.org/base/head@241610 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f
  • Loading branch information...
commit 3d5ac4ff2065c5a85ada4df30b352312aa6e2dd0 1 parent 47df79b
authored October 16, 2012
7  UPDATING
@@ -24,6 +24,13 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 10.x IS SLOW:
24 24
 	disable the most expensive debugging functionality run
25 25
 	"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
26 26
 
  27
+20121016:
  28
+	The interface cloning API and ABI has changed. The following
  29
+	modules need to be recompiled together with kernel:
  30
+	ipfw(4), pfsync(4), pflog(4), usb(4), wlan(4), stf(4),
  31
+	vlan(4), disc(4), edsc(4), if_bridge(4), gif(4), tap(4),
  32
+	faith(4), epair(4), enc(4), tun(4), if_lagg(4), gre(4).
  33
+
27 34
 20121015:
28 35
 	The sdhci driver was split in two parts: sdhci (generic SD Host
29 36
 	Controller logic) and sdhci_pci (actual hardware driver).
24  sys/dev/usb/usb_pf.c
@@ -60,8 +60,6 @@ __FBSDID("$FreeBSD$");
60 60
 #include <dev/usb/usb_pf.h>
61 61
 #include <dev/usb/usb_transfer.h>
62 62
 
63  
-#define	USBUSNAME	"usbus"
64  
-
65 63
 static void usbpf_init(void);
66 64
 static void usbpf_uninit(void);
67 65
 static int usbpf_ioctl(struct ifnet *, u_long, caddr_t);
@@ -74,9 +72,8 @@ static uint32_t usbpf_aggregate_status(struct usb_xfer_flags_int *);
74 72
 static int usbpf_xfer_frame_is_read(struct usb_xfer *, uint32_t);
75 73
 static uint32_t usbpf_xfer_precompute_size(struct usb_xfer *, int);
76 74
 
77  
-static struct if_clone usbpf_cloner = IFC_CLONE_INITIALIZER(
78  
-    USBUSNAME, NULL, IF_MAXUNIT,
79  
-    NULL, usbpf_clone_match, usbpf_clone_create, usbpf_clone_destroy);
  75
+static struct if_clone *usbpf_cloner;
  76
+static const char usbusname[] = "usbus";
80 77
 
81 78
 SYSINIT(usbpf_init, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, usbpf_init, NULL);
82 79
 SYSUNINIT(usbpf_uninit, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, usbpf_uninit, NULL);
@@ -85,7 +82,8 @@ static void
85 82
 usbpf_init(void)
86 83
 {
87 84
 
88  
-	if_clone_attach(&usbpf_cloner);
  85
+	usbpf_cloner = if_clone_advanced(usbusname, 0, usbpf_clone_match,
  86
+	    usbpf_clone_create, usbpf_clone_destroy);
89 87
 }
90 88
 
91 89
 static void
@@ -98,9 +96,9 @@ usbpf_uninit(void)
98 96
 	int error;
99 97
 	int i;
100 98
 	
101  
-	if_clone_detach(&usbpf_cloner);
  99
+	if_clone_detach(usbpf_cloner);
102 100
 
103  
-	dc = devclass_find(USBUSNAME);
  101
+	dc = devclass_find(usbusname);
104 102
 	if (dc == NULL)
105 103
 		return;
106 104
 	error = devclass_get_devices(dc, &devlp, &devlcnt);
@@ -109,7 +107,7 @@ usbpf_uninit(void)
109 107
 	for (i = 0; i < devlcnt; i++) {
110 108
 		ubus = device_get_softc(devlp[i]);
111 109
 		if (ubus != NULL && ubus->ifp != NULL)
112  
-			usbpf_clone_destroy(&usbpf_cloner, ubus->ifp);
  110
+			usbpf_clone_destroy(usbpf_cloner, ubus->ifp);
113 111
 	}
114 112
 	free(devlp, M_TEMP);
115 113
 }
@@ -130,12 +128,12 @@ usbpf_ifname2ubus(const char *ifname)
130 128
 	int unit;
131 129
 	int error;
132 130
 
133  
-	if (strncmp(ifname, USBUSNAME, sizeof(USBUSNAME) - 1) != 0)
  131
+	if (strncmp(ifname, usbusname, sizeof(usbusname) - 1) != 0)
134 132
 		return (NULL);
135 133
 	error = ifc_name2unit(ifname, &unit);
136 134
 	if (error || unit < 0)
137 135
 		return (NULL);
138  
-	dc = devclass_find(USBUSNAME);
  136
+	dc = devclass_find(usbusname);
139 137
 	if (dc == NULL)
140 138
 		return (NULL);
141 139
 	dev = devclass_get_device(dc, unit);
@@ -195,7 +193,7 @@ usbpf_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
195 193
 	}
196 194
 	strlcpy(ifp->if_xname, name, sizeof(ifp->if_xname));
197 195
 	ifp->if_softc = ubus;
198  
-	ifp->if_dname = ifc->ifc_name;
  196
+	ifp->if_dname = usbusname;
199 197
 	ifp->if_dunit = unit;
200 198
 	ifp->if_ioctl = usbpf_ioctl;
201 199
 	if_attach(ifp);
@@ -242,7 +240,7 @@ usbpf_detach(struct usb_bus *ubus)
242 240
 {
243 241
 
244 242
 	if (ubus->ifp != NULL)
245  
-		usbpf_clone_destroy(&usbpf_cloner, ubus->ifp);
  243
+		usbpf_clone_destroy(usbpf_cloner, ubus->ifp);
246 244
 	if (bootverbose)
247 245
 		device_printf(ubus->parent, "usbpf: Detached\n");
248 246
 }
10  sys/net/if_bridge.c
@@ -481,7 +481,8 @@ const int bridge_control_table_size =
481 481
 
482 482
 LIST_HEAD(, bridge_softc) bridge_list;
483 483
 
484  
-IFC_SIMPLE_DECLARE(bridge, 0);
  484
+static struct if_clone *bridge_cloner;
  485
+static const char bridge_name[] = "bridge";
485 486
 
486 487
 static int
487 488
 bridge_modevent(module_t mod, int type, void *data)
@@ -490,7 +491,8 @@ bridge_modevent(module_t mod, int type, void *data)
490 491
 	switch (type) {
491 492
 	case MOD_LOAD:
492 493
 		mtx_init(&bridge_list_mtx, "if_bridge list", NULL, MTX_DEF);
493  
-		if_clone_attach(&bridge_cloner);
  494
+		bridge_cloner = if_clone_simple(bridge_name,
  495
+		    bridge_clone_create, bridge_clone_destroy, 0);
494 496
 		bridge_rtnode_zone = uma_zcreate("bridge_rtnode",
495 497
 		    sizeof(struct bridge_rtnode), NULL, NULL, NULL, NULL,
496 498
 		    UMA_ALIGN_PTR, 0);
@@ -506,7 +508,7 @@ bridge_modevent(module_t mod, int type, void *data)
506 508
 	case MOD_UNLOAD:
507 509
 		EVENTHANDLER_DEREGISTER(ifnet_departure_event,
508 510
 		    bridge_detach_cookie);
509  
-		if_clone_detach(&bridge_cloner);
  511
+		if_clone_detach(bridge_cloner);
510 512
 		uma_zdestroy(bridge_rtnode_zone);
511 513
 		bridge_input_p = NULL;
512 514
 		bridge_output_p = NULL;
@@ -595,7 +597,7 @@ bridge_clone_create(struct if_clone *ifc, int unit, caddr_t params)
595 597
 	LIST_INIT(&sc->sc_spanlist);
596 598
 
597 599
 	ifp->if_softc = sc;
598  
-	if_initname(ifp, ifc->ifc_name, unit);
  600
+	if_initname(ifp, bridge_name, unit);
599 601
 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
600 602
 	ifp->if_ioctl = bridge_ioctl;
601 603
 	ifp->if_transmit = bridge_transmit;
224  sys/net/if_clone.c
... ...
@@ -1,4 +1,5 @@
1 1
 /*-
  2
+ * Copyright (c) 2012 Gleb Smirnoff <glebius@FreeBSD.org>
2 3
  * Copyright (c) 1980, 1986, 1993
3 4
  *	The Regents of the University of California.  All rights reserved.
4 5
  *
@@ -42,19 +43,65 @@
42 43
 
43 44
 #include <net/if.h>
44 45
 #include <net/if_clone.h>
45  
-#if 0
46  
-#include <net/if_dl.h>
47  
-#endif
48  
-#include <net/if_types.h>
49 46
 #include <net/if_var.h>
50 47
 #include <net/radix.h>
51 48
 #include <net/route.h>
52 49
 #include <net/vnet.h>
53 50
 
  51
+/* Current IF_MAXUNIT expands maximum to 5 characters. */
  52
+#define	IFCLOSIZ	(IFNAMSIZ - 5)
  53
+
  54
+/*
  55
+ * Structure describing a `cloning' interface.
  56
+ *
  57
+ * List of locks
  58
+ * (c)		const until freeing
  59
+ * (d)		driver specific data, may need external protection.
  60
+ * (e)		locked by if_cloners_mtx
  61
+ * (i)		locked by ifc_mtx mtx
  62
+ */
  63
+struct if_clone {
  64
+	char ifc_name[IFCLOSIZ];	/* (c) Name of device, e.g. `gif' */
  65
+	struct unrhdr *ifc_unrhdr;	/* (c) alloc_unr(9) header */
  66
+	int ifc_maxunit;		/* (c) maximum unit number */
  67
+	long ifc_refcnt;		/* (i) Reference count. */
  68
+	LIST_HEAD(, ifnet) ifc_iflist;	/* (i) List of cloned interfaces */
  69
+	struct mtx ifc_mtx;		/* Mutex to protect members. */
  70
+
  71
+	enum { SIMPLE, ADVANCED } ifc_type; /* (c) */
  72
+
  73
+	/* (c) Driver specific cloning functions.  Called with no locks held. */
  74
+	union {
  75
+		struct {	/* advanced cloner */
  76
+			ifc_match_t	*_ifc_match;
  77
+			ifc_create_t	*_ifc_create;
  78
+			ifc_destroy_t	*_ifc_destroy;
  79
+		} A;
  80
+		struct {	/* simple cloner */
  81
+			ifcs_create_t	*_ifcs_create;
  82
+			ifcs_destroy_t	*_ifcs_destroy;
  83
+			int		_ifcs_minifs;	/* minimum ifs */
  84
+
  85
+		} S;
  86
+	} U;
  87
+#define	ifc_match	U.A._ifc_match
  88
+#define	ifc_create	U.A._ifc_create
  89
+#define	ifc_destroy	U.A._ifc_destroy
  90
+#define	ifcs_create	U.S._ifcs_create
  91
+#define	ifcs_destroy	U.S._ifcs_destroy
  92
+#define	ifcs_minifs	U.S._ifcs_minifs
  93
+
  94
+	LIST_ENTRY(if_clone) ifc_list;	/* (e) On list of cloners */
  95
+};
  96
+
54 97
 static void	if_clone_free(struct if_clone *ifc);
55 98
 static int	if_clone_createif(struct if_clone *ifc, char *name, size_t len,
56 99
 		    caddr_t params);
57 100
 
  101
+static int     ifc_simple_match(struct if_clone *, const char *);
  102
+static int     ifc_simple_create(struct if_clone *, char *, size_t, caddr_t);
  103
+static int     ifc_simple_destroy(struct if_clone *, struct ifnet *);
  104
+
58 105
 static struct mtx	if_cloners_mtx;
59 106
 static VNET_DEFINE(int, if_cloners_count);
60 107
 VNET_DEFINE(LIST_HEAD(, if_clone), if_cloners);
@@ -138,18 +185,25 @@ if_clone_create(char *name, size_t len, caddr_t params)
138 185
 
139 186
 	/* Try to find an applicable cloner for this request */
140 187
 	IF_CLONERS_LOCK();
141  
-	LIST_FOREACH(ifc, &V_if_cloners, ifc_list) {
142  
-		if (ifc->ifc_match(ifc, name)) {
143  
-			break;
  188
+	LIST_FOREACH(ifc, &V_if_cloners, ifc_list)
  189
+		if (ifc->ifc_type == SIMPLE) {
  190
+			if (ifc_simple_match(ifc, name))
  191
+				break;
  192
+		} else {
  193
+			if (ifc->ifc_match(ifc, name))
  194
+				break;
144 195
 		}
145  
-	}
146 196
 #ifdef VIMAGE
147 197
 	if (ifc == NULL && !IS_DEFAULT_VNET(curvnet)) {
148 198
 		CURVNET_SET_QUIET(vnet0);
149  
-		LIST_FOREACH(ifc, &V_if_cloners, ifc_list) {
150  
-			if (ifc->ifc_match(ifc, name))
151  
-				break;
152  
-		}
  199
+		LIST_FOREACH(ifc, &V_if_cloners, ifc_list)
  200
+			if (ifc->ifc_type == SIMPLE) {
  201
+				if (ifc_simple_match(ifc, name))
  202
+					break;
  203
+			} else {
  204
+				if (ifc->ifc_match(ifc, name))
  205
+					break;
  206
+			}
153 207
 		CURVNET_RESTORE();
154 208
 	}
155 209
 #endif
@@ -173,7 +227,10 @@ if_clone_createif(struct if_clone *ifc, char *name, size_t len, caddr_t params)
173 227
 	if (ifunit(name) != NULL)
174 228
 		return (EEXIST);
175 229
 
176  
-	err = (*ifc->ifc_create)(ifc, name, len, params);
  230
+	if (ifc->ifc_type == SIMPLE)
  231
+		err = ifc_simple_create(ifc, name, len, params);
  232
+	else
  233
+		err = (*ifc->ifc_create)(ifc, name, len, params);
177 234
 	
178 235
 	if (!err) {
179 236
 		ifp = ifunit(name);
@@ -214,10 +271,14 @@ if_clone_destroy(const char *name)
214 271
 #ifdef VIMAGE
215 272
 	if (ifc == NULL && !IS_DEFAULT_VNET(curvnet)) {
216 273
 		CURVNET_SET_QUIET(vnet0);
217  
-		LIST_FOREACH(ifc, &V_if_cloners, ifc_list) {
218  
-			if (ifc->ifc_match(ifc, name))
219  
-				break;
220  
-		}
  274
+		LIST_FOREACH(ifc, &V_if_cloners, ifc_list)
  275
+			if (ifc->type == SIMPLE) {
  276
+				if (ifc_simple_match(ifc, name))
  277
+					break;
  278
+			} else {
  279
+				if (ifc->ifc_match(ifc, name))
  280
+					break;
  281
+			}
221 282
 		CURVNET_RESTORE();
222 283
 	}
223 284
 #endif
@@ -241,7 +302,7 @@ if_clone_destroyif(struct if_clone *ifc, struct ifnet *ifp)
241 302
 	int err;
242 303
 	struct ifnet *ifcifp;
243 304
 
244  
-	if (ifc->ifc_destroy == NULL)
  305
+	if (ifc->ifc_type == ADVANCED && ifc->ifc_destroy == NULL)
245 306
 		return(EOPNOTSUPP);
246 307
 
247 308
 	/*
@@ -266,7 +327,10 @@ if_clone_destroyif(struct if_clone *ifc, struct ifnet *ifp)
266 327
 
267 328
 	if_delgroup(ifp, ifc->ifc_name);
268 329
 
269  
-	err =  (*ifc->ifc_destroy)(ifc, ifp);
  330
+	if (ifc->ifc_type == SIMPLE)
  331
+		err = ifc_simple_destroy(ifc, ifp);
  332
+	else
  333
+		err = (*ifc->ifc_destroy)(ifc, ifp);
270 334
 
271 335
 	if (err != 0) {
272 336
 		if_addgroup(ifp, ifc->ifc_name);
@@ -279,21 +343,29 @@ if_clone_destroyif(struct if_clone *ifc, struct ifnet *ifp)
279 343
 	return (err);
280 344
 }
281 345
 
282  
-/*
283  
- * Register a network interface cloner.
284  
- */
285  
-int
286  
-if_clone_attach(struct if_clone *ifc)
  346
+static struct if_clone *
  347
+if_clone_alloc(const char *name, int maxunit)
287 348
 {
288  
-	struct if_clone *ifc1;
  349
+	struct if_clone *ifc;
289 350
 
290  
-	KASSERT(ifc->ifc_name != NULL, ("%s: no name\n", __func__));
  351
+	KASSERT(name != NULL, ("%s: no name\n", __func__));
291 352
 
  353
+	ifc = malloc(sizeof(struct if_clone), M_CLONE, M_WAITOK | M_ZERO);
  354
+	strncpy(ifc->ifc_name, name, IFCLOSIZ-1);
292 355
 	IF_CLONE_LOCK_INIT(ifc);
293 356
 	IF_CLONE_ADDREF(ifc);
  357
+	ifc->ifc_maxunit = maxunit ? maxunit : IF_MAXUNIT;
294 358
 	ifc->ifc_unrhdr = new_unrhdr(0, ifc->ifc_maxunit, &ifc->ifc_mtx);
295 359
 	LIST_INIT(&ifc->ifc_iflist);
296 360
 
  361
+	return (ifc);
  362
+}
  363
+	
  364
+static int
  365
+if_clone_attach(struct if_clone *ifc)
  366
+{
  367
+	struct if_clone *ifc1;
  368
+
297 369
 	IF_CLONERS_LOCK();
298 370
 	LIST_FOREACH(ifc1, &V_if_cloners, ifc_list)
299 371
 		if (strcmp(ifc->ifc_name, ifc1->ifc_name) == 0) {
@@ -305,11 +377,63 @@ if_clone_attach(struct if_clone *ifc)
305 377
 	V_if_cloners_count++;
306 378
 	IF_CLONERS_UNLOCK();
307 379
 
308  
-	if (ifc->ifc_attach != NULL)
309  
-		(*ifc->ifc_attach)(ifc);
  380
+	return (0);
  381
+}
  382
+
  383
+struct if_clone *
  384
+if_clone_advanced(const char *name, u_int maxunit, ifc_match_t match,
  385
+	ifc_create_t create, ifc_destroy_t destroy)
  386
+{
  387
+	struct if_clone *ifc;
  388
+
  389
+	ifc = if_clone_alloc(name, maxunit);
  390
+	ifc->ifc_type = ADVANCED;
  391
+	ifc->ifc_match = match;
  392
+	ifc->ifc_create = create;
  393
+	ifc->ifc_destroy = destroy;
  394
+
  395
+	if (if_clone_attach(ifc) != 0) {
  396
+		if_clone_free(ifc);
  397
+		return (NULL);
  398
+	}
  399
+
310 400
 	EVENTHANDLER_INVOKE(if_clone_event, ifc);
311 401
 
312  
-	return (0);
  402
+	return (ifc);
  403
+}
  404
+
  405
+struct if_clone *
  406
+if_clone_simple(const char *name, ifcs_create_t create, ifcs_destroy_t destroy,
  407
+	u_int minifs)
  408
+{
  409
+	struct if_clone *ifc;
  410
+	u_int unit;
  411
+
  412
+	ifc = if_clone_alloc(name, 0);
  413
+	ifc->ifc_type = SIMPLE;
  414
+	ifc->ifcs_create = create;
  415
+	ifc->ifcs_destroy = destroy;
  416
+	ifc->ifcs_minifs = minifs;
  417
+
  418
+	if (if_clone_attach(ifc) != 0) {
  419
+		if_clone_free(ifc);
  420
+		return (NULL);
  421
+	}
  422
+
  423
+	for (unit = 0; unit < minifs; unit++) {
  424
+		char name[IFNAMSIZ];
  425
+		int error;
  426
+
  427
+		snprintf(name, IFNAMSIZ, "%s%d", ifc->ifc_name, unit);
  428
+		error = if_clone_createif(ifc, name, IFNAMSIZ, NULL);
  429
+		KASSERT(error == 0,
  430
+		    ("%s: failed to create required interface %s",
  431
+		    __func__, name));
  432
+	}
  433
+
  434
+	EVENTHANDLER_INVOKE(if_clone_event, ifc);
  435
+
  436
+	return (ifc);
313 437
 }
314 438
 
315 439
 /*
@@ -318,7 +442,6 @@ if_clone_attach(struct if_clone *ifc)
318 442
 void
319 443
 if_clone_detach(struct if_clone *ifc)
320 444
 {
321  
-	struct ifc_simple_data *ifcs = ifc->ifc_data;
322 445
 
323 446
 	IF_CLONERS_LOCK();
324 447
 	LIST_REMOVE(ifc, ifc_list);
@@ -326,8 +449,8 @@ if_clone_detach(struct if_clone *ifc)
326 449
 	IF_CLONERS_UNLOCK();
327 450
 
328 451
 	/* Allow all simples to be destroyed */
329  
-	if (ifc->ifc_attach == ifc_simple_attach)
330  
-		ifcs->ifcs_minifs = 0;
  452
+	if (ifc->ifc_type == SIMPLE)
  453
+		ifc->ifcs_minifs = 0;
331 454
 
332 455
 	/* destroy all interfaces for this cloner */
333 456
 	while (!LIST_EMPTY(&ifc->ifc_iflist))
@@ -345,6 +468,7 @@ if_clone_free(struct if_clone *ifc)
345 468
 
346 469
 	IF_CLONE_LOCK_DESTROY(ifc);
347 470
 	delete_unrhdr(ifc->ifc_unrhdr);
  471
+	free(ifc, M_CLONE);
348 472
 }
349 473
 
350 474
 /*
@@ -483,29 +607,7 @@ ifc_free_unit(struct if_clone *ifc, int unit)
483 607
 	IF_CLONE_REMREF(ifc);
484 608
 }
485 609
 
486  
-void
487  
-ifc_simple_attach(struct if_clone *ifc)
488  
-{
489  
-	int err;
490  
-	int unit;
491  
-	char name[IFNAMSIZ];
492  
-	struct ifc_simple_data *ifcs = ifc->ifc_data;
493  
-
494  
-	KASSERT(ifcs->ifcs_minifs - 1 <= ifc->ifc_maxunit,
495  
-	    ("%s: %s requested more units than allowed (%d > %d)",
496  
-	    __func__, ifc->ifc_name, ifcs->ifcs_minifs,
497  
-	    ifc->ifc_maxunit + 1));
498  
-
499  
-	for (unit = 0; unit < ifcs->ifcs_minifs; unit++) {
500  
-		snprintf(name, IFNAMSIZ, "%s%d", ifc->ifc_name, unit);
501  
-		err = if_clone_createif(ifc, name, IFNAMSIZ, NULL);
502  
-		KASSERT(err == 0,
503  
-		    ("%s: failed to create required interface %s",
504  
-		    __func__, name));
505  
-	}
506  
-}
507  
-
508  
-int
  610
+static int
509 611
 ifc_simple_match(struct if_clone *ifc, const char *name)
510 612
 {
511 613
 	const char *cp;
@@ -526,14 +628,13 @@ ifc_simple_match(struct if_clone *ifc, const char *name)
526 628
 	return (1);
527 629
 }
528 630
 
529  
-int
  631
+static int
530 632
 ifc_simple_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
531 633
 {
532 634
 	char *dp;
533 635
 	int wildcard;
534 636
 	int unit;
535 637
 	int err;
536  
-	struct ifc_simple_data *ifcs = ifc->ifc_data;
537 638
 
538 639
 	err = ifc_name2unit(name, &unit);
539 640
 	if (err != 0)
@@ -545,7 +646,7 @@ ifc_simple_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
545 646
 	if (err != 0)
546 647
 		return (err);
547 648
 
548  
-	err = ifcs->ifcs_create(ifc, unit, params);
  649
+	err = ifc->ifcs_create(ifc, unit, params);
549 650
 	if (err != 0) {
550 651
 		ifc_free_unit(ifc, unit);
551 652
 		return (err);
@@ -569,18 +670,17 @@ ifc_simple_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
569 670
 	return (0);
570 671
 }
571 672
 
572  
-int
  673
+static int
573 674
 ifc_simple_destroy(struct if_clone *ifc, struct ifnet *ifp)
574 675
 {
575 676
 	int unit;
576  
-	struct ifc_simple_data *ifcs = ifc->ifc_data;
577 677
 
578 678
 	unit = ifp->if_dunit;
579 679
 
580  
-	if (unit < ifcs->ifcs_minifs) 
  680
+	if (unit < ifc->ifcs_minifs) 
581 681
 		return (EINVAL);
582 682
 
583  
-	ifcs->ifcs_destroy(ifp);
  683
+	ifc->ifcs_destroy(ifp);
584 684
 
585 685
 	ifc_free_unit(ifc, unit);
586 686
 
97  sys/net/if_clone.h
@@ -35,87 +35,42 @@
35 35
 
36 36
 #ifdef _KERNEL
37 37
 
38  
-#define IFC_CLONE_INITIALIZER(name, data, maxunit,			\
39  
-    attach, match, create, destroy)					\
40  
-    {									\
41  
-	.ifc_name = name,						\
42  
-	.ifc_maxunit = maxunit,						\
43  
-	.ifc_data = data,						\
44  
-	.ifc_attach = attach,						\
45  
-	.ifc_match = match,						\
46  
-	.ifc_create = create,						\
47  
-	.ifc_destroy = destroy,						\
48  
-    }
49  
-
50  
-/*
51  
- * Structure describing a `cloning' interface.
52  
- *
53  
- * List of locks
54  
- * (c)		const until freeing
55  
- * (d)		driver specific data, may need external protection.
56  
- * (e)		locked by if_cloners_mtx
57  
- * (i)		locked by ifc_mtx mtx
58  
- */
59  
-struct if_clone {
60  
-	LIST_ENTRY(if_clone) ifc_list;	/* (e) On list of cloners */
61  
-	const char *ifc_name;		/* (c) Name of device, e.g. `gif' */
62  
-	int ifc_maxunit;		/* (c) Maximum unit number */
63  
-	struct unrhdr *ifc_unrhdr;	/* (c) alloc_unr(9) header */
64  
-	void *ifc_data;			/* (*) Data for ifc_* functions. */
65  
-
66  
-	/* (c) Driver specific cloning functions.  Called with no locks held. */
67  
-	void	(*ifc_attach)(struct if_clone *);
68  
-	int	(*ifc_match)(struct if_clone *, const char *);
69  
-	int	(*ifc_create)(struct if_clone *, char *, size_t, caddr_t);
70  
-	int	(*ifc_destroy)(struct if_clone *, struct ifnet *);
71  
-
72  
-	long ifc_refcnt;		/* (i) Refrence count. */
73  
-	struct mtx ifc_mtx;		/* Mutex to protect members. */
74  
-	LIST_HEAD(, ifnet) ifc_iflist;	/* (i) List of cloned interfaces */
75  
-};
76  
-
77  
-void	if_clone_init(void);
78  
-int	if_clone_attach(struct if_clone *);
  38
+struct if_clone;
  39
+
  40
+/* Methods. */
  41
+typedef int	ifc_match_t(struct if_clone *, const char *);
  42
+typedef int	ifc_create_t(struct if_clone *, char *, size_t, caddr_t);
  43
+typedef int	ifc_destroy_t(struct if_clone *, struct ifnet *);
  44
+
  45
+typedef int	ifcs_create_t(struct if_clone *, int, caddr_t);
  46
+typedef void	ifcs_destroy_t(struct ifnet *);
  47
+
  48
+/* Interface cloner (de)allocating functions. */
  49
+struct if_clone *
  50
+	if_clone_advanced(const char *, u_int, ifc_match_t, ifc_create_t,
  51
+		      ifc_destroy_t);
  52
+struct if_clone *
  53
+	if_clone_simple(const char *, ifcs_create_t, ifcs_destroy_t, u_int);
79 54
 void	if_clone_detach(struct if_clone *);
80  
-void	vnet_if_clone_init(void);
81  
-
82  
-int	if_clone_create(char *, size_t, caddr_t);
83  
-int	if_clone_destroy(const char *);
84  
-int	if_clone_destroyif(struct if_clone *, struct ifnet *);
85  
-int	if_clone_list(struct if_clonereq *);
86 55
 
  56
+/* Unit (de)allocating fucntions. */
87 57
 int	ifc_name2unit(const char *name, int *unit);
88 58
 int	ifc_alloc_unit(struct if_clone *, int *);
89 59
 void	ifc_free_unit(struct if_clone *, int);
90 60
 
91  
-/*
92  
- * The ifc_simple functions, structures, and macros implement basic
93  
- * cloning as in 5.[012].
94  
- */
95  
-
96  
-struct ifc_simple_data {
97  
-	int ifcs_minifs;		/* minimum number of interfaces */
98  
-
99  
-	int	(*ifcs_create)(struct if_clone *, int, caddr_t);
100  
-	void	(*ifcs_destroy)(struct ifnet *);
101  
-};
102  
-
103  
-/* interface clone event */
  61
+/* Interface clone event. */
104 62
 typedef void (*if_clone_event_handler_t)(void *, struct if_clone *);
105 63
 EVENTHANDLER_DECLARE(if_clone_event, if_clone_event_handler_t);
106 64
 
107  
-#define IFC_SIMPLE_DECLARE(name, minifs)				\
108  
-struct ifc_simple_data name##_cloner_data =				\
109  
-    {minifs, name##_clone_create, name##_clone_destroy};		\
110  
-struct if_clone name##_cloner =						\
111  
-    IFC_CLONE_INITIALIZER(#name, &name##_cloner_data, IF_MAXUNIT,	\
112  
-    ifc_simple_attach, ifc_simple_match, ifc_simple_create, ifc_simple_destroy)
  65
+/* The below interfaces used only by net/if.c. */
  66
+void	if_clone_init(void);
  67
+void	vnet_if_clone_init(void);
  68
+int	if_clone_create(char *, size_t, caddr_t);
  69
+int	if_clone_destroy(const char *);
  70
+int	if_clone_list(struct if_clonereq *);
113 71
 
114  
-void	ifc_simple_attach(struct if_clone *);
115  
-int	ifc_simple_match(struct if_clone *, const char *);
116  
-int	ifc_simple_create(struct if_clone *, char *, size_t, caddr_t);
117  
-int	ifc_simple_destroy(struct if_clone *, struct ifnet *);
  72
+/* The below interface used only by epair(4). */
  73
+int	if_clone_destroyif(struct if_clone *, struct ifnet *);
118 74
 
119 75
 #endif /* _KERNEL */
120  
-
121 76
 #endif /* !_NET_IF_CLONE_H_ */
14  sys/net/if_disc.c
@@ -59,8 +59,6 @@
59 59
 #define DSMTU	65532
60 60
 #endif
61 61
 
62  
-#define DISCNAME	"disc"
63  
-
64 62
 struct disc_softc {
65 63
 	struct ifnet *sc_ifp;
66 64
 };
@@ -72,9 +70,10 @@ static int	discioctl(struct ifnet *, u_long, caddr_t);
72 70
 static int	disc_clone_create(struct if_clone *, int, caddr_t);
73 71
 static void	disc_clone_destroy(struct ifnet *);
74 72
 
75  
-static MALLOC_DEFINE(M_DISC, DISCNAME, "Discard interface");
  73
+static const char discname[] = "disc";
  74
+static MALLOC_DEFINE(M_DISC, discname, "Discard interface");
76 75
 
77  
-IFC_SIMPLE_DECLARE(disc, 0);
  76
+static struct if_clone *disc_cloner;
78 77
 
79 78
 static int
80 79
 disc_clone_create(struct if_clone *ifc, int unit, caddr_t params)
@@ -90,7 +89,7 @@ disc_clone_create(struct if_clone *ifc, int unit, caddr_t params)
90 89
 	}
91 90
 
92 91
 	ifp->if_softc = sc;
93  
-	if_initname(ifp, ifc->ifc_name, unit);
  92
+	if_initname(ifp, discname, unit);
94 93
 	ifp->if_mtu = DSMTU;
95 94
 	/*
96 95
 	 * IFF_LOOPBACK should not be removed from disc's flags because
@@ -135,10 +134,11 @@ disc_modevent(module_t mod, int type, void *data)
135 134
 
136 135
 	switch (type) {
137 136
 	case MOD_LOAD:
138  
-		if_clone_attach(&disc_cloner);
  137
+		disc_cloner = if_clone_simple(discname, disc_clone_create,
  138
+		    disc_clone_destroy, 0);
139 139
 		break;
140 140
 	case MOD_UNLOAD:
141  
-		if_clone_detach(&disc_cloner);
  141
+		if_clone_detach(disc_cloner);
142 142
 		break;
143 143
 	default:
144 144
 		return (EOPNOTSUPP);
27  sys/net/if_edsc.c
@@ -51,6 +51,8 @@
51 51
 #include <net/if_types.h>	/* IFT_ETHER and friends */
52 52
 #include <net/if_var.h>		/* kernel-only part of ifnet(9) */
53 53
 
  54
+static const char edscname[] = "edsc";
  55
+
54 56
 /*
55 57
  * Software configuration of an interface specific to this device type.
56 58
  */
@@ -64,9 +66,9 @@ struct edsc_softc {
64 66
 };
65 67
 
66 68
 /*
67  
- * Simple cloning methods.
68  
- * IFC_SIMPLE_DECLARE() expects precisely these names.
  69
+ * Attach to the interface cloning framework.
69 70
  */
  71
+static struct if_clone *edsc_cloner;
70 72
 static int	edsc_clone_create(struct if_clone *, int, caddr_t);
71 73
 static void	edsc_clone_destroy(struct ifnet *);
72 74
 
@@ -81,15 +83,7 @@ static void	edsc_start(struct ifnet *ifp);
81 83
 /*
82 84
  * We'll allocate softc instances from this.
83 85
  */
84  
-static		MALLOC_DEFINE(M_EDSC, "edsc", "Ethernet discard interface");
85  
-
86  
-/*
87  
- * Attach to the interface cloning framework under the name of "edsc".
88  
- * The second argument is the number of units to be created from
89  
- * the outset.  It's also the minimum number of units allowed.
90  
- * We don't want any units created as soon as the driver is loaded.
91  
- */
92  
-IFC_SIMPLE_DECLARE(edsc, 0);
  86
+static		MALLOC_DEFINE(M_EDSC, edscname, "Ethernet discard interface");
93 87
 
94 88
 /*
95 89
  * Create an interface instance.
@@ -116,7 +110,7 @@ edsc_clone_create(struct if_clone *ifc, int unit, caddr_t params)
116 110
 	/*
117 111
 	 * Get a name for this particular interface in its ifnet structure.
118 112
 	 */
119  
-	if_initname(ifp, ifc->ifc_name, unit);
  113
+	if_initname(ifp, edscname, unit);
120 114
 
121 115
 	/*
122 116
 	 * Typical Ethernet interface flags: we can do broadcast and
@@ -323,8 +317,13 @@ edsc_modevent(module_t mod, int type, void *data)
323 317
 	case MOD_LOAD:
324 318
 		/*
325 319
 		 * Connect to the network interface cloning framework.
  320
+		 * The last argument is the number of units to be created
  321
+		 * from the outset.  It's also the minimum number of units
  322
+		 * allowed.  We don't want any units created as soon as the
  323
+		 * driver is loaded.
326 324
 		 */
327  
-		if_clone_attach(&edsc_cloner);
  325
+		edsc_cloner = if_clone_simple(edscname, edsc_clone_create,
  326
+		    edsc_clone_destroy, 0);
328 327
 		break;
329 328
 
330 329
 	case MOD_UNLOAD:
@@ -332,7 +331,7 @@ edsc_modevent(module_t mod, int type, void *data)
332 331
 		 * Disconnect from the cloning framework.
333 332
 		 * Existing interfaces will be disposed of properly.
334 333
 		 */
335  
-		if_clone_detach(&edsc_cloner);
  334
+		if_clone_detach(edsc_cloner);
336 335
 		break;
337 336
 
338 337
 	default:
9  sys/net/if_enc.c
@@ -91,8 +91,8 @@ static int	enc_output(struct ifnet *ifp, struct mbuf *m,
91 91
 		    struct sockaddr *dst, struct route *ro);
92 92
 static int	enc_clone_create(struct if_clone *, int, caddr_t);
93 93
 static void	enc_clone_destroy(struct ifnet *);
94  
-
95  
-IFC_SIMPLE_DECLARE(enc, 1);
  94
+static struct if_clone *enc_cloner;
  95
+static const char encname[] = "enc";
96 96
 
97 97
 /*
98 98
  * Sysctls.
@@ -143,7 +143,7 @@ enc_clone_create(struct if_clone *ifc, int unit, caddr_t params)
143 143
 		return (ENOSPC);
144 144
 	}
145 145
 
146  
-	if_initname(ifp, ifc->ifc_name, unit);
  146
+	if_initname(ifp, encname, unit);
147 147
 	ifp->if_mtu = ENCMTU;
148 148
 	ifp->if_ioctl = enc_ioctl;
149 149
 	ifp->if_output = enc_output;
@@ -167,7 +167,8 @@ enc_modevent(module_t mod, int type, void *data)
167 167
 	switch (type) {
168 168
 	case MOD_LOAD:
169 169
 		mtx_init(&enc_mtx, "enc mtx", NULL, MTX_DEF);
170  
-		if_clone_attach(&enc_cloner);
  170
+		enc_cloner = if_clone_simple(encname, enc_clone_create,
  171
+		    enc_clone_destroy, 0);
171 172
 		break;
172 173
 	case MOD_UNLOAD:
173 174
 		printf("enc module unload - not possible for this module\n");
35  sys/net/if_epair.c
@@ -72,8 +72,6 @@ __FBSDID("$FreeBSD$");
72 72
 #include <net/netisr.h>
73 73
 #include <net/vnet.h>
74 74
 
75  
-#define	EPAIRNAME	"epair"
76  
-
77 75
 SYSCTL_DECL(_net_link);
78 76
 static SYSCTL_NODE(_net_link, OID_AUTO, epair, CTLFLAG_RW, 0, "epair sysctl");
79 77
 
@@ -100,9 +98,11 @@ static int epair_clone_match(struct if_clone *, const char *);
100 98
 static int epair_clone_create(struct if_clone *, char *, size_t, caddr_t);
101 99
 static int epair_clone_destroy(struct if_clone *, struct ifnet *);
102 100
 
  101
+static const char epairname[] = "epair";
  102
+
103 103
 /* Netisr realted definitions and sysctl. */
104 104
 static struct netisr_handler epair_nh = {
105  
-	.nh_name	= EPAIRNAME,
  105
+	.nh_name	= epairname,
106 106
 	.nh_proto	= NETISR_EPAIR,
107 107
 	.nh_policy	= NETISR_POLICY_CPU,
108 108
 	.nh_handler	= epair_nh_sintr,
@@ -168,12 +168,10 @@ STAILQ_HEAD(eid_list, epair_ifp_drain);
168 168
 #define	EPAIR_REFCOUNT_ASSERT(a, p)
169 169
 #endif
170 170
 
171  
-static MALLOC_DEFINE(M_EPAIR, EPAIRNAME,
  171
+static MALLOC_DEFINE(M_EPAIR, epairname,
172 172
     "Pair of virtual cross-over connected Ethernet-like interfaces");
173 173
 
174  
-static struct if_clone epair_cloner = IFC_CLONE_INITIALIZER(
175  
-    EPAIRNAME, NULL, IF_MAXUNIT,
176  
-    NULL, epair_clone_match, epair_clone_create, epair_clone_destroy);
  174
+static struct if_clone *epair_cloner;
177 175
 
178 176
 /*
179 177
  * DPCPU area and functions.
@@ -692,10 +690,10 @@ epair_clone_match(struct if_clone *ifc, const char *name)
692 690
 	 * - epair<n>
693 691
 	 * but not the epair<n>[ab] versions.
694 692
 	 */
695  
-	if (strncmp(EPAIRNAME, name, sizeof(EPAIRNAME)-1) != 0)
  693
+	if (strncmp(epairname, name, sizeof(epairname)-1) != 0)
696 694
 		return (0);
697 695
 
698  
-	for (cp = name + sizeof(EPAIRNAME) - 1; *cp != '\0'; cp++) {
  696
+	for (cp = name + sizeof(epairname) - 1; *cp != '\0'; cp++) {
699 697
 		if (*cp < '0' || *cp > '9')
700 698
 			return (0);
701 699
 	}
@@ -714,7 +712,7 @@ epair_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
714 712
 
715 713
 	/*
716 714
 	 * We are abusing params to create our second interface.
717  
-	 * Actually we already created it and called if_clone_createif()
  715
+	 * Actually we already created it and called if_clone_create()
718 716
 	 * for it to do the official insertion procedure the moment we knew
719 717
 	 * it cannot fail anymore. So just do attach it here.
720 718
 	 */
@@ -807,7 +805,7 @@ epair_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
807 805
 	ifp = sca->ifp;
808 806
 	ifp->if_softc = sca;
809 807
 	strlcpy(ifp->if_xname, name, IFNAMSIZ);
810  
-	ifp->if_dname = ifc->ifc_name;
  808
+	ifp->if_dname = epairname;
811 809
 	ifp->if_dunit = unit;
812 810
 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
813 811
 	ifp->if_capabilities = IFCAP_VLAN_MTU;
@@ -833,7 +831,7 @@ epair_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
833 831
 	ifp = scb->ifp;
834 832
 	ifp->if_softc = scb;
835 833
 	strlcpy(ifp->if_xname, name, IFNAMSIZ);
836  
-	ifp->if_dname = ifc->ifc_name;
  834
+	ifp->if_dname = epairname;
837 835
 	ifp->if_dunit = unit;
838 836
 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
839 837
 	ifp->if_capabilities = IFCAP_VLAN_MTU;
@@ -843,10 +841,10 @@ epair_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
843 841
 	ifp->if_init  = epair_init;
844 842
 	ifp->if_snd.ifq_maxlen = ifqmaxlen;
845 843
 	/* We need to play some tricks here for the second interface. */
846  
-	strlcpy(name, EPAIRNAME, len);
  844
+	strlcpy(name, epairname, len);
847 845
 	error = if_clone_create(name, len, (caddr_t)scb);
848 846
 	if (error)
849  
-		panic("%s: if_clone_createif() for our 2nd iface failed: %d",
  847
+		panic("%s: if_clone_create() for our 2nd iface failed: %d",
850 848
 		    __func__, error);
851 849
 	scb->if_qflush = ifp->if_qflush;
852 850
 	ifp->if_qflush = epair_qflush;
@@ -958,16 +956,17 @@ epair_modevent(module_t mod, int type, void *data)
958 956
 		if (TUNABLE_INT_FETCH("net.link.epair.netisr_maxqlen", &qlimit))
959 957
 		    epair_nh.nh_qlimit = qlimit;
960 958
 		netisr_register(&epair_nh);
961  
-		if_clone_attach(&epair_cloner);
  959
+		epair_cloner = if_clone_advanced(epairname, 0,
  960
+		    epair_clone_match, epair_clone_create, epair_clone_destroy);
962 961
 		if (bootverbose)
963  
-			printf("%s initialized.\n", EPAIRNAME);
  962
+			printf("%s initialized.\n", epairname);
964 963
 		break;
965 964
 	case MOD_UNLOAD:
966  
-		if_clone_detach(&epair_cloner);
  965
+		if_clone_detach(epair_cloner);
967 966
 		netisr_unregister(&epair_nh);
968 967
 		epair_dpcpu_detach();
969 968
 		if (bootverbose)
970  
-			printf("%s unloaded.\n", EPAIRNAME);
  969
+			printf("%s unloaded.\n", epairname);
971 970
 		break;
972 971
 	default:
973 972
 		return (EOPNOTSUPP);
16  sys/net/if_faith.c
@@ -79,8 +79,6 @@
79 79
 #include <netinet6/ip6_var.h>
80 80
 #endif
81 81
 
82  
-#define FAITHNAME	"faith"
83  
-
84 82
 struct faith_softc {
85 83
 	struct ifnet *sc_ifp;
86 84
 };
@@ -95,12 +93,12 @@ static int faithprefix(struct in6_addr *);
95 93
 
96 94
 static int faithmodevent(module_t, int, void *);
97 95
 
98  
-static MALLOC_DEFINE(M_FAITH, FAITHNAME, "Firewall Assisted Tunnel Interface");
  96
+static const char faithname[] = "faith";
  97
+static MALLOC_DEFINE(M_FAITH, faithname, "Firewall Assisted Tunnel Interface");
99 98
 
100 99
 static int	faith_clone_create(struct if_clone *, int, caddr_t);
101 100
 static void	faith_clone_destroy(struct ifnet *);
102  
-
103  
-IFC_SIMPLE_DECLARE(faith, 0);
  101
+static struct if_clone *faith_cloner;
104 102
 
105 103
 #define	FAITHMTU	1500
106 104
 
@@ -113,8 +111,8 @@ faithmodevent(mod, type, data)
113 111
 
114 112
 	switch (type) {
115 113
 	case MOD_LOAD:
116  
-		if_clone_attach(&faith_cloner);
117  
-
  114
+		faith_cloner = if_clone_simple(faithname, faith_clone_create,
  115
+		    faith_clone_destroy, 0);
118 116
 #ifdef INET6
119 117
 		faithprefix_p = faithprefix;
120 118
 #endif
@@ -125,7 +123,7 @@ faithmodevent(mod, type, data)
125 123
 		faithprefix_p = NULL;
126 124
 #endif
127 125
 
128  
-		if_clone_detach(&faith_cloner);
  126
+		if_clone_detach(faith_cloner);
129 127
 		break;
130 128
 	default:
131 129
 		return EOPNOTSUPP;
@@ -159,7 +157,7 @@ faith_clone_create(ifc, unit, params)
159 157
 	}
160 158
 
161 159
 	ifp->if_softc = sc;
162  
-	if_initname(sc->sc_ifp, ifc->ifc_name, unit);
  160
+	if_initname(sc->sc_ifp, faithname, unit);
163 161
 
164 162
 	ifp->if_mtu = FAITHMTU;
165 163
 	/* Change to BROADCAST experimentaly to announce its prefix. */
12  sys/net/if_gif.c
@@ -88,7 +88,7 @@
88 88
 
89 89
 #include <security/mac/mac_framework.h>
90 90
 
91  
-#define GIFNAME		"gif"
  91
+static const char gifname[] = "gif";
92 92
 
93 93
 /*
94 94
  * gif_mtx protects the global gif_softc_list.
@@ -106,8 +106,7 @@ void	(*ng_gif_detach_p)(struct ifnet *ifp);
106 106
 static void	gif_start(struct ifnet *);
107 107
 static int	gif_clone_create(struct if_clone *, int, caddr_t);
108 108
 static void	gif_clone_destroy(struct ifnet *);
109  
-
110  
-IFC_SIMPLE_DECLARE(gif, 0);
  109
+static struct if_clone *gif_cloner;
111 110
 
112 111
 static int gifmodevent(module_t, int, void *);
113 112
 
@@ -171,7 +170,7 @@ gif_clone_create(ifc, unit, params)
171 170
 	GIF_LOCK_INIT(sc);
172 171
 
173 172
 	GIF2IFP(sc)->if_softc = sc;
174  
-	if_initname(GIF2IFP(sc), ifc->ifc_name, unit);
  173
+	if_initname(GIF2IFP(sc), gifname, unit);
175 174
 
176 175
 	sc->encap_cookie4 = sc->encap_cookie6 = NULL;
177 176
 	sc->gif_options = GIF_ACCEPT_REVETHIP;
@@ -256,11 +255,12 @@ gifmodevent(mod, type, data)
256 255
 	switch (type) {
257 256
 	case MOD_LOAD:
258 257
 		mtx_init(&gif_mtx, "gif_mtx", NULL, MTX_DEF);
259  
-		if_clone_attach(&gif_cloner);
  258
+		gif_cloner = if_clone_simple(gifname, gif_clone_create,
  259
+		    gif_clone_destroy, 0);
260 260
 		break;
261 261
 
262 262
 	case MOD_UNLOAD:
263  
-		if_clone_detach(&gif_cloner);
  263
+		if_clone_detach(gif_cloner);
264 264
 		mtx_destroy(&gif_mtx);
265 265
 		break;
266 266
 	default:
16  sys/net/if_gre.c
@@ -90,8 +90,6 @@
90 90
  */
91 91
 #define GREMTU	1476
92 92
 
93  
-#define GRENAME	"gre"
94  
-
95 93
 #define	MTAG_COOKIE_GRE		1307983903
96 94
 #define	MTAG_GRE_NESTING	1
97 95
 struct mtag_gre_nesting {
@@ -105,18 +103,19 @@ struct mtag_gre_nesting {
105 103
  * XXX: gre_softc data not protected yet.
106 104
  */
107 105
 struct mtx gre_mtx;
108  
-static MALLOC_DEFINE(M_GRE, GRENAME, "Generic Routing Encapsulation");
  106
+static const char grename[] = "gre";
  107
+static MALLOC_DEFINE(M_GRE, grename, "Generic Routing Encapsulation");
109 108
 
110 109
 struct gre_softc_head gre_softc_list;
111 110
 
112 111
 static int	gre_clone_create(struct if_clone *, int, caddr_t);
113 112
 static void	gre_clone_destroy(struct ifnet *);
  113
+static struct if_clone *gre_cloner;
  114
+
114 115
 static int	gre_ioctl(struct ifnet *, u_long, caddr_t);
115 116
 static int	gre_output(struct ifnet *, struct mbuf *, struct sockaddr *,
116 117
 		    struct route *ro);
117 118
 
118  
-IFC_SIMPLE_DECLARE(gre, 0);
119  
-
120 119
 static int gre_compute_route(struct gre_softc *sc);
121 120
 
122 121
 static void	greattach(void);
@@ -172,7 +171,8 @@ greattach(void)
172 171
 
173 172
 	mtx_init(&gre_mtx, "gre_mtx", NULL, MTX_DEF);
174 173
 	LIST_INIT(&gre_softc_list);
175  
-	if_clone_attach(&gre_cloner);
  174
+	gre_cloner = if_clone_simple(grename, gre_clone_create,
  175
+	    gre_clone_destroy, 0);
176 176
 }
177 177
 
178 178
 static int
@@ -192,7 +192,7 @@ gre_clone_create(ifc, unit, params)
192 192
 	}
193 193
 
194 194
 	GRE2IFP(sc)->if_softc = sc;
195  
-	if_initname(GRE2IFP(sc), ifc->ifc_name, unit);
  195
+	if_initname(GRE2IFP(sc), grename, unit);
196 196
 
197 197
 	GRE2IFP(sc)->if_snd.ifq_maxlen = ifqmaxlen;
198 198
 	GRE2IFP(sc)->if_addrlen = 0;
@@ -961,7 +961,7 @@ gremodevent(module_t mod, int type, void *data)
961 961
 		greattach();
962 962
 		break;
963 963
 	case MOD_UNLOAD:
964  
-		if_clone_detach(&gre_cloner);
  964
+		if_clone_detach(gre_cloner);
965 965
 		mtx_destroy(&gre_mtx);
966 966
 		break;
967 967
 	default:
12  sys/net/if_lagg.c
@@ -85,6 +85,9 @@ eventhandler_tag	lagg_detach_cookie = NULL;
85 85
 
86 86
 static int	lagg_clone_create(struct if_clone *, int, caddr_t);
87 87
 static void	lagg_clone_destroy(struct ifnet *);
  88
+static struct if_clone *lagg_cloner;
  89
+static const char laggname[] = "lagg";
  90
+
88 91
 static void	lagg_lladdr(struct lagg_softc *, uint8_t *);
89 92
 static void	lagg_capabilities(struct lagg_softc *);
90 93
 static void	lagg_port_lladdr(struct lagg_port *, uint8_t *);
@@ -118,8 +121,6 @@ static struct lagg_port *lagg_link_active(struct lagg_softc *,
118 121
 	    struct lagg_port *);
119 122
 static const void *lagg_gethdr(struct mbuf *, u_int, u_int, void *);
120 123
 
121  
-IFC_SIMPLE_DECLARE(lagg, 0);
122  
-
123 124
 /* Simple round robin */
124 125
 static int	lagg_rr_attach(struct lagg_softc *);
125 126
 static int	lagg_rr_detach(struct lagg_softc *);
@@ -187,7 +188,8 @@ lagg_modevent(module_t mod, int type, void *data)
187 188
 	case MOD_LOAD:
188 189
 		mtx_init(&lagg_list_mtx, "if_lagg list", NULL, MTX_DEF);
189 190
 		SLIST_INIT(&lagg_list);
190  
-		if_clone_attach(&lagg_cloner);
  191
+		lagg_cloner = if_clone_simple(laggname, lagg_clone_create,
  192
+		    lagg_clone_destroy, 0);
191 193
 		lagg_input_p = lagg_input;
192 194
 		lagg_linkstate_p = lagg_port_state;
193 195
 		lagg_detach_cookie = EVENTHANDLER_REGISTER(
@@ -197,7 +199,7 @@ lagg_modevent(module_t mod, int type, void *data)
197 199
 	case MOD_UNLOAD:
198 200
 		EVENTHANDLER_DEREGISTER(ifnet_departure_event,
199 201
 		    lagg_detach_cookie);
200  
-		if_clone_detach(&lagg_cloner);
  202
+		if_clone_detach(lagg_cloner);
201 203
 		lagg_input_p = NULL;
202 204
 		lagg_linkstate_p = NULL;
203 205
 		mtx_destroy(&lagg_list_mtx);
@@ -311,7 +313,7 @@ lagg_clone_create(struct if_clone *ifc, int unit, caddr_t params)
311 313
 	ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_AUTO, 0, NULL);
312 314
 	ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_AUTO);
313 315
 
314  
-	if_initname(ifp, ifc->ifc_name, unit);
  316
+	if_initname(ifp, laggname, unit);
315 317
 	ifp->if_softc = sc;
316 318
 	ifp->if_transmit = lagg_transmit;
317 319
 	ifp->if_qflush = lagg_qflush;
19  sys/net/if_loop.c
@@ -108,13 +108,12 @@ static void	lo_clone_destroy(struct ifnet *);
108 108
 VNET_DEFINE(struct ifnet *, loif);	/* Used externally */
109 109
 
110 110
 #ifdef VIMAGE
111  
-static VNET_DEFINE(struct ifc_simple_data, lo_cloner_data);
112  
-static VNET_DEFINE(struct if_clone, lo_cloner);
113  
-#define	V_lo_cloner_data	VNET(lo_cloner_data)
  111
+static VNET_DEFINE(struct if_clone *, lo_cloner);
114 112
 #define	V_lo_cloner		VNET(lo_cloner)
115 113
 #endif
116 114
 
117  
-IFC_SIMPLE_DECLARE(lo, 1);
  115
+static struct if_clone *lo_cloner;
  116
+static const char loname[] = "lo";
118 117
 
119 118
 static void
120 119
 lo_clone_destroy(struct ifnet *ifp)
@@ -139,7 +138,7 @@ lo_clone_create(struct if_clone *ifc, int unit, caddr_t params)
139 138
 	if (ifp == NULL)
140 139
 		return (ENOSPC);
141 140
 
142  
-	if_initname(ifp, ifc->ifc_name, unit);
  141
+	if_initname(ifp, loname, unit);
143 142
 	ifp->if_mtu = LOMTU;
144 143
 	ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST;
145 144
 	ifp->if_ioctl = loioctl;
@@ -161,12 +160,12 @@ vnet_loif_init(const void *unused __unused)
161 160
 {
162 161
 
163 162
 #ifdef VIMAGE
  163
+	lo_cloner = if_clone_simple(loname, lo_clone_create, lo_clone_destroy,
  164
+	    1);
164 165
 	V_lo_cloner = lo_cloner;
165  
-	V_lo_cloner_data = lo_cloner_data;
166  
-	V_lo_cloner.ifc_data = &V_lo_cloner_data;
167  
-	if_clone_attach(&V_lo_cloner);
168 166
 #else
169  
-	if_clone_attach(&lo_cloner);
  167
+	lo_cloner = if_clone_simple(loname, lo_clone_create, lo_clone_destroy,
  168
+	    1);
170 169
 #endif
171 170
 }
172 171
 VNET_SYSINIT(vnet_loif_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
@@ -177,7 +176,7 @@ static void
177 176
 vnet_loif_uninit(const void *unused __unused)
178 177
 {
179 178
 
180  
-	if_clone_detach(&V_lo_cloner);
  179
+	if_clone_detach(V_lo_cloner);
181 180
 	V_loif = NULL;
182 181
 }
183 182
 VNET_SYSUNINIT(vnet_loif_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
15  sys/net/if_stf.c
@@ -127,7 +127,6 @@ static int stf_route_cache = 1;
127 127
 SYSCTL_INT(_net_link_stf, OID_AUTO, route_cache, CTLFLAG_RW,
128 128
     &stf_route_cache, 0, "Caching of IPv4 routes for 6to4 Output");
129 129
 
130  
-#define STFNAME		"stf"
131 130
 #define STFUNIT		0
132 131
 
133 132
 #define IN6_IS_ADDR_6TO4(x)	(ntohs((x)->s6_addr16[0]) == 0x2002)
@@ -151,11 +150,13 @@ struct stf_softc {