diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/net/if_faith.c | 66 | ||||
-rw-r--r-- | sys/net/if_gre.c | 101 | ||||
-rw-r--r-- | sys/net/if_gre.h | 6 | ||||
-rw-r--r-- | sys/net/if_loop.c | 80 | ||||
-rw-r--r-- | sys/net/if_tun.c | 149 | ||||
-rw-r--r-- | sys/netinet/ip_gre.c | 5 |
6 files changed, 262 insertions, 145 deletions
diff --git a/sys/net/if_faith.c b/sys/net/if_faith.c index e9e07601303..fcd26c3b556 100644 --- a/sys/net/if_faith.c +++ b/sys/net/if_faith.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_faith.c,v 1.15 2003/06/02 23:28:12 millert Exp $ */ +/* $OpenBSD: if_faith.c,v 1.16 2003/12/03 14:53:04 markus Exp $ */ /* * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. @@ -71,9 +71,12 @@ int faithoutput(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); static void faithrtrequest(int, struct rtentry *, struct rt_addrinfo *); -void faithattach(int); +void faithattach(int); +int faith_clone_create(struct if_clone *, int); +void faith_clone_destroy(struct ifnet *ifp); -static struct ifnet faithif[NFAITH]; +struct if_clone faith_cloner = + IF_CLONE_INITIALIZER("faith", faith_clone_create, faith_clone_destroy); #define FAITHMTU 1500 @@ -82,27 +85,48 @@ void faithattach(faith) int faith; { + if_clone_attach(&faith_cloner); +} + +int +faith_clone_create(ifc, unit) + struct if_clone *ifc; + int unit; +{ struct ifnet *ifp; - int i; - - for (i = 0; i < NFAITH; i++) { - ifp = &faithif[i]; - bzero(ifp, sizeof(faithif[i])); - snprintf(ifp->if_xname, sizeof ifp->if_xname, "faith%d", i); - ifp->if_mtu = FAITHMTU; - /* Change to BROADCAST experimentaly to announce its prefix. */ - ifp->if_flags = /* IFF_LOOPBACK */ IFF_BROADCAST | IFF_MULTICAST; - ifp->if_ioctl = faithioctl; - ifp->if_output = faithoutput; - ifp->if_type = IFT_FAITH; - ifp->if_hdrlen = 0; - ifp->if_addrlen = 0; - if_attach(ifp); - if_alloc_sadl(ifp); + + ifp = malloc(sizeof(*ifp), M_DEVBUF, M_NOWAIT); + if (!ifp) + return (ENOMEM); + bzero(ifp, sizeof(*ifp)); + snprintf(ifp->if_xname, sizeof ifp->if_xname, "%s%d", ifc->ifc_name, + unit); + ifp->if_mtu = FAITHMTU; + /* Change to BROADCAST experimentaly to announce its prefix. */ + ifp->if_flags = /* IFF_LOOPBACK */ IFF_BROADCAST | IFF_MULTICAST; + ifp->if_ioctl = faithioctl; + ifp->if_output = faithoutput; + ifp->if_type = IFT_FAITH; + ifp->if_hdrlen = 0; + ifp->if_addrlen = 0; + if_attach(ifp); + if_alloc_sadl(ifp); #if NBPFILTER > 0 - bpfattach(&ifp->if_bpf, ifp, DLT_NULL, sizeof(u_int)); + bpfattach(&ifp->if_bpf, ifp, DLT_NULL, sizeof(u_int)); #endif - } + return (0); +} + +void +faith_clone_destroy(ifp) + struct ifnet *ifp; +{ +#if NBPFILTER > 0 + bpfdetach(ifp); +#endif + if_detach(ifp); + + free(ifp, M_DEVBUF); } int diff --git a/sys/net/if_gre.c b/sys/net/if_gre.c index 103b89e5262..c761fc8bf9e 100644 --- a/sys/net/if_gre.c +++ b/sys/net/if_gre.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_gre.c,v 1.28 2003/08/15 20:32:19 tedu Exp $ */ +/* $OpenBSD: if_gre.c,v 1.29 2003/12/03 14:52:23 markus Exp $ */ /* $NetBSD: if_gre.c,v 1.9 1999/10/25 19:18:11 drochner Exp $ */ /* @@ -99,9 +99,12 @@ before changing if state to up to find the correct value */ -struct gre_softc *gre = 0; +int gre_clone_create(struct if_clone *, int); +void gre_clone_destroy(struct ifnet *); -int ngre = 0; +struct gre_softc_head gre_softc_list; +struct if_clone gre_cloner = + IF_CLONE_INITIALIZER("gre", gre_clone_create, gre_clone_destroy); /* * We can control the acceptance of GRE and MobileIP packets by @@ -119,43 +122,71 @@ int ip_mobile_allow = 0; static void gre_compute_route(struct gre_softc *sc); void -greattach(n) - int n; +greattach(int n) +{ + LIST_INIT(&gre_softc_list); + if_clone_attach(&gre_cloner); +} + +int +gre_clone_create(struct if_clone *ifc, int unit) { struct gre_softc *sc; - int i; - - ngre = n; - gre = sc = malloc(ngre * sizeof(struct gre_softc), M_DEVBUF, M_WAIT); - bzero(sc, ngre * sizeof(struct gre_softc)); - for (i = 0; i < ngre ; sc++) { - snprintf(sc->sc_if.if_xname, sizeof(sc->sc_if.if_xname), - "gre%d", i++); - sc->sc_if.if_softc = sc; - sc->sc_if.if_type = IFT_OTHER; - sc->sc_if.if_addrlen = 0; - sc->sc_if.if_hdrlen = 24; /* IP + GRE */ - sc->sc_if.if_mtu = GREMTU; - sc->sc_if.if_flags = IFF_POINTOPOINT|IFF_MULTICAST; - sc->sc_if.if_output = gre_output; - sc->sc_if.if_ioctl = gre_ioctl; - sc->sc_if.if_collisions = 0; - sc->sc_if.if_ierrors = 0; - sc->sc_if.if_oerrors = 0; - sc->sc_if.if_ipackets = 0; - sc->sc_if.if_opackets = 0; - sc->g_dst.s_addr = sc->g_src.s_addr = INADDR_ANY; - sc->g_proto = IPPROTO_GRE; - sc->sc_if.if_flags |= IFF_LINK0; - - if_attach(&sc->sc_if); - if_alloc_sadl(&sc->sc_if); + int s; + + sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT); + if (!sc) + return (ENOMEM); + bzero(sc, sizeof(*sc)); + snprintf(sc->sc_if.if_xname, sizeof sc->sc_if.if_xname, "%s%d", + ifc->ifc_name, unit); + sc->sc_if.if_softc = sc; + sc->sc_if.if_type = IFT_OTHER; + sc->sc_if.if_addrlen = 0; + sc->sc_if.if_hdrlen = 24; /* IP + GRE */ + sc->sc_if.if_mtu = GREMTU; + sc->sc_if.if_flags = IFF_POINTOPOINT|IFF_MULTICAST; + sc->sc_if.if_output = gre_output; + sc->sc_if.if_ioctl = gre_ioctl; + sc->sc_if.if_collisions = 0; + sc->sc_if.if_ierrors = 0; + sc->sc_if.if_oerrors = 0; + sc->sc_if.if_ipackets = 0; + sc->sc_if.if_opackets = 0; + sc->g_dst.s_addr = sc->g_src.s_addr = INADDR_ANY; + sc->g_proto = IPPROTO_GRE; + sc->sc_if.if_flags |= IFF_LINK0; + + if_attach(&sc->sc_if); + if_alloc_sadl(&sc->sc_if); #if NBPFILTER > 0 - bpfattach(&sc->sc_if.if_bpf, &sc->sc_if, DLT_RAW, - sizeof(u_int32_t)); + bpfattach(&sc->sc_if.if_bpf, &sc->sc_if, DLT_RAW, + sizeof(u_int32_t)); #endif - } + s = splnet(); + LIST_INSERT_HEAD(&gre_softc_list, sc, sc_list); + splx(s); + + return (0); +} + +void +gre_clone_destroy(struct ifnet *ifp) +{ + struct gre_softc *sc = ifp->if_softc; + int s; + + s = splnet(); + LIST_REMOVE(sc, sc_list); + splx(s); + +#if NBPFILTER > 0 + bpfdetach(ifp); +#endif + if_detach(ifp); + + free(sc, M_DEVBUF); } /* diff --git a/sys/net/if_gre.h b/sys/net/if_gre.h index 6230f00ba88..ed7fcbb67ca 100644 --- a/sys/net/if_gre.h +++ b/sys/net/if_gre.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_gre.h,v 1.8 2003/11/16 20:30:07 avsm Exp $ */ +/* $OpenBSD: if_gre.h,v 1.9 2003/12/03 14:52:23 markus Exp $ */ /* $NetBSD: if_gre.h,v 1.5 1999/11/19 20:41:19 thorpej Exp $ */ /* @@ -42,6 +42,7 @@ struct gre_softc { struct ifnet sc_if; + LIST_ENTRY(gre_softc) sc_list; int gre_unit; int gre_flags; struct in_addr g_src; /* source address of gre packets */ @@ -138,8 +139,7 @@ struct mobip_h { */ #ifdef _KERNEL -extern struct gre_softc *gre; -extern int ngre; +extern LIST_HEAD(gre_softc_head, gre_softc) gre_softc_list; extern int gre_allow; extern int gre_wccp; extern int ip_mobile_allow; diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c index a4892bf624d..17b196c67aa 100644 --- a/sys/net/if_loop.c +++ b/sys/net/if_loop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_loop.c,v 1.29 2003/06/02 23:28:12 millert Exp $ */ +/* $OpenBSD: if_loop.c,v 1.30 2003/12/03 14:53:04 markus Exp $ */ /* $NetBSD: if_loop.c,v 1.15 1996/05/07 02:40:33 thorpej Exp $ */ /* @@ -173,39 +173,71 @@ static void lo_altqstart(struct ifnet *); #endif +int loop_clone_create(struct if_clone *, int); +void loop_clone_destroy(struct ifnet *); + +struct if_clone loop_cloner = + IF_CLONE_INITIALIZER("lo", loop_clone_create, loop_clone_destroy); + +/* ARGSUSED */ void loopattach(n) int n; { - register int i; - register struct ifnet *ifp; + (void) loop_clone_create(&loop_cloner, 0); + if_clone_attach(&loop_cloner); +} - for (i = n; i--; ) { - MALLOC(ifp, struct ifnet *, sizeof(*ifp), M_DEVBUF, M_NOWAIT); - if (ifp == NULL) - return; - bzero(ifp, sizeof(struct ifnet)); - if (i == 0) - lo0ifp = ifp; - snprintf(ifp->if_xname, sizeof ifp->if_xname, "lo%d", i); - ifp->if_softc = NULL; - ifp->if_mtu = LOMTU; - ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST; - ifp->if_ioctl = loioctl; - ifp->if_output = looutput; - ifp->if_type = IFT_LOOP; - ifp->if_hdrlen = sizeof(u_int32_t); - ifp->if_addrlen = 0; - IFQ_SET_READY(&ifp->if_snd); +int +loop_clone_create(ifc, unit) + struct if_clone *ifc; + int unit; +{ + struct ifnet *ifp; + + MALLOC(ifp, struct ifnet *, sizeof(*ifp), M_DEVBUF, M_NOWAIT); + if (ifp == NULL) + return (ENOMEM); + bzero(ifp, sizeof(struct ifnet)); + + snprintf(ifp->if_xname, sizeof ifp->if_xname, "lo%d", unit); + ifp->if_softc = NULL; + ifp->if_mtu = LOMTU; + ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST; + ifp->if_ioctl = loioctl; + ifp->if_output = looutput; + ifp->if_type = IFT_LOOP; + ifp->if_hdrlen = sizeof(u_int32_t); + ifp->if_addrlen = 0; + IFQ_SET_READY(&ifp->if_snd); #ifdef ALTQ - ifp->if_start = lo_altqstart; + ifp->if_start = lo_altqstart; #endif + if (unit == 0) { + lo0ifp = ifp; if_attachhead(ifp); - if_alloc_sadl(ifp); + } else + if_attach(ifp); + if_alloc_sadl(ifp); #if NBPFILTER > 0 - bpfattach(&ifp->if_bpf, ifp, DLT_LOOP, sizeof(u_int32_t)); + bpfattach(&ifp->if_bpf, ifp, DLT_LOOP, sizeof(u_int32_t)); #endif - } + return (0); +} + +void +loop_clone_destroy(ifp) + struct ifnet *ifp; +{ + if (ifp == lo0ifp) + return; /* XXX silently fail for lo0 */ + +#if NBPFILTER > 0 + bpfdetach(ifp); +#endif + if_detach(ifp); + + free(ifp, M_DEVBUF); } int diff --git a/sys/net/if_tun.c b/sys/net/if_tun.c index f58709957f6..68dc5b1684f 100644 --- a/sys/net/if_tun.c +++ b/sys/net/if_tun.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_tun.c,v 1.51 2003/12/02 06:00:18 mickey Exp $ */ +/* $OpenBSD: if_tun.c,v 1.52 2003/12/03 14:53:04 markus Exp $ */ /* $NetBSD: if_tun.c,v 1.24 1996/05/07 02:40:48 thorpej Exp $ */ /* @@ -106,6 +106,8 @@ struct tun_softc { uid_t tun_sigeuid; /* euid for process that set tun_pgid */ struct selinfo tun_rsel; /* read select */ struct selinfo tun_wsel; /* write select (not used) */ + int tun_unit; + LIST_ENTRY(tun_softc) tun_list; /* all tunnel interfaces */ }; #ifdef TUN_DEBUG @@ -115,9 +117,6 @@ int tundebug = TUN_DEBUG; #define TUNDEBUG(a) /* (tundebug? printf a : 0) */ #endif -struct tun_softc *tunctl; -int ntun; - extern int ifqmaxlen; void tunattach(int); @@ -131,7 +130,8 @@ int tunread(dev_t, struct uio *, int); int tunwrite(dev_t, struct uio *, int); int tunpoll(dev_t, int, struct proc *); int tunkqfilter(dev_t, struct knote *); - +int tun_clone_create(struct if_clone *, int); +struct tun_softc *tun_lookup(int); static int tuninit(struct tun_softc *); #ifdef ALTQ @@ -148,46 +148,80 @@ struct filterops tunread_filtops = struct filterops tunwrite_filtops = { 1, NULL, filt_tunwdetach, filt_tunwrite}; +LIST_HEAD(, tun_softc) tun_softc_list; + +struct if_clone tun_cloner = + IF_CLONE_INITIALIZER("tun", tun_clone_create, NULL); + void tunattach(n) int n; { - register int i; + LIST_INIT(&tun_softc_list); + if_clone_attach(&tun_cloner); +} + +int +tun_clone_create(ifc, unit) + struct if_clone *ifc; + int unit; +{ + struct tun_softc *tp; struct ifnet *ifp; + int s; + + tp = malloc(sizeof(*tp), M_DEVBUF, M_NOWAIT); + if (!tp) + return (ENOMEM); + bzero(tp, sizeof(*tp)); + + tp->tun_unit = unit; + tp->tun_flags = TUN_INITED; - ntun = n; - tunctl = malloc(ntun * sizeof(*tunctl), M_DEVBUF, M_WAITOK); - bzero(tunctl, ntun * sizeof(*tunctl)); - for (i = 0; i < ntun; i++) { - tunctl[i].tun_flags = TUN_INITED; - - ifp = &tunctl[i].tun_if; - snprintf(ifp->if_xname, sizeof ifp->if_xname, "tun%d", i); - ifp->if_softc = &tunctl[i]; - ifp->if_mtu = TUNMTU; - ifp->if_ioctl = tun_ioctl; - ifp->if_output = tun_output; + ifp = &tp->tun_if; + snprintf(ifp->if_xname, sizeof ifp->if_xname, "%s%d", ifc->ifc_name, + unit); + ifp->if_softc = tp; + ifp->if_mtu = TUNMTU; + ifp->if_ioctl = tun_ioctl; + ifp->if_output = tun_output; #ifdef ALTQ - ifp->if_start = tunstart; + ifp->if_start = tunstart; #endif - ifp->if_flags = IFF_POINTOPOINT; - ifp->if_type = IFT_PROPVIRTUAL; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - IFQ_SET_READY(&ifp->if_snd); - ifp->if_hdrlen = sizeof(u_int32_t); - ifp->if_collisions = 0; - ifp->if_ierrors = 0; - ifp->if_oerrors = 0; - ifp->if_ipackets = 0; - ifp->if_opackets = 0; - ifp->if_ibytes = 0; - ifp->if_obytes = 0; - if_attach(ifp); - if_alloc_sadl(ifp); + ifp->if_flags = IFF_POINTOPOINT; + ifp->if_type = IFT_PROPVIRTUAL; + IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); + IFQ_SET_READY(&ifp->if_snd); + ifp->if_hdrlen = sizeof(u_int32_t); + ifp->if_collisions = 0; + ifp->if_ierrors = 0; + ifp->if_oerrors = 0; + ifp->if_ipackets = 0; + ifp->if_opackets = 0; + ifp->if_ibytes = 0; + ifp->if_obytes = 0; + if_attach(ifp); + if_alloc_sadl(ifp); #if NBPFILTER > 0 - bpfattach(&ifp->if_bpf, ifp, DLT_LOOP, sizeof(u_int32_t)); + bpfattach(&ifp->if_bpf, ifp, DLT_LOOP, sizeof(u_int32_t)); #endif - } + s = splnet(); + LIST_INSERT_HEAD(&tun_softc_list, tp, tun_list); + splx(s); + + return (0); +} + +struct tun_softc * +tun_lookup(unit) + int unit; +{ + struct tun_softc *tp; + + LIST_FOREACH(tp, &tun_softc_list, tun_list) + if (tp->tun_unit == unit) + return (tp); + return (NULL); } /* @@ -202,15 +236,19 @@ tunopen(dev, flag, mode, p) { struct tun_softc *tp; struct ifnet *ifp; - register int unit, error; + int error; if ((error = suser(p, 0)) != 0) return (error); - if ((unit = minor(dev)) >= ntun) - return (ENXIO); + if ((tp = tun_lookup(minor(dev))) == NULL) { + /* create on demand */ + (void) tun_clone_create(&tun_cloner, minor(dev)); + + if ((tp = tun_lookup(minor(dev))) == NULL) + return (ENXIO); + } - tp = &tunctl[unit]; if (tp->tun_flags & TUN_OPEN) return EBUSY; @@ -231,14 +269,13 @@ tunclose(dev, flag, mode, p) int mode; struct proc *p; { - register int unit, s; + int s; struct tun_softc *tp; struct ifnet *ifp; - if ((unit = minor(dev)) >= ntun) + if ((tp = tun_lookup(minor(dev))) == NULL) return (ENXIO); - tp = &tunctl[unit]; ifp = &tp->tun_if; tp->tun_flags &= ~TUN_OPEN; @@ -460,16 +497,14 @@ tunioctl(dev, cmd, data, flag, p) int flag; struct proc *p; { - int unit, s; + int s; struct tun_softc *tp; struct tuninfo *tunp; struct mbuf *m; - if ((unit = minor(dev)) >= ntun) + if ((tp = tun_lookup(minor(dev))) == NULL) return (ENXIO); - tp = &tunctl[unit]; - s = splimp(); switch (cmd) { case TUNSIFINFO: @@ -557,16 +592,14 @@ tunread(dev, uio, ioflag) struct uio *uio; int ioflag; { - int unit; struct tun_softc *tp; struct ifnet *ifp; struct mbuf *m, *m0; int error = 0, len, s; - if ((unit = minor(dev)) >= ntun) + if ((tp = tun_lookup(minor(dev))) == NULL) return (ENXIO); - tp = &tunctl[unit]; ifp = &tp->tun_if; TUNDEBUG(("%s: read\n", ifp->if_xname)); if ((tp->tun_flags & TUN_READY) != TUN_READY) { @@ -628,7 +661,7 @@ tunwrite(dev, uio, ioflag) struct uio *uio; int ioflag; { - int unit; + struct tun_softc *tp; struct ifnet *ifp; struct ifqueue *ifq; u_int32_t *th; @@ -636,10 +669,10 @@ tunwrite(dev, uio, ioflag) int isr; int error=0, s, tlen, mlen; - if ((unit = minor(dev)) >= ntun) + if ((tp = tun_lookup(minor(dev))) == NULL) return (ENXIO); - ifp = &tunctl[unit].tun_if; + ifp = &tp->tun_if; TUNDEBUG(("%s: tunwrite\n", ifp->if_xname)); if (uio->uio_resid == 0 || uio->uio_resid > TUNMRU) { @@ -760,15 +793,14 @@ tunpoll(dev, events, p) int events; struct proc *p; { - int unit, revents, s; + int revents, s; struct tun_softc *tp; struct ifnet *ifp; struct mbuf *m; - if ((unit = minor(dev)) >= ntun) + if ((tp = tun_lookup(minor(dev))) == NULL) return (ENXIO); - tp = &tunctl[unit]; ifp = &tp->tun_if; revents = 0; s = splimp(); @@ -803,15 +835,14 @@ tunpoll(dev, events, p) int tunkqfilter(dev_t dev,struct knote *kn) { - int unit, s; + int s; struct klist *klist; struct tun_softc *tp; struct ifnet *ifp; - if ((unit = minor(dev)) >= ntun) - return ENXIO; + if ((tp = tun_lookup(minor(dev))) == NULL) + return (ENXIO); - tp = &tunctl[unit]; ifp = &tp->tun_if; s = splimp(); diff --git a/sys/netinet/ip_gre.c b/sys/netinet/ip_gre.c index 32577201e83..e476c4d61ae 100644 --- a/sys/netinet/ip_gre.c +++ b/sys/netinet/ip_gre.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_gre.c,v 1.22 2003/07/09 22:03:16 itojun Exp $ */ +/* $OpenBSD: ip_gre.c,v 1.23 2003/12/03 14:52:23 markus Exp $ */ /* $NetBSD: ip_gre.c,v 1.9 1999/10/25 19:18:11 drochner Exp $ */ /* @@ -390,9 +390,8 @@ gre_lookup(m, proto) { struct ip *ip = mtod(m, struct ip *); struct gre_softc *sc; - int i; - for (i = 0, sc = gre; i < ngre; i++, sc++) { + LIST_FOREACH(sc, &gre_softc_list, sc_list) { if ((sc->g_dst.s_addr == ip->ip_src.s_addr) && (sc->g_src.s_addr == ip->ip_dst.s_addr) && (sc->g_proto == proto) && |