From 9380aef83fa91def90c9f0e74a13f817ffb6c892 Mon Sep 17 00:00:00 2001 From: brooks Date: Sat, 25 May 2002 20:20:35 +0000 Subject: Make discard devices clonable and unloadable. Also, change the interface name from ds# to disc#. --- sys/net/if_disc.c | 72 +++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 57 insertions(+), 15 deletions(-) (limited to 'sys/net/if_disc.c') diff --git a/sys/net/if_disc.c b/sys/net/if_disc.c index 7c2dc4f..6e30668 100644 --- a/sys/net/if_disc.c +++ b/sys/net/if_disc.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -61,20 +62,39 @@ #define DSMTU 65532 #endif -static void discattach(void); +#define DISCNAME "disc" -static struct ifnet discif; -static int discoutput(struct ifnet *, struct mbuf *, - struct sockaddr *, struct rtentry *); -static void discrtrequest(int, struct rtentry *, struct rt_addrinfo *); -static int discioctl(struct ifnet *, u_long, caddr_t); +struct disc_softc { + struct ifnet sc_if; /* must be first */ + LIST_ENTRY(disc_softc) sc_list; +}; -static void -discattach(void) +static int discoutput(struct ifnet *, struct mbuf *, + struct sockaddr *, struct rtentry *); +static void discrtrequest(int, struct rtentry *, struct rt_addrinfo *); +static int discioctl(struct ifnet *, u_long, caddr_t); +static int disc_clone_create(struct if_clone *, int); +static void disc_clone_destroy(struct ifnet *); + +static MALLOC_DEFINE(M_DISC, DISCNAME, "Discard interface"); +static LIST_HEAD(, disc_softc) disc_softc_list; +static struct if_clone disc_cloner = IF_CLONE_INITIALIZER(DISCNAME, + disc_clone_create, disc_clone_destroy, 0, IF_MAXUNIT); + +static int +disc_clone_create(struct if_clone *ifc, int unit) { - struct ifnet *ifp = &discif; + struct ifnet *ifp; + struct disc_softc *sc; - ifp->if_name = "ds"; + sc = malloc(sizeof(struct disc_softc), M_DISC, M_WAITOK); + bzero(sc, sizeof(struct disc_softc)); + + ifp = &sc->sc_if; + + ifp->if_softc = sc; + ifp->if_name = DISCNAME; + ifp->if_unit = unit; ifp->if_mtu = DSMTU; ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST; ifp->if_ioctl = discioctl; @@ -85,6 +105,23 @@ discattach(void) ifp->if_snd.ifq_maxlen = 20; if_attach(ifp); bpfattach(ifp, DLT_NULL, sizeof(u_int)); + LIST_INSERT_HEAD(&disc_softc_list, sc, sc_list); + + return (0); +} + +static void +disc_clone_destroy(struct ifnet *ifp) +{ + struct disc_softc *sc; + + sc = ifp->if_softc; + + LIST_REMOVE(sc, sc_list); + bpfdetach(ifp); + if_detach(ifp); + + free(sc, M_DISC); } static int @@ -92,11 +129,16 @@ disc_modevent(module_t mod, int type, void *data) { switch (type) { case MOD_LOAD: - discattach(); + LIST_INIT(&disc_softc_list); + if_clone_attach(&disc_cloner); break; case MOD_UNLOAD: - printf("if_disc module unload - not possible for this module type\n"); - return EINVAL; + if_clone_detach(&disc_cloner); + + while (!LIST_EMPTY(&disc_softc_list)) + disc_clone_destroy( + &LIST_FIRST(&disc_softc_list)->sc_if); + break; } return 0; } @@ -123,7 +165,7 @@ discoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, m->m_data += sizeof(int); } - if (discif.if_bpf) { + if (ifp->if_bpf) { /* * We need to prepend the address family as * a four byte field. Cons up a dummy header @@ -138,7 +180,7 @@ discoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, m0.m_len = 4; m0.m_data = (char *)⁡ - bpf_mtap(&discif, &m0); + bpf_mtap(ifp, &m0); } m->m_pkthdr.rcvif = ifp; -- cgit v1.1