summaryrefslogtreecommitdiffstats
path: root/sys/netinet/ip_fw2.c
diff options
context:
space:
mode:
authormlaier <mlaier@FreeBSD.org>2004-02-13 19:14:16 +0000
committermlaier <mlaier@FreeBSD.org>2004-02-13 19:14:16 +0000
commitda4d773b129fb1339d7b5fc23b93388b18952d3b (patch)
tree75fdee3c73dd1369e60e6348343749bdf159313a /sys/netinet/ip_fw2.c
parent09ad0862e6acad72dd0217846a1c16d5bea5c454 (diff)
downloadFreeBSD-src-da4d773b129fb1339d7b5fc23b93388b18952d3b.zip
FreeBSD-src-da4d773b129fb1339d7b5fc23b93388b18952d3b.tar.gz
This set of changes eliminates the use of MT_TAG "pseudo mbufs", replacing
them mostly with packet tags (one case is handled by using an mbuf flag since the linkage between "caller" and "callee" is direct and there's no need to incur the overhead of a packet tag). This is (mostly) work from: sam Silence from: -arch Approved by: bms(mentor), sam, rwatson
Diffstat (limited to 'sys/netinet/ip_fw2.c')
-rw-r--r--sys/netinet/ip_fw2.c30
1 files changed, 25 insertions, 5 deletions
diff --git a/sys/netinet/ip_fw2.c b/sys/netinet/ip_fw2.c
index 836be9d..7097b20 100644
--- a/sys/netinet/ip_fw2.c
+++ b/sys/netinet/ip_fw2.c
@@ -66,6 +66,7 @@
#include <netinet/ip_var.h>
#include <netinet/ip_icmp.h>
#include <netinet/ip_fw.h>
+#include <netinet/ip_divert.h>
#include <netinet/ip_dummynet.h>
#include <netinet/tcp.h>
#include <netinet/tcp_timer.h>
@@ -1457,6 +1458,7 @@ ipfw_chk(struct ip_fw_args *args)
int dyn_dir = MATCH_UNKNOWN;
ipfw_dyn_rule *q = NULL;
struct ip_fw_chain *chain = &layer3_chain;
+ struct m_tag *mtag;
if (m->m_flags & M_SKIP_FIREWALL)
return 0; /* accept */
@@ -1545,6 +1547,7 @@ ipfw_chk(struct ip_fw_args *args)
after_ip_checks:
IPFW_LOCK(chain); /* XXX expensive? can we run lock free? */
+ mtag = m_tag_find(m, PACKET_TAG_DIVERT, NULL);
if (args->rule) {
/*
* Packet has already been tagged. Look for the next rule
@@ -1567,7 +1570,7 @@ after_ip_checks:
* Find the starting rule. It can be either the first
* one, or the one after divert_rule if asked so.
*/
- int skipto = args->divert_rule;
+ int skipto = mtag ? divert_cookie(mtag) : 0;
f = chain->rules;
if (args->eh == NULL && skipto != 0) {
@@ -1583,7 +1586,9 @@ after_ip_checks:
}
}
}
- args->divert_rule = 0; /* reset to avoid confusion later */
+ /* reset divert rule to avoid confusion later */
+ if (mtag)
+ m_tag_delete(m, mtag);
/*
* Now scan the rules, and parse microinstructions for each rule.
@@ -2018,14 +2023,29 @@ check_body:
goto done;
case O_DIVERT:
- case O_TEE:
+ case O_TEE: {
+ struct divert_tag *dt;
+
if (args->eh) /* not on layer 2 */
break;
- args->divert_rule = f->rulenum;
- retval = (cmd->opcode == O_DIVERT) ?
+ mtag = m_tag_get(PACKET_TAG_DIVERT,
+ sizeof(struct divert_tag),
+ M_NOWAIT);
+ if (mtag == NULL) {
+ /* XXX statistic */
+ /* drop packet */
+ IPFW_UNLOCK(chain);
+ return IP_FW_PORT_DENY_FLAG;
+ }
+ dt = (struct divert_tag *)(mtag+1);
+ dt->cookie = f->rulenum;
+ dt->info = (cmd->opcode == O_DIVERT) ?
cmd->arg1 :
cmd->arg1 | IP_FW_PORT_TEE_FLAG;
+ m_tag_prepend(m, mtag);
+ retval = dt->info;
goto done;
+ }
case O_COUNT:
case O_SKIPTO:
OpenPOWER on IntegriCloud