From d5ab5191cf5df5bcf63257124ddb49c77c2d7137 Mon Sep 17 00:00:00 2001 From: glebius Date: Tue, 13 Dec 2005 12:16:03 +0000 Subject: Add a new feature for optimizining ipfw rulesets - substitution of the action argument with the value obtained from table lookup. The feature is now applicable only to "pipe", "queue", "divert", "tee", "netgraph" and "ngtee" rules. An example usage: ipfw pipe 1000 config bw 1000Kbyte/s ipfw pipe 4000 config bw 4000Kbyte/s ipfw table 1 add x.x.x.x 1000 ipfw table 1 add x.x.x.y 4000 ipfw pipe tablearg ip from table(1) to any In the example above the rule will throw different packets to different pipes. TODO: - Support "skipto" action, but without searching all rules. - Improve parser, so that it warns about bad rules. These are: - "tablearg" argument to action, but no "table" in the rule. All traffic will be blocked. - "tablearg" argument to action, but "table" searches for entry with a specific value. All traffic will be blocked. - "tablearg" argument to action, and two "table" looks - for src and for dst. The last lookup will match. --- sys/netinet/ip_fw.h | 2 ++ sys/netinet/ip_fw2.c | 21 ++++++++++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) (limited to 'sys/netinet') diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h index dc5b563..e6ab185 100644 --- a/sys/netinet/ip_fw.h +++ b/sys/netinet/ip_fw.h @@ -461,6 +461,8 @@ typedef struct _ipfw_table { ipfw_table_entry ent[0]; /* entries */ } ipfw_table; +#define IP_FW_TABLEARG 65535 + /* * Main firewall chains definitions and global var's definitions. */ diff --git a/sys/netinet/ip_fw2.c b/sys/netinet/ip_fw2.c index 92c01a4..7627080 100644 --- a/sys/netinet/ip_fw2.c +++ b/sys/netinet/ip_fw2.c @@ -2383,9 +2383,9 @@ do { \ * Now scan the rules, and parse microinstructions for each rule. */ for (; f; f = f->next) { - int l, cmdlen; ipfw_insn *cmd; - int skip_or; /* skip rest of OR block */ + uint32_t tablearg = 0; + int l, cmdlen, skip_or; /* skip rest of OR block */ again: if (set_disable & (1 << f->set) ) @@ -2548,6 +2548,8 @@ check_body: if (cmdlen == F_INSN_SIZE(ipfw_insn_u32)) match = ((ipfw_insn_u32 *)cmd)->d[0] == v; + else + tablearg = v; } break; @@ -2999,7 +3001,10 @@ check_body: case O_PIPE: case O_QUEUE: args->rule = f; /* report matching rule */ - args->cookie = cmd->arg1; + if (cmd->arg1 == IP_FW_TABLEARG) + args->cookie = tablearg; + else + args->cookie = cmd->arg1; retval = IP_FW_DUMMYNET; goto done; @@ -3020,7 +3025,10 @@ check_body: } dt = (struct divert_tag *)(mtag+1); dt->cookie = f->rulenum; - dt->info = cmd->arg1; + 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; @@ -3085,7 +3093,10 @@ check_body: case O_NETGRAPH: case O_NGTEE: args->rule = f; /* report matching rule */ - args->cookie = cmd->arg1; + if (cmd->arg1 == IP_FW_TABLEARG) + args->cookie = tablearg; + else + args->cookie = cmd->arg1; retval = (cmd->opcode == O_NETGRAPH) ? IP_FW_NETGRAPH : IP_FW_NGTEE; goto done; -- cgit v1.1