summaryrefslogtreecommitdiff
path: root/sys/net/if_gif.c
diff options
context:
space:
mode:
authorMarkus Friedl <markus@cvs.openbsd.org>2003-12-03 14:51:06 +0000
committerMarkus Friedl <markus@cvs.openbsd.org>2003-12-03 14:51:06 +0000
commitf011df21d7190430bdfb5446677e0c2fcd867dd1 (patch)
treee995311624db6497e40ad244e6ca2569bd032f81 /sys/net/if_gif.c
parent65ce751e45d7d4413ef1e39660d0a6a0266e8ae3 (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.c104
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)