diff options
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/if_faith.c | 187 | ||||
-rw-r--r-- | sys/net/if_faith.h | 43 |
2 files changed, 142 insertions, 88 deletions
diff --git a/sys/net/if_faith.c b/sys/net/if_faith.c index 631049f..1dac1b6 100644 --- a/sys/net/if_faith.c +++ b/sys/net/if_faith.c @@ -46,9 +46,6 @@ #include "opt_inet.h" #include "opt_inet6.h" -#include "faith.h" -#if NFAITH > 0 - #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> @@ -58,13 +55,16 @@ #include <sys/sockio.h> #include <sys/time.h> #include <sys/queue.h> +#include <sys/types.h> +#include <sys/malloc.h> +#include <machine/bus.h> /* XXX: Shouldn't really be required! */ +#include <sys/rman.h> #include <net/if.h> #include <net/if_types.h> #include <net/netisr.h> #include <net/route.h> #include <net/bpf.h> -#include <net/if_faith.h> #ifdef INET #include <netinet/in.h> @@ -82,54 +82,157 @@ #include <netinet6/ip6_var.h> #endif -#include "bpf.h" -#define NBPFILTER NBPF - #include <net/net_osdep.h> +#define FAITHNAME "faith" +#define FAITH_MAXUNIT 0x7fff /* ifp->if_unit is only 15 bits */ + +struct faith_softc { + struct ifnet sc_if; /* must be first */ + struct resource *r_unit; + LIST_ENTRY(faith_softc) sc_list; +}; + static int faithioctl __P((struct ifnet *, u_long, caddr_t)); int faithoutput __P((struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *)); static void faithrtrequest __P((int, struct rtentry *, struct sockaddr *)); +static int faithprefix __P((struct in6_addr *)); + +static int faithmodevent __P((module_t, int, void *)); + +static MALLOC_DEFINE(M_FAITH, FAITHNAME, "Firewall Assisted Tunnel Interface"); +static struct rman faithunits[1]; +LIST_HEAD(, faith_softc) faith_softc_list; -void faithattach __P((void *)); -PSEUDO_SET(faithattach, if_faith); +int faith_clone_create __P((struct if_clone *, int *)); +void faith_clone_destroy __P((struct ifnet *)); -static struct ifnet faithif[NFAITH]; +struct if_clone faith_cloner = + IF_CLONE_INITIALIZER(FAITHNAME, faith_clone_create, faith_clone_destroy); #define FAITHMTU 1500 -/* ARGSUSED */ -void -faithattach(faith) - void *faith; +static int +faithmodevent(mod, type, data) + module_t mod; + int type; + void *data; { - struct ifnet *ifp; - int i; - - for (i = 0; i < NFAITH; i++) { - ifp = &faithif[i]; - bzero(ifp, sizeof(faithif[i])); - ifp->if_name = "faith"; - ifp->if_unit = i; - ifp->if_mtu = FAITHMTU; - /* LOOPBACK commented out to announce IPv6 routes to faith */ - ifp->if_flags = /* IFF_LOOPBACK | */ IFF_MULTICAST; - ifp->if_ioctl = faithioctl; - ifp->if_output = faithoutput; - ifp->if_type = IFT_FAITH; - ifp->if_snd.ifq_maxlen = ifqmaxlen; - ifp->if_hdrlen = 0; - ifp->if_addrlen = 0; - if_attach(ifp); -#if NBPFILTER > 0 -#ifdef HAVE_OLD_BPF - bpfattach(ifp, DLT_NULL, sizeof(u_int)); -#else - bpfattach(&ifp->if_bpf, ifp, DLT_NULL, sizeof(u_int)); + int err; + + switch (type) { + case MOD_LOAD: + faithunits->rm_type = RMAN_ARRAY; + faithunits->rm_descr = "configurable if_faith units"; + err = rman_init(faithunits); + if (err != 0) + return (err); + err = rman_manage_region(faithunits, 0, FAITH_MAXUNIT); + if (err != 0) { + printf("%s: faithunits: rman_manage_region: " + "Failed %d\n", FAITHNAME, err); + rman_fini(faithunits); + return (err); + } + LIST_INIT(&faith_softc_list); + if_clone_attach(&faith_cloner); + +#ifdef INET6 + faithprefix_p = faithprefix; #endif + + break; + case MOD_UNLOAD: +#ifdef INET6 + faithprefix_p = NULL; #endif + + if_clone_detach(&faith_cloner); + + while (!LIST_EMPTY(&faith_softc_list)) + faith_clone_destroy( + &LIST_FIRST(&faith_softc_list)->sc_if); + + err = rman_fini(faithunits); + if (err != 0) + return (err); + + break; } + return 0; +} + +static moduledata_t faith_mod = { + "if_faith", + faithmodevent, + 0 +}; + +DECLARE_MODULE(if_faith, faith_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); +MODULE_VERSION(if_faith, 1); + +int +faith_clone_create(ifc, unit) + struct if_clone *ifc; + int *unit; +{ + struct resource *r; + struct faith_softc *sc; + + if (*unit > FAITH_MAXUNIT) + return (ENXIO); + + if (*unit < 0) { + r = rman_reserve_resource(faithunits, 0, FAITH_MAXUNIT, 1, + RF_ALLOCATED | RF_ACTIVE, NULL); + if (r == NULL) + return (ENOSPC); + *unit = rman_get_start(r); + } else { + r = rman_reserve_resource(faithunits, *unit, *unit, 1, + RF_ALLOCATED | RF_ACTIVE, NULL); + if (r == NULL) + return (ENOSPC); + } + + sc = malloc(sizeof(struct faith_softc), M_FAITH, M_WAITOK); + bzero(sc, sizeof(struct faith_softc)); + + sc->sc_if.if_softc = sc; + sc->sc_if.if_name = FAITHNAME; + sc->sc_if.if_unit = *unit; + sc->r_unit = r; + + sc->sc_if.if_mtu = FAITHMTU; + /* Change to BROADCAST experimentaly to announce its prefix. */ + sc->sc_if.if_flags = /* IFF_LOOPBACK */ IFF_BROADCAST | IFF_MULTICAST; + sc->sc_if.if_ioctl = faithioctl; + sc->sc_if.if_output = faithoutput; + sc->sc_if.if_type = IFT_FAITH; + sc->sc_if.if_hdrlen = 0; + sc->sc_if.if_addrlen = 0; + if_attach(&sc->sc_if); + bpfattach(&sc->sc_if, DLT_NULL, sizeof(u_int)); + LIST_INSERT_HEAD(&faith_softc_list, sc, sc_list); + return (0); +} + +void +faith_clone_destroy(ifp) + struct ifnet *ifp; +{ + int err; + struct faith_softc *sc = (void *) ifp; + + LIST_REMOVE(sc, sc_list); + bpfdetach(ifp); + if_detach(ifp); + + err = rman_release_resource(sc->r_unit); + KASSERT(err == 0, ("Unexpected error freeing resource")); + + free(sc, M_FAITH); } int @@ -144,7 +247,7 @@ faithoutput(ifp, m, dst, rt) if ((m->m_flags & M_PKTHDR) == 0) panic("faithoutput no HDR"); -#if NBPFILTER > 0 + /* BPF write needs to be handled specially */ if (dst->sa_family == AF_UNSPEC) { dst->sa_family = *(mtod(m, int *)); @@ -168,13 +271,8 @@ faithoutput(ifp, m, dst, rt) m0.m_len = 4; m0.m_data = (char *)⁡ -#ifdef HAVE_OLD_BPF bpf_mtap(ifp, &m0); -#else - bpf_mtap(ifp->if_bpf, &m0); -#endif } -#endif if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) { m_freem(m); @@ -297,7 +395,7 @@ faithioctl(ifp, cmd, data) * XXX could be slow * XXX could be layer violation to call sys/net from sys/netinet6 */ -int +static int faithprefix(in6) struct in6_addr *in6; { @@ -323,4 +421,3 @@ faithprefix(in6) return ret; } #endif -#endif /* NFAITH > 0 */ diff --git a/sys/net/if_faith.h b/sys/net/if_faith.h deleted file mode 100644 index 7fa9b5a..0000000 --- a/sys/net/if_faith.h +++ /dev/null @@ -1,43 +0,0 @@ -/* $FreeBSD$ */ -/* $KAME: if_faith.h,v 1.1 2000/07/26 05:49:21 itojun Exp $ */ - -/* - * Copyright (C) 2000 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef _NET_IF_FAITH_H_ -#define _NET_IF_FAITH_H_ - -#ifdef _KERNEL -#ifdef INET6 -struct in6_addr; -int faithprefix __P((struct in6_addr *)); -#endif -#endif - -#endif /* _NET_IF_FAITH_H_ */ |