Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 6 Mar 2002 22:22:49 +0100
From:      Maxime Henrion <mux@FreeBSD.org>
To:        freebsd-net@FreeBSD.org
Subject:   [CFR] Patch for clonable interfaces
Message-ID:  <20020306212249.GC2371@nebula.noos.fr>

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

--k+w/mQv8wyuph6w0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

	Hi,


Currently, every clonable interface which uses the if_clone_*()
framework has a chunk of duplicated rman code to handle unit allocation.
This is exactly the same code in every clonable interface driver.
Moreover, this code is only used in the case of a "wildcard" creation,
i.e. when the user does "ifconfig gif create" without specifying an unit
number.  The other necessary checks (to not create an already-existing
interface, or to not remove a non-existing one) are already done in the
generic layer.

The intent of this patch is to move all the unit allocation code into
the generic layer to avoid all the duplicated code.  This code doesn't
use rman, for several reasons.  First, rman returns a struct resource *
pointer for every unit allocated, which has to be stored somewhere in
order to deallocate the unit later.  This is problematic since the
generic layer doesn't maintain per-clone structures, so it would have to
pass it down to the interface-dependant code and have it store it for
us, or to maintain another set of per-clone structures.  Both solutions
are gross and really unbeautiful.  Second, rman can fail and return an
error, but our if_clone_{attach,detach} functions are void at the
moment and cannot fail.

That's why I chosed to implement unit allocation using a bitmap.  It's
fast, and much cleaner than rman here.  It also allows us to keep our
if_clone_{attach,detach} functions void.  The current code has only one
problem that I know of, it's not very space-efficient.  The driver
passes the maximum allowed unit number to the generic code and thus
avoid allocation a big bitmap if the interface wants only one clone
(e.g. if_stf), but most drivers will pass IF_MAXUNIT (0x7fff) which
requires a 4K bitmap.  A future improvement could be to allocate chunks
of bitmaps on demand rather than one big bitmap, but I'm not sure if it's
really needed.

Note that having the unit management code into the generic layer implies
that you can't bypass it, otherwise it would result in bitmaps
inconsistencies.  However, it is still OK to call the foo_clone_destroy()
functions directly at module unload, unless I'm missing something here
:-)

Any reviews or comments are appreciated.

Thanks,
Maxime

--k+w/mQv8wyuph6w0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="net.patch"

Index: if.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if.c,v
retrieving revision 1.132
diff -u -r1.132 if.c
--- if.c	5 Mar 2002 17:50:35 -0000	1.132
+++ if.c	6 Mar 2002 19:45:54 -0000
@@ -119,6 +119,7 @@
 
 MALLOC_DEFINE(M_IFADDR, "ifaddr", "interface address");
 MALLOC_DEFINE(M_IFMADDR, "ether_multi", "link-level multicast address");
+MALLOC_DEFINE(M_CLONE, "clone", "interface cloning framework");
 
 #define CDEV_MAJOR	165
 
@@ -580,7 +581,7 @@
 {
 	struct if_clone *ifc;
 	char *dp;
-	int wildcard;
+	int wildcard, bytoff, bitoff;
 	int unit;
 	int err;
 
@@ -591,12 +592,41 @@
 	if (ifunit(name) != NULL)
 		return (EEXIST);
 
+	bytoff = bitoff = 0;
 	wildcard = (unit < 0);
+	/*
+	 * Find a free unit if none was given.
+	 */ 
+	if (wildcard) {
+		while ((bytoff < ifc->ifc_bmlen)
+		    && (ifc->ifc_units[bytoff] == 0xff))
+			bytoff++;
+		if (bytoff >= ifc->ifc_bmlen)
+			return (ENOSPC);
+		while ((ifc->ifc_units[bytoff] & (1 << bitoff)) != 0)
+			bitoff++;
+		unit = (bytoff << 3) + bitoff;
+	}
+
+	if (unit > ifc->ifc_maxunit)
+		return (ENXIO);
 
-	err = (*ifc->ifc_create)(ifc, &unit);
+	err = (*ifc->ifc_create)(ifc, unit);
 	if (err != 0)
 		return (err);
 
+	if (!wildcard) {
+		bytoff = unit >> 3;
+		bitoff = unit - (bytoff << 3);
+	}
+
+	/*
+	 * Allocate the unit in the bitmap.
+	 */
+	KASSERT((ifc->ifc_units[bytoff] & (1 << bitoff)) == 0,
+	    ("%s: bit is already set", __func__));
+	ifc->ifc_units[bytoff] |= (1 << bitoff);
+
 	/* In the wildcard case, we need to update the name. */
 	if (wildcard) {
 		for (dp = name; *dp != '\0'; dp++);
@@ -624,8 +654,10 @@
 {
 	struct if_clone *ifc;
 	struct ifnet *ifp;
+	int bytoff, bitoff;
+	int err, unit;
 
-	ifc = if_clone_lookup(name, NULL);
+	ifc = if_clone_lookup(name, &unit);
 	if (ifc == NULL)
 		return (EINVAL);
 
@@ -636,7 +668,19 @@
 	if (ifc->ifc_destroy == NULL)
 		return (EOPNOTSUPP);
 
-	return ((*ifc->ifc_destroy)(ifp));
+	err = (*ifc->ifc_destroy)(ifp);
+	if (err != 0)
+		return (err);
+
+	/*
+	 * Compute offset in the bitmap and deallocate the unit.
+	 */
+	bytoff = unit >> 3;
+	bitoff = unit - (bytoff << 3);
+	KASSERT((ifc->ifc_units[bytoff] & (1 << bitoff)) != 0,
+	    ("%s: bit is already cleared", __func__));
+	ifc->ifc_units[bytoff] &= ~(1 << bitoff);
+	return (0);
 }
 
 /*
@@ -689,7 +733,17 @@
 if_clone_attach(ifc)
 	struct if_clone *ifc;
 {
+	int len, maxclone;
 
+	/*
+	 * Compute bitmap size and allocate it.
+	 */
+	maxclone = ifc->ifc_maxunit + 1;
+	len = maxclone >> 3;
+	if ((len << 3) < maxclone)
+		len++;
+	ifc->ifc_units = malloc(len, M_CLONE, M_WAITOK | M_ZERO);
+	ifc->ifc_bmlen = len;
 	LIST_INSERT_HEAD(&if_cloners, ifc, ifc_list);
 	if_cloners_count++;
 }
@@ -703,6 +757,7 @@
 {
 
 	LIST_REMOVE(ifc, ifc_list);
+	free(ifc->ifc_units, M_CLONE);
 	if_cloners_count--;
 }
 
Index: if.h
===================================================================
RCS file: /home/ncvs/src/sys/net/if.h,v
retrieving revision 1.69
diff -u -r1.69 if.h
--- if.h	4 Mar 2002 21:43:49 -0000	1.69
+++ if.h	6 Mar 2002 11:58:06 -0000
@@ -55,6 +55,7 @@
  */
 #define		IFNAMSIZ	16
 #define		IF_NAMESIZE	IFNAMSIZ
+#define		IF_MAXUNIT	0x7fff	/* ifp->if_unit is only 15 bits */
 
 /*
  * Structure describing a `cloning' interface.
@@ -63,13 +64,16 @@
 	LIST_ENTRY(if_clone) ifc_list;	/* on list of cloners */
 	const char *ifc_name;		/* name of device, e.g. `gif' */
 	size_t ifc_namelen;		/* length of name */
+	int ifc_maxunit;		/* maximum unit number */
+	unsigned char *ifc_units;	/* bitmap to handle units */
+	int ifc_bmlen;			/* bitmap length */
 
-	int	(*ifc_create)(struct if_clone *, int *);
+	int	(*ifc_create)(struct if_clone *, int);
 	int	(*ifc_destroy)(struct ifnet *);
 };
 
-#define IF_CLONE_INITIALIZER(name, create, destroy)			\
-	{ { 0 }, name, sizeof(name) - 1, create, destroy }
+#define IF_CLONE_INITIALIZER(name, create, destroy, maxunit)		\
+	{ { 0 }, name, sizeof(name) - 1, maxunit, NULL, 0, create, destroy }
 
 /*
  * Structure used to query names of interface cloners.
Index: if_faith.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if_faith.c,v
retrieving revision 1.12
diff -u -r1.12 if_faith.c
--- if_faith.c	4 Mar 2002 21:43:49 -0000	1.12
+++ if_faith.c	6 Mar 2002 19:43:34 -0000
@@ -57,8 +57,6 @@
 #include <sys/queue.h>
 #include <sys/types.h>
 #include <sys/malloc.h>
-#include <machine/bus.h>	/* XXX: Shouldn't really be required! */
-#include <sys/rman.h>
 
 #include <net/if.h>
 #include <net/if_types.h>
@@ -85,11 +83,9 @@
 #include <net/net_osdep.h>
 
 #define FAITHNAME	"faith"
-#define FAITH_MAXUNIT	0x7fff	/* ifp->if_unit is only 15 bits */
 
 struct faith_softc {
 	struct ifnet sc_if;	/* must be first */
-	struct resource *r_unit;
 	LIST_ENTRY(faith_softc) sc_list;
 };
 
@@ -104,14 +100,13 @@
 static int faithmodevent __P((module_t, int, void *));
 
 static MALLOC_DEFINE(M_FAITH, FAITHNAME, "Firewall Assisted Tunnel Interface");
-static struct rman faithunits[1];
 static LIST_HEAD(, faith_softc) faith_softc_list;
 
-int	faith_clone_create __P((struct if_clone *, int *));
+int	faith_clone_create __P((struct if_clone *, int));
 int	faith_clone_destroy __P((struct ifnet *));
 
-struct if_clone faith_cloner =
-    IF_CLONE_INITIALIZER(FAITHNAME, faith_clone_create, faith_clone_destroy);
+struct if_clone faith_cloner = IF_CLONE_INITIALIZER(FAITHNAME,
+    faith_clone_create, faith_clone_destroy, IF_MAXUNIT);
 
 #define	FAITHMTU	1500
 
@@ -121,22 +116,9 @@
 	int type;
 	void *data;
 {
-	int err;
 
 	switch (type) {
 	case MOD_LOAD:
-		faithunits->rm_type = RMAN_ARRAY;
-		faithunits->rm_descr = "configurable if_faith units";
-		err = rman_init(faithunits);
-		if (err != 0)
-			return (err);
-		err = rman_manage_region(faithunits, 0, FAITH_MAXUNIT);
-		if (err != 0) {
-			printf("%s: faithunits: rman_manage_region: "
-			    "Failed %d\n", FAITHNAME, err);
-			rman_fini(faithunits);
-			return (err);
-		}
 		LIST_INIT(&faith_softc_list);
 		if_clone_attach(&faith_cloner);
 
@@ -156,10 +138,6 @@
 			faith_clone_destroy(
 			    &LIST_FIRST(&faith_softc_list)->sc_if);
 
-		err = rman_fini(faithunits);
-		if (err != 0)
-			return (err);
-
 		break;
 	}
 	return 0;
@@ -177,34 +155,16 @@
 int
 faith_clone_create(ifc, unit)
 	struct if_clone *ifc;
-	int *unit;
+	int unit;
 {
-	struct resource *r;
 	struct faith_softc *sc;
 
-	if (*unit > FAITH_MAXUNIT)
-		return (ENXIO);
-
-	if (*unit < 0) {
-		r = rman_reserve_resource(faithunits, 0, FAITH_MAXUNIT, 1,
-		    RF_ALLOCATED | RF_ACTIVE, NULL);
-		if (r == NULL)
-			return (ENOSPC);
-		*unit = rman_get_start(r);
-	} else {
-		r = rman_reserve_resource(faithunits, *unit, *unit, 1,
-		    RF_ALLOCATED | RF_ACTIVE, NULL);
-		if (r == NULL)
-			return (ENOSPC);
-	}
-
 	sc = malloc(sizeof(struct faith_softc), M_FAITH, M_WAITOK);
 	bzero(sc, sizeof(struct faith_softc));
 
 	sc->sc_if.if_softc = sc;
 	sc->sc_if.if_name = FAITHNAME;
-	sc->sc_if.if_unit = *unit;
-	sc->r_unit = r;
+	sc->sc_if.if_unit = unit;
 
 	sc->sc_if.if_mtu = FAITHMTU;
 	/* Change to BROADCAST experimentaly to announce its prefix. */
@@ -225,15 +185,11 @@
 faith_clone_destroy(ifp)
 	struct ifnet *ifp;
 {
-	int err;
 	struct faith_softc *sc = (void *) ifp;
 
 	LIST_REMOVE(sc, sc_list);
 	bpfdetach(ifp);
 	if_detach(ifp);
-
-	err = rman_release_resource(sc->r_unit);
-	KASSERT(err == 0, ("Unexpected error freeing resource"));
 
 	free(sc, M_FAITH);
 	return (0);
Index: if_gif.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if_gif.c,v
retrieving revision 1.20
diff -u -r1.20 if_gif.c
--- if_gif.c	4 Mar 2002 21:43:49 -0000	1.20
+++ if_gif.c	6 Mar 2002 19:42:52 -0000
@@ -46,8 +46,6 @@
 #include <sys/syslog.h>
 #include <sys/protosw.h>
 #include <sys/conf.h>
-#include <machine/bus.h>	/* XXX: Shouldn't really be required! */
-#include <sys/rman.h>
 #include <machine/cpu.h>
 
 #include <net/if.h>
@@ -82,10 +80,8 @@
 #include <net/net_osdep.h>
 
 #define GIFNAME		"gif"
-#define GIF_MAXUNIT	0x7fff	/* ifp->if_unit is only 15 bits */
 
 static MALLOC_DEFINE(M_GIF, "gif", "Generic Tunnel Interface");
-static struct rman gifunits[1];
 static LIST_HEAD(, gif_softc) gif_softc_list;
 
 void	(*ng_gif_input_p)(struct ifnet *ifp, struct mbuf **mp, int af);
@@ -93,11 +89,11 @@
 void	(*ng_gif_attach_p)(struct ifnet *ifp);
 void	(*ng_gif_detach_p)(struct ifnet *ifp);
 
-int	gif_clone_create __P((struct if_clone *, int *));
+int	gif_clone_create __P((struct if_clone *, int));
 int	gif_clone_destroy __P((struct ifnet *));
 
-struct if_clone gif_cloner =
-    IF_CLONE_INITIALIZER("gif", gif_clone_create, gif_clone_destroy);
+struct if_clone gif_cloner = IF_CLONE_INITIALIZER("gif",
+    gif_clone_create, gif_clone_destroy, IF_MAXUNIT);
 
 static int gifmodevent __P((module_t, int, void *));
 void gif_delete_tunnel __P((struct gif_softc *));
@@ -158,34 +154,16 @@
 int
 gif_clone_create(ifc, unit)
 	struct if_clone *ifc;
-	int *unit;
+	int unit;
 {
-	struct resource *r;
 	struct gif_softc *sc;
 
-	if (*unit > GIF_MAXUNIT)
-		return (ENXIO);
-
-	if (*unit < 0) {
-		r = rman_reserve_resource(gifunits, 0, GIF_MAXUNIT, 1,
-		    RF_ALLOCATED | RF_ACTIVE, NULL);
-		if (r == NULL)
-			return (ENOSPC);
-		*unit = rman_get_start(r);
-	} else {
-		r = rman_reserve_resource(gifunits, *unit, *unit, 1,
-		    RF_ALLOCATED | RF_ACTIVE, NULL);
-		if (r == NULL)
-			return (EEXIST);
-	}
-	
 	sc = malloc (sizeof(struct gif_softc), M_GIF, M_WAITOK);
 	bzero(sc, sizeof(struct gif_softc));
 
 	sc->gif_if.if_softc = sc;
 	sc->gif_if.if_name = GIFNAME;
-	sc->gif_if.if_unit = *unit;
-	sc->r_unit = r;
+	sc->gif_if.if_unit = unit;
 
 	sc->encap_cookie4 = sc->encap_cookie6 = NULL;
 #ifdef INET
@@ -252,9 +230,6 @@
 	bpfdetach(ifp);
 	if_detach(ifp);
 
-	err = rman_release_resource(sc->r_unit);
-	KASSERT(err == 0, ("Unexpected error freeing resource"));
-
 	free(sc, M_GIF);
 	return (0);
 }
@@ -265,22 +240,9 @@
 	int type;
 	void *data;
 {
-	int err;
 
 	switch (type) {
 	case MOD_LOAD:
-		gifunits->rm_type = RMAN_ARRAY;
-		gifunits->rm_descr = "configurable if_gif units";
-		err = rman_init(gifunits);
-		if (err != 0)
-			return (err);
-		err = rman_manage_region(gifunits, 0, GIF_MAXUNIT);
-		if (err != 0) {
-			printf("%s: gifunits: rman_manage_region: Failed %d\n",
-			    GIFNAME, err);
-			rman_fini(gifunits);
-			return (err);
-		}
 		LIST_INIT(&gif_softc_list);
 		if_clone_attach(&gif_cloner);
 
@@ -295,9 +257,6 @@
 		while (!LIST_EMPTY(&gif_softc_list))
 			gif_clone_destroy(&LIST_FIRST(&gif_softc_list)->gif_if);
 
-		err = rman_fini(gifunits);
-		if (err != 0)
-			return (err);
 #ifdef INET6
 		ip6_gif_hlim = 0;
 #endif
Index: if_gif.h
===================================================================
RCS file: /home/ncvs/src/sys/net/if_gif.h,v
retrieving revision 1.8
diff -u -r1.8 if_gif.h
--- if_gif.h	27 Sep 2001 03:14:16 -0000	1.8
+++ if_gif.h	21 Feb 2002 02:07:39 -0000
@@ -68,7 +68,6 @@
 	int		gif_flags;
 	const struct encaptab *encap_cookie4;
 	const struct encaptab *encap_cookie6;
-	struct resource *r_unit;	/* resource allocated for this unit */
 	void		*gif_netgraph;	/* ng_gif(4) netgraph node info */
 	LIST_ENTRY(gif_softc) gif_link; /* all gif's are linked */
 };
Index: if_loop.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if_loop.c,v
retrieving revision 1.68
diff -u -r1.68 if_loop.c
--- if_loop.c	4 Mar 2002 21:46:00 -0000	1.68
+++ if_loop.c	6 Mar 2002 19:50:14 -0000
@@ -99,21 +99,18 @@
 #endif
 
 #define LONAME	"lo"
-#define LOMAXUNIT	0x7fff	/* ifp->if_unit is only 15 bits */
 
 struct lo_softc {
 	struct	ifnet sc_if;		/* network-visible interface */
 	LIST_ENTRY(lo_softc) sc_next;
-	struct resource *r_unit;
 };
 
 int		loioctl(struct ifnet *, u_long, caddr_t);
 static void	lortrequest(int, struct rtentry *, struct rt_addrinfo *);
 int		looutput(struct ifnet *ifp, struct mbuf *m,
 		    struct sockaddr *dst, struct rtentry *rt);
-int		lo_clone_create(struct if_clone *, int *);
+int		lo_clone_create(struct if_clone *, int);
 int		lo_clone_destroy(struct ifnet *);
-static void	locreate(int, struct resource *);
 
 struct ifnet *loif = NULL;			/* Used externally */
 
@@ -122,41 +119,12 @@
 static LIST_HEAD(lo_list, lo_softc) lo_list;
 
 struct if_clone lo_cloner =
-    IF_CLONE_INITIALIZER(LONAME, lo_clone_create, lo_clone_destroy);
-
-static struct rman lounits[1];
-
-int
-lo_clone_create(ifc, unit)
-	struct if_clone *ifc;
-	int *unit;
-{
-	struct resource *r;
-
-	if (*unit > LOMAXUNIT)
-		return (ENXIO);
-
-	if (*unit < 0) {
-		r = rman_reserve_resource(lounits, 0, LOMAXUNIT, 1,
-		    RF_ALLOCATED | RF_ACTIVE, NULL);
-		if (r == NULL)
-			return (ENOSPC);
-		*unit = rman_get_start(r);
-	} else {
-		r = rman_reserve_resource(lounits, *unit, *unit, 1,
-		    RF_ALLOCATED | RF_ACTIVE, NULL);
-		if (r == NULL)
-			return (EEXIST);
-	}
-	locreate(*unit, r);
-	return (0);
-}
+    IF_CLONE_INITIALIZER(LONAME, lo_clone_create, lo_clone_destroy, IF_MAXUNIT);
 
 int
 lo_clone_destroy(ifp)
 	struct ifnet *ifp;
 {
-	int err;
 	struct lo_softc *sc;
 	
 	sc = ifp->if_softc;
@@ -167,9 +135,6 @@
 	if (loif == ifp)
 		return (EINVAL);
 
-	err = rman_release_resource(sc->r_unit);
-	KASSERT(err == 0, ("Unexpected error freeing resource"));
-
 	bpfdetach(ifp);
 	if_detach(ifp);
 	LIST_REMOVE(sc, sc_next);
@@ -177,8 +142,10 @@
 	return (0);
 }
 
-static void
-locreate(int unit, struct resource *r)
+int
+lo_clone_create(ifc, unit)
+	struct if_clone *ifc;
+	int unit;
 {
 	struct lo_softc *sc;
 
@@ -193,40 +160,27 @@
 	sc->sc_if.if_type = IFT_LOOP;
 	sc->sc_if.if_snd.ifq_maxlen = ifqmaxlen;
 	sc->sc_if.if_softc = sc;
-	sc->r_unit = r;
 	if_attach(&sc->sc_if);
 	bpfattach(&sc->sc_if, DLT_NULL, sizeof(u_int));
 	LIST_INSERT_HEAD(&lo_list, sc, sc_next);
 	if (loif == NULL)
 		loif = &sc->sc_if;
+
+	return (0);
 }
 
 static int
 loop_modevent(module_t mod, int type, void *data) 
 { 
 	int err;
-	int unit;
 
 	switch (type) { 
 	case MOD_LOAD: 
-		lounits->rm_type = RMAN_ARRAY;
-		lounits->rm_descr = "configurable if_loop units";
-		err = rman_init(lounits);
-		if (err != 0)
-			return (err);
-		err = rman_manage_region(lounits, 0, LOMAXUNIT);
-		if (err != 0) {
-			printf("%s: lounits: rman_manage_region: Failed %d\n",
-			    LONAME, err);
-			rman_fini(lounits);
-			return (err);
-		}
 		LIST_INIT(&lo_list);
 		if_clone_attach(&lo_cloner);
 
 		/* Create lo0 */
-		unit = 0;
-		err = lo_clone_create(NULL, &unit);
+		err = if_clone_create("lo0", sizeof ("lo0"));
 		KASSERT(err == 0, ("%s: can't create lo0", __func__));
 		break; 
 	case MOD_UNLOAD: 
Index: if_stf.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if_stf.c,v
retrieving revision 1.18
diff -u -r1.18 if_stf.c
--- if_stf.c	4 Mar 2002 21:43:49 -0000	1.18
+++ if_stf.c	6 Mar 2002 19:35:18 -0000
@@ -86,8 +86,6 @@
 #include <sys/kernel.h>
 #include <sys/protosw.h>
 #include <sys/queue.h>
-#include <machine/bus.h>	/* XXX: Shouldn't really be required! */ 
-#include <sys/rman.h>
 #include <machine/cpu.h>
 
 #include <sys/malloc.h>
@@ -118,7 +116,6 @@
 #include <net/bpf.h>
 
 #define STFNAME		"stf"
-#define STF_MAXUNIT	0	/* only one is currently allowed */
 
 #define IN6_IS_ADDR_6TO4(x)	(ntohs((x)->s6_addr16[0]) == 0x2002)
 #define GET_V4(x)	((struct in_addr *)(&(x)->s6_addr16[1]))
@@ -131,14 +128,12 @@
 	} __sc_ro46;
 #define sc_ro	__sc_ro46.__sc_ro4
 	const struct encaptab *encap_cookie;
-	struct resource *r_unit;	/* resource allocated for this unit */
 	LIST_ENTRY(stf_softc) sc_list;	/* all stf's are linked */
 };
 
 static LIST_HEAD(, stf_softc) stf_softc_list;
 
 static MALLOC_DEFINE(M_STF, STFNAME, "6to4 Tunnel Interface");
-static struct rman stfunits[1];
 static int ip_stf_ttl = 40;
 
 extern  struct domain inetdomain;
@@ -162,40 +157,23 @@
 static void stf_rtrequest __P((int, struct rtentry *, struct rt_addrinfo *));
 static int stf_ioctl __P((struct ifnet *, u_long, caddr_t));
 
-int	stf_clone_create __P((struct if_clone *, int *));
+int	stf_clone_create __P((struct if_clone *, int));
 int	stf_clone_destroy __P((struct ifnet *));
 
+/* only one clone is currently allowed */
 struct if_clone stf_cloner =
-    IF_CLONE_INITIALIZER(STFNAME, stf_clone_create, stf_clone_destroy);
+    IF_CLONE_INITIALIZER(STFNAME, stf_clone_create, stf_clone_destroy, 0);
 
 int
 stf_clone_create(ifc, unit)
 	struct if_clone *ifc;
-	int *unit;
+	int unit;
 {
-	struct resource *r;
 	struct stf_softc *sc;
 
-	if (*unit > STF_MAXUNIT)
-		return (ENXIO);
-
-	if (*unit < 0) {
-		 r = rman_reserve_resource(stfunits, 0, STF_MAXUNIT, 1,
-		     RF_ALLOCATED | RF_ACTIVE, NULL);
-		 if (r == NULL)
-			return (ENOSPC);
-		 *unit = rman_get_start(r);
-	} else {
-		r = rman_reserve_resource(stfunits, *unit, *unit, 1,
-		    RF_ALLOCATED | RF_ACTIVE, NULL);
-		if (r == NULL)
-			 return (EEXIST);
-	}
-
 	sc = malloc(sizeof(struct stf_softc), M_STF, M_WAITOK | M_ZERO);
 	sc->sc_if.if_name = STFNAME;
-	sc->sc_if.if_unit = *unit;
-	sc->r_unit = r;
+	sc->sc_if.if_unit = unit;
 
 	sc->encap_cookie = encap_attach_func(AF_INET, IPPROTO_IPV6,
 	    stf_encapcheck, &in_stf_protosw, sc);
@@ -229,9 +207,6 @@
 	bpfdetach(ifp);
 	if_detach(ifp);
 
-	err = rman_release_resource(sc->r_unit);
-	KASSERT(err == 0, ("Unexpected error freeing resource"));
-
 	free(sc, M_STF);
 	return (0);
 }
@@ -242,22 +217,9 @@
 	int type;
 	void *data;
 {
-	int err;
 
 	switch (type) {
 	case MOD_LOAD:
-		stfunits->rm_type = RMAN_ARRAY;
-		stfunits->rm_descr = "configurable if_stf units";
-		err = rman_init(stfunits);
-		if (err != 0)
-			return (err);
-		err = rman_manage_region(stfunits, 0, STF_MAXUNIT);
-		if (err != 0) {
-			printf("%s: stfunits: rman_manage_region: Failed %d\n",
-			    STFNAME, err);
-			rman_fini(stfunits);
-			return (err);
-		}
 		LIST_INIT(&stf_softc_list);
 		if_clone_attach(&stf_cloner);
 
@@ -267,10 +229,6 @@
 
 		while (!LIST_EMPTY(&stf_softc_list))
 			stf_clone_destroy(&LIST_FIRST(&stf_softc_list)->sc_if);
-
-		err = rman_fini(stfunits);
-		KASSERT(err == 0, ("Unexpected error freeing resource"));
-
 		break;
 	}
 
Index: if_vlan.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if_vlan.c,v
retrieving revision 1.38
diff -u -r1.38 if_vlan.c
--- if_vlan.c	4 Mar 2002 21:43:49 -0000	1.38
+++ if_vlan.c	6 Mar 2002 19:42:23 -0000
@@ -66,8 +66,6 @@
 #include <sys/sockio.h>
 #include <sys/sysctl.h>
 #include <sys/systm.h>
-#include <machine/bus.h>	/* XXX: Shouldn't really be required! */
-#include <sys/rman.h>
 
 #include <net/bpf.h>
 #include <net/ethernet.h>
@@ -83,17 +81,15 @@
 #endif
 
 #define VLANNAME	"vlan"
-#define VLAN_MAXUNIT	0x7fff	/* ifp->if_unit is only 15 bits */
 
 SYSCTL_DECL(_net_link);
 SYSCTL_NODE(_net_link, IFT_L2VLAN, vlan, CTLFLAG_RW, 0, "IEEE 802.1Q VLAN");
 SYSCTL_NODE(_net_link_vlan, PF_LINK, link, CTLFLAG_RW, 0, "for consistency");
 
 static MALLOC_DEFINE(M_VLAN, "vlan", "802.1Q Virtual LAN Interface");
-static struct rman vlanunits[1];
 static LIST_HEAD(, ifvlan) ifv_list;
 
-static	int vlan_clone_create(struct if_clone *, int *);
+static	int vlan_clone_create(struct if_clone *, int);
 static	int vlan_clone_destroy(struct ifnet *);
 static	void vlan_start(struct ifnet *ifp);
 static	void vlan_ifinit(void *foo);
@@ -105,8 +101,8 @@
 static	int vlan_unconfig(struct ifnet *ifp);
 static	int vlan_config(struct ifvlan *ifv, struct ifnet *p);
 
-struct if_clone vlan_cloner =
-    IF_CLONE_INITIALIZER("vlan", vlan_clone_create, vlan_clone_destroy);
+struct if_clone vlan_cloner = IF_CLONE_INITIALIZER("vlan",
+    vlan_clone_create, vlan_clone_destroy, IF_MAXUNIT);
 
 /*
  * Program our multicast filter. What we're actually doing is
@@ -176,22 +172,9 @@
 static int
 vlan_modevent(module_t mod, int type, void *data) 
 { 
-	int err;
 
 	switch (type) { 
 	case MOD_LOAD: 
-		vlanunits->rm_type = RMAN_ARRAY;
-		vlanunits->rm_descr = "configurable if_vlan units";
-		err = rman_init(vlanunits);
-		if (err != 0)
-			return (err);
-		err = rman_manage_region(vlanunits, 0, VLAN_MAXUNIT);
-		if (err != 0) {
-			printf("%s: vlanunits: rman_manage_region: Failed %d\n",
-			    VLANNAME, err);
-			rman_fini(vlanunits);
-			return (err);
-		}
 		LIST_INIT(&ifv_list);
 		vlan_input_p = vlan_input;
 		vlan_input_tag_p = vlan_input_tag;
@@ -203,9 +186,6 @@
 		vlan_input_tag_p = NULL;
 		while (!LIST_EMPTY(&ifv_list))
 			vlan_clone_destroy(&LIST_FIRST(&ifv_list)->ifv_if);
-		err = rman_fini(vlanunits);
-		if (err != 0)
-			 return (err);
 		break;
 	} 
 	return 0; 
@@ -220,29 +200,12 @@
 DECLARE_MODULE(if_vlan, vlan_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
 
 static int
-vlan_clone_create(struct if_clone *ifc, int *unit)
+vlan_clone_create(struct if_clone *ifc, int unit)
 {
-	struct resource *r;
 	struct ifvlan *ifv;
 	struct ifnet *ifp;
 	int s;
 
-	if (*unit > VLAN_MAXUNIT)
-		return (ENXIO);
-
-	if (*unit < 0) {
-		r  = rman_reserve_resource(vlanunits, 0, VLAN_MAXUNIT, 1,
-		    RF_ALLOCATED | RF_ACTIVE, NULL);
-		if (r == NULL)
-			return (ENOSPC);
-		*unit = rman_get_start(r);
-	} else {
-		r  = rman_reserve_resource(vlanunits, *unit, *unit, 1,
-		    RF_ALLOCATED | RF_ACTIVE, NULL);
-		if (r == NULL)
-			return (EEXIST);
-	}
-
 	ifv = malloc(sizeof(struct ifvlan), M_VLAN, M_WAITOK | M_ZERO);
 	ifp = &ifv->ifv_if;
 	SLIST_INIT(&ifv->vlan_mc_listhead);
@@ -253,8 +216,7 @@
 
 	ifp->if_softc = ifv;
 	ifp->if_name = "vlan";
-	ifp->if_unit = *unit;
-	ifv->r_unit = r;
+	ifp->if_unit = unit;
 	/* NB: flags are not set here */
 	ifp->if_linkmib = &ifv->ifv_mib;
 	ifp->if_linkmiblen = sizeof ifv->ifv_mib;
@@ -279,7 +241,6 @@
 {
 	struct ifvlan *ifv = ifp->if_softc;
 	int s;
-	int err;
 
 	s = splnet();
 	LIST_REMOVE(ifv, ifv_list);
@@ -288,8 +249,6 @@
 
 	ether_ifdetach(ifp, ETHER_BPF_SUPPORTED);
 
-	err = rman_release_resource(ifv->r_unit);
-	KASSERT(err == 0, ("Unexpected error freeing resource"));
 	free(ifv, M_VLAN);
 	return (0);
 }
Index: if_vlan_var.h
===================================================================
RCS file: /home/ncvs/src/sys/net/if_vlan_var.h,v
retrieving revision 1.10
diff -u -r1.10 if_vlan_var.h
--- if_vlan_var.h	5 Sep 2001 21:10:28 -0000	1.10
+++ if_vlan_var.h	21 Feb 2002 02:09:34 -0000
@@ -48,7 +48,6 @@
 	}	ifv_mib;
 	SLIST_HEAD(__vlan_mchead, vlan_mc_entry)	vlan_mc_listhead;
 	LIST_ENTRY(ifvlan) ifv_list;
-	struct resource *r_unit;	/* resource allocated for this unit */
 };
 #define	ifv_if	ifv_ac.ac_if
 #define	ifv_tag	ifv_mib.ifvm_tag

--k+w/mQv8wyuph6w0--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message




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