ipfw add skipto tablearg....
Julian Elischer
julian at elischer.org
Fri Aug 1 01:50:42 UTC 2008
looking int he code I noticed that the following command gave
no error but didn't work..
ipfw add 1000 skipto tablearg ip from any to table(31)
and as I have a use for that, I implemented it..
see attached patch... (hopefully not stripped)
Of course it is hoped that the rules you are skipping to are nearby
as it iterates through the rules following the skipto to find the
target,
but....
if you had a thousand table entries and wanted to sort them into
20 buckets, it could save you puting them into 20 different
tables and doing 20 table lookups on them.
here I sort into two categories.. possibly already a win..
julian at trafmon2:cat ipfw-test.sh
#!/bin/sh
ipfw add 100 skipto 10000 ip from any to not 1.1.1.0/24
ipfw add 1000 skipto tablearg ip from any to "table(31)"
ipfw add 2000 drop ip from any to any
ipfw add 2001 drop ip from any to any
ipfw add 3000 drop ip from any to any
ipfw add 3001 drop ip from any to any
ipfw add 10000 count ip from any to any
ipfw table 31 add 1.1.1.1 2000
ipfw table 31 add 1.1.1.2 3000
julian at trafmon2: ping 1.1.1.1
[...] (2 packets bounced)
julian at trafmon2: ping 1.1.1.2
[...] (12 packets bounced)
julian at trafmon2: ipfw show
00100 220 19633 skipto 10000 ip from any to not 1.1.1.0/24
01000 14 1176 skipto tablearg ip from any to table(31)
02000 2 168 deny ip from any to any
02001 0 0 deny ip from any to any
03000 12 1008 deny ip from any to any
03001 0 0 deny ip from any to any
10000 209 18549 count ip from any to any
65535 1751 153792 allow ip from any to any
comments?
-------------- next part --------------
Index: ip_fw2.c
===================================================================
RCS file: /usr/local/cvsroot/freebsd/src/sys/netinet/ip_fw2.c,v
retrieving revision 1.186
diff -u -r1.186 ip_fw2.c
--- ip_fw2.c 9 May 2008 23:02:57 -0000 1.186
+++ ip_fw2.c 1 Aug 2008 01:15:06 -0000
@@ -1738,10 +1738,11 @@
*/
static struct ip_fw *
-lookup_next_rule(struct ip_fw *me)
+lookup_next_rule(struct ip_fw *me, u_int32_t tablearg)
{
struct ip_fw *rule = NULL;
ipfw_insn *cmd;
+ u_int16_t rulenum;
/* look for action, in case it is a skipto */
cmd = ACTION_PTR(me);
@@ -1751,10 +1752,18 @@
cmd += F_LEN(cmd);
if (cmd->opcode == O_TAG)
cmd += F_LEN(cmd);
- if ( cmd->opcode == O_SKIPTO )
- for (rule = me->next; rule ; rule = rule->next)
- if (rule->rulenum >= cmd->arg1)
+ if (cmd->opcode == O_SKIPTO ) {
+ if (tablearg != 0) {
+ rulenum = (u_int16_t)tablearg;
+ } else {
+ rulenum = cmd->arg1;
+ }
+ for (rule = me->next; rule ; rule = rule->next) {
+ if (rule->rulenum >= rulenum) {
break;
+ }
+ }
+ }
if (rule == NULL) /* failure or not a skipto */
rule = me->next;
me->next_rule = rule;
@@ -2475,7 +2484,7 @@
f = args->rule->next_rule;
if (f == NULL)
- f = lookup_next_rule(args->rule);
+ f = lookup_next_rule(args->rule, 0);
} else {
/*
* Find the starting rule. It can be either the first
@@ -3226,9 +3235,13 @@
if (cmd->opcode == O_COUNT)
goto next_rule;
/* handle skipto */
- if (f->next_rule == NULL)
- lookup_next_rule(f);
- f = f->next_rule;
+ if (cmd->arg1 == IP_FW_TABLEARG) {
+ f = lookup_next_rule(f, tablearg);
+ } else {
+ if (f->next_rule == NULL)
+ lookup_next_rule(f, 0);
+ f = f->next_rule;
+ }
goto again;
case O_REJECT:
More information about the freebsd-net
mailing list