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 | |
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
-rw-r--r-- | sys/modules/bridge/Makefile | 8 | ||||
-rw-r--r-- | sys/modules/dummynet/Makefile | 9 | ||||
-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 | ||||
-rw-r--r-- | sys/netinet/ip_dummynet.c | 135 | ||||
-rw-r--r-- | sys/netinet/ip_dummynet.h | 19 | ||||
-rw-r--r-- | sys/netinet/ip_fw.c | 18 | ||||
-rw-r--r-- | sys/netinet/ip_input.c | 22 | ||||
-rw-r--r-- | sys/netinet/ip_output.c | 11 | ||||
-rw-r--r-- | sys/netinet/raw_ip.c | 16 |
11 files changed, 201 insertions, 176 deletions
diff --git a/sys/modules/bridge/Makefile b/sys/modules/bridge/Makefile new file mode 100644 index 0000000..7f9835a --- /dev/null +++ b/sys/modules/bridge/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../net +KMOD= bridge +SRCS= bridge.c +NOMAN= + +.include <bsd.kmod.mk> diff --git a/sys/modules/dummynet/Makefile b/sys/modules/dummynet/Makefile new file mode 100644 index 0000000..6ba65ec --- /dev/null +++ b/sys/modules/dummynet/Makefile @@ -0,0 +1,9 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../netinet +KMOD= dummynet +SRCS= ip_dummynet.c opt_bdg.h +NOMAN= +KMODDEPS= ipfw + +.include <bsd.kmod.mk> 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); diff --git a/sys/netinet/ip_dummynet.c b/sys/netinet/ip_dummynet.c index cdadd37..a1a61ca 100644 --- a/sys/netinet/ip_dummynet.c +++ b/sys/netinet/ip_dummynet.c @@ -47,6 +47,7 @@ * * Most important Changes: * + * 011004: KLDable * 010124: Fixed WF2Q behaviour * 010122: Fixed spl protection. * 000601: WF2Q support @@ -78,11 +79,11 @@ #include <netinet/ip_dummynet.h> #include <netinet/ip_var.h> +#if !defined(KLD_MODULE) #include "opt_bdg.h" -#ifdef BRIDGE +#endif #include <netinet/if_ether.h> /* for struct arpcom */ #include <net/bridge.h> -#endif /* * We keep a private variable for the simulation time, but we could @@ -111,6 +112,9 @@ static int red_max_pkt_size = 1500; /* RED - default max packet size */ * extract_heap contains pipes associated with delay lines. * */ + +MALLOC_DEFINE(M_DUMMYNET, "dummynet", "dummynet heap"); + static struct dn_heap ready_heap, extract_heap, wfq_ready_heap ; static int heap_init(struct dn_heap *h, int size) ; @@ -123,6 +127,8 @@ static void ready_event(struct dn_flow_queue *q); static struct dn_pipe *all_pipes = NULL ; /* list of all pipes */ static struct dn_flow_set *all_flow_sets = NULL ;/* list of all flow_sets */ +static struct callout_handle dn_timeout; + #ifdef SYSCTL_NODE SYSCTL_NODE(_net_inet_ip, OID_AUTO, dummynet, CTLFLAG_RW, 0, "Dummynet"); @@ -158,6 +164,10 @@ static void rt_unref(struct rtentry *); static void dummynet(void *); static void dummynet_flush(void); void dummynet_drain(void); +static int dummynet_io(int pipe, int dir, struct mbuf *m, struct ifnet *ifp, + struct route *ro, struct sockaddr_in * dst, + struct ip_fw *rule, int flags); +void dn_rule_delete(void *); int if_tx_rdy(struct ifnet *ifp); @@ -207,14 +217,14 @@ heap_init(struct dn_heap *h, int new_size) return 0 ; } new_size = (new_size + HEAP_INCREMENT ) & ~HEAP_INCREMENT ; - p = malloc(new_size * sizeof(*p), M_IPFW, M_DONTWAIT ); + p = malloc(new_size * sizeof(*p), M_DUMMYNET, M_DONTWAIT ); if (p == NULL) { printf(" heap_init, resize %d failed\n", new_size ); return 1 ; /* error */ } if (h->size > 0) { bcopy(h->p, p, h->size * sizeof(*p) ); - free(h->p, M_IPFW); + free(h->p, M_DUMMYNET); } h->p = p ; h->size = new_size ; @@ -375,7 +385,7 @@ static void heap_free(struct dn_heap *h) { if (h->size >0 ) - free(h->p, M_IPFW); + free(h->p, M_DUMMYNET); bzero(h, sizeof(*h) ); } @@ -433,40 +443,38 @@ transmit_event(struct dn_pipe *pipe) ip_input((struct mbuf *)pkt) ; break ; -#ifdef BRIDGE - case DN_TO_BDG_FWD : { - struct mbuf *m = (struct mbuf *)pkt; - struct ether_header *eh; + case DN_TO_BDG_FWD : + if (bdg_forward_ptr != NULL) { + struct mbuf *m = (struct mbuf *)pkt; + struct ether_header *eh; - if (pkt->dn_m->m_len < ETHER_HDR_LEN - && (pkt->dn_m = m_pullup(pkt->dn_m, ETHER_HDR_LEN)) == NULL) { - printf("dummynet/bridge: pullup fail, dropping pkt\n"); - break; - } - /* - * same as ether_input, make eh be a pointer into the mbuf - */ - eh = mtod(pkt->dn_m, struct ether_header *); - m_adj(pkt->dn_m, ETHER_HDR_LEN); - /* - * bdg_forward() wants a pointer to the pseudo-mbuf-header, but - * on return it will supply the pointer to the actual packet - * (originally pkt->dn_m, but could be something else now) if - * it has not consumed it. - */ - m = bdg_forward(m, eh, pkt->ifp); - if (m) - m_freem(m); + if (pkt->dn_m->m_len < ETHER_HDR_LEN && + (pkt->dn_m = m_pullup(pkt->dn_m, ETHER_HDR_LEN)) == NULL) { + printf("dummynet/bridge: pullup fail, dropping pkt\n"); + break; + } + /* + * same as ether_input, make eh be a pointer into the mbuf + */ + eh = mtod(pkt->dn_m, struct ether_header *); + m_adj(pkt->dn_m, ETHER_HDR_LEN); + /* + * bdg_forward_ptr() wants a pointer to the pseudo-mbuf-header, + * but on return it will supply the pointer to the actual packet + * (originally pkt->dn_m, but could be something else now) if + * it has not consumed it. + */ + m = bdg_forward_ptr(m, eh, pkt->ifp); + if (m) + m_freem(m); } break ; -#endif - default: printf("dummynet: bad switch %d!\n", pkt->dn_dir); m_freem(pkt->dn_m); break ; } - FREE(pkt, M_IPFW); + FREE(pkt, M_DUMMYNET); } /* if there are leftover packets, put into the heap for next event */ if ( (pkt = pipe->head) ) @@ -741,7 +749,7 @@ dummynet(void * __unused unused) pe->sum -= q->fs->weight ; } splx(s); - timeout(dummynet, NULL, 1); + dn_timeout = timeout(dummynet, NULL, 1); } /* @@ -800,7 +808,7 @@ expire_queues(struct dn_flow_set *fs) else fs->rq[i] = q = q->next ; fs->rq_elements-- ; - free(old_q, M_IPFW); + free(old_q, M_DUMMYNET); } return initial_elements - fs->rq_elements ; } @@ -823,7 +831,7 @@ create_queue(struct dn_flow_set *fs, int i) if ( fs->rq[i] != NULL ) return fs->rq[i] ; } - q = malloc(sizeof(*q), M_IPFW, M_DONTWAIT | M_ZERO); /* M_ZERO needed */ + q = malloc(sizeof(*q), M_DUMMYNET, M_DONTWAIT | M_ZERO); /* M_ZERO needed */ if (q == NULL) { printf("sorry, cannot allocate queue for new flow\n"); return NULL ; @@ -881,7 +889,7 @@ find_queue(struct dn_flow_set *fs) else fs->rq[i] = q = q->next ; fs->rq_elements-- ; - free(old_q, M_IPFW); + free(old_q, M_DUMMYNET); continue ; } prev = q ; @@ -1084,7 +1092,7 @@ dummynet_io(int pipe_nr, int dir, /* pipe_nr can also be a fs_nr */ goto dropit ; /* XXX expensive to zero, see if we can remove it*/ - pkt = (struct dn_pkt *)malloc(sizeof (*pkt), M_IPFW, M_NOWAIT | M_ZERO); + pkt = (struct dn_pkt *)malloc(sizeof (*pkt), M_DUMMYNET, M_NOWAIT | M_ZERO); if ( pkt == NULL ) goto dropit ; /* cannot allocate packet header */ /* ok, i can handle the pkt now... */ @@ -1211,7 +1219,7 @@ dropit: rt_unref ( n->ro.ro_rt ) ; \ m_freem(n->dn_m); \ pkt = DN_NEXT(n) ; \ - free(n, M_IPFW) ; } + free(n, M_DUMMYNET) ; } /* * Dispose all packets and flow_queues on a flow_set. @@ -1231,7 +1239,7 @@ purge_flow_set(struct dn_flow_set *fs, int all) for (pkt = q->head ; pkt ; ) DN_FREE_PKT(pkt) ; qn = q->next ; - free(q, M_IPFW); + free(q, M_DUMMYNET); } fs->rq[i] = NULL ; } @@ -1239,12 +1247,12 @@ purge_flow_set(struct dn_flow_set *fs, int all) if (all) { /* RED - free lookup table */ if (fs->w_q_lookup) - free(fs->w_q_lookup, M_IPFW); + free(fs->w_q_lookup, M_DUMMYNET); if (fs->rq) - free(fs->rq, M_IPFW); + free(fs->rq, M_DUMMYNET); /* if this fs is not part of a pipe, free it */ if (fs->pipe && fs != &(fs->pipe->fs) ) - free(fs, M_IPFW); + free(fs, M_DUMMYNET); } } @@ -1308,7 +1316,7 @@ dummynet_flush() purge_pipe(p); curr_p = p ; p = p->next ; - free(curr_p, M_IPFW); + free(curr_p, M_DUMMYNET); } } @@ -1376,18 +1384,18 @@ config_red(struct dn_flow_set *p, struct dn_flow_set * x) /* if the lookup table already exist, free and create it again */ if (x->w_q_lookup) - free(x->w_q_lookup, M_IPFW); + free(x->w_q_lookup, M_DUMMYNET); if (red_lookup_depth == 0) { printf("\nnet.inet.ip.dummynet.red_lookup_depth must be > 0"); - free(x, M_IPFW); + free(x, M_DUMMYNET); return EINVAL; } x->lookup_depth = red_lookup_depth; x->w_q_lookup = (u_int *) malloc(x->lookup_depth * sizeof(int), - M_IPFW, M_DONTWAIT); + M_DUMMYNET, M_DONTWAIT); if (x->w_q_lookup == NULL) { printf("sorry, cannot allocate red lookup table\n"); - free(x, M_IPFW); + free(x, M_DUMMYNET); return ENOSPC; } @@ -1422,7 +1430,7 @@ alloc_hash(struct dn_flow_set *x, struct dn_flow_set *pfs) } else /* one is enough for null mask */ x->rq_size = 1; x->rq = malloc((1 + x->rq_size) * sizeof(struct dn_flow_queue *), - M_IPFW, M_DONTWAIT | M_ZERO); + M_DUMMYNET, M_DONTWAIT | M_ZERO); if (x->rq == NULL) { printf("sorry, cannot allocate queue\n"); return ENOSPC; @@ -1481,7 +1489,7 @@ config_pipe(struct dn_pipe *p) a = b , b = b->next) ; if (b == NULL || b->pipe_nr != p->pipe_nr) { /* new pipe */ - x = malloc(sizeof(struct dn_pipe), M_IPFW, M_DONTWAIT | M_ZERO); + x = malloc(sizeof(struct dn_pipe), M_DUMMYNET, M_DONTWAIT | M_ZERO); if (x == NULL) { printf("ip_dummynet.c: no memory for new pipe\n"); return ENOSPC; @@ -1506,7 +1514,7 @@ config_pipe(struct dn_pipe *p) if ( x->fs.rq == NULL ) { /* a new pipe */ s = alloc_hash(&(x->fs), pfs) ; if (s) { - free(x, M_IPFW); + free(x, M_DUMMYNET); return s ; } s = splimp() ; @@ -1527,7 +1535,7 @@ config_pipe(struct dn_pipe *p) if (b == NULL || b->fs_nr != pfs->fs_nr) { /* new */ if (pfs->parent_nr == 0) /* need link to a pipe */ return EINVAL ; - x = malloc(sizeof(struct dn_flow_set), M_IPFW, M_DONTWAIT | M_ZERO); + x = malloc(sizeof(struct dn_flow_set), M_DUMMYNET, M_DONTWAIT | M_ZERO); if (x == NULL) { printf("ip_dummynet.c: no memory for new flow_set\n"); return ENOSPC; @@ -1550,7 +1558,7 @@ config_pipe(struct dn_pipe *p) if ( x->rq == NULL ) { /* a new flow_set */ s = alloc_hash(x, pfs) ; if (s) { - free(x, M_IPFW); + free(x, M_DUMMYNET); return s ; } s = splimp() ; @@ -1677,7 +1685,7 @@ delete_pipe(struct dn_pipe *p) pipe_remove_from_heap(&extract_heap, b); pipe_remove_from_heap(&wfq_ready_heap, b); splx(s); - free(b, M_IPFW); + free(b, M_DUMMYNET); } else { /* this is a WF2Q queue (dn_flow_set) */ struct dn_flow_set *a, *b; @@ -1860,7 +1868,7 @@ ip_dn_ctl(struct sockopt *sopt) static void ip_dn_init(void) { - printf("DUMMYNET initialized (010124)\n"); + printf("DUMMYNET initialized (011004)\n"); all_pipes = NULL ; all_flow_sets = NULL ; ready_heap.size = ready_heap.elements = 0 ; @@ -1872,27 +1880,30 @@ ip_dn_init(void) extract_heap.size = extract_heap.elements = 0 ; extract_heap.offset = 0 ; ip_dn_ctl_ptr = ip_dn_ctl; - timeout(dummynet, NULL, 1); + ip_dn_ruledel_ptr = dn_rule_delete; + ip_dn_io_ptr = dummynet_io; + bzero(&dn_timeout, sizeof(struct callout_handle)); + dn_timeout = timeout(dummynet, NULL, 1); } -static ip_dn_ctl_t *old_dn_ctl_ptr ; - static int dummynet_modevent(module_t mod, int type, void *data) { - int s ; + int s; switch (type) { case MOD_LOAD: s = splimp(); - old_dn_ctl_ptr = ip_dn_ctl_ptr; ip_dn_init(); splx(s); break; case MOD_UNLOAD: + untimeout(dummynet, NULL, dn_timeout); + dummynet_flush(); s = splimp(); - ip_dn_ctl_ptr = old_dn_ctl_ptr; + ip_dn_ctl_ptr = NULL; + ip_dn_io_ptr = NULL; + ip_dn_ruledel_ptr = NULL; splx(s); - dummynet_flush(); break ; default: break ; @@ -1904,5 +1915,7 @@ static moduledata_t dummynet_mod = { "dummynet", dummynet_modevent, NULL -} ; +}; DECLARE_MODULE(dummynet, dummynet_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); +MODULE_DEPEND(dummynet, ipfw, 1, 1, 1); +MODULE_VERSION(dummynet, 1); diff --git a/sys/netinet/ip_dummynet.h b/sys/netinet/ip_dummynet.h index 279ae36..16cff51 100644 --- a/sys/netinet/ip_dummynet.h +++ b/sys/netinet/ip_dummynet.h @@ -340,17 +340,14 @@ struct dn_pipe { /* a pipe */ }; #ifdef _KERNEL - -MALLOC_DECLARE(M_IPFW); - -typedef int ip_dn_ctl_t (struct sockopt *) ; -extern ip_dn_ctl_t *ip_dn_ctl_ptr; - -void dn_rule_delete(void *r); /* used in ip_fw.c */ -int dummynet_io(int pipe, int dir, - struct mbuf *m, struct ifnet *ifp, struct route *ro, - struct sockaddr_in * dst, - struct ip_fw *rule, int flags); +typedef int ip_dn_ctl_t(struct sockopt *); /* raw_ip.c */ +typedef void ip_dn_ruledel_t(void *); /* ip_fw.c */ +typedef int ip_dn_io_t(int pipe, int dir, struct mbuf *m, + struct ifnet *ifp, struct route *ro, struct sockaddr_in * dst, + struct ip_fw *rule, int flags); /* ip_{in,out}put.c, bridge.c */ +extern ip_dn_ctl_t *ip_dn_ctl_ptr; +extern ip_dn_ruledel_t *ip_dn_ruledel_ptr; +extern ip_dn_io_t *ip_dn_io_ptr; #endif #endif /* _IP_DUMMYNET_H */ diff --git a/sys/netinet/ip_fw.c b/sys/netinet/ip_fw.c index f2b31e8..fbd2e90 100644 --- a/sys/netinet/ip_fw.c +++ b/sys/netinet/ip_fw.c @@ -54,9 +54,7 @@ #include <netinet/ip_var.h> #include <netinet/ip_icmp.h> #include <netinet/ip_fw.h> -#ifdef DUMMYNET #include <netinet/ip_dummynet.h> -#endif #include <netinet/tcp.h> #include <netinet/tcp_timer.h> #include <netinet/tcp_var.h> @@ -236,6 +234,8 @@ static int ip_fw_chk (struct ip **pip, int hlen, struct sockaddr_in **next_hop); static int ip_fw_ctl (struct sockopt *sopt); +ip_dn_ruledel_t *ip_dn_ruledel_ptr = NULL; + static char err_prefix[] = "ip_fw_ctl:"; /* @@ -562,7 +562,6 @@ ipfw_report(struct ip_fw *f, struct ip *ip, int offset, int ip_len, snprintf(SNPARGS(action2, 0), "SkipTo %d", f->fw_skipto_rule); break; -#ifdef DUMMYNET case IP_FW_F_PIPE: snprintf(SNPARGS(action2, 0), "Pipe %d", f->fw_skipto_rule); @@ -571,7 +570,6 @@ ipfw_report(struct ip_fw *f, struct ip *ip, int offset, int ip_len, snprintf(SNPARGS(action2, 0), "Queue %d", f->fw_skipto_rule); break; -#endif #ifdef IPFIREWALL_FORWARD case IP_FW_F_FWD: if (f->fw_fwd_ip.sin_port) @@ -1518,12 +1516,10 @@ got_match: if (!f) goto dropit; goto again ; -#ifdef DUMMYNET case IP_FW_F_PIPE: case IP_FW_F_QUEUE: *flow_id = f; return(f->fw_pipe_nr | IP_FW_PORT_DYNT_FLAG); -#endif #ifdef IPFIREWALL_FORWARD case IP_FW_F_FWD: /* Change the next-hop address for this packet. @@ -1704,9 +1700,8 @@ free_chain(struct ip_fw *fcp) DELETE_DYN_CHAIN(fcp); LIST_REMOVE(fcp, next); static_count--; -#ifdef DUMMYNET - dn_rule_delete(fcp) ; -#endif + if (ip_dn_ruledel_ptr != NULL) + ip_dn_ruledel_ptr(fcp) ; flush_rule_ptrs(); /* more efficient to do outside the loop */ free(fcp, M_IPFW); return n; @@ -1903,21 +1898,17 @@ check_ipfw_struct(struct ip_fw *frwl) return (EINVAL); } break; -#if defined(IPDIVERT) || defined(DUMMYNET) #ifdef IPDIVERT case IP_FW_F_DIVERT: /* Diverting to port zero is invalid */ case IP_FW_F_TEE: #endif -#ifdef DUMMYNET case IP_FW_F_PIPE: /* pipe 0 is invalid */ case IP_FW_F_QUEUE: /* queue 0 is invalid */ -#endif if (frwl->fw_divert_port == 0) { dprintf(("%s 0 is an invalid argument\n", err_prefix)); return (EINVAL); } break; -#endif /* IPDIVERT || DUMMYNET */ case IP_FW_F_DENY: case IP_FW_F_ACCEPT: case IP_FW_F_COUNT: @@ -2181,3 +2172,4 @@ static moduledata_t ipfwmod = { 0 }; DECLARE_MODULE(ipfw, ipfwmod, SI_SUB_PSEUDO, SI_ORDER_ANY); +MODULE_VERSION(ipfw, 1); diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index fa345f6..c09bb48 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -79,16 +79,14 @@ #include <sys/socketvar.h> #include <netinet/ip_fw.h> +#include <netinet/ip_dummynet.h> + #ifdef IPSEC #include <netinet6/ipsec.h> #include <netkey/key.h> #endif -#ifdef DUMMYNET -#include <netinet/ip_dummynet.h> -#endif - int rsvp_on = 0; static int ip_rsvp_on; struct socket *ip_rsvpd; @@ -190,12 +188,10 @@ SYSCTL_INT(_net_inet_ip, OID_AUTO, stealth, CTLFLAG_RW, /* Firewall hooks */ ip_fw_chk_t *ip_fw_chk_ptr; -ip_fw_ctl_t *ip_fw_ctl_ptr; int fw_enable = 1 ; -#ifdef DUMMYNET -ip_dn_ctl_t *ip_dn_ctl_ptr; -#endif +/* Dummynet hooks */ +ip_dn_io_t *ip_dn_io_ptr; /* @@ -301,7 +297,6 @@ ip_input(struct mbuf *m) divert_cookie = 0; #endif -#if defined(IPFIREWALL) && defined(DUMMYNET) /* * dummynet packet are prepended a vestigial mbuf with * m_type = MT_DUMMYNET and m_data pointing to the matching @@ -315,7 +310,6 @@ ip_input(struct mbuf *m) goto iphack ; } else rule = NULL ; -#endif #ifdef DIAGNOSTIC if (m == NULL || (m->m_flags & M_PKTHDR) == 0) @@ -420,9 +414,7 @@ tooshort: * - Encapsulate: put it in another IP and send out. <unimp.> */ -#if defined(IPFIREWALL) && defined(DUMMYNET) iphack: -#endif #ifdef PFIL_HOOKS /* @@ -477,14 +469,12 @@ iphack: } if (i == 0 && ip_fw_fwd_addr == NULL) /* common case */ goto pass; -#ifdef DUMMYNET - if ((i & IP_FW_PORT_DYNT_FLAG) != 0) { + if (ip_dn_io_ptr != NULL && (i & IP_FW_PORT_DYNT_FLAG) != 0) { /* Send packet to the appropriate pipe */ - dummynet_io(i&0xffff,DN_TO_IP_IN,m,NULL,NULL,0, rule, + ip_dn_io_ptr(i&0xffff,DN_TO_IP_IN,m,NULL,NULL,0, rule, 0); return; } -#endif #ifdef IPDIVERT if (i != 0 && (i & IP_FW_PORT_DYNT_FLAG) == 0) { /* Divert or tee packet */ diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 71c7ad2..31ae0f2 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -78,10 +78,7 @@ static MALLOC_DEFINE(M_IPMOPTS, "ip_moptions", "internet multicast options"); #endif /*IPSEC*/ #include <netinet/ip_fw.h> - -#ifdef DUMMYNET #include <netinet/ip_dummynet.h> -#endif #ifdef IPFIREWALL_FORWARD_DEBUG #define print_ip(a) printf("%ld.%ld.%ld.%ld",(ntohl(a.s_addr)>>24)&0xFF,\ @@ -153,7 +150,6 @@ ip_output(m0, opt, ro, flags, imo) divert_cookie = 0; #endif -#if defined(IPFIREWALL) && defined(DUMMYNET) /* * dummynet packet are prepended a vestigial mbuf with * m_type = MT_DUMMYNET and m_data pointing to the matching @@ -184,7 +180,6 @@ ip_output(m0, opt, ro, flags, imo) goto sendit; } else rule = NULL ; -#endif #ifdef IPSEC so = ipsec_getsocket(m); (void)ipsec_setsocket(m, NULL); @@ -627,8 +622,7 @@ skip_ipsec: } if (off == 0 && dst == old) /* common case */ goto pass ; -#ifdef DUMMYNET - if ((off & IP_FW_PORT_DYNT_FLAG) != 0) { + if (ip_dn_io_ptr != NULL && (off & IP_FW_PORT_DYNT_FLAG) != 0) { /* * pass the pkt to dummynet. Need to include * pipe number, m, ifp, ro, dst because these are @@ -638,11 +632,10 @@ skip_ipsec: * XXX note: if the ifp or ro entry are deleted * while a pkt is in dummynet, we are in trouble! */ - error = dummynet_io(off & 0xffff, DN_TO_IP_OUT, m, + error = ip_dn_io_ptr(off & 0xffff, DN_TO_IP_OUT, m, ifp,ro,dst,rule, flags); goto done; } -#endif #ifdef IPDIVERT if (off != 0 && (off & IP_FW_PORT_DYNT_FLAG) == 0) { struct mbuf *clone = NULL; diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c index 178b483..54c30ac 100644 --- a/sys/netinet/raw_ip.c +++ b/sys/netinet/raw_ip.c @@ -63,19 +63,21 @@ #include <netinet/ip_mroute.h> #include <netinet/ip_fw.h> +#include <netinet/ip_dummynet.h> #ifdef IPSEC #include <netinet6/ipsec.h> #endif /*IPSEC*/ #include "opt_ipdn.h" -#ifdef DUMMYNET -#include <netinet/ip_dummynet.h> -#endif struct inpcbhead ripcb; struct inpcbinfo ripcbinfo; +/* control hooks for ipfw and dummynet */ +ip_fw_ctl_t *ip_fw_ctl_ptr; +ip_dn_ctl_t *ip_dn_ctl_ptr; + /* * Nominal space allocated to a raw ip socket. */ @@ -287,20 +289,18 @@ rip_ctloutput(so, sopt) case IP_FW_ADD: case IP_FW_GET: - if (ip_fw_ctl_ptr == 0) + if (ip_fw_ctl_ptr == NULL) error = ENOPROTOOPT; else error = ip_fw_ctl_ptr(sopt); break; -#ifdef DUMMYNET case IP_DUMMYNET_GET: if (ip_dn_ctl_ptr == NULL) - error = ENOPROTOOPT ; + error = ENOPROTOOPT; else error = ip_dn_ctl_ptr(sopt); break ; -#endif /* DUMMYNET */ case MRT_INIT: case MRT_DONE: @@ -343,7 +343,6 @@ rip_ctloutput(so, sopt) error = ip_fw_ctl_ptr(sopt); break; -#ifdef DUMMYNET case IP_DUMMYNET_CONFIGURE: case IP_DUMMYNET_DEL: case IP_DUMMYNET_FLUSH: @@ -352,7 +351,6 @@ rip_ctloutput(so, sopt) else error = ip_dn_ctl_ptr(sopt); break ; -#endif case IP_RSVP_ON: error = ip_rsvp_init(so); |