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:
parent
1ab77b0945
commit
88aa2a208a
127
sys/net/bridge.c
127
sys/net/bridge.c
@ -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 ;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)) {
|
||||
|
@ -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 ;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user