kern/77570: [PATCH] ipfw: Multiple rules may have the same number.

Wojciech A. Koszek dunstan at freebsd.czest.pl
Tue Feb 15 12:00:47 PST 2005


>Number:         77570
>Category:       kern
>Synopsis:       [PATCH] ipfw: Multiple rules may have the same number.
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Feb 15 20:00:46 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator:     Wojciech A. Koszek
>Release:        FreeBSD 5.3-STABLE i386
>Organization:
>Environment:
System: FreeBSD dunstan.freebsd.czest.pl 5.3-STABLE FreeBSD 5.3-STABLE #0: Sat Feb 12 11:15:23 CET 2005 root at dunstan.freebsd.czest.pl:/usr/obj/usr/src/sys/HOME6 i386

This problem exists in either -STABLE or -CURRENT.

>Description:
There is a problem while inserting ipfw2 rule with specified rule number.

	# ipfw add <num> <action>

While executing this command N times, it will add N rules with the same
number <num>. I don't really like this behaviour, since rule number has to
represent the unique rule.

>How-To-Repeat:

This problem may be easily reproduced:

# ipfw add 100 allow all from any to any 
00100 allow ip from any to any
# ipfw add 100 allow all from any to any
00100 allow ip from any to any
# ipfw add 100 allow all from any to any
00100 allow ip from any to any
# ipfw show | grep 00100
00100 0   0 allow ip from any to any
00100 0   0 allow ip from any to any
00100 0   0 allow ip from any to any

>Fix:
Attached patch [diff.0.ipfw2] should correct this problem. It also adds predefinition of
remove_rule(), because after applying this patch, add_rule() requires it.

--- diff.0.ipfw2 begins here ---
Patch against FreeBSD 5.3-STABLE, kern.osreldate: 503102.

diff -upr /usr/src/sys/netinet/ip_fw2.c src/sys/netinet/ip_fw2.c
--- /usr/src/sys/netinet/ip_fw2.c	Sat Feb 12 09:36:43 2005
+++ src/sys/netinet/ip_fw2.c	Tue Feb 15 20:11:17 2005
@@ -104,6 +104,9 @@ static struct callout ipfw_timeout;
 static uma_zone_t ipfw_dyn_rule_zone;
 #define	IPFW_DEFAULT_RULE	65535
 
+static struct ip_fw *
+remove_rule(struct ip_fw_chain *, struct ip_fw *, struct ip_fw *);
+
 /*
  * Data structure to cache our ucred related
  * information. This structure only gets used if
@@ -2599,7 +2602,19 @@ add_rule(struct ip_fw_chain *chain, stru
 	 * Now insert the new rule in the right place in the sorted list.
 	 */
 	for (prev = NULL, f = chain->rules; f; prev = f, f = f->next) {
-		if (f->rulenum > rule->rulenum) { /* found the location */
+		if (f->rulenum == rule->rulenum) { /* exact match */
+			rule->next = f->next;
+			(void) remove_rule(chain, f, prev);
+			if (prev != NULL) {
+				prev->next = rule;
+			}
+			else { /* head insert */
+				rule->next = chain->rules;
+				chain->rules = rule;
+			}
+			break;
+		}
+		else if (f->rulenum > rule->rulenum) { /* found the location */
 			if (prev) {
 				rule->next = f;
 				prev->next = rule;
--- diff.0.ipfw2 ends here ---

>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list