Index: if.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if.c,v
retrieving revision 1.127
diff -u -r1.127 if.c
--- if.c	18 Jan 2002 14:33:03 -0000	1.127
+++ if.c	12 Feb 2002 03:48:20 -0000
@@ -633,8 +633,7 @@
 	if (ifc->ifc_destroy == NULL)
 		return (EOPNOTSUPP);
 
-	(*ifc->ifc_destroy)(ifp);
-	return (0);
+	return ((*ifc->ifc_destroy)(ifp));
 }
 
 /*
Index: if.h
===================================================================
RCS file: /home/ncvs/src/sys/net/if.h,v
retrieving revision 1.68
diff -u -r1.68 if.h
--- if.h	18 Jan 2002 14:33:03 -0000	1.68
+++ if.h	12 Feb 2002 03:48:44 -0000
@@ -65,7 +65,7 @@
 	size_t ifc_namelen;		/* length of name */
 
 	int	(*ifc_create)(struct if_clone *, int *);
-	void	(*ifc_destroy)(struct ifnet *);
+	int	(*ifc_destroy)(struct ifnet *);
 };
 
 #define IF_CLONE_INITIALIZER(name, create, destroy)			\
Index: if_faith.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if_faith.c,v
retrieving revision 1.10
diff -u -r1.10 if_faith.c
--- if_faith.c	8 Jan 2002 10:30:09 -0000	1.10
+++ if_faith.c	12 Feb 2002 15:03:07 -0000
@@ -106,7 +106,7 @@
 static LIST_HEAD(, faith_softc) faith_softc_list;
 
 int	faith_clone_create __P((struct if_clone *, int *));
-void	faith_clone_destroy __P((struct ifnet *));
+int	faith_clone_destroy __P((struct ifnet *));
 
 struct if_clone faith_cloner =
     IF_CLONE_INITIALIZER(FAITHNAME, faith_clone_create, faith_clone_destroy);
@@ -219,7 +219,7 @@
 	return (0);
 }
 
-void
+int
 faith_clone_destroy(ifp)
 	struct ifnet *ifp;
 {
@@ -234,6 +234,7 @@
 	KASSERT(err == 0, ("Unexpected error freeing resource"));
 
 	free(sc, M_FAITH);
+	return (0);
 }
 
 int
Index: if_gif.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if_gif.c,v
retrieving revision 1.17
diff -u -r1.17 if_gif.c
--- if_gif.c	8 Jan 2002 10:30:09 -0000	1.17
+++ if_gif.c	12 Feb 2002 15:01:04 -0000
@@ -93,7 +93,7 @@
 void	(*ng_gif_detach_p)(struct ifnet *ifp);
 
 int	gif_clone_create __P((struct if_clone *, int *));
-void	gif_clone_destroy __P((struct ifnet *));
+int	gif_clone_destroy __P((struct ifnet *));
 
 struct if_clone gif_cloner =
     IF_CLONE_INITIALIZER("gif", gif_clone_create, gif_clone_destroy);
@@ -210,7 +210,7 @@
 	return (0);
 }
 
-void
+int
 gif_clone_destroy(ifp)
 	struct ifnet *ifp;
 {
@@ -237,6 +237,7 @@
 	KASSERT(err == 0, ("Unexpected error freeing resource"));
 
 	free(sc, M_GIF);
+	return (0);
 }
 
 static int
Index: if_loop.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if_loop.c,v
retrieving revision 1.67
diff -u -r1.67 if_loop.c
--- if_loop.c	29 Dec 2001 08:45:17 -0000	1.67
+++ if_loop.c	13 Feb 2002 00:17:17 -0000
@@ -49,6 +49,8 @@
 #include <sys/malloc.h>
 #include <sys/mbuf.h>
 #include <sys/module.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
 #include <sys/socket.h>
 #include <sys/sockio.h>
 #include <sys/sysctl.h>
@@ -88,12 +90,6 @@
 #include <netatalk/at_var.h>
 #endif
 
-int loioctl __P((struct ifnet *, u_long, caddr_t));
-static void lortrequest __P((int, struct rtentry *, struct rt_addrinfo *));
-
-int looutput __P((struct ifnet *ifp,
-		struct mbuf *m, struct sockaddr *dst, struct rtentry *rt));
-
 #ifdef TINY_LOMTU
 #define	LOMTU	(1024+512)
 #elif defined(LARGE_LOMTU)
@@ -102,26 +98,93 @@
 #define LOMTU	16384
 #endif
 
-static int nloop = 1;
-
-struct ifnet *loif;			/* Used externally */
-
-static MALLOC_DEFINE(M_LO, "lo", "Loopback Interface");
+#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_destroy(struct ifnet *);
+static void	locreate(int, struct resource *);
+
+struct ifnet *loif = NULL;			/* Used externally */
+
+static MALLOC_DEFINE(M_LO, LONAME, "Loopback Interface");
+
 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);
+}
+
+int
+lo_clone_destroy(ifp)
+	struct ifnet *ifp;
+{
+	int err;
+	struct lo_softc *sc;
+	
+	sc = ifp->if_softc;
+
+	/*
+	 * Prevent lo0 from being destroyed.
+	 */
+	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);
+	FREE(sc, M_LO);
+	return (0);
+}
+
 static void
-locreate(int unit)
+locreate(int unit, struct resource *r)
 {
 	struct lo_softc *sc;
 
 	MALLOC(sc, struct lo_softc *, sizeof(*sc), M_LO, M_WAITOK | M_ZERO);
 
-	sc->sc_if.if_name = "lo";
+	sc->sc_if.if_name = LONAME;
 	sc->sc_if.if_unit = unit;
 	sc->sc_if.if_mtu = LOMTU;
 	sc->sc_if.if_flags = IFF_LOOPBACK | IFF_MULTICAST;
@@ -129,6 +192,8 @@
 	sc->sc_if.if_output = looutput;
 	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);
@@ -136,55 +201,33 @@
 		loif = &sc->sc_if;
 }
 
-static void
-lodestroy(struct lo_softc *sc)
-{
-	bpfdetach(&sc->sc_if);
-	if_detach(&sc->sc_if);
-	LIST_REMOVE(sc, sc_next);
-	FREE(sc, M_LO);
-}
-
-
-static int
-sysctl_net_nloop(SYSCTL_HANDLER_ARGS)
-{
-	int newnloop;
-	int error;
-
-	newnloop = nloop;
-
-	error = sysctl_handle_opaque(oidp, &newnloop, sizeof newnloop, req);
-	if (error || !req->newptr)
-		return (error);
-
-	if (newnloop < 1)
-		return (EINVAL);
-	while (newnloop > nloop) {
-		locreate(nloop);
-		nloop++;
-	}
-	while (newnloop < nloop) {
-		lodestroy(LIST_FIRST(&lo_list));
-		nloop--;
-	}
-	return (0);
-}
-SYSCTL_PROC(_net, OID_AUTO, nloop, CTLTYPE_INT | CTLFLAG_RW,
-	    0, 0, sysctl_net_nloop, "I", "");
-
 static int
 loop_modevent(module_t mod, int type, void *data) 
 { 
-	int i;
+	int err;
+	int unit;
 
 	switch (type) { 
 	case MOD_LOAD: 
-		TUNABLE_INT_FETCH("net.nloop", &nloop);
-		if (nloop < 1)			/* sanity check */
-			nloop = 1;
-		for (i = 0; i < nloop; i++)
-			locreate(i);
+		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);
+		KASSERT(err == 0, ("%s: can't create lo0", __func__));
 		break; 
 	case MOD_UNLOAD: 
 		printf("loop module unload - not possible for this module type\n"); 
Index: if_stf.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if_stf.c,v
retrieving revision 1.16
diff -u -r1.16 if_stf.c
--- if_stf.c	8 Jan 2002 10:30:09 -0000	1.16
+++ if_stf.c	12 Feb 2002 15:02:39 -0000
@@ -163,7 +163,7 @@
 static int stf_ioctl __P((struct ifnet *, u_long, caddr_t));
 
 int	stf_clone_create __P((struct if_clone *, int *));
-void	stf_clone_destroy __P((struct ifnet *));
+int	stf_clone_destroy __P((struct ifnet *));
 
 struct if_clone stf_cloner =
     IF_CLONE_INITIALIZER(STFNAME, stf_clone_create, stf_clone_destroy);
@@ -216,7 +216,7 @@
 	return (0);
 }
 
-void
+int
 stf_clone_destroy(ifp)
 	struct ifnet *ifp;
 {
@@ -233,6 +233,7 @@
 	KASSERT(err == 0, ("Unexpected error freeing resource"));
 
 	free(sc, M_STF);
+	return (0);
 }
 
 static int
Index: if_vlan.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if_vlan.c,v
retrieving revision 1.36
diff -u -r1.36 if_vlan.c
--- if_vlan.c	21 Nov 2001 20:29:08 -0000	1.36
+++ if_vlan.c	12 Feb 2002 15:00:32 -0000
@@ -94,7 +94,7 @@
 static LIST_HEAD(, ifvlan) ifv_list;
 
 static	int vlan_clone_create(struct if_clone *, int *);
-static	void vlan_clone_destroy(struct ifnet *);
+static	int vlan_clone_destroy(struct ifnet *);
 static	void vlan_start(struct ifnet *ifp);
 static	void vlan_ifinit(void *foo);
 static	int vlan_input(struct ether_header *eh, struct mbuf *m);
@@ -274,7 +274,7 @@
 	return (0);
 }
 
-static void
+static int
 vlan_clone_destroy(struct ifnet *ifp)
 {
 	struct ifvlan *ifv = ifp->if_softc;
@@ -291,6 +291,7 @@
 	err = rman_release_resource(ifv->r_unit);
 	KASSERT(err == 0, ("Unexpected error freeing resource"));
 	free(ifv, M_VLAN);
+	return (0);
 }
 
 static void
