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 #include #include +#include +#include #include #include #include @@ -88,12 +90,6 @@ #include #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