svn commit: r201346 - in user/luigi/ipfw3-head/sys: net netgraph
netinet netinet/ipfw
Luigi Rizzo
luigi at FreeBSD.org
Thu Dec 31 18:28:40 UTC 2009
Author: luigi
Date: Thu Dec 31 18:28:40 2009
New Revision: 201346
URL: http://svn.freebsd.org/changeset/base/201346
Log:
snapshot (probably not compiling)
Modified:
user/luigi/ipfw3-head/sys/net/if_bridge.c
user/luigi/ipfw3-head/sys/net/if_ethersubr.c
user/luigi/ipfw3-head/sys/netgraph/ng_ipfw.c
user/luigi/ipfw3-head/sys/netinet/ip_divert.c
user/luigi/ipfw3-head/sys/netinet/ip_divert.h
user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h
user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c
user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw2.c
user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_dynamic.c
user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_pfil.c
user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_private.h
Modified: user/luigi/ipfw3-head/sys/net/if_bridge.c
==============================================================================
--- user/luigi/ipfw3-head/sys/net/if_bridge.c Thu Dec 31 18:02:48 2009 (r201345)
+++ user/luigi/ipfw3-head/sys/net/if_bridge.c Thu Dec 31 18:28:40 2009 (r201346)
@@ -3040,25 +3040,26 @@ bridge_pfil(struct mbuf **mp, struct ifn
}
/* XXX this section is also in if_ethersubr.c */
- if (V_ip_fw_chk_ptr && pfil_ipfw != 0 && dir == PFIL_OUT && ifp != NULL) {
+ // XXX PFIL_OUT or DIR_OUT ?
+ if (V_ip_fw_chk_ptr && pfil_ipfw != 0 &&
+ dir == PFIL_OUT && ifp != NULL) {
struct m_tag *mtag;
error = -1;
- mtag = m_tag_find(*mp, PACKET_TAG_DUMMYNET, NULL);
+ /* fetch the start point from existing tags, if any */
+ mtag = m_tag_locate(*mp, MTAG_IPFW_RULE, 0, NULL);
if (mtag == NULL) {
- args.slot = 0;
+ args.rule.slot = 0;
} else {
struct dn_pkt_tag *dn_tag;
+ /* XXX can we free the tag after use ? */
mtag->m_tag_id = PACKET_TAG_NONE;
dn_tag = (struct dn_pkt_tag *)(mtag + 1);
- if (dn_tag->slot != 0 && V_fw_one_pass)
- /* packet already partially processed */
+ /* packet already partially processed ? */
+ if (dn_tag->rule.slot != 0 && V_fw_one_pass)
goto ipfwpass;
- args.slot = dn_tag->slot; /* next rule to use */
- args.chain_id = dn_tag->chain_id;
- args.rulenum = dn_tag->rulenum;
- args.rule_id = dn_tag->rule_id;
+ args.rule = dn_tag->rule;
}
args.m = *mp;
Modified: user/luigi/ipfw3-head/sys/net/if_ethersubr.c
==============================================================================
--- user/luigi/ipfw3-head/sys/net/if_ethersubr.c Thu Dec 31 18:02:48 2009 (r201345)
+++ user/luigi/ipfw3-head/sys/net/if_ethersubr.c Thu Dec 31 18:28:40 2009 (r201346)
@@ -469,21 +469,20 @@ ether_ipfw_chk(struct mbuf **m0, struct
struct ip_fw_args args;
struct m_tag *mtag;
- mtag = m_tag_find(*m0, PACKET_TAG_DUMMYNET, NULL);
+ /* fetch start point from rule, if any */
+ mtag = m_tag_locate(*m0, MTAG_IPFW_RULE, 0, NULL);
if (mtag == NULL) {
- args.slot = 0;
+ args.rule.slot = 0;
} else {
struct dn_pkt_tag *dn_tag;
+ /* XXX can we free it after use ? */
mtag->m_tag_id = PACKET_TAG_NONE;
dn_tag = (struct dn_pkt_tag *)(mtag + 1);
- if (dn_tag->slot != 0 && V_fw_one_pass)
+ if (dn_tag->rule.slot != 0 && V_fw_one_pass)
/* dummynet packet, already partially processed */
return (1);
- args.slot = dn_tag->slot; /* matching rule to restart */
- args.rulenum = dn_tag->rulenum;
- args.rule_id = dn_tag->rule_id;
- args.chain_id = dn_tag->chain_id;
+ args.rule = dn_tag->rule;
}
/*
Modified: user/luigi/ipfw3-head/sys/netgraph/ng_ipfw.c
==============================================================================
--- user/luigi/ipfw3-head/sys/netgraph/ng_ipfw.c Thu Dec 31 18:02:48 2009 (r201345)
+++ user/luigi/ipfw3-head/sys/netgraph/ng_ipfw.c Thu Dec 31 18:28:40 2009 (r201346)
@@ -221,19 +221,20 @@ ng_ipfw_findhook1(node_p node, u_int16_t
static int
ng_ipfw_rcvdata(hook_p hook, item_p item)
{
- struct ng_ipfw_tag *ngit;
+ struct ipfw_start_info *ngit;
struct mbuf *m;
NGI_GET_M(item, m);
NG_FREE_ITEM(item);
- if ((ngit = (struct ng_ipfw_tag *)m_tag_locate(m, NGM_IPFW_COOKIE, 0,
- NULL)) == NULL) {
+ ngit = (struct ipfw_start_info *)
+ m_tag_locate(m, NGM_IPFW_COOKIE, 0, NULL);
+ if (ngit == NULL) {
NG_FREE_M(m);
return (EINVAL); /* XXX: find smth better */
};
- switch (ngit->dir) {
+ switch (ngit->info) {
case DIR_OUT:
{
struct ip *ip;
@@ -263,7 +264,7 @@ static int
ng_ipfw_input(struct mbuf **m0, int dir, struct ip_fw_args *fwa, int tee)
{
struct mbuf *m;
- struct ng_ipfw_tag *ngit;
+ struct ipfw_start_info *ngit;
struct ip *ip;
hook_p hook;
int error = 0;
@@ -284,21 +285,21 @@ ng_ipfw_input(struct mbuf **m0, int dir,
* a copy of a packet and forward it into netgraph without a tag.
*/
if (tee == 0) {
+ struct m_tag *tag;
+ struct ipfw_start_info *ngit;
m = *m0;
*m0 = NULL; /* it belongs now to netgraph */
- if ((ngit = (struct ng_ipfw_tag *)m_tag_alloc(NGM_IPFW_COOKIE,
- 0, TAGSIZ, M_NOWAIT|M_ZERO)) == NULL) {
+ tag = m_tag_alloc(NGM_IPFW_COOKIE, sizeof(*mt),
+ M_NOWAIT|M_ZERO);
+ if (tagn == NULL) {
m_freem(m);
return (ENOMEM);
}
- ngit->slot = fwa->slot;
- ngit->rulenum = fwa->rulenum;
- ngit->rule_id = fwa->rule_id;
- ngit->chain_id = fwa->chain_id;
- ngit->dir = dir;
-// ngit->ifp = fwa->oif; /* XXX do we use it ? */
- m_tag_prepend(m, &ngit->mt);
+ ngit = (struct ipfw_start_info *)(tag + 1);
+ *ngit = fwa->start
+ ngit->info = dir;
+ m_tag_prepend(m, tag);
} else
if ((m = m_dup(*m0, M_DONTWAIT)) == NULL)
Modified: user/luigi/ipfw3-head/sys/netinet/ip_divert.c
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ip_divert.c Thu Dec 31 18:02:48 2009 (r201345)
+++ user/luigi/ipfw3-head/sys/netinet/ip_divert.c Thu Dec 31 18:28:40 2009 (r201346)
@@ -72,10 +72,10 @@ __FBSDID("$FreeBSD$");
#include <netinet/in_systm.h>
#include <netinet/in_var.h>
#include <netinet/ip.h>
-#include <netinet/ip_divert.h>
#include <netinet/ip_var.h>
#include <netinet/ip_fw.h>
#include <netinet/ipfw/ip_fw_private.h>
+#include <netinet/ip_divert.h>
#ifdef SCTP
#include <netinet/sctp_crc32.h>
#endif
@@ -301,6 +301,9 @@ divert_packet(struct mbuf *m, int incomi
/* Put packet on socket queue, if any */
sa = NULL;
nport = htons((u_int16_t)divert_info(mtag));
+ printf("divert rule %d %s to port %d\n", divsrc.sin_port,
+ incoming ? "in" : "out",
+ ntohs(nport));
INP_INFO_RLOCK(&V_divcbinfo);
LIST_FOREACH(inp, &V_divcb, inp_list) {
/* XXX why does only one socket match? */
@@ -339,7 +342,7 @@ div_output(struct socket *so, struct mbu
struct mbuf *control)
{
struct m_tag *mtag;
- struct divert_tag *dt;
+ struct ipfw_rule_ref *dt;
int error = 0;
struct mbuf *options;
@@ -354,23 +357,35 @@ div_output(struct socket *so, struct mbu
if (control)
m_freem(control); /* XXX */
- if ((mtag = m_tag_find(m, PACKET_TAG_DIVERT, NULL)) == NULL) {
- mtag = m_tag_get(PACKET_TAG_DIVERT, sizeof(struct divert_tag),
- M_NOWAIT | M_ZERO);
+ mtag = m_tag_locate(m, MTAG_IPFW_RULE, 0, NULL);
+ if (mtag == NULL) {
+ /* this should be normal */
+ printf("create divert tag\n");
+ mtag = m_tag_alloc(MTAG_IPFW_RULE, 0,
+ sizeof(struct ipfw_rule_ref), M_NOWAIT | M_ZERO);
if (mtag == NULL) {
error = ENOBUFS;
goto cantsend;
}
- dt = (struct divert_tag *)(mtag+1);
m_tag_prepend(m, mtag);
- } else
- dt = (struct divert_tag *)(mtag+1);
+ }
+ dt = (struct ipfw_rule_ref *)(mtag+1);
+ printf("%s sin %p dst rule %d addr 0x%x\n", __FUNCTION__,
+ sin, sin? sin->sin_port : -1,
+ sin ? sin->sin_addr.s_addr : 0xdeaddead);
/* Loopback avoidance and state recovery */
if (sin) {
int i;
- dt->cookie = sin->sin_port;
+ /* set the starting point. We provide a non-zero slot,
+ * but a non_matching chain_id to skip that info and use
+ * the rulenum/rule_id.
+ */
+ dt->slot = 1; /* dummy, chain_id is invalid */
+ dt->chain_id = 0;
+ dt->rulenum = sin->sin_port+1; /* host format ? */
+ dt->rule_id = 0;
/*
* Find receive interface with the given name, stuffed
* (if it exists) in the sin_zero[] field.
@@ -455,6 +470,7 @@ div_output(struct socket *so, struct mbu
}
} else {
dt->info |= IP_FW_DIVERT_LOOPBACK_FLAG;
+ printf("divert to loopback\n");
if (m->m_pkthdr.rcvif == NULL) {
/*
* No luck with the name, check by IP address.
@@ -467,6 +483,7 @@ div_output(struct socket *so, struct mbu
sin->sin_port = 0;
ifa = ifa_ifwithaddr((struct sockaddr *) sin);
if (ifa == NULL) {
+ printf("%s ifa not found ???\n", __FUNCTION__);
error = EADDRNOTAVAIL;
goto cantsend;
}
Modified: user/luigi/ipfw3-head/sys/netinet/ip_divert.h
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ip_divert.h Thu Dec 31 18:02:48 2009 (r201345)
+++ user/luigi/ipfw3-head/sys/netinet/ip_divert.h Thu Dec 31 18:28:40 2009 (r201346)
@@ -45,10 +45,6 @@ SYSCTL_DECL(_net_inet_divert);
/*
* Divert socket definitions.
*/
-struct divert_tag {
- u_int32_t info; /* port & flags */
- u_int16_t cookie; /* ipfw rule number */
-};
/*
* Return the divert cookie associated with the mbuf; if any.
@@ -56,13 +52,7 @@ struct divert_tag {
static __inline u_int16_t
divert_cookie(struct m_tag *mtag)
{
- return ((struct divert_tag *)(mtag+1))->cookie;
-}
-static __inline u_int16_t
-divert_find_cookie(struct mbuf *m)
-{
- struct m_tag *mtag = m_tag_find(m, PACKET_TAG_DIVERT, NULL);
- return mtag ? divert_cookie(mtag) : 0;
+ return ((struct ipfw_rule_ref *)(mtag+1))->rulenum;
}
/*
@@ -71,13 +61,7 @@ divert_find_cookie(struct mbuf *m)
static __inline u_int32_t
divert_info(struct m_tag *mtag)
{
- return ((struct divert_tag *)(mtag+1))->info;
-}
-static __inline u_int32_t
-divert_find_info(struct mbuf *m)
-{
- struct m_tag *mtag = m_tag_find(m, PACKET_TAG_DIVERT, NULL);
- return mtag ? divert_info(mtag) : 0;
+ return ((struct ipfw_rule_ref *)(mtag+1))->info;
}
typedef void ip_divert_packet_t(struct mbuf *m, int incoming);
Modified: user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h Thu Dec 31 18:02:48 2009 (r201345)
+++ user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h Thu Dec 31 18:28:40 2009 (r201346)
@@ -114,11 +114,7 @@ struct dn_heap {
* other forms of packet reinjection.
*/
struct dn_pkt_tag {
- /* first part, reinject info */
- uint32_t slot; /* slot of next rule to use */
- uint32_t rulenum; /* matching rule number */
- uint32_t rule_id; /* matching rule id */
- uint32_t chain_id; /* ruleset id */
+ struct ipfw_rule_ref rule; /* matching rule */
/* second part, dummynet specific */
int dn_dir; /* action when packet comes out. */
Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Thu Dec 31 18:02:48 2009 (r201345)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Thu Dec 31 18:28:40 2009 (r201346)
@@ -468,7 +468,7 @@ heap_free(struct dn_heap *h)
*/
static __inline void *dn_free_pkt(struct mbuf *m)
{
- m_freem(m);
+ FREE_PKT(m);
return NULL;
}
@@ -975,8 +975,10 @@ dummynet_send(struct mbuf *m)
dst = DIR_DROP;
} else {
struct dn_pkt_tag *pkt = dn_tag_get(m);
+ /* extract the dummynet info, rename the tag */
dst = pkt->dn_dir;
ifp = pkt->ifp;
+ // XXX rename the tag
}
switch (dst) {
@@ -1364,7 +1366,7 @@ dummynet_io(struct mbuf **m0, int dir, s
struct dn_pipe *pipe;
uint64_t len = m->m_pkthdr.len;
struct dn_flow_queue *q = NULL;
- int is_pipe = fwa->cookie & 0x8000000 ? 0 : 1;
+ int is_pipe = fwa->rule.info & 0x8000000 ? 0 : 1;
KASSERT(m->m_nextpkt == NULL,
("dummynet_io: mbuf queue passed to dummynet"));
@@ -1378,11 +1380,11 @@ dummynet_io(struct mbuf **m0, int dir, s
* below can be simplified.
*/
if (is_pipe) {
- pipe = locate_pipe(fwa->cookie & 0xffff);
+ pipe = locate_pipe(fwa->rule.info & 0xffff);
if (pipe != NULL)
fs = &(pipe->fs);
} else
- fs = locate_flowset(fwa->cookie & 0xffff);
+ fs = locate_flowset(fwa->rule.info & 0xffff);
if (fs == NULL)
goto dropit; /* This queue/pipe does not exist! */
@@ -1428,12 +1430,8 @@ dummynet_io(struct mbuf **m0, int dir, s
* Ok, i can handle the pkt now...
* Build and enqueue packet + parameters.
*/
- pkt->slot = fwa->slot;
- pkt->rulenum = fwa->rulenum;
- pkt->rule_id = fwa->rule_id;
- pkt->chain_id = fwa->chain_id;
+ pkt->rule = fwa->rule;
pkt->dn_dir = dir;
-
pkt->ifp = fwa->oif;
if (q->head == NULL)
Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw2.c
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw2.c Thu Dec 31 18:02:48 2009 (r201345)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw2.c Thu Dec 31 18:28:40 2009 (r201346)
@@ -560,7 +560,7 @@ send_reject6(struct ip_fw_args *args, in
ip6_output(m0, NULL, NULL, 0, NULL, NULL,
NULL);
}
- m_freem(m);
+ FREE_PKT(m);
} else if (code != ICMP6_UNREACH_RST) { /* Send an ICMPv6 unreach. */
#if 0
/*
@@ -576,7 +576,7 @@ send_reject6(struct ip_fw_args *args, in
#endif
icmp6_error(m, ICMP6_DST_UNREACH, code, 0);
} else
- m_freem(m);
+ FREE_PKT(m);
args->m = NULL;
}
@@ -616,9 +616,9 @@ send_reject(struct ip_fw_args *args, int
if (m != NULL)
ip_output(m, NULL, NULL, 0, NULL, NULL);
}
- m_freem(args->m);
+ FREE_PKT(args->m);
} else
- m_freem(args->m);
+ FREE_PKT(args->m);
args->m = NULL;
}
@@ -707,16 +707,18 @@ check_uidgid(ipfw_insn_u32 *insn, int pr
}
/*
- * Helper function to write the matching rule into args
+ * Helper function to set args with info on the rule after the matching
+ * one. slot is precise, whereas we guess rule_id as they are
+ * assigned sequentially.
*/
static inline void
set_match(struct ip_fw_args *args, int slot,
struct ip_fw_chain *chain)
{
- args->chain_id = chain->id;
- args->slot = slot + 1; /* we use 0 as a marker */
- args->rule_id = chain->map[slot]->id;
- args->rulenum = chain->map[slot]->rulenum;
+ args->rule.chain_id = chain->id;
+ args->rule.slot = slot + 1; /* we use 0 as a marker */
+ args->rule.rule_id = 1 + chain->map[slot]->id;
+ args->rule.rulenum = chain->map[slot]->rulenum;
}
/*
@@ -741,7 +743,7 @@ set_match(struct ip_fw_args *args, int s
* args->rule Pointer to the last matching rule (in/out)
* args->next_hop Socket we are forwarding to (out).
* args->f_id Addresses grabbed from the packet (out)
- * args->cookie a cookie depending on rule action
+ * args->rule.info a cookie depending on rule action
*
* Return value:
*
@@ -751,6 +753,8 @@ set_match(struct ip_fw_args *args, int s
* IP_FW_TEE tee packet, port in m_tag
* IP_FW_DUMMYNET to dummynet, pipe in args->cookie
* IP_FW_NETGRAPH into netgraph, cookie args->cookie
+ * args->rule contains the matching rule,
+ * args->rule.info has additional information.
*
*/
int
@@ -1133,45 +1137,25 @@ do { \
IPFW_RUNLOCK(chain);
return (IP_FW_PASS); /* accept */
}
- /* XXX divert should be handled same as other tags */
- mtag = m_tag_find(m, PACKET_TAG_DIVERT, NULL);
- if (args->slot) {
+ if (args->rule.slot) {
/*
* Packet has already been tagged as a result of a previous
* match on rule args->rule aka args->rule_id (PIPE, QUEUE,
- * REASS, NETGRAPH and similar, never a skipto).
+ * REASS, NETGRAPH, DIVERT/TEE...)
* Validate the slot and continue from the next one
* if still present, otherwise do a lookup.
*/
- if (V_fw_one_pass) {
- IPFW_RUNLOCK(chain);
- return (IP_FW_PASS);
- }
- f_pos = (args->chain_id == chain->id) ?
- args->slot /* already incremented */ :
- ipfw_find_rule(chain, args->rulenum, args->rule_id+1);
+ f_pos = (args->rule.chain_id == chain->id) ?
+ args->rule.slot :
+ ipfw_find_rule(chain, args->rule.rulenum,
+ args->rule.rule_id);
} else {
- /*
- * Find the starting rule. It can be either the first
- * one, or the one after divert_rule if asked so.
- */
- int skipto = mtag ? divert_cookie(mtag) : 0;
-
f_pos = 0;
- if (args->eh == NULL && skipto != 0) {
- if (skipto >= IPFW_DEFAULT_RULE) {
- IPFW_RUNLOCK(chain);
- return (IP_FW_DENY); /* invalid */
- }
- f_pos = ipfw_find_rule(chain, skipto+1, 0);
- }
}
- /* reset divert rule to avoid confusion later */
- if (mtag) {
+#if 0 // XXX to be fixed
divinput_flags = divert_info(mtag) &
(IP_FW_DIVERT_OUTPUT_FLAG | IP_FW_DIVERT_LOOPBACK_FLAG);
- m_tag_delete(m, mtag);
- }
+#endif
/*
* Now scan the rules, and parse microinstructions for each rule.
@@ -1761,12 +1745,13 @@ do { \
if (cmd->len & F_NOT) { /* `untag' action */
if (mtag != NULL)
m_tag_delete(m, mtag);
+ match = 0;
} else if (mtag == NULL) {
if ((mtag = m_tag_alloc(MTAG_IPFW,
tag, 0, M_NOWAIT)) != NULL)
m_tag_prepend(m, mtag);
+ match = 1;
}
- match = (cmd->len & F_NOT) ? 0: 1;
break;
}
@@ -1916,10 +1901,10 @@ do { \
case O_PIPE:
case O_QUEUE:
set_match(args, f_pos, chain);
- args->cookie = (cmd->arg1 == IP_FW_TABLEARG) ?
+ args->rule.info = (cmd->arg1 == IP_FW_TABLEARG) ?
tablearg : cmd->arg1;
if (cmd->opcode == O_QUEUE)
- args->cookie |= 0x80000000;
+ args->rule.info |= 0x80000000;
retval = IP_FW_DUMMYNET;
l = 0; /* exit inner loop */
done = 1; /* exit outer loop */
@@ -1932,23 +1917,9 @@ do { \
/* otherwise this is terminal */
l = 0; /* exit inner loop */
done = 1; /* exit outer loop */
- mtag = m_tag_get(PACKET_TAG_DIVERT,
- sizeof(struct divert_tag),
- M_NOWAIT);
- if (mtag == NULL) {
- retval = IP_FW_DENY;
- } else {
- struct divert_tag *dt;
- dt = (struct divert_tag *)(mtag+1);
- dt->cookie = f->rulenum;
- if (cmd->arg1 == IP_FW_TABLEARG)
- dt->info = tablearg;
- else
- dt->info = cmd->arg1;
- m_tag_prepend(m, mtag);
- retval = (cmd->opcode == O_DIVERT) ?
- IP_FW_DIVERT : IP_FW_TEE;
- }
+ set_match(args, f_pos, chain);
+ args->rule.info = (cmd->arg1 == IP_FW_TABLEARG) ?
+ tablearg : cmd->arg1;
break;
case O_COUNT:
@@ -2064,7 +2035,7 @@ do { \
case O_NETGRAPH:
case O_NGTEE:
set_match(args, f_pos, chain);
- args->cookie = (cmd->arg1 == IP_FW_TABLEARG) ?
+ args->rule.info = (cmd->arg1 == IP_FW_TABLEARG) ?
tablearg : cmd->arg1;
retval = (cmd->opcode == O_NETGRAPH) ?
IP_FW_NETGRAPH : IP_FW_NGTEE;
Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_dynamic.c
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_dynamic.c Thu Dec 31 18:02:48 2009 (r201345)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_dynamic.c Thu Dec 31 18:28:40 2009 (r201346)
@@ -917,7 +917,7 @@ ipfw_send_pkt(struct mbuf *replyto, stru
#endif
default:
/* XXX: log me?!? */
- m_freem(m);
+ FREE_PKT(m);
return (NULL);
}
dir = ((flags & (TH_SYN | TH_RST)) == TH_SYN);
Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_pfil.c
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_pfil.c Thu Dec 31 18:02:48 2009 (r201345)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_pfil.c Thu Dec 31 18:28:40 2009 (r201346)
@@ -106,8 +106,7 @@ ipfw_check_hook(void *arg, struct mbuf *
struct inpcb *inp)
{
struct ip_fw_args args;
- struct ng_ipfw_tag *ng_tag;
- struct m_tag *dn_tag;
+ struct m_tag *tag;
int ipfw;
int ret;
#ifdef IPFIREWALL_FORWARD
@@ -118,29 +117,11 @@ ipfw_check_hook(void *arg, struct mbuf *
dir = (dir == PFIL_IN) ? DIR_IN : DIR_OUT;
bzero(&args, sizeof(args));
- ng_tag = (struct ng_ipfw_tag *)m_tag_locate(*m0, NGM_IPFW_COOKIE, 0,
- NULL);
- if (ng_tag != NULL) {
- KASSERT(ng_tag->dir == dir,
- ("ng_ipfw tag with wrong direction"));
- args.slot = ng_tag->slot;
- args.rulenum = ng_tag->rulenum;
- args.rule_id = ng_tag->rule_id;
- args.chain_id = ng_tag->chain_id;
- m_tag_delete(*m0, (struct m_tag *)ng_tag);
- }
-
again:
- dn_tag = m_tag_find(*m0, PACKET_TAG_DUMMYNET, NULL);
- if (dn_tag != NULL) {
- struct dn_pkt_tag *dt;
-
- dt = (struct dn_pkt_tag *)(dn_tag+1);
- args.slot = dt->slot;
- args.rulenum = dt->rulenum;
- args.rule_id = dt->rule_id;
- args.chain_id = dt->chain_id;
- m_tag_delete(*m0, dn_tag);
+ tag = m_tag_locate(*m0, MTAG_IPFW_RULE, 0, NULL);
+ if (tag != NULL) {
+ args.rule = *((struct ipfw_rule_ref *)(tag+1));
+ m_tag_delete(*m0, tag);
}
args.m = *m0;
@@ -150,7 +131,7 @@ again:
/* all the processing now uses ip_len in net format */
SET_NET_IPLEN(mtod(*m0, struct ip *));
- if (V_fw_one_pass == 0 || args.slot == 0) {
+ if (V_fw_one_pass == 0 || args.rule.slot == 0) {
ipfw = ipfw_chk(&args);
*m0 = args.m;
} else
@@ -224,15 +205,19 @@ again:
ret = EACCES;
break; /* i.e. drop */
}
- ipfw_divert(m0, dir, (ipfw == IP_FW_TEE) ? 1 : 0);
- if (*m0) {
- /* continue processing for this one. We set
- * args.slot=0, but the divert tag is processed
- * in ipfw_chk to jump to the right place.
- */
- args.slot = 0;
- goto again; /* continue with packet */
+ tag = m_tag_alloc(MTAG_IPFW_RULE, 0,
+ sizeof(struct ipfw_rule_ref), M_NOWAIT);
+ if (tag == NULL) {
+ ret = EACCES;
+ break; /* i.e. drop */
}
+ *((struct ipfw_rule_ref *)(tag+1)) = args.rule;
+ m_tag_prepend(*m0, tag);
+
+ ipfw_divert(m0, dir, (ipfw == IP_FW_TEE) ? 1 : 0);
+ /* continue processing for the original packet (tee) */
+ if (*m0)
+ goto again;
break;
case IP_FW_NGTEE:
@@ -257,7 +242,7 @@ again:
if (ret != 0) {
if (*m0)
- m_freem(*m0);
+ FREE_PKT(*m0);
*m0 = NULL;
}
if (*m0)
Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_private.h
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_private.h Thu Dec 31 18:02:48 2009 (r201345)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_private.h Thu Dec 31 18:28:40 2009 (r201346)
@@ -36,6 +36,7 @@
#ifdef _KERNEL
#define MTAG_IPFW 1148380143 /* IPFW-tagged cookie */
+#define MTAG_IPFW_RULE 1262273568 /* rule reference */
/* Return values from ipfw_chk() */
enum {
@@ -70,6 +71,20 @@ struct _ip6dn_args {
};
/*
+ * Reference to an ipfw rule that can be carried outside critical sections.
+ * A rule is identified by rulenum:rule_id which is ordered.
+ * In version chain_id the rule can be found in slot 'slot', so
+ * we don't need a lookup if chain_id == chain->id.
+ */
+struct ipfw_rule_ref {
+ uint32_t slot; /* slot for matching rule */
+ uint32_t rulenum; /* matching rule number */
+ uint32_t rule_id; /* matching rule id */
+ uint32_t chain_id; /* ruleset id */
+ uint32_t info; /* reason for reinject */
+};
+
+/*
* Arguments for calling ipfw_chk() and dummynet_io(). We put them
* all into a structure because this way it is easier and more
* efficient to pass variables around and extend the interface.
@@ -79,19 +94,19 @@ struct ip_fw_args {
struct ifnet *oif; /* output interface */
struct sockaddr_in *next_hop; /* forward address */
- /* chain_id validates 'slot', the location of the pointer to
- * a matching rule.
- * If invalid, we can lookup the rule using rule_id and rulenum
+ /*
+ * On return, it points to the matching rule.
+ * On entry, rule.slot > 0 means the info is valid and
+ * contains the the starting rule for an ipfw search.
+ * If chain_id == chain->id && slot >0 then jump to that slot.
+ * Otherwise, we locate the first rule >= rulenum:rule_id
*/
- uint32_t slot; /* slot for matching rule */
- uint32_t rulenum; /* matching rule number */
- uint32_t rule_id; /* matching rule id */
- uint32_t chain_id; /* ruleset id */
+ struct ipfw_rule_ref rule; /* match/restart info */
struct ether_header *eh; /* for bridged packets */
struct ipfw_flow_id f_id; /* grabbed from IP header */
- uint32_t cookie; /* a cookie depending on rule action */
+ //uint32_t cookie; /* a cookie depending on rule action */
struct inpcb *inp;
struct _ip6dn_args dummypar; /* dummynet->ip6_output */
@@ -122,6 +137,9 @@ enum {
/* PROTO_OLDBDG = 0x14, unused, old bridge */
};
+/* wrapper for freeing a packet, in case we need to do more work */
+#define FREE_PKT(m) m_freem(m)
+
/*
* Function definitions.
*/
@@ -277,18 +295,6 @@ typedef int ng_ipfw_input_t(struct mbuf
extern ng_ipfw_input_t *ng_ipfw_input_p;
#define NG_IPFW_LOADED (ng_ipfw_input_p != NULL)
-struct ng_ipfw_tag {
- struct m_tag mt; /* tag header */
- /* reinject info */
- uint32_t slot; /* slot for next rule */
- uint32_t rulenum; /* matching rule number */
- uint32_t rule_id; /* matching rule id */
- uint32_t chain_id; /* ruleset id */
- int dir;
-
-// struct ifnet *ifp; /* interface, for ip_output */
-};
-
#define TAGSIZ (sizeof(struct ng_ipfw_tag) - sizeof(struct m_tag))
More information about the svn-src-user
mailing list