diff options
author | Markus Friedl <markus@cvs.openbsd.org> | 2003-12-03 14:51:06 +0000 |
---|---|---|
committer | Markus Friedl <markus@cvs.openbsd.org> | 2003-12-03 14:51:06 +0000 |
commit | f011df21d7190430bdfb5446677e0c2fcd867dd1 (patch) | |
tree | e995311624db6497e40ad244e6ca2569bd032f81 /sys/net/if_gif.c | |
parent | 65ce751e45d7d4413ef1e39660d0a6a0266e8ae3 (diff) |
add support for ifconfig clone/destroy; ok henning deraadt
Diffstat (limited to 'sys/net/if_gif.c')
-rw-r--r-- | sys/net/if_gif.c | 104 |
1 files changed, 72 insertions, 32 deletions
diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c index d790dcb256d..87d64d5ed2d 100644 --- a/sys/net/if_gif.c +++ b/sys/net/if_gif.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_gif.c,v 1.28 2003/05/03 21:15:11 deraadt Exp $ */ +/* $OpenBSD: if_gif.c,v 1.29 2003/12/03 14:51:05 markus Exp $ */ /* $KAME: if_gif.c,v 1.43 2001/02/20 08:51:07 itojun Exp $ */ /* @@ -63,44 +63,86 @@ extern int ifqmaxlen; -int ngif; -void gifattach(int); +void gifattach(int); +int gif_clone_create(struct if_clone *, int); +void gif_clone_destroy(struct ifnet *); /* * gif global variable definitions */ -struct gif_softc *gif_softc = 0; +struct gif_softc_head gif_softc_list; +struct if_clone gif_cloner = + IF_CLONE_INITIALIZER("gif", gif_clone_create, gif_clone_destroy); +/* ARGSUSED */ void -gifattach(n) - int n; +gifattach(count) + int count; { - register struct gif_softc *sc; - register int i; - - ngif = n; - gif_softc = sc = malloc (ngif * sizeof(struct gif_softc), - M_DEVBUF, M_WAIT); - bzero(sc, ngif * sizeof(struct gif_softc)); - for (i = 0; i < ngif; sc++, i++) { - snprintf(sc->gif_if.if_xname, sizeof sc->gif_if.if_xname, - "gif%d", i); - sc->gif_if.if_mtu = GIF_MTU; - sc->gif_if.if_flags = IFF_POINTOPOINT | IFF_MULTICAST; - sc->gif_if.if_ioctl = gif_ioctl; - sc->gif_if.if_start = gif_start; - sc->gif_if.if_output = gif_output; - sc->gif_if.if_type = IFT_GIF; - sc->gif_if.if_snd.ifq_maxlen = ifqmaxlen; - sc->gif_if.if_softc = sc; - if_attach(&sc->gif_if); - if_alloc_sadl(&sc->gif_if); + LIST_INIT(&gif_softc_list); + if_clone_attach(&gif_cloner); +} + +int +gif_clone_create(ifc, unit) + struct if_clone *ifc; + int unit; +{ + struct gif_softc *sc; + int s; + + sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT); + if (!sc) + return (ENOMEM); + bzero(sc, sizeof(*sc)); + + snprintf(sc->gif_if.if_xname, sizeof sc->gif_if.if_xname, + "%s%d", ifc->ifc_name, unit); + sc->gif_if.if_mtu = GIF_MTU; + sc->gif_if.if_flags = IFF_POINTOPOINT | IFF_MULTICAST; + sc->gif_if.if_ioctl = gif_ioctl; + sc->gif_if.if_start = gif_start; + sc->gif_if.if_output = gif_output; + sc->gif_if.if_type = IFT_GIF; + sc->gif_if.if_snd.ifq_maxlen = ifqmaxlen; + sc->gif_if.if_softc = sc; + if_attach(&sc->gif_if); + if_alloc_sadl(&sc->gif_if); #if NBPFILTER > 0 - bpfattach(&sc->gif_if.if_bpf, &sc->gif_if, DLT_NULL, - sizeof(u_int)); + bpfattach(&sc->gif_if.if_bpf, &sc->gif_if, DLT_NULL, + sizeof(u_int)); #endif - } + s = splnet(); + LIST_INSERT_HEAD(&gif_softc_list, sc, gif_list); + splx(s); + + return (0); +} + +void +gif_clone_destroy(ifp) + struct ifnet *ifp; +{ + struct gif_softc *sc = ifp->if_softc; + int s; + + s = splnet(); + LIST_REMOVE(sc, gif_list); + splx(s); + +#if NBPFILTER > 0 + bpfdetach(ifp); +#endif + if_detach(ifp); + + if (sc->gif_psrc) + free((caddr_t)sc->gif_psrc, M_IFADDR); + sc->gif_psrc = NULL; + if (sc->gif_pdst) + free((caddr_t)sc->gif_pdst, M_IFADDR); + sc->gif_pdst = NULL; + free(sc, M_DEVBUF); } void @@ -245,7 +287,6 @@ gif_ioctl(ifp, cmd, data) int error = 0, size; struct sockaddr *dst, *src; struct sockaddr *sa; - int i; int s; struct gif_softc *sc2; @@ -360,8 +401,7 @@ gif_ioctl(ifp, cmd, data) break; } - for (i = 0; i < ngif; i++) { - sc2 = gif_softc + i; + LIST_FOREACH(sc2, &gif_softc_list, gif_list) { if (sc2 == sc) continue; if (!sc2->gif_pdst || !sc2->gif_psrc) |