diff options
author | ps <ps@FreeBSD.org> | 2001-10-05 05:45:27 +0000 |
---|---|---|
committer | ps <ps@FreeBSD.org> | 2001-10-05 05:45:27 +0000 |
commit | d0afbb304af764bf12d6222552917b0f272c5201 (patch) | |
tree | 0b476ffbda93b6f592ea67ee5913d3d077fee0cf /sys/net | |
parent | da7f535b3c9dff24f74f65a207240841d391ec18 (diff) | |
download | FreeBSD-src-d0afbb304af764bf12d6222552917b0f272c5201.zip FreeBSD-src-d0afbb304af764bf12d6222552917b0f272c5201.tar.gz |
Make it so dummynet and bridge can be loaded as modules.
Submitted by: billf
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/bridge.c | 82 | ||||
-rw-r--r-- | sys/net/bridge.h | 15 | ||||
-rw-r--r-- | sys/net/if_ethersubr.c | 42 |
3 files changed, 82 insertions, 57 deletions
diff --git a/sys/net/bridge.c b/sys/net/bridge.c index f63a751..5823ecc 100644 --- a/sys/net/bridge.c +++ b/sys/net/bridge.c @@ -87,19 +87,20 @@ #include <netinet/ip.h> #include <netinet/if_ether.h> /* for struct arpcom */ +#if !defined(KLD_MODULE) #include "opt_ipfw.h" #include "opt_ipdn.h" +#endif -#if defined(IPFIREWALL) #include <net/route.h> #include <netinet/ip_fw.h> -#if defined(DUMMYNET) #include <netinet/ip_dummynet.h> -#endif -#endif - #include <net/bridge.h> +static struct ifnet *bridge_in(struct ifnet *, struct ether_header *); +static struct mbuf *bdg_forward(struct mbuf *, struct ether_header *const, struct ifnet *); +static void bdgtakeifaces(void); + /* * For debugging, you can use the following macros. * remember, rdtsc() only works on Pentium-class machines @@ -123,18 +124,14 @@ static void parse_bdg_cfg(void); static int bdg_initialized = 0; static int bdg_ipfw = 0 ; -int do_bridge = 0; bdg_hash_table *bdg_table = NULL ; /* * System initialization */ -SYSINIT(interfaces, SI_SUB_PROTO_IF, SI_ORDER_FIRST, bdginit, NULL) - static struct bdg_stats bdg_stats ; -struct bdg_softc *ifp2sc = NULL ; -/* XXX make it static of size BDG_MAX_PORTS */ +static struct callout_handle bdg_timeout_h ; #define IFP_CHK(ifp, x) \ if (ifp2sc[ifp->if_index].magic != 0xDEADBEEF) { x ; } @@ -337,7 +334,6 @@ SYSCTL_INT(_net_link_ether, OID_AUTO, bridge_ipfw_collisions, SYSCTL_PROC(_net_link_ether, OID_AUTO, bridge_refresh, CTLTYPE_INT|CTLFLAG_WR, NULL, 0, &sysctl_refresh, "I", "iface refresh"); -#if 1 /* diagnostic vars */ SY(_net_link_ether, verbose, "Be verbose"); SY(_net_link_ether, bdg_split_pkts, "Packets split in bdg_forward"); @@ -352,7 +348,6 @@ SY(_net_link_ether, bdg_predict, "Correctly predicted header location"); SY(_net_link_ether, bdg_fw_avg, "Cycle counter avg"); SY(_net_link_ether, bdg_fw_ticks, "Cycle counter item"); SY(_net_link_ether, bdg_fw_count, "Cycle counter count"); -#endif SYSCTL_STRUCT(_net_link_ether, PF_BDG, bdgstats, CTLFLAG_RD, &bdg_stats , bdg_stats, "bridge statistics"); @@ -408,7 +403,7 @@ bdg_timeout(void *dummy) bdg_loops = 0 ; } } - timeout(bdg_timeout, (void *)0, 2*hz ); + bdg_timeout_h = timeout(bdg_timeout, NULL, 2*hz ); } /* @@ -442,7 +437,7 @@ bdginit(void *dummy) do_bridge=0; } -void +static void bdgtakeifaces(void) { int i ; @@ -457,7 +452,7 @@ bdgtakeifaces(void) bdg_ports = 0 ; *bridge_cfg = '\0'; - printf("BRIDGE 010131, have %d interfaces\n", if_index); + printf("BRIDGE 011004, have %d interfaces\n", if_index); for (i = 0 , ifp = TAILQ_FIRST(&ifnet) ; i < if_index ; i++, ifp = TAILQ_NEXT(ifp, if_link)) if (ifp->if_type == IFT_ETHER) { /* ethernet ? */ @@ -503,7 +498,7 @@ bdgtakeifaces(void) * to fetch more of the packet, or simply drop it completely. */ -struct ifnet * +static struct ifnet * bridge_in(struct ifnet *ifp, struct ether_header *eh) { int index; @@ -607,7 +602,7 @@ bridge_in(struct ifnet *ifp, struct ether_header *eh) * * XXX be careful about eh, it can be a pointer into *m */ -struct mbuf * +static struct mbuf * bdg_forward(struct mbuf *m0, struct ether_header *const eh, struct ifnet *dst) { struct ifnet *src = m0->m_pkthdr.rcvif; /* could be NULL in output */ @@ -615,9 +610,7 @@ bdg_forward(struct mbuf *m0, struct ether_header *const eh, struct ifnet *dst) int shared = bdg_copy ; /* someone else is using the mbuf */ int once = 0; /* loop only once */ struct ifnet *real_dst = dst ; /* real dst from ether_output */ -#ifdef IPFIREWALL struct ip_fw *rule = NULL ; /* did we match a firewall rule ? */ -#endif /* * XXX eh is usually a pointer within the mbuf (some ethernet drivers @@ -628,7 +621,6 @@ bdg_forward(struct mbuf *m0, struct ether_header *const eh, struct ifnet *dst) DEB(quad_t ticks; ticks = rdtsc();) -#if defined(IPFIREWALL) && defined(DUMMYNET) if (m0->m_type == MT_DUMMYNET) { /* extract info from dummynet header */ rule = (struct ip_fw *)(m0->m_data) ; @@ -636,7 +628,6 @@ bdg_forward(struct mbuf *m0, struct ether_header *const eh, struct ifnet *dst) src = m0->m_pkthdr.rcvif; shared = 0 ; /* For sure this is our own mbuf. */ } else -#endif bdg_thru++; /* only count once */ if (src == NULL) /* packet from ether_output */ @@ -663,7 +654,6 @@ bdg_forward(struct mbuf *m0, struct ether_header *const eh, struct ifnet *dst) if ( (u_int)(ifp) <= (u_int)BDG_FORWARD ) panic("bdg_forward: bad dst"); -#ifdef IPFIREWALL /* * Do filtering in a very similar way to what is done in ip_output. * Only if firewall is loaded, enabled, and the packet is not @@ -721,8 +711,7 @@ bdg_forward(struct mbuf *m0, struct ether_header *const eh, struct ifnet *dst) if (i == 0) /* a PASS rule. */ goto forward ; -#ifdef DUMMYNET - if (i & IP_FW_PORT_DYNT_FLAG) { + if (do_bridge && ip_dn_io_ptr != NULL && (i & IP_FW_PORT_DYNT_FLAG)) { /* * Pass the pkt to dummynet, which consumes it. * If shared, make a copy and keep the original. @@ -752,10 +741,9 @@ bdg_forward(struct mbuf *m0, struct ether_header *const eh, struct ifnet *dst) return m0 ; bcopy(&save_eh, mtod(m, struct ether_header *), ETHER_HDR_LEN); } - dummynet_io((i & 0xffff),DN_TO_BDG_FWD,m,real_dst,NULL,0,rule,0); + ip_dn_io_ptr((i & 0xffff),DN_TO_BDG_FWD,m,real_dst,NULL,0,rule,0); return m0 ; } -#endif /* * XXX add divert/forward actions... */ @@ -765,7 +753,6 @@ bdg_forward(struct mbuf *m0, struct ether_header *const eh, struct ifnet *dst) return m0 ; } forward: -#endif /* IPFIREWALL */ /* * Again, bring up the headers in case of shared bufs to avoid * corruptions in the future. @@ -841,3 +828,44 @@ forward: if (bdg_fw_count != 0) bdg_fw_avg = bdg_fw_ticks/bdg_fw_count; ) return m0 ; } + +static int +bridge_modevent(module_t mod, int type, void *unused) +{ + int s; + + s = splimp(); + switch (type) { + case MOD_LOAD: + bridge_in_ptr = bridge_in; + bdg_forward_ptr = bdg_forward; + bdgtakeifaces_ptr = bdgtakeifaces; + bdginit(NULL); + break; + case MOD_UNLOAD: + s = splimp(); + do_bridge = 0; + bridge_in_ptr = NULL; + bdg_forward_ptr = NULL; + bdgtakeifaces_ptr = NULL; + untimeout(bdg_timeout, NULL, bdg_timeout_h); + if (bdg_table != NULL) + free(bdg_table, M_IFADDR); + if (ifp2sc != NULL) + free(ifp2sc, M_IFADDR); + break; + default: + break; + } + splx(s); + return 0; +} + +static moduledata_t bridge_mod = { + "bridge", + bridge_modevent, + 0 +}; + +DECLARE_MODULE(bridge, bridge_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); +MODULE_VERSION(bridge, 1); diff --git a/sys/net/bridge.h b/sys/net/bridge.h index 4f81ebe..82db1ca 100644 --- a/sys/net/bridge.h +++ b/sys/net/bridge.h @@ -76,8 +76,6 @@ typedef struct _bdg_addr { extern bdg_addr bdg_addresses[BDG_MAX_PORTS]; extern int bdg_ports ; -extern void bdgtakeifaces(void); - /* * out of the 6 bytes, the last ones are more "variable". Since * we are on a little endian machine, we have to do some gimmick... @@ -86,10 +84,6 @@ extern void bdgtakeifaces(void); #define HASH_FN(addr) ( \ ntohs( ((short *)addr)[1] ^ ((short *)addr)[2] ) & (HASH_SIZE -1)) -struct ifnet *bridge_in(struct ifnet *ifp, struct ether_header *eh); -/* bdg_forward frees the mbuf if necessary, returning null */ -struct mbuf *bdg_forward(struct mbuf *m0, struct ether_header *eh, struct ifnet *dst); - #ifdef __i386__ #define BDG_MATCH(a,b) ( \ ((unsigned short *)(a))[2] == ((unsigned short *)(b))[2] && \ @@ -136,6 +130,15 @@ struct bdg_stats { #define BDG_STAT(ifp, type) bdg_stats.s[ifp->if_index].p_in[(int)type]++ #ifdef _KERNEL +typedef struct ifnet *bridge_in_t(struct ifnet *, struct ether_header *); +/* bdg_forward frees the mbuf if necessary, returning null */ +typedef struct mbuf *bdg_forward_t(struct mbuf *, struct ether_header *const, + struct ifnet *); +typedef void bdgtakeifaces_t(void); +extern bridge_in_t *bridge_in_ptr; +extern bdg_forward_t *bdg_forward_ptr; +extern bdgtakeifaces_t *bdgtakeifaces_ptr; + /* * Find the right pkt destination: * BDG_BCAST is a broadcast diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index 0031af8..2e7a49a 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -59,6 +59,7 @@ #include <net/if_types.h> #include <net/bpf.h> #include <net/ethernet.h> +#include <net/bridge.h> #if defined(INET) || defined(INET6) #include <netinet/in.h> @@ -97,10 +98,6 @@ extern u_char at_org_code[3]; extern u_char aarp_org_code[3]; #endif /* NETATALK */ -#ifdef BRIDGE -#include <net/bridge.h> -#endif - /* netgraph node hooks for ng_ether(4) */ void (*ng_ether_input_p)(struct ifnet *ifp, struct mbuf **mp, struct ether_header *eh); @@ -114,6 +111,13 @@ int (*vlan_input_p)(struct ether_header *eh, struct mbuf *m); int (*vlan_input_tag_p)(struct ether_header *eh, struct mbuf *m, u_int16_t t); +/* bridge support */ +int do_bridge = 0; +bridge_in_t *bridge_in_ptr; +bdg_forward_t *bdg_forward_ptr; +bdgtakeifaces_t *bdgtakeifaces_ptr; +struct bdg_softc *ifp2sc = NULL; + static int ether_resolvemulti __P((struct ifnet *, struct sockaddr **, struct sockaddr *)); u_char etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; @@ -360,19 +364,17 @@ ether_output_frame(ifp, m) { int error = 0; -#ifdef BRIDGE - if (do_bridge && BDG_USED(ifp) ) { + if (do_bridge && bdg_forward_ptr != NULL && BDG_USED(ifp) ) { struct ether_header *eh; /* a ptr suffices */ m->m_pkthdr.rcvif = NULL; eh = mtod(m, struct ether_header *); m_adj(m, ETHER_HDR_LEN); - m = bdg_forward(m, eh, ifp); + m = bdg_forward_ptr(m, eh, ifp); if (m != NULL) m_freem(m); return (0); } -#endif /* * Queue message on interface, update output statistics if @@ -406,9 +408,7 @@ ether_input(ifp, eh, m) struct ether_header *eh; struct mbuf *m; { -#ifdef BRIDGE struct ether_header save_eh; -#endif /* Check for a BPF tap */ if (ifp->if_bpf != NULL) { @@ -428,13 +428,12 @@ ether_input(ifp, eh, m) return; } -#ifdef BRIDGE /* Check for bridging mode */ - if (do_bridge && BDG_USED(ifp) ) { + if (do_bridge && bdg_forward_ptr != NULL && BDG_USED(ifp) ) { struct ifnet *bif; /* Check with bridging code */ - if ((bif = bridge_in(ifp, eh)) == BDG_DROP) { + if ((bif = bridge_in_ptr(ifp, eh)) == BDG_DROP) { m_freem(m); return; } @@ -442,9 +441,9 @@ ether_input(ifp, eh, m) struct mbuf *oldm = m ; save_eh = *eh ; /* because it might change */ - m = bdg_forward(m, eh, bif); /* needs forwarding */ + m = bdg_forward_ptr(m, eh, bif); /* needs forwarding */ /* - * Do not continue if bdg_forward() processed our + * Do not continue if bdg_forward_ptr() processed our * packet (and cleared the mbuf pointer m) or if * it dropped (m_free'd) the packet itself. */ @@ -466,11 +465,8 @@ ether_input(ifp, eh, m) m_freem(m); return; } -#endif -#ifdef BRIDGE recvLocal: -#endif /* Continue with upper layer processing */ ether_demux(ifp, eh, m); /* First chunk of an mbuf contains good junk */ @@ -677,9 +673,8 @@ ether_ifattach(ifp, bpf) bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header)); if (ng_ether_attach_p != NULL) (*ng_ether_attach_p)(ifp); -#ifdef BRIDGE - bdgtakeifaces(); -#endif + if (bdgtakeifaces_ptr != NULL) + bdgtakeifaces_ptr(); } /* @@ -695,9 +690,8 @@ ether_ifdetach(ifp, bpf) if (bpf) bpfdetach(ifp); if_detach(ifp); -#ifdef BRIDGE - bdgtakeifaces(); -#endif + if (bdgtakeifaces_ptr != NULL) + bdgtakeifaces_ptr(); } SYSCTL_DECL(_net_link); |