MFS: sync the ipfw/dummynet/bridge code with the one recently merged

into stable (mostly , but not only, formatting and comments changes).
This commit is contained in:
Luigi Rizzo 2001-11-04 22:56:25 +00:00
parent 60b49f05fa
commit 7b109fa404
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=86047
11 changed files with 347 additions and 267 deletions

View File

@ -66,7 +66,6 @@
#endif
#include <net/bpf.h>
#include "opt_bdg.h"
#include <net/bridge.h>
#include <machine/md_var.h>
@ -2710,8 +2709,7 @@ ed_get_packet(sc, buf, len)
* Don't read in the entire packet if we know we're going to drop it
* and no bpf is active.
*/
if (!sc->arpcom.ac_if.if_bpf && do_bridge && bdg_forward_ptr != NULL &&
BDG_USED( (&sc->arpcom.ac_if) ) ) {
if (!sc->arpcom.ac_if.if_bpf && BDG_ACTIVE( (&sc->arpcom.ac_if) ) ) {
struct ifnet *bif;
ed_ring_copy(sc, buf, (char *)eh, ETHER_HDR_LEN);

View File

@ -74,12 +74,12 @@
#include <sys/malloc.h>
#include <sys/systm.h>
#include <sys/socket.h> /* for net/if.h */
#include <sys/ctype.h> /* string functions */
#include <sys/kernel.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_types.h>
#include <net/if_var.h>
#include <netinet/in.h> /* for struct arpcom */
#include <netinet/in_systm.h>
@ -87,18 +87,14 @@
#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
#include <net/route.h>
#include <netinet/ip_fw.h>
#include <netinet/ip_dummynet.h>
#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 struct mbuf *bdg_forward(struct mbuf *,
struct ether_header *const, struct ifnet *);
static void bdgtakeifaces(void);
/*
@ -116,15 +112,24 @@ static void bdgtakeifaces(void);
#define DDB(x) x
#define DEB(x)
static void bdginit(void *);
static int bdginit(void);
static void flush_table(void);
static void bdg_promisc_on(void);
static void parse_bdg_cfg(void);
static int bdg_initialized = 0;
static int bdg_ipfw = 0 ;
bdg_hash_table *bdg_table = NULL ;
static bdg_hash_table *bdg_table = NULL ;
static char *bdg_dst_names[] = {
"BDG_NULL ",
"BDG_BCAST ",
"BDG_MCAST ",
"BDG_LOCAL ",
"BDG_DROP ",
"BDG_UNKNOWN ",
"BDG_IN ",
"BDG_OUT ",
"BDG_FORWARD " };
/*
* System initialization
@ -136,6 +141,45 @@ static struct callout_handle bdg_timeout_h ;
#define IFP_CHK(ifp, x) \
if (ifp2sc[ifp->if_index].magic != 0xDEADBEEF) { x ; }
/*
* Find the right pkt destination:
* BDG_BCAST is a broadcast
* BDG_MCAST is a multicast
* BDG_LOCAL is for a local address
* BDG_DROP must be dropped
* other ifp of the dest. interface (incl.self)
*
* We assume this is only called for interfaces for which bridging
* is enabled, i.e. BDG_USED(ifp) is true.
*/
static __inline
struct ifnet *
bridge_dst_lookup(struct ether_header *eh)
{
struct ifnet *dst ;
int index ;
bdg_addr *p ;
if (IS_ETHER_BROADCAST(eh->ether_dhost))
return BDG_BCAST ;
if (eh->ether_dhost[0] & 1)
return BDG_MCAST ;
/*
* Lookup local addresses in case one matches.
*/
for (index = bdg_ports, p = bdg_addresses ; index ; index--, p++ )
if (BDG_MATCH(p->etheraddr, eh->ether_dhost) )
return BDG_LOCAL ;
/*
* Look for a possible destination in table
*/
index= HASH_FN( eh->ether_dhost );
dst = bdg_table[index].name;
if ( dst && BDG_MATCH( bdg_table[index].etheraddr, eh->ether_dhost) )
return dst ;
else
return BDG_UNKNOWN ;
}
/*
* turn off promisc mode, optionally clear the IFF_USED flag.
* The flag is turned on by parse_bdg_config
@ -207,8 +251,6 @@ sysctl_bdg(SYSCTL_HANDLER_ARGS)
oidp->oid_name, oidp->oid_arg2,
oldval, do_bridge); )
if (bdg_table == NULL)
do_bridge = 0 ;
if (oldval != do_bridge) {
bdg_promisc_off( 1 ); /* reset previously used interfaces */
flush_table();
@ -225,6 +267,8 @@ static char bridge_cfg[256] = { "" } ;
/*
* parse the config string, set IFF_USED, name and cluster_id
* for all interfaces found.
* The config string is a list of "if[:cluster]" with
* a number of possible separators (see "sep").
*/
static void
parse_bdg_cfg()
@ -232,20 +276,21 @@ parse_bdg_cfg()
char *p, *beg ;
int i, l, cluster;
struct bdg_softc *b;
static char *sep = ", \t";
for (p= bridge_cfg; *p ; p++) {
/* interface names begin with [a-z] and continue up to ':' */
if (*p < 'a' || *p > 'z')
for (p = bridge_cfg; *p ; p++) {
if (index(sep, *p)) /* skip separators */
continue ;
for ( beg = p ; *p && *p != ':' ; p++ )
/* names are lowercase and digits */
for ( beg = p ; islower(*p) || isdigit(*p) ; p++ )
;
if (*p == 0) /* end of string, ':' not found */
return ;
l = p - beg ; /* length of name string */
p++ ;
DEB(printf("-- match beg(%d) <%s> p <%s>\n", l, beg, p);)
for (cluster = 0 ; *p && *p >= '0' && *p <= '9' ; p++)
cluster = cluster*10 + (*p -'0');
l = p - beg ; /* length of name string */
if (l == 0) /* invalid name */
break ;
if ( *p != ':' ) /* no ':', assume default cluster 1 */
cluster = 1 ;
else /* fetch cluster */
cluster = strtoul( p+1, &p, 10);
/*
* now search in bridge strings
*/
@ -256,7 +301,7 @@ parse_bdg_cfg()
if (ifp == NULL)
continue;
sprintf(buf, "%s%d", ifp->if_name, ifp->if_unit);
if (!strncmp(beg, buf, l)) { /* XXX not correct for >10 if! */
if (!strncmp(beg, buf, l)) {
b->cluster_id = htons(cluster) ;
b->flags |= IFF_USED ;
sprintf(bdg_stats.s[ifp->if_index].name,
@ -267,8 +312,6 @@ parse_bdg_cfg()
break ;
}
}
if (*p == '\0')
break ;
}
}
@ -319,6 +362,10 @@ SYSCTL_PROC(_net_link_ether, OID_AUTO, bridge, CTLTYPE_INT|CTLFLAG_RW,
SYSCTL_INT(_net_link_ether, OID_AUTO, bridge_ipfw, CTLFLAG_RW,
&bdg_ipfw,0,"Pass bridged pkts through firewall");
/*
* The follow macro declares a variable, and maps it to
* a SYSCTL_INT entry with the same name.
*/
#define SY(parent, var, comment) \
static int var ; \
SYSCTL_INT(parent, OID_AUTO, var, CTLFLAG_RW, &(var), 0, comment);
@ -334,6 +381,7 @@ 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");
@ -348,6 +396,7 @@ 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");
@ -362,8 +411,6 @@ flush_table()
{
int s,i;
if (bdg_table == NULL)
return ;
s = splimp();
for (i=0; i< HASH_SIZE; i++)
bdg_table[i].name= NULL; /* clear table */
@ -411,32 +458,46 @@ bdg_timeout(void *dummy)
* much faster.
*/
bdg_addr bdg_addresses[BDG_MAX_PORTS];
int bdg_ports ;
static int bdg_ports ;
static int bdg_max_ports = BDG_MAX_PORTS ;
/*
* initialization of bridge code. This needs to be done after all
* interfaces have been configured.
*/
static void
bdginit(void *dummy)
static int
bdginit(void)
{
bdg_initialized++;
if (bdg_table == NULL)
bdg_table = (struct hash_table *)
malloc(HASH_SIZE * sizeof(struct hash_table),
M_IFADDR, M_WAITOK);
flush_table();
ifp2sc = malloc(BDG_MAX_PORTS * sizeof(struct bdg_softc),
bdg_table = (struct hash_table *)
malloc(HASH_SIZE * sizeof(struct hash_table),
M_IFADDR, M_WAITOK | M_ZERO);
if (bdg_table == NULL)
return ENOMEM;
ifp2sc = malloc(BDG_MAX_PORTS * sizeof(struct bdg_softc),
M_IFADDR, M_WAITOK | M_ZERO );
if (ifp2sc == NULL) {
free(bdg_table, M_IFADDR);
bdg_table = NULL ;
return ENOMEM ;
}
bridge_in_ptr = bridge_in;
bdg_forward_ptr = bdg_forward;
bdgtakeifaces_ptr = bdgtakeifaces;
flush_table();
bzero(&bdg_stats, sizeof(bdg_stats) );
bdgtakeifaces();
bdg_timeout(0);
do_bridge=0;
return 0 ;
}
/**
* fetch interfaces that can do bridging.
* This is re-done every time we attach or detach an interface.
*/
static void
bdgtakeifaces(void)
{
@ -445,15 +506,14 @@ bdgtakeifaces(void)
bdg_addr *p = bdg_addresses ;
struct bdg_softc *bp;
if (!bdg_initialized)
return;
bdg_ports = 0 ;
*bridge_cfg = '\0';
printf("BRIDGE 011004, have %d interfaces\n", if_index);
printf("BRIDGE 011031, have %d interfaces\n", if_index);
TAILQ_FOREACH(ifp, &ifnet, if_link)
if (ifp->if_type == IFT_ETHER) { /* ethernet ? */
/*
* XXX should try to grow the arrays as needed.
*/
bp = &ifp2sc[ifp->if_index] ;
ac = (struct arpcom *)ifp;
sprintf(bridge_cfg + strlen(bridge_cfg),
@ -479,11 +539,11 @@ bdgtakeifaces(void)
}
/*
/**
* bridge_in() is invoked to perform bridging decision on input packets.
*
* On Input:
* eh Ethernet header of the incoming packet.
* eh Ethernet header of the incoming packet. We only need this.
*
* On Return: destination of packet, one of
* BDG_BCAST broadcast
@ -517,7 +577,7 @@ bridge_in(struct ifnet *ifp, struct ether_header *eh)
bdg_table[index].name = NULL ;
} else if (old != ifp) {
/*
* found a loop. Either a machine has moved, or there
* Found a loop. Either a machine has moved, or there
* is a misconfiguration/reconfiguration of the network.
* First, do not forward this packet!
* Record the relocation anyways; then, if loops persist,
@ -548,12 +608,14 @@ bridge_in(struct ifnet *ifp, struct ether_header *eh)
bdg_table[index].name = ifp ;
}
dst = bridge_dst_lookup(eh);
/* Return values:
/*
* bridge_dst_lookup can return the following values:
* BDG_BCAST, BDG_MCAST, BDG_LOCAL, BDG_UNKNOWN, BDG_DROP, ifp.
* For muted interfaces, the first 3 are changed in BDG_LOCAL,
* and others to BDG_DROP. Also, for incoming packets, ifp is changed
* to BDG_DROP in case ifp == src . These mods are not necessary
* for outgoing packets from ether_output().
* For muted interfaces, or when we detect a loop, the first 3 are
* changed in BDG_LOCAL (we still listen to incoming traffic),
* and others to BDG_DROP (no use for the local host).
* Also, for incoming packets, ifp is changed to BDG_DROP if ifp == src.
* These changes are not necessary for outgoing packets from ether_output().
*/
BDG_STAT(ifp, BDG_IN);
switch ((uintptr_t)dst) {
@ -574,36 +636,44 @@ bridge_in(struct ifnet *ifp, struct ether_header *eh)
if ( dropit ) {
if (dst == BDG_BCAST || dst == BDG_MCAST || dst == BDG_LOCAL)
return BDG_LOCAL ;
dst = BDG_LOCAL ;
else
return BDG_DROP ;
dst = BDG_DROP ;
} else {
return (dst == ifp ? BDG_DROP : dst ) ;
if (dst == ifp)
dst = BDG_DROP;
}
DEB(printf("bridge_in %6D ->%6D ty 0x%04x dst %s%d\n",
eh->ether_shost, ".",
eh->ether_dhost, ".",
ntohs(eh->ether_type),
(dst <= BDG_FORWARD) ? bdg_dst_names[(int)dst] :
dst->if_name,
(dst <= BDG_FORWARD) ? 0 : dst->if_unit); )
return dst ;
}
/*
* Forward to dst, excluding src port and muted interfaces.
* Forward a packet to dst -- which can be a single interface or
* an entire cluster. The src port and muted interfaces are excluded.
*
* If src == NULL, the pkt comes from ether_output, and dst is the real
* interface the packet is originally sent to. In this case we must forward
* it to the whole cluster. We never call bdg_forward ether_output on
* interfaces which are not part of a cluster.
* interface the packet is originally sent to. In this case, we must forward
* it to the whole cluster.
* We never call bdg_forward from ether_output on interfaces which are
* not part of a cluster.
*
* The packet is freed if possible (i.e. surely not of interest for
* the upper layer), otherwise a copy is left for use by the caller
* (pointer in m0).
* If possible (i.e. we can determine that the caller does not need
* a copy), the packet is consumed here, and bdg_forward returns NULL.
* Otherwise, a pointer to a copy of the packet is returned.
*
* It would be more efficient to make bdg_forward() always consume
* the packet, leaving to the caller the task to check if it needs a copy
* and get one in case. As it is now, bdg_forward() can sometimes make
* a copy whereas it is not necessary.
*
* XXX be careful about eh, it can be a pointer into *m
* XXX be careful with eh, it can be a pointer into *m
*/
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 */
struct ifnet *src = m0->m_pkthdr.rcvif; /* NULL when called by *_output */
struct ifnet *ifp, *last = NULL ;
int shared = bdg_copy ; /* someone else is using the mbuf */
int once = 0; /* loop only once */
@ -626,7 +696,7 @@ 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
bdg_thru++; /* only count once */
bdg_thru++; /* count packet, only once */
if (src == NULL) /* packet from ether_output */
dst = bridge_dst_lookup(eh);
@ -659,7 +729,7 @@ bdg_forward(struct mbuf *m0, struct ether_header *const eh, struct ifnet *dst)
* Additional restrictions may apply e.g. non-IP, short packets,
* and pkts already gone through a pipe.
*/
if (ip_fw_chk_ptr && bdg_ipfw != 0 && src != NULL) {
if (IPFW_LOADED && bdg_ipfw != 0 && src != NULL) {
struct ip *ip ;
int i;
@ -696,7 +766,7 @@ bdg_forward(struct mbuf *m0, struct ether_header *const eh, struct ifnet *dst)
* The firewall knows this is a bridged packet as the cookie ptr
* is NULL.
*/
i = (*ip_fw_chk_ptr)(&ip, 0, NULL, NULL /* cookie */, &m0, &rule, NULL);
i = ip_fw_chk_ptr(&ip, 0, NULL, NULL /* cookie */, &m0, &rule, NULL);
if ( (i & IP_FW_PORT_DENY_FLAG) || m0 == NULL) /* drop */
return m0 ;
/*
@ -709,7 +779,7 @@ bdg_forward(struct mbuf *m0, struct ether_header *const eh, struct ifnet *dst)
if (i == 0) /* a PASS rule. */
goto forward ;
if (do_bridge && ip_dn_io_ptr != NULL && (i & IP_FW_PORT_DYNT_FLAG)) {
if (DUMMYNET_LOADED && (i & IP_FW_PORT_DYNT_FLAG)) {
/*
* Pass the pkt to dummynet, which consumes it.
* If shared, make a copy and keep the original.
@ -734,7 +804,8 @@ bdg_forward(struct mbuf *m0, struct ether_header *const eh, struct ifnet *dst)
bdg_predict++;
} else {
M_PREPEND(m, ETHER_HDR_LEN, M_DONTWAIT);
if (!m && verbose) printf("M_PREPEND failed\n");
if (!m && verbose)
printf("M_PREPEND failed\n");
if (m == NULL) /* nope... */
return m0 ;
bcopy(&save_eh, mtod(m, struct ether_header *), ETHER_HDR_LEN);
@ -792,7 +863,8 @@ bdg_forward(struct mbuf *m0, struct ether_header *const eh, struct ifnet *dst)
bdg_predict++;
} else {
M_PREPEND(m, ETHER_HDR_LEN, M_DONTWAIT);
if (!m && verbose) printf("M_PREPEND failed\n");
if (!m && verbose)
printf("M_PREPEND failed\n");
if (m == NULL)
return m0;
bcopy(&save_eh, mtod(m, struct ether_header *), ETHER_HDR_LEN);
@ -827,35 +899,48 @@ bdg_forward(struct mbuf *m0, struct ether_header *const eh, struct ifnet *dst)
return m0 ;
}
/*
* initialization code, both for static and dynamic loading.
*/
static int
bridge_modevent(module_t mod, int type, void *unused)
{
int s;
int err;
s = splimp();
switch (type) {
case MOD_LOAD:
bridge_in_ptr = bridge_in;
bdg_forward_ptr = bdg_forward;
bdgtakeifaces_ptr = bdgtakeifaces;
bdginit(NULL);
if (BDG_LOADED) {
err = EEXIST;
break ;
}
s = splimp();
err = bdginit();
splx(s);
break;
case MOD_UNLOAD:
#if !defined(KLD_MODULE)
printf("bridge statically compiled, cannot unload\n");
err = EINVAL ;
#else
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);
free(bdg_table, M_IFADDR);
bdg_table = NULL ;
free(ifp2sc, M_IFADDR);
ifp2sc = NULL ;
splx(s);
#endif
break;
default:
err = EINVAL ;
break;
}
splx(s);
return 0;
return err;
}
static moduledata_t bridge_mod = {

View File

@ -67,6 +67,11 @@ extern struct bdg_softc *ifp2sc;
#define BDG_SAMECLUSTER(ifp,src) \
(src == NULL || BDG_CLUSTER(ifp) == BDG_CLUSTER(src) )
/*
* BDG_ACTIVE(ifp) does all checks to see if bridging is loaded,
* activated and used on a given interface.
*/
#define BDG_ACTIVE(ifp) (do_bridge && BDG_LOADED && BDG_USED(ifp))
#define BDG_MAX_PORTS 128
typedef struct _bdg_addr {
@ -92,7 +97,7 @@ extern int bdg_ports ;
*((unsigned int *)(a)) == 0xffffffff && \
((unsigned short *)(a))[2] == 0xffff )
#else
/* Unaligned access versions. */
/* for machines that do not support unaligned access */
#define BDG_MATCH(a,b) (!bcmp(a, b, ETHER_ADDR_LEN) )
#define IS_ETHER_BROADCAST(a) (!bcmp(a, "\377\377\377\377\377\377", 6))
#endif
@ -135,49 +140,10 @@ 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);
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
* BDG_MCAST is a multicast
* BDG_LOCAL is for a local address
* BDG_DROP must be dropped
* other ifp of the dest. interface (incl.self)
*
* We assume this is only called for interfaces for which bridging
* is enabled, i.e. BDG_USED(ifp) is true.
*/
static __inline
struct ifnet *
bridge_dst_lookup(struct ether_header *eh)
{
struct ifnet *dst ;
int index ;
bdg_addr *p ;
if (IS_ETHER_BROADCAST(eh->ether_dhost))
return BDG_BCAST ;
if (eh->ether_dhost[0] & 1)
return BDG_MCAST ;
/*
* Lookup local addresses in case one matches.
*/
for (index = bdg_ports, p = bdg_addresses ; index ; index--, p++ )
if (BDG_MATCH(p->etheraddr, eh->ether_dhost) )
return BDG_LOCAL ;
/*
* Look for a possible destination in table
*/
index= HASH_FN( eh->ether_dhost );
dst = bdg_table[index].name;
if ( dst && BDG_MATCH( bdg_table[index].etheraddr, eh->ether_dhost) )
return dst ;
else
return BDG_UNKNOWN ;
}
#define BDG_LOADED (bdgtakeifaces_ptr != NULL)
#endif /* KERNEL */

View File

@ -364,7 +364,7 @@ ether_output_frame(ifp, m)
{
int error = 0;
if (do_bridge && bdg_forward_ptr != NULL && BDG_USED(ifp) ) {
if (BDG_ACTIVE(ifp) ) {
struct ether_header *eh; /* a ptr suffices */
m->m_pkthdr.rcvif = NULL;
@ -429,7 +429,7 @@ ether_input(ifp, eh, m)
}
/* Check for bridging mode */
if (do_bridge && bdg_forward_ptr != NULL && BDG_USED(ifp) ) {
if (BDG_ACTIVE(ifp) ) {
struct ifnet *bif;
/* Check with bridging code */
@ -441,7 +441,7 @@ ether_input(ifp, eh, m)
struct mbuf *oldm = m ;
save_eh = *eh ; /* because it might change */
m = bdg_forward_ptr(m, eh, bif); /* needs forwarding */
m = bdg_forward_ptr(m, eh, bif); /* needs forwarding */
/*
* Do not continue if bdg_forward_ptr() processed our
* packet (and cleared the mbuf pointer m) or if
@ -462,7 +462,7 @@ ether_input(ifp, eh, m)
/* If not local and not multicast, just drop it */
if (m != NULL)
m_freem(m);
m_freem(m);
return;
}
@ -488,7 +488,7 @@ ether_demux(ifp, eh, m)
#if defined(NETATALK)
register struct llc *l;
#endif
if (! (BDG_ACTIVE(ifp) ) )
/* Discard packet if upper layers shouldn't see it because it was
unicast to a different Ethernet address. If the driver is working
properly, then this situation can only happen when the interface
@ -674,7 +674,7 @@ ether_ifattach(ifp, bpf)
bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
if (ng_ether_attach_p != NULL)
(*ng_ether_attach_p)(ifp);
if (bdgtakeifaces_ptr != NULL)
if (BDG_LOADED)
bdgtakeifaces_ptr();
}
@ -691,7 +691,7 @@ ether_ifdetach(ifp, bpf)
if (bpf)
bpfdetach(ifp);
if_detach(ifp);
if (bdgtakeifaces_ptr != NULL)
if (BDG_LOADED)
bdgtakeifaces_ptr();
}

View File

@ -79,9 +79,6 @@
#include <netinet/ip_dummynet.h>
#include <netinet/ip_var.h>
#if !defined(KLD_MODULE)
#include "opt_bdg.h"
#endif
#include <netinet/if_ether.h> /* for struct arpcom */
#include <net/bridge.h>
@ -165,9 +162,9 @@ 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 *);
struct route *ro, struct sockaddr_in * dst,
struct ip_fw *rule, int flags);
static void dn_rule_delete(void *);
int if_tx_rdy(struct ifnet *ifp);
@ -249,7 +246,7 @@ heap_init(struct dn_heap *h, int new_size)
*/
#define RESET_OFFSET(heap, node) \
if (heap->offset > 0) \
*((int *)((char *)(heap->p[node].object) + heap->offset)) = -1 ;
*((int *)((char *)(heap->p[node].object) + heap->offset)) = -1 ;
static int
heap_insert(struct dn_heap *h, dn_key key1, void *p)
{
@ -444,8 +441,12 @@ transmit_event(struct dn_pipe *pipe)
break ;
case DN_TO_BDG_FWD :
if (bdg_forward_ptr != NULL) {
struct mbuf *m = (struct mbuf *)pkt;
if (!BDG_LOADED) {
/* somebody unloaded the bridge module. Drop pkt */
printf("-- dropping bridged packet trapped in pipe--\n");
m_freem(pkt->dn_m);
} else {
struct mbuf *m = (struct mbuf *)pkt ;
struct ether_header *eh;
if (pkt->dn_m->m_len < ETHER_HDR_LEN &&
@ -459,8 +460,8 @@ transmit_event(struct dn_pipe *pipe)
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
* 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.
*/
@ -474,7 +475,7 @@ transmit_event(struct dn_pipe *pipe)
m_freem(pkt->dn_m);
break ;
}
FREE(pkt, M_DUMMYNET);
free(pkt, M_DUMMYNET);
}
/* if there are leftover packets, put into the heap for next event */
if ( (pkt = pipe->head) )
@ -831,7 +832,7 @@ create_queue(struct dn_flow_set *fs, int i)
if ( fs->rq[i] != NULL )
return fs->rq[i] ;
}
q = malloc(sizeof(*q), M_DUMMYNET, M_DONTWAIT | M_ZERO); /* M_ZERO needed */
q = malloc(sizeof(*q), M_DUMMYNET, M_DONTWAIT | M_ZERO);
if (q == NULL) {
printf("sorry, cannot allocate queue for new flow\n");
return NULL ;
@ -1092,7 +1093,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_DUMMYNET, 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... */
@ -1383,8 +1384,10 @@ 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)
if (x->w_q_lookup) {
free(x->w_q_lookup, M_DUMMYNET);
x->w_q_lookup = NULL ;
}
if (red_lookup_depth == 0) {
printf("\nnet.inet.ip.dummynet.red_lookup_depth must be > 0");
free(x, M_DUMMYNET);
@ -1470,13 +1473,13 @@ config_pipe(struct dn_pipe *p)
int s ;
struct dn_flow_set *pfs = &(p->fs);
/*
* The config program passes parameters as follows:
/*
* The config program passes parameters as follows:
* bw = bits/second (0 means no limits),
* delay = ms, must be translated into ticks.
* qsize = slots/bytes
*/
p->delay = ( p->delay * hz ) / 1000 ;
*/
p->delay = ( p->delay * hz ) / 1000 ;
/* We need either a pipe number or a flow_set number */
if (p->pipe_nr == 0 && pfs->fs_nr == 0)
return EINVAL ;
@ -1535,7 +1538,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_DUMMYNET, 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;
@ -1812,7 +1815,7 @@ dummynet_get(struct sockopt *sopt)
}
splx(s);
error = sooptcopyout(sopt, buf, size);
FREE(buf, M_TEMP);
free(buf, M_TEMP);
return error ;
}
@ -1868,7 +1871,7 @@ ip_dn_ctl(struct sockopt *sopt)
static void
ip_dn_init(void)
{
printf("DUMMYNET initialized (011004)\n");
printf("DUMMYNET initialized (011031)\n");
all_pipes = NULL ;
all_flow_sets = NULL ;
ready_heap.size = ready_heap.elements = 0 ;
@ -1880,8 +1883,8 @@ ip_dn_init(void)
extract_heap.size = extract_heap.elements = 0 ;
extract_heap.offset = 0 ;
ip_dn_ctl_ptr = ip_dn_ctl;
ip_dn_ruledel_ptr = dn_rule_delete;
ip_dn_io_ptr = dummynet_io;
ip_dn_ruledel_ptr = dn_rule_delete;
bzero(&dn_timeout, sizeof(struct callout_handle));
dn_timeout = timeout(dummynet, NULL, 1);
}
@ -1893,17 +1896,28 @@ dummynet_modevent(module_t mod, int type, void *data)
switch (type) {
case MOD_LOAD:
s = splimp();
if (DUMMYNET_LOADED) {
splx(s);
printf("DUMMYNET already loaded\n");
return EEXIST ;
}
ip_dn_init();
splx(s);
break;
case MOD_UNLOAD:
#if !defined(KLD_MODULE)
printf("dummynet statically compiled, cannot unload\n");
return EINVAL ;
#else
s = splimp();
untimeout(dummynet, NULL, dn_timeout);
dummynet_flush();
s = splimp();
ip_dn_ctl_ptr = NULL;
ip_dn_io_ptr = NULL;
ip_dn_ruledel_ptr = NULL;
splx(s);
#endif
break ;
default:
break ;

View File

@ -343,11 +343,12 @@ struct dn_pipe { /* a pipe */
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 */
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;
#define DUMMYNET_LOADED (ip_dn_io_ptr != NULL)
#endif
#endif /* _IP_DUMMYNET_H */

View File

@ -155,7 +155,8 @@ SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, permanent_rules, CTLFLAG_RW,
static struct ipfw_dyn_rule **ipfw_dyn_v = NULL ;
static u_int32_t dyn_buckets = 256 ; /* must be power of 2 */
static u_int32_t curr_dyn_buckets = 256 ; /* must be power of 2 */
/**
/*
* timeouts for various events in handing dynamic rules.
*/
static u_int32_t dyn_ack_lifetime = 300 ;
@ -200,8 +201,7 @@ SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_short_lifetime, CTLFLAG_RW,
SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_grace_time, CTLFLAG_RD,
&dyn_grace_time, 0, "Grace time for dyn. rules");
#endif
#endif /* SYSCTL_NODE */
#define dprintf(a) do { \
if (fw_debug) \
@ -674,22 +674,21 @@ hash_packet(struct ipfw_flow_id *id)
* head is a pointer to the head of the queue.
* Modifies q and potentially also head.
*/
#define UNLINK_DYN_RULE(prev, head, q) { \
struct ipfw_dyn_rule *old_q = q; \
\
/* remove a refcount to the parent */ \
if (q->dyn_type == DYN_LIMIT) \
q->parent->count--; \
DEB(printf("-- unlink entry 0x%08x %d -> 0x%08x %d, %d left\n", \
(q->id.src_ip), (q->id.src_port), \
(q->id.dst_ip), (q->id.dst_port), dyn_count-1 ); ) \
if (prev != NULL) \
prev->next = q = q->next ; \
else \
ipfw_dyn_v[i] = q = q->next ; \
dyn_count-- ; \
free(old_q, M_IPFW); }
#define UNLINK_DYN_RULE(prev, head, q) { \
struct ipfw_dyn_rule *old_q = q; \
\
/* remove a refcount to the parent */ \
if (q->dyn_type == DYN_LIMIT) \
q->parent->count--; \
DEB(printf("-- unlink entry 0x%08x %d -> 0x%08x %d, %d left\n", \
(q->id.src_ip), (q->id.src_port), \
(q->id.dst_ip), (q->id.dst_port), dyn_count-1 ); ) \
if (prev != NULL) \
prev->next = q = q->next ; \
else \
ipfw_dyn_v[i] = q = q->next ; \
dyn_count-- ; \
free(old_q, M_IPFW); }
#define TIME_LEQ(a,b) ((int)((a)-(b)) <= 0)
/**
@ -733,8 +732,9 @@ remove_dyn_rule(struct ip_fw *rule, int force)
max_pass = 1; /* we need a second pass */
if (zap == 1 && (pass == 0 || q->count != 0) ) {
zap = 0 ;
if (q->count != 0)
printf("cannot remove parent, count %d\n", q->count);
if (pass == 1) /* should not happen */
printf("OUCH! cannot remove rule, count %d\n",
q->count);
}
}
if (zap) {
@ -775,7 +775,7 @@ lookup_dyn_rule(struct ipfw_flow_id *pkt, int *match_direction)
goto next;
if (TIME_LEQ( q->expire , time_second ) ) { /* expire entry */
UNLINK_DYN_RULE(prev, ipfw_dyn_v[i], q);
continue ;
continue;
}
if ( pkt->proto == q->id.proto) {
if (pkt->src_ip == q->id.src_ip &&
@ -789,8 +789,8 @@ lookup_dyn_rule(struct ipfw_flow_id *pkt, int *match_direction)
pkt->dst_ip == q->id.src_ip &&
pkt->src_port == q->id.dst_port &&
pkt->dst_port == q->id.src_port ) {
dir = 0 ; /* reverse match */
goto found ;
dir = 0 ; /* reverse match */
goto found ;
}
}
next:
@ -876,9 +876,9 @@ add_dyn_rule(struct ipfw_flow_id *id, u_int8_t dyn_type, struct ip_fw *rule)
dyn_buckets = curr_dyn_buckets ; /* reset */
else {
curr_dyn_buckets = dyn_buckets ;
if (ipfw_dyn_v != NULL)
if (ipfw_dyn_v != NULL)
free(ipfw_dyn_v, M_IPFW);
ipfw_dyn_v = malloc(curr_dyn_buckets * sizeof r,
ipfw_dyn_v = malloc(curr_dyn_buckets * sizeof r,
M_IPFW, M_DONTWAIT | M_ZERO);
if (ipfw_dyn_v == NULL)
return NULL; /* failed ! */
@ -888,8 +888,8 @@ add_dyn_rule(struct ipfw_flow_id *id, u_int8_t dyn_type, struct ip_fw *rule)
r = malloc(sizeof *r, M_IPFW, M_DONTWAIT | M_ZERO);
if (r == NULL) {
printf ("sorry cannot allocate state\n");
return NULL ;
printf ("sorry cannot allocate state\n");
return NULL ;
}
/* increase refcount on parent, and set pointer */
@ -921,7 +921,7 @@ add_dyn_rule(struct ipfw_flow_id *id, u_int8_t dyn_type, struct ip_fw *rule)
}
/**
* lookup dynamic parent rule using pkt and chain as search keys.
* lookup dynamic parent rule using pkt and rule as search keys.
* If the lookup fails, then install one.
*/
static struct ipfw_dyn_rule *
@ -986,10 +986,11 @@ install_state(struct ip_fw *rule)
}
return 1; /* cannot install, notify caller */
}
switch (type) {
case DYN_KEEP_STATE: /* bidir rule */
add_dyn_rule(&last_pkt, DYN_KEEP_STATE, rule);
break ;
add_dyn_rule(&last_pkt, DYN_KEEP_STATE, rule);
break ;
case DYN_LIMIT: /* limit number of sessions */
{
u_int16_t limit_mask = rule->limit_mask ;
@ -1014,7 +1015,7 @@ install_state(struct ip_fw *rule)
parent = lookup_dyn_parent(&id, rule);
if (parent == NULL) {
printf("add parent failed\n");
return 1;
return 1;
}
if (parent->count >= conn_limit) {
EXPIRE_DYN_CHAIN(rule); /* try to expire some */
@ -1037,7 +1038,7 @@ install_state(struct ip_fw *rule)
/*
* given an ip_fw *, lookup_next_rule will return a pointer
* of the same type to the next one. This can be either the jump
* target (for skipto instructions) or the next one in the chain (in
* target (for skipto instructions) or the next one in the list (in
* all other cases including a missing jump target).
* Backward jumps are not allowed, so start looking from the next
* rule...
@ -1053,7 +1054,7 @@ lookup_next_rule(struct ip_fw *me)
if ( (me->fw_flg & IP_FW_F_COMMAND) == IP_FW_F_SKIPTO )
for (rule = LIST_NEXT(me,next); rule ; rule = LIST_NEXT(rule,next))
if (rule->fw_number >= rulenum)
return rule ;
return rule ;
return LIST_NEXT(me,next) ; /* failure or not a skipto */
}
@ -1198,7 +1199,7 @@ ip_fw_chk(struct ip **pip, int hlen,
goto dropit;
} else {
/*
* Go down the chain, looking for enlightment.
* Go down the list, looking for enlightment.
* If we've been asked to start at a given rule, do so.
*/
f = LIST_FIRST(&ip_fw_chain_head);
@ -1212,7 +1213,6 @@ ip_fw_chk(struct ip **pip, int hlen,
}
}
for (; f; f = LIST_NEXT(f, next)) {
again:
if (f->fw_number == IPFW_DEFAULT_RULE)
@ -1516,7 +1516,7 @@ ip_fw_chk(struct ip **pip, int hlen,
goto again ;
case IP_FW_F_PIPE:
case IP_FW_F_QUEUE:
*flow_id = f;
*flow_id = f; /* XXX set flow id */
return(f->fw_pipe_nr | IP_FW_PORT_DYNT_FLAG);
#ifdef IPFIREWALL_FORWARD
case IP_FW_F_FWD:
@ -1608,7 +1608,7 @@ ip_fw_chk(struct ip **pip, int hlen,
* when a rule is added/deleted, zero the direct pointers within
* all firewall rules. These will be reconstructed on the fly
* as packets are matched.
* Must be called at splnet().
* Must be called at splimp().
*/
static void
flush_rule_ptrs()
@ -1630,7 +1630,6 @@ add_entry(struct ip_fw_head *head, struct ip_fw *rule)
ftmp = malloc(sizeof *ftmp, M_IPFW, M_DONTWAIT | M_ZERO);
if (!ftmp)
return (ENOSPC);
bcopy(rule, ftmp, sizeof(*ftmp));
ftmp->fw_in_if.fu_via_if.name[FW_IFNLEN - 1] = '\0';
@ -1639,7 +1638,7 @@ add_entry(struct ip_fw_head *head, struct ip_fw *rule)
ftmp->next_rule_ptr = NULL ;
ftmp->pipe_ptr = NULL ;
s = splnet();
s = splimp();
if (LIST_FIRST(head) == 0) {
LIST_INSERT_HEAD(head, ftmp, next);
@ -1683,11 +1682,11 @@ add_entry(struct ip_fw_head *head, struct ip_fw *rule)
}
/**
* free storage associated with a static chain entry (including
* free storage associated with a static rule entry (including
* dependent dynamic rules), and zeroes rule pointers to avoid
* dangling pointer dereferences.
* @return a pointer to the next entry.
* Must be called at splnet() and with a non-null argument.
* Must be called at splimp() and with a non-null argument.
*/
static struct ip_fw *
free_chain(struct ip_fw *fcp)
@ -1698,7 +1697,7 @@ free_chain(struct ip_fw *fcp)
DELETE_DYN_CHAIN(fcp);
LIST_REMOVE(fcp, next);
static_count--;
if (ip_dn_ruledel_ptr != NULL)
if (DUMMYNET_LOADED)
ip_dn_ruledel_ptr(fcp) ;
flush_rule_ptrs(); /* more efficient to do outside the loop */
free(fcp, M_IPFW);
@ -1718,7 +1717,7 @@ del_entry(struct ip_fw_head *chainptr, u_short number)
if (rule->fw_number == number) {
int s ;
s = splnet(); /* prevent access to rules while removing */
s = splimp(); /* prevent access to rules while removing */
while (rule && rule->fw_number == number)
rule = free_chain(rule);
/* XXX could move flush_rule_ptrs() here */
@ -1746,7 +1745,7 @@ zero_entry(struct ip_fw *frwl, int log_only)
char *msg ;
if (frwl == 0) {
s = splnet();
s = splimp();
LIST_FOREACH(rule, &ip_fw_chain_head, next) {
if (log_only == 0) {
rule->fw_bcnt = rule->fw_pcnt = 0;
@ -1756,19 +1755,18 @@ zero_entry(struct ip_fw *frwl, int log_only)
}
splx(s);
msg = log_only ? "ipfw: All logging counts cleared.\n" :
"ipfw: Accounting cleared.\n";
"ipfw: Accounting cleared.\n";
} else {
int cleared = 0;
number = frwl->fw_number ;
/*
* It's possible to insert multiple chain entries with the
* It is possible to insert multiple chain entries with the
* same number, so we don't stop after finding the first
* match if zeroing a specific entry.
*/
LIST_FOREACH(rule, &ip_fw_chain_head, next)
if (number == rule->fw_number) {
s = splnet();
s = splimp();
while (rule && number == rule->fw_number) {
if (log_only == 0) {
rule->fw_bcnt = rule->fw_pcnt = 0;
@ -1781,10 +1779,10 @@ zero_entry(struct ip_fw *frwl, int log_only)
cleared = 1;
break;
}
if (!cleared) /* we didn't find any matching rules */
if (!cleared) /* we did not find any matching rules */
return (EINVAL);
msg = log_only ? "Entry %d logging count reset.\n" :
"ipfw: Entry %d cleared.\n";
"ipfw: Entry %d cleared.\n";
}
if (fw_verbose)
log(LOG_SECURITY | LOG_NOTICE, msg, number);
@ -1946,7 +1944,13 @@ ip_fw_ctl(struct sockopt *sopt)
switch (sopt->sopt_name) {
case IP_FW_GET:
s = splnet();
/*
* pass up a copy of the current rules. Static rules
* come first (the last of which has number 65535),
* followed by a possibly empty list of dynamic rule.
* The last dynamic rule has NULL in the "next" field.
*/
s = splimp();
/* size of static rules */
size = static_count * sizeof(struct ip_fw) ;
if (ipfw_dyn_v) /* add size of dyn.rules */
@ -1960,9 +1964,9 @@ ip_fw_ctl(struct sockopt *sopt)
*/
buf = malloc(size, M_TEMP, M_WAITOK);
if (buf == 0) {
splx(s);
error = ENOBUFS;
break;
splx(s);
error = ENOBUFS;
break;
}
bp = buf ;
@ -1979,7 +1983,12 @@ ip_fw_ctl(struct sockopt *sopt)
for ( p = ipfw_dyn_v[i] ; p != NULL ; p = p->next, dst++ ) {
bcopy(p, dst, sizeof *p);
(int)dst->rule = p->rule->fw_number ;
dst->next = dst ; /* fake non-null pointer... */
/*
* store a non-null value in "next". The userland
* code will interpret a NULL here as a marker
* for the last dynamic rule.
*/
dst->next = dst ;
last = dst ;
if (TIME_LEQ(dst->expire, time_second) )
dst->expire = 0 ;
@ -1987,12 +1996,12 @@ ip_fw_ctl(struct sockopt *sopt)
dst->expire -= time_second ;
}
if (last != NULL)
last->next = NULL ;
last->next = NULL ; /* mark last dynamic rule */
}
splx(s);
error = sooptcopyout(sopt, buf, size);
FREE(buf, M_TEMP);
free(buf, M_TEMP);
break;
case IP_FW_FLUSH:
@ -2009,7 +2018,7 @@ ip_fw_ctl(struct sockopt *sopt)
* the old list without the need for a lock.
*/
s = splnet();
s = splimp();
while ( (fcp = LIST_FIRST(&ip_fw_chain_head)) &&
fcp->fw_number != IPFW_DEFAULT_RULE )
free_chain(fcp);
@ -2055,7 +2064,7 @@ ip_fw_ctl(struct sockopt *sopt)
if (sopt->sopt_val != 0) {
error = sooptcopyin(sopt, &frwl, sizeof frwl, sizeof frwl);
if (error)
break ;
break;
arg = &frwl ;
}
error = zero_entry(arg, cmd);
@ -2130,38 +2139,48 @@ ip_fw_init(void)
#endif
}
static ip_fw_chk_t *old_chk_ptr;
static ip_fw_ctl_t *old_ctl_ptr;
static int
ipfw_modevent(module_t mod, int type, void *unused)
{
int s;
int err = 0 ;
struct ip_fw *fcp;
switch (type) {
case MOD_LOAD:
s = splnet();
old_chk_ptr = ip_fw_chk_ptr;
old_ctl_ptr = ip_fw_ctl_ptr;
ip_fw_init();
splx(s);
return 0;
printf("IPFW: MOD_LOAD\n");
s = splimp();
if (IPFW_LOADED) {
splx(s);
printf("IP firewall already loaded\n");
err = EEXIST ;
} else {
ip_fw_init();
splx(s);
}
break ;
case MOD_UNLOAD:
s = splnet();
ip_fw_chk_ptr = old_chk_ptr;
ip_fw_ctl_ptr = old_ctl_ptr;
printf("IPFW: MOD_UNLOAD\n");
#if !defined(KLD_MODULE)
printf("ipfw statically compiled, cannot unload\n");
err = EBUSY;
#else
s = splimp();
ip_fw_chk_ptr = NULL ;
ip_fw_ctl_ptr = NULL ;
{
struct ip_fw *fcp;
while ( (fcp = LIST_FIRST(&ip_fw_chain_head)) != NULL)
free_chain(fcp);
}
splx(s);
printf("IP firewall unloaded\n");
return 0;
#endif
break;
default:
break;
}
return 0;
return err;
}
static moduledata_t ipfwmod = {

View File

@ -327,6 +327,7 @@ extern ip_fw_ctl_t *ip_fw_ctl_ptr;
extern int fw_one_pass;
extern int fw_enable;
extern struct ipfw_flow_id last_pkt;
#define IPFW_LOADED (ip_fw_chk_ptr != NULL)
#endif /* _KERNEL */
#endif /* _IP_FW_H */

View File

@ -81,7 +81,6 @@
#include <netinet/ip_fw.h>
#include <netinet/ip_dummynet.h>
#ifdef IPSEC
#include <netinet6/ipsec.h>
#include <netkey/key.h>
@ -439,7 +438,7 @@ ip_input(struct mbuf *m)
}
#endif /* PFIL_HOOKS */
if (fw_enable && ip_fw_chk_ptr) {
if (fw_enable && IPFW_LOADED) {
#ifdef IPFIREWALL_FORWARD
/*
* If we've been forwarded from the output side, then
@ -452,7 +451,7 @@ ip_input(struct mbuf *m)
* See the comment in ip_output for the return values
* produced by the firewall.
*/
i = (*ip_fw_chk_ptr)(&ip,
i = ip_fw_chk_ptr(&ip,
hlen, NULL, &divert_cookie, &m, &rule, &ip_fw_fwd_addr);
if (i & IP_FW_PORT_DENY_FLAG) { /* XXX new interface-denied */
if (m)
@ -469,7 +468,7 @@ ip_input(struct mbuf *m)
}
if (i == 0 && ip_fw_fwd_addr == NULL) /* common case */
goto pass;
if (ip_dn_io_ptr != NULL && (i & IP_FW_PORT_DYNT_FLAG) != 0) {
if (DUMMYNET_LOADED && (i & IP_FW_PORT_DYNT_FLAG) != 0) {
/* Send packet to the appropriate pipe */
ip_dn_io_ptr(i&0xffff,DN_TO_IP_IN,m,NULL,NULL,0, rule,
0);
@ -541,7 +540,7 @@ ip_input(struct mbuf *m)
* is not locally generated and the packet is not subject to
* 'ipfw fwd'.
*
* XXX - Checking also should be disabled if the destination
* XXX - Checking also should be disabled if the destination
* address is ipnat'ed to a different interface.
*
* XXX - Checking is incompatible with IP aliases added

View File

@ -586,10 +586,10 @@ ip_output(m0, opt, ro, flags, imo)
/*
* Check with the firewall...
*/
if (fw_enable && ip_fw_chk_ptr) {
if (fw_enable && IPFW_LOADED) {
struct sockaddr_in *old = dst;
off = (*ip_fw_chk_ptr)(&ip,
off = ip_fw_chk_ptr(&ip,
hlen, ifp, &divert_cookie, &m, &rule, &dst);
/*
* On return we must do the following:
@ -623,7 +623,7 @@ ip_output(m0, opt, ro, flags, imo)
}
if (off == 0 && dst == old) /* common case */
goto pass ;
if (ip_dn_io_ptr != NULL && (off & IP_FW_PORT_DYNT_FLAG) != 0) {
if (DUMMYNET_LOADED && (off & IP_FW_PORT_DYNT_FLAG) != 0) {
/*
* pass the pkt to dummynet. Need to include
* pipe number, m, ifp, ro, dst because these are

View File

@ -70,8 +70,6 @@
#include <netinet6/ipsec.h>
#endif /*IPSEC*/
#include "opt_ipdn.h"
struct inpcbhead ripcb;
struct inpcbinfo ripcbinfo;
@ -288,19 +286,19 @@ rip_ctloutput(so, sopt)
error = sooptcopyout(sopt, &optval, sizeof optval);
break;
case IP_FW_ADD:
case IP_FW_ADD: /* ADD actually returns the body... */
case IP_FW_GET:
if (ip_fw_ctl_ptr == NULL)
error = ENOPROTOOPT;
else
if (IPFW_LOADED)
error = ip_fw_ctl_ptr(sopt);
else
error = ENOPROTOOPT;
break;
case IP_DUMMYNET_GET:
if (ip_dn_ctl_ptr == NULL)
error = ENOPROTOOPT;
else
if (DUMMYNET_LOADED)
error = ip_dn_ctl_ptr(sopt);
else
error = ENOPROTOOPT;
break ;
case MRT_INIT:
@ -333,24 +331,23 @@ rip_ctloutput(so, sopt)
inp->inp_flags &= ~INP_HDRINCL;
break;
case IP_FW_ADD:
case IP_FW_DEL:
case IP_FW_FLUSH:
case IP_FW_ZERO:
case IP_FW_RESETLOG:
if (ip_fw_ctl_ptr == 0)
error = ENOPROTOOPT;
else
if (IPFW_LOADED)
error = ip_fw_ctl_ptr(sopt);
else
error = ENOPROTOOPT;
break;
case IP_DUMMYNET_CONFIGURE:
case IP_DUMMYNET_DEL:
case IP_DUMMYNET_FLUSH:
if (ip_dn_ctl_ptr == NULL)
error = ENOPROTOOPT ;
else
if (DUMMYNET_LOADED)
error = ip_dn_ctl_ptr(sopt);
else
error = ENOPROTOOPT ;
break ;
case IP_RSVP_ON: