Date: Wed, 9 May 2007 00:30:12 +0600 From: "A. Skrobov" <tyomitch@gmail.com> To: freebsd-ipfw@freebsd.org Subject: a sysctl variable to query last ipfw rule number Message-ID: <2a38baa40705081130o52ad24d6l9ab1e6d6647e81ef@mail.gmail.com>
next in thread | raw e-mail | index | archive | help
Such a variable is useful in scripts that add blocks of rules containing skipto actions; instead of hardcoding numbers for all the rules, they could be derived dynamically. As an additional bonus, keeping track of the last rule number reduces overhead in add_rule when no rule number is specified (and partially puts that overhead to remove_rule instead). Since rules are added more often than they are deleted, this seems a performance improvement as well. Could someone please review my patch? It's made for a very old ipfw2 version, the one bundled with 5.4-RELEASE, but the relevant code doesn't seem to have changed since then. *** ip_fw2.c.orig Sun Feb 6 21:16:20 2005 --- ip_fw2.c Tue May 8 23:38:37 2007 *************** *** 191,196 **** --- 191,197 ---- static int fw_debug = 1; static int autoinc_step = 100; /* bounded to 1..1000 in add_rule() */ + static unsigned int last_rule = 0; #ifdef SYSCTL_NODE SYSCTL_NODE(_net_inet_ip, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall"); *************** *** 199,204 **** --- 200,207 ---- &fw_enable, 0, "Enable ipfw"); SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, autoinc_step, CTLFLAG_RW, &autoinc_step, 0, "Rule number autincrement step"); + SYSCTL_UINT(_net_inet_ip_fw, OID_AUTO, last_rule, CTLFLAG_RD, + &last_rule, 0, "Number of last added rule"); SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, one_pass, CTLFLAG_RW | CTLFLAG_SECURE3, &fw_one_pass, 0, *************** *** 2585,2595 **** /* * locate the highest numbered rule before default */ ! for (f = chain->rules; f; f = f->next) { ! if (f->rulenum == IPFW_DEFAULT_RULE) ! break; ! rule->rulenum = f->rulenum; ! } if (rule->rulenum < IPFW_DEFAULT_RULE - autoinc_step) rule->rulenum += autoinc_step; input_rule->rulenum = rule->rulenum; --- 2588,2594 ---- /* * locate the highest numbered rule before default */ ! rule->rulenum = last_rule; if (rule->rulenum < IPFW_DEFAULT_RULE - autoinc_step) rule->rulenum += autoinc_step; input_rule->rulenum = rule->rulenum; *************** *** 2612,2617 **** --- 2611,2618 ---- } flush_rule_ptrs(chain); done: + if (last_rule < rule->rulenum) + last_rule = rule->rulenum; static_count++; static_len += l; IPFW_WUNLOCK(chain); *************** *** 2631,2637 **** static struct ip_fw * remove_rule(struct ip_fw_chain *chain, struct ip_fw *rule, struct ip_fw *prev) { ! struct ip_fw *n; int l = RULESIZE(rule); IPFW_WLOCK_ASSERT(chain); --- 2632,2638 ---- static struct ip_fw * remove_rule(struct ip_fw_chain *chain, struct ip_fw *rule, struct ip_fw *prev) { ! struct ip_fw *n, *f; int l = RULESIZE(rule); IPFW_WLOCK_ASSERT(chain); *************** *** 2647,2652 **** --- 2648,2660 ---- static_count--; static_len -= l; + if (rule->rulenum >= last_rule) /* it should always be <=, but who knows */ + for (f = chain->rules; f; f = f->next) { + if (f->rulenum == IPFW_DEFAULT_RULE) + break; + last_rule = f->rulenum; + } + rule->next = chain->reap; chain->reap = rule; *************** *** 2690,2695 **** --- 2698,2705 ---- prev = rule; rule = rule->next; } + + last_rule = 0; /* how come static_count doesn't need the explicit reset? */ } /** *************** *** 3454,3459 **** --- 3464,3470 ---- IPFW_LOCK_DESTROY(&layer3_chain); return (error); } + last_rule = 0; ip_fw_default_rule = layer3_chain.rules; printf("ipfw2 initialized, divert %s, "
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?2a38baa40705081130o52ad24d6l9ab1e6d6647e81ef>