summaryrefslogtreecommitdiffstats
path: root/sys/net
diff options
context:
space:
mode:
authorps <ps@FreeBSD.org>2001-10-05 05:45:27 +0000
committerps <ps@FreeBSD.org>2001-10-05 05:45:27 +0000
commitd0afbb304af764bf12d6222552917b0f272c5201 (patch)
tree0b476ffbda93b6f592ea67ee5913d3d077fee0cf /sys/net
parentda7f535b3c9dff24f74f65a207240841d391ec18 (diff)
downloadFreeBSD-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.c82
-rw-r--r--sys/net/bridge.h15
-rw-r--r--sys/net/if_ethersubr.c42
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);
OpenPOWER on IntegriCloud