Sync with the bridge/dummynet/ipfw code already tested in stable.

In ip_fw.[ch] change a couple of variable and field names to
avoid having types, variables and fields with the same name.
This commit is contained in:
Luigi Rizzo 2001-02-10 00:10:18 +00:00
parent 7a504379b7
commit 7e1cd0d23d
6 changed files with 113 additions and 132 deletions

View File

@ -79,6 +79,7 @@
#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>
@ -153,9 +154,9 @@ bdg_promisc_off(int clear_used)
ret = ifpromisc(ifp, 0);
splx(s);
ifp2sc[ifp->if_index].flags &= ~(IFF_BDG_PROMISC|IFF_MUTE) ;
printf(">> now %s%d promisc OFF if_flags 0x%x bdg_flags 0x%x\n",
DEB(printf(">> now %s%d promisc OFF if_flags 0x%x bdg_flags 0x%x\n",
ifp->if_name, ifp->if_unit,
ifp->if_flags, ifp2sc[ifp->if_index].flags);
ifp->if_flags, ifp2sc[ifp->if_index].flags);)
}
if (clear_used) {
ifp2sc[ifp->if_index].flags &= ~(IFF_USED) ;
@ -245,7 +246,7 @@ parse_bdg_cfg()
return ;
l = p - beg ; /* length of name string */
p++ ;
DDB(printf("-- match beg(%d) <%s> p <%s>\n", l, beg, 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');
/*
@ -264,7 +265,7 @@ parse_bdg_cfg()
sprintf(bdg_stats.s[ifp->if_index].name,
"%s%d:%d", ifp->if_name, ifp->if_unit, cluster);
DDB(printf("--++ found %s\n",
DEB(printf("--++ found %s\n",
bdg_stats.s[ifp->if_index].name);)
break ;
}
@ -590,6 +591,11 @@ bridge_in(struct ifnet *ifp, struct ether_header *eh)
/*
* Forward to dst, excluding src port and muted interfaces.
* 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.
*
* 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).
@ -609,6 +615,10 @@ bdg_forward(struct mbuf *m0, struct ether_header *const eh, struct ifnet *dst)
int s ;
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_chain *rule = NULL ; /* did we match a firewall rule ? */
#endif
/*
* XXX eh is usually a pointer within the mbuf (some ethernet drivers
@ -618,17 +628,24 @@ bdg_forward(struct mbuf *m0, struct ether_header *const eh, struct ifnet *dst)
struct ether_header save_eh = *eh ;
DEB(quad_t ticks; ticks = rdtsc();)
bdg_thru++;
#if defined(IPFIREWALL) && defined(DUMMYNET)
if (m0->m_type == MT_DUMMYNET) {
/* extract info from dummynet header */
rule = (struct ip_fw_chain *)(m0->m_data) ;
m0 = m0->m_next ;
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 */
dst = bridge_dst_lookup(eh);
if (dst == BDG_DROP) { /* this should not happen */
printf("xx bdg_forward for BDG_DROP\n");
#ifdef DUMMYNET
if (m0->m_type == MT_DUMMYNET)
/* XXX: Shouldn't have to be doing this. */
m_freem(m0->m_next);
else
#endif
m_freem(m0);
m_freem(m0);
return NULL;
}
if (dst == BDG_LOCAL) { /* this should not happen as well */
@ -649,37 +666,18 @@ bdg_forward(struct mbuf *m0, struct ether_header *const eh, struct ifnet *dst)
#ifdef IPFIREWALL
/*
* do filtering in a very similar way to what is done
* in ip_output. Only for IP packets, and only pass/fail/dummynet
* is supported. The tricky thing is to make sure that enough of
* the packet (basically, Eth+IP+TCP/UDP headers) is contiguous
* so that calls to m_pullup in ip_fw_chk will not kill the
* ethernet header.
* 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
* from ether_output() (src==NULL, or we would filter it twice).
* Additional restrictions may apply e.g. non-IP, short packets,
* and pkts already gone through a pipe.
*/
if (ip_fw_chk_ptr) {
struct ip_fw_chain *rule = NULL ;
if (ip_fw_chk_ptr && bdg_ipfw != 0 && src != NULL) {
struct ip *ip ;
int i;
#ifdef DUMMYNET
if (m0->m_type == MT_DUMMYNET) {
/*
* the packet was already tagged, so part of the
* processing was already done, and we need to go down.
*/
rule = (struct ip_fw_chain *)(m0->m_data) ;
m0 = m0->m_next ;
src = m0->m_pkthdr.rcvif; /* could be NULL in output */
shared = 0 ; /* for sure, a copy is not needed later. */
bdg_thru--; /* already accounted for once */
if (rule != NULL) /* dummynet packet, already partially processed */
goto forward; /* HACK! I should obey the fw_one_pass */
}
#endif
if (bdg_ipfw == 0) /* this test must be here. */
goto forward ;
if (src == NULL)
goto forward ; /* do not apply to packets from ether_output */
if (ntohs(save_eh.ether_type) != ETHERTYPE_IP)
goto forward ; /* not an IP packet, ipfw is not appropriate */
if (m0->m_pkthdr.len < sizeof(struct ip) )
@ -712,32 +710,23 @@ bdg_forward(struct mbuf *m0, struct ether_header *const eh, struct ifnet *dst)
* is NULL.
*/
i = (*ip_fw_chk_ptr)(&ip, 0, NULL, NULL /* cookie */, &m0, &rule, NULL);
if (i & IP_FW_PORT_DENY_FLAG) { /* XXX new interface - discard */
m_freem(m0);
m0 = NULL ;
} else if (m0 == NULL) {
printf("firewall using old interface\n");
}
if (m0 == NULL) { /* pkt discarded by firewall */
if (verbose) printf("pkt discarded by firewall\n");
return NULL ;
}
if ( (i & IP_FW_PORT_DENY_FLAG) || m0 == NULL) /* drop */
return m0 ;
/*
* If we get here, the firewall has passed the pkt, but the
* mbuf pointer might have changed. Restore the fields NTOHS()'d.
* If we get here, the firewall has passed the pkt, but the mbuf
* pointer might have changed. Restore ip and the fields NTOHS()'d.
*/
ip = mtod(m0, struct ip *);
HTONS(ip->ip_len);
HTONS(ip->ip_off);
if (i == 0) /* a PASS rule. */
goto forward ;
#ifdef DUMMYNET
if (i & 0x10000) {
if (i & IP_FW_PORT_DYNT_FLAG) {
/*
* pass the pkt to dummynet, which consumes it.
* If shared, make a copy and keep the origina.
* Pass the pkt to dummynet, which consumes it.
* If shared, make a copy and keep the original.
* Need to prepend the ethernet header, optimize the common
* case of eh pointing already into the original mbuf.
*/
@ -764,7 +753,7 @@ 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, dst, NULL, 0, rule, 0);
dummynet_io((i & 0xffff),DN_TO_BDG_FWD,m,real_dst,NULL,0,rule,0);
return m0 ;
}
#endif
@ -791,8 +780,11 @@ bdg_forward(struct mbuf *m0, struct ether_header *const eh, struct ifnet *dst)
return NULL ;
}
}
/* now real_dst is used to determine the cluster where to forward */
if (src != NULL) /* pkt comes from ether_input */
real_dst = src ;
for (;;) {
if (last) { /* need to forward packet */
if (last) { /* need to forward packet leftover from previous loop */
struct mbuf *m ;
if (shared == 0 && once ) { /* no need to copy */
m = m0 ;
@ -805,9 +797,9 @@ bdg_forward(struct mbuf *m0, struct ether_header *const eh, struct ifnet *dst)
}
}
/*
* Last part of ether_output: add header, queue pkt and start
* output if interface not yet active. Optimized for the
* common case of eh pointing already into the mbuf
* Add header (optimized for the common case of eh pointing
* already into the mbuf) and execute last part of ether_output:
* queue pkt and start output if interface not yet active.
*/
if ( (void *)(eh + 1) == (void *)m->m_data) {
m->m_data -= ETHER_HDR_LEN ;
@ -833,12 +825,14 @@ bdg_forward(struct mbuf *m0, struct ether_header *const eh, struct ifnet *dst)
}
if (ifp == NULL)
break ;
if (ifp != src && /* do not send to self */
BDG_USED(ifp) && /* if used for bridging */
! _IF_QFULL(&ifp->if_snd) &&
(ifp->if_flags & (IFF_UP|IFF_RUNNING)) ==
(IFF_UP|IFF_RUNNING) &&
BDG_SAMECLUSTER(ifp, src) && !BDG_MUTED(ifp) )
/*
* If the interface is used for bridging, not muted, not full,
* up and running, is not the source interface, and belongs to
* the same cluster as the 'real_dst', then send here.
*/
if ( BDG_USED(ifp) && !BDG_MUTED(ifp) && !_IF_QFULL(&ifp->if_snd) &&
(ifp->if_flags & (IFF_UP|IFF_RUNNING)) == (IFF_UP|IFF_RUNNING) &&
ifp != src && BDG_SAMECLUSTER(ifp, real_dst) )
last = ifp ;
ifp = TAILQ_NEXT(ifp, if_link) ;
if (ifp == NULL)
@ -846,6 +840,5 @@ bdg_forward(struct mbuf *m0, struct ether_header *const eh, struct ifnet *dst)
}
DEB(bdg_fw_ticks += (u_long)(rdtsc() - ticks) ; bdg_fw_count++ ;
if (bdg_fw_count != 0) bdg_fw_avg = bdg_fw_ticks/bdg_fw_count; )
return m0 ;
}

View File

@ -364,15 +364,10 @@ ether_output_frame(ifp, m)
#ifdef BRIDGE
if (do_bridge && BDG_USED(ifp) ) {
struct ether_header *eh; /* a ptr suffices */
struct ifnet *oifp = ifp ;
m->m_pkthdr.rcvif = NULL;
eh = mtod(m, struct ether_header *);
m_adj(m, ETHER_HDR_LEN);
ifp = bridge_dst_lookup(eh);
if (ifp > BDG_FORWARD && !BDG_SAMECLUSTER(ifp, oifp)) {
printf("ether_out_frame: bad output if\n");
}
m = bdg_forward(m, eh, ifp);
if (m != NULL)
m_freem(m);
@ -448,7 +443,7 @@ 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(m, eh, bif); /* needs forwarding */
/*
* Do not continue if bdg_forward() processed our
* packet (and cleared the mbuf pointer m) or if

View File

@ -569,20 +569,15 @@ in_arpinput(m)
}
la = arplookup(isaddr.s_addr, itaddr.s_addr == myaddr.s_addr, 0);
if (la && (rt = la->la_rt) && (sdl = SDL(rt->rt_gateway))) {
#ifdef BRIDGE
if (!do_bridge) { /* the following is not an error when doing bridging */
#else
{
#endif
if (rt->rt_ifp != &ac->ac_if) {
if (log_arp_wrong_iface)
/* the following is not an error when doing bridging */
if (!BRIDGE_TEST && rt->rt_ifp != &ac->ac_if) {
if (log_arp_wrong_iface)
log(LOG_ERR, "arp: %s is on %s%d but got reply from %6D on %s%d\n",
inet_ntoa(isaddr),
rt->rt_ifp->if_name, rt->rt_ifp->if_unit,
ea->arp_sha, ":",
ac->ac_if.if_name, ac->ac_if.if_unit);
goto reply;
}
goto reply;
}
if (sdl->sdl_alen &&
bcmp((caddr_t)ea->arp_sha, LLADDR(sdl), sdl->sdl_alen)) {

View File

@ -164,7 +164,7 @@ int if_tx_rdy(struct ifnet *ifp);
* ip_fw_chain is used when deleting a pipe, because ipfw rules can
* hold references to the pipe.
*/
extern LIST_HEAD (ip_fw_head, ip_fw_chain) ip_fw_chain;
extern LIST_HEAD (ip_fw_head, ip_fw_chain) ip_fw_chain_head;
static void
rt_unref(struct rtentry *rt)
@ -453,7 +453,7 @@ transmit_event(struct dn_pipe *pipe)
* (originally pkt->dn_m, but could be something else now) if
* it has not consumed it.
*/
m = bdg_forward(&m, eh, pkt->ifp);
m = bdg_forward(m, eh, pkt->ifp);
if (m)
m_freem(m);
}
@ -1282,7 +1282,7 @@ dummynet_flush()
s = splimp() ;
/* remove all references to pipes ...*/
for (chain= LIST_FIRST(&ip_fw_chain) ; chain; chain = LIST_NEXT(chain, chain))
LIST_FOREACH(chain, &ip_fw_chain_head, next)
chain->rule->pipe_ptr = NULL ;
/* prevent future matches... */
p = all_pipes ;
@ -1658,7 +1658,7 @@ delete_pipe(struct dn_pipe *p)
else
a->next = b->next ;
/* remove references to this pipe from the ip_fw rules. */
for (chain = LIST_FIRST(&ip_fw_chain) ; chain; chain = LIST_NEXT(chain, chain))
LIST_FOREACH(chain, &ip_fw_chain_head, next)
if (chain->rule->pipe_ptr == &(b->fs))
chain->rule->pipe_ptr = NULL ;
@ -1692,7 +1692,7 @@ delete_pipe(struct dn_pipe *p)
else
a->next = b->next ;
/* remove references to this flow_set from the ip_fw rules. */
LIST_FOREACH(chain, &ip_fw_chain, chain)
LIST_FOREACH(chain, &ip_fw_chain_head, next)
if (chain->rule->pipe_ptr == b)
chain->rule->pipe_ptr = NULL ;

View File

@ -89,7 +89,7 @@ struct ipfw_flow_id last_pkt ;
#define IPFW_DEFAULT_RULE ((u_int)(u_short)~0)
LIST_HEAD (ip_fw_head, ip_fw_chain) ip_fw_chain;
LIST_HEAD (ip_fw_head, ip_fw_chain) ip_fw_chain_head;
MALLOC_DEFINE(M_IPFW, "IpFw/IpAcct", "IpFw/IpAcct chain's");
@ -903,10 +903,10 @@ lookup_next_rule(struct ip_fw_chain *me)
int rule = me->rule->fw_skipto_rule ; /* guess... */
if ( (me->rule->fw_flg & IP_FW_F_COMMAND) == IP_FW_F_SKIPTO )
for (chain = LIST_NEXT(me, chain); chain ; chain = LIST_NEXT(chain, chain) )
for (chain = LIST_NEXT(me,next); chain ; chain = LIST_NEXT(chain,next))
if (chain->rule->fw_number >= rule)
return chain ;
return LIST_NEXT(me, chain) ; /* failure or not a skipto */
return LIST_NEXT(me,next) ; /* failure or not a skipto */
}
/*
@ -924,6 +924,7 @@ lookup_next_rule(struct ip_fw_chain *me)
*
* Return value:
*
* IP_FW_PORT_DENY_FLAG the packet must be dropped.
* 0 The packet is to be accepted and routed normally OR
* the packet was denied/rejected and has been dropped;
* in the latter case, *m is equal to NULL upon return.
@ -1038,7 +1039,7 @@ ip_fw_chk(struct ip **pip, int hlen,
* Packet has already been tagged. Look for the next rule
* to restart processing.
*/
chain = LIST_NEXT(*flow_id, chain);
chain = LIST_NEXT(*flow_id, next);
if ((chain = (*flow_id)->rule->next_rule_ptr) == NULL)
chain = (*flow_id)->rule->next_rule_ptr =
@ -1050,19 +1051,19 @@ ip_fw_chk(struct ip **pip, int hlen,
* Go down the chain, looking for enlightment.
* If we've been asked to start at a given rule, do so.
*/
chain = LIST_FIRST(&ip_fw_chain);
chain = LIST_FIRST(&ip_fw_chain_head);
if (skipto != 0) {
if (skipto >= IPFW_DEFAULT_RULE)
goto dropit;
while (chain && chain->rule->fw_number <= skipto)
chain = LIST_NEXT(chain, chain);
chain = LIST_NEXT(chain, next);
if (chain == NULL)
goto dropit;
}
}
for (; chain; chain = LIST_NEXT(chain, chain)) {
for (; chain; chain = LIST_NEXT(chain, next)) {
again:
f = chain->rule;
if (f->fw_number == IPFW_DEFAULT_RULE)
@ -1093,7 +1094,7 @@ ip_fw_chk(struct ip **pip, int hlen,
}
/* Check if rule only valid for bridged packets */
if ((f->fw_flg & IP_FW_BRIDGED) != 0 && ! (BRIDGED) )
if ((f->fw_flg & IP_FW_BRIDGED) != 0 && !(BRIDGED))
continue;
if (oif) {
@ -1444,9 +1445,7 @@ ip_fw_chk(struct ip **pip, int hlen,
/*
* Finally, drop the packet.
*/
if (*m)
return(IP_FW_PORT_DENY_FLAG);
return(0);
return(IP_FW_PORT_DENY_FLAG);
#undef BRIDGED
}
@ -1461,7 +1460,7 @@ flush_rule_ptrs()
{
struct ip_fw_chain *fcp ;
LIST_FOREACH(fcp, &ip_fw_chain, chain) {
LIST_FOREACH(fcp, &ip_fw_chain_head, next) {
fcp->rule->next_rule_ptr = NULL ;
}
}
@ -1501,14 +1500,14 @@ add_entry(struct ip_fw_head *chainptr, struct ip_fw *frwl)
s = splnet();
if (LIST_FIRST(chainptr) == 0) {
LIST_INSERT_HEAD(chainptr, fwc, chain);
LIST_INSERT_HEAD(chainptr, fwc, next);
splx(s);
return(0);
}
/* If entry number is 0, find highest numbered rule and add 100 */
if (ftmp->fw_number == 0) {
LIST_FOREACH(fcp, chainptr, chain) {
LIST_FOREACH(fcp, chainptr, next) {
if (fcp->rule->fw_number != (u_short)-1)
nbr = fcp->rule->fw_number;
else
@ -1520,12 +1519,12 @@ add_entry(struct ip_fw_head *chainptr, struct ip_fw *frwl)
}
/* Got a valid number; now insert it, keeping the list ordered */
LIST_FOREACH(fcp, chainptr, chain) {
LIST_FOREACH(fcp, chainptr, next) {
if (fcp->rule->fw_number > ftmp->fw_number) {
if (fcpl) {
LIST_INSERT_AFTER(fcpl, fwc, chain);
LIST_INSERT_AFTER(fcpl, fwc, next);
} else {
LIST_INSERT_HEAD(chainptr, fwc, chain);
LIST_INSERT_HEAD(chainptr, fwc, next);
}
break;
} else {
@ -1545,7 +1544,7 @@ del_entry(struct ip_fw_head *chainptr, u_short number)
fcp = LIST_FIRST(chainptr);
if (number != (u_short)-1) {
for (; fcp; fcp = LIST_NEXT(fcp, chain)) {
for (; fcp; fcp = LIST_NEXT(fcp, next)) {
if (fcp->rule->fw_number == number) {
int s;
@ -1555,8 +1554,8 @@ del_entry(struct ip_fw_head *chainptr, u_short number)
struct ip_fw_chain *next;
remove_dyn_rule(fcp, 1 /* delete */);
next = LIST_NEXT(fcp, chain);
LIST_REMOVE(fcp, chain);
next = LIST_NEXT(fcp, next);
LIST_REMOVE(fcp, next);
#ifdef DUMMYNET
dn_rule_delete(fcp) ;
#endif
@ -1582,7 +1581,7 @@ zero_entry(struct ip_fw *frwl)
if (frwl == 0) {
s = splnet();
LIST_FOREACH(fcp, &ip_fw_chain, chain) {
LIST_FOREACH(fcp, &ip_fw_chain_head, next) {
fcp->rule->fw_bcnt = fcp->rule->fw_pcnt = 0;
fcp->rule->fw_loghighest = fcp->rule->fw_logamount;
fcp->rule->timestamp = 0;
@ -1597,7 +1596,7 @@ zero_entry(struct ip_fw *frwl)
* same number, so we don't stop after finding the first
* match if zeroing a specific entry.
*/
LIST_FOREACH(fcp, &ip_fw_chain, chain)
LIST_FOREACH(fcp, &ip_fw_chain_head, next)
if (frwl->fw_number == fcp->rule->fw_number) {
s = splnet();
while (fcp && frwl->fw_number == fcp->rule->fw_number) {
@ -1605,7 +1604,7 @@ zero_entry(struct ip_fw *frwl)
fcp->rule->fw_loghighest =
fcp->rule->fw_logamount;
fcp->rule->timestamp = 0;
fcp = LIST_NEXT(fcp, chain);
fcp = LIST_NEXT(fcp, next);
}
splx(s);
cleared = 1;
@ -1636,7 +1635,7 @@ resetlog_entry(struct ip_fw *frwl)
if (frwl == 0) {
s = splnet();
counter = 0;
LIST_FOREACH(fcp, &ip_fw_chain, chain)
LIST_FOREACH(fcp, &ip_fw_chain_head, next)
fcp->rule->fw_loghighest = fcp->rule->fw_pcnt +
fcp->rule->fw_logamount;
splx(s);
@ -1649,14 +1648,14 @@ resetlog_entry(struct ip_fw *frwl)
* same number, so we don't stop after finding the first
* match if zeroing a specific entry.
*/
LIST_FOREACH(fcp, &ip_fw_chain, chain)
LIST_FOREACH(fcp, &ip_fw_chain_head, next)
if (frwl->fw_number == fcp->rule->fw_number) {
s = splnet();
while (fcp && frwl->fw_number == fcp->rule->fw_number) {
fcp->rule->fw_loghighest =
fcp->rule->fw_pcnt +
fcp->rule->fw_logamount;
fcp = LIST_NEXT(fcp, chain);
fcp = LIST_NEXT(fcp, next);
}
splx(s);
cleared = 1;
@ -1835,9 +1834,9 @@ ip_fw_ctl(struct sockopt *sopt)
switch (sopt->sopt_name) {
case IP_FW_GET:
for (fcp = LIST_FIRST(&ip_fw_chain), size = 0; fcp;
fcp = LIST_NEXT(fcp, chain))
size += sizeof *fcp->rule;
size = 0 ;
LIST_FOREACH(fcp, &ip_fw_chain_head, next)
size += sizeof(struct ip_fw) ;
if (ipfw_dyn_v) {
int i ;
struct ipfw_dyn_rule *p ;
@ -1852,8 +1851,8 @@ ip_fw_ctl(struct sockopt *sopt)
break;
}
for (fcp = LIST_FIRST(&ip_fw_chain), bp = buf; fcp;
fcp = LIST_NEXT(fcp, chain)) {
bp = buf ;
LIST_FOREACH(fcp, &ip_fw_chain_head, next) {
bcopy(fcp->rule, bp, sizeof *fcp->rule);
bp->pipe_ptr = (void *)(intptr_t)
((struct ip_fw_ext *)fcp->rule)->dont_match_prob;
@ -1888,11 +1887,10 @@ ip_fw_ctl(struct sockopt *sopt)
s = splnet();
remove_dyn_rule(NULL, 1 /* force delete */);
splx(s);
for (fcp = LIST_FIRST(&ip_fw_chain);
fcp != 0 && fcp->rule->fw_number != IPFW_DEFAULT_RULE;
fcp = LIST_FIRST(&ip_fw_chain)) {
while ( (fcp = LIST_FIRST(&ip_fw_chain_head)) &&
fcp->rule->fw_number != IPFW_DEFAULT_RULE ) {
s = splnet();
LIST_REMOVE(fcp, chain);
LIST_REMOVE(fcp, next);
#ifdef DUMMYNET
dn_rule_delete(fcp);
#endif
@ -1923,7 +1921,7 @@ ip_fw_ctl(struct sockopt *sopt)
(unsigned)IPFW_DEFAULT_RULE));
error = EINVAL;
} else {
error = add_entry(&ip_fw_chain, &frwl);
error = add_entry(&ip_fw_chain_head, &frwl);
if (!error && sopt->sopt_dir == SOPT_GET)
error = sooptcopyout(sopt, &frwl, sizeof frwl);
}
@ -1939,7 +1937,7 @@ ip_fw_ctl(struct sockopt *sopt)
(unsigned)IPFW_DEFAULT_RULE));
error = EINVAL;
} else {
error = del_entry(&ip_fw_chain, frwl.fw_number);
error = del_entry(&ip_fw_chain_head, frwl.fw_number);
}
break;
@ -1971,7 +1969,7 @@ ip_fw_init(void)
ip_fw_chk_ptr = ip_fw_chk;
ip_fw_ctl_ptr = ip_fw_ctl;
LIST_INIT(&ip_fw_chain);
LIST_INIT(&ip_fw_chain_head);
bzero(&default_rule, sizeof default_rule);
default_rule.fw_prot = IPPROTO_IP;
@ -1983,10 +1981,10 @@ ip_fw_init(void)
#endif
default_rule.fw_flg |= IP_FW_F_IN | IP_FW_F_OUT;
if (check_ipfw_struct(&default_rule) != 0 ||
add_entry(&ip_fw_chain, &default_rule))
add_entry(&ip_fw_chain_head, &default_rule))
panic("ip_fw_init");
ip_fw_default_rule = LIST_FIRST(&ip_fw_chain) ;
ip_fw_default_rule = LIST_FIRST(&ip_fw_chain_head) ;
printf("IP packet filtering initialized, "
#ifdef IPDIVERT
"divert enabled, "
@ -2021,6 +2019,7 @@ static int
ipfw_modevent(module_t mod, int type, void *unused)
{
int s;
struct ip_fw_chain *fcp;
switch (type) {
case MOD_LOAD:
@ -2037,9 +2036,8 @@ ipfw_modevent(module_t mod, int type, void *unused)
ip_fw_chk_ptr = old_chk_ptr;
ip_fw_ctl_ptr = old_ctl_ptr;
remove_dyn_rule(NULL, 1 /* force delete */);
while (LIST_FIRST(&ip_fw_chain) != NULL) {
struct ip_fw_chain *fcp = LIST_FIRST(&ip_fw_chain);
LIST_REMOVE(LIST_FIRST(&ip_fw_chain), chain);
while ( (fcp = LIST_FIRST(&ip_fw_chain_head)) != NULL) {
LIST_REMOVE(fcp, next);
#ifdef DUMMYNET
dn_rule_delete(fcp);
#endif

View File

@ -130,8 +130,8 @@ struct ip_fw_ext { /* extended structure */
#define fw_fwd_ip fw_un.fu_fwd_ip
struct ip_fw_chain {
LIST_ENTRY(ip_fw_chain) chain;
struct ip_fw *rule;
LIST_ENTRY(ip_fw_chain) next;
struct ip_fw *rule;
};
/*