From 711ca7efbbdfd14d72ba86f40c864d8c1274271b Mon Sep 17 00:00:00 2001 From: Julian Elischer Date: Fri, 1 Aug 2008 22:21:03 +0000 Subject: [PATCH] The IPFW code accepts the use of the tablearg keyword along with the skipto keyword. But it doesn't work. Two options.. make it no longer accept it, or actually make it work.. I chose the 2nd.. Allow the tablearg to be used to specify a skipto destination. This is actually a very powerful construct if used correctly, or a sink of cpu cycles if used badly. changes t teh man page will follow. --- sys/netinet/ip_fw2.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/sys/netinet/ip_fw2.c b/sys/netinet/ip_fw2.c index 2346df641758..650ed1a99d6d 100644 --- a/sys/netinet/ip_fw2.c +++ b/sys/netinet/ip_fw2.c @@ -1738,10 +1738,11 @@ send_reject(struct ip_fw_args *args, int code, int ip_len, struct ip *ip) */ 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 @@ lookup_next_rule(struct ip_fw *me) 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 @@ do { \ 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 @@ check_body: 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: