From nobody@FreeBSD.org  Fri Jun 11 20:40:21 2010
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 69936106568F
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 11 Jun 2010 20:40:21 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id C9AA68FC21
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 11 Jun 2010 20:40:20 +0000 (UTC)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id o5BKeKr5066729
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 11 Jun 2010 20:40:20 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id o5BKeKqI066727;
	Fri, 11 Jun 2010 20:40:20 GMT
	(envelope-from nobody)
Message-Id: <201006112040.o5BKeKqI066727@www.freebsd.org>
Date: Fri, 11 Jun 2010 20:40:20 GMT
From: Dmitry Pryanishnikov <lynx.ripe@gmail.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: ipfw skipto skips over the complex rule
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         147798
>Category:       kern
>Synopsis:       [ipfw]: skipto skips over the complex rule
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    glebius
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Jun 11 20:50:01 UTC 2010
>Closed-Date:    Thu Jul 08 12:34:06 UTC 2010
>Last-Modified:  Thu Jul 08 12:34:06 UTC 2010
>Originator:     Dmitry Pryanishnikov
>Release:        RELENG_8
>Organization:
Home
>Environment:
FreeBSD lynx.homenet 8.1-PRERELEASE FreeBSD 8.1-PRERELEASE #0: Fri Jun 11 21:59:46 EEST 2010     dmitry@lynx.homenet:/databig/obj/databig/ftp/RELENG_8/src/sys/lynx  i386

>Description:
In the following pared-down ipfw ruleset (yes, it's complete):

25150  208 22046 skipto 25199 ip from any to any
30410    0     0 nat 1 ip from not 192.168.1.0/24 to not table(1) out via em0
30610    0     0 nat 1 ip from not table(1) to 192.168.1.2 in
65000  372 38232 allow ip from any to any
65535 1178 53032 deny ip from any to any

packets from 192.168.251.1 fail to match against the rule number 30410 (despite being directed to IP absent in table(1) via em0. IP-addresses 192.168.1.2 and 192.168.251.1 are local; nat 1 is configured as "nat 1 config ip 192.168.1.2", 
table 1 contains non-globally routable networks:

0.0.0.0/8 0
10.0.0.0/8 0
169.254.0.0/16 0
172.16.0.0/12 0
192.0.2.0/24 0
192.168.0.0/16 0
224.0.0.0/4 0
240.0.0.0/4 0

However, adding dummy 'count' rule between 'skipto' and 'nat' works around the problem:

25150  303 31614 skipto 25199 ip from any to any
26000   16  1268 count ip from any to any
30410    7   588 nat 1 ip from not 192.168.1.0/24 to not table(1) out via em0
30610    7   588 nat 1 ip from not table(1) to 192.168.1.2 in
65000  467 47800 allow ip from any to any
65535 1178 53032 deny ip from any to any


Note that simpicated forms of the rule 30410 (e.g. nat 1 ip from 192.168.251.1 to not table(1) out via em0) don't become skipped over - only form shown in the first ruleset does.
>How-To-Repeat:

>Fix:


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->freebsd-ipfw 
Responsible-Changed-By: remko 
Responsible-Changed-When: Sun Jun 13 07:57:02 UTC 2010 
Responsible-Changed-Why:  
Reassign to ipfw team 

http://www.freebsd.org/cgi/query-pr.cgi?pr=147798 
Responsible-Changed-From-To: freebsd-ipfw->glebius 
Responsible-Changed-By: glebius 
Responsible-Changed-When: Tue Jun 29 16:48:11 UTC 2010 
Responsible-Changed-Why:  
Take this one. 

The problem in the starting "no" operand of the skipto rule. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=147798 
State-Changed-From-To: open->patched 
State-Changed-By: glebius 
State-Changed-When: Tue Jun 29 16:57:40 UTC 2010 
State-Changed-Why:  
Fixed in head/. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=147798 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/147798: commit references a PR
Date: Tue, 29 Jun 2010 16:57:42 +0000 (UTC)

 Author: glebius
 Date: Tue Jun 29 16:57:30 2010
 New Revision: 209589
 URL: http://svn.freebsd.org/changeset/base/209589
 
 Log:
   After processing the O_SKIPTO opcode our cmd points to the next rule, and
   "match" processing at the end of inner loop would look ahead into the next
   rule, which is incorrect. Particularly, in the case when the next rule
   started with F_NOT opcode it was skipped blindly.
   
   To fix this, exit the inner loop with the continue operator forcibly and
   explicitly.
   
   PR:		kern/147798
 
 Modified:
   head/sys/netinet/ipfw/ip_fw2.c
 
 Modified: head/sys/netinet/ipfw/ip_fw2.c
 ==============================================================================
 --- head/sys/netinet/ipfw/ip_fw2.c	Tue Jun 29 14:32:01 2010	(r209588)
 +++ head/sys/netinet/ipfw/ip_fw2.c	Tue Jun 29 16:57:30 2010	(r209589)
 @@ -2012,14 +2012,15 @@ do {								\
  				     (1 << chain->map[f_pos]->set));
  				    f_pos++)
  				;
 -			    /* prepare to enter the inner loop */
 +			    /* Re-enter the inner loop at the skipto rule. */
  			    f = chain->map[f_pos];
  			    l = f->cmd_len;
  			    cmd = f->cmd;
  			    match = 1;
  			    cmdlen = 0;
  			    skip_or = 0;
 -			    break;
 +			    continue;
 +			    break;	/* not reached */
  
  			case O_REJECT:
  				/*
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/147798: commit references a PR
Date: Thu,  8 Jul 2010 12:21:08 +0000 (UTC)

 Author: glebius
 Date: Thu Jul  8 12:20:15 2010
 New Revision: 209795
 URL: http://svn.freebsd.org/changeset/base/209795
 
 Log:
   Merge 209589 from head:
     After processing the O_SKIPTO opcode our cmd points to the next rule, and
     "match" processing at the end of inner loop would look ahead into the next
     rule, which is incorrect. Particularly, in the case when the next rule
     started with F_NOT opcode it was skipped blindly.
   
     To fix this, exit the inner loop with the continue operator forcibly and
     explicitly.
   
   PR:		kern/147798
 
 Modified:
   stable/8/sys/netinet/ipfw/ip_fw2.c
 
 Modified: stable/8/sys/netinet/ipfw/ip_fw2.c
 ==============================================================================
 --- stable/8/sys/netinet/ipfw/ip_fw2.c	Thu Jul  8 11:21:11 2010	(r209794)
 +++ stable/8/sys/netinet/ipfw/ip_fw2.c	Thu Jul  8 12:20:15 2010	(r209795)
 @@ -2012,14 +2012,15 @@ do {								\
  				     (1 << chain->map[f_pos]->set));
  				    f_pos++)
  				;
 -			    /* prepare to enter the inner loop */
 +			    /* Re-enter the inner loop at the skipto rule. */
  			    f = chain->map[f_pos];
  			    l = f->cmd_len;
  			    cmd = f->cmd;
  			    match = 1;
  			    cmdlen = 0;
  			    skip_or = 0;
 -			    break;
 +			    continue;
 +			    break;	/* not reached */
  
  			case O_REJECT:
  				/*
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: glebius 
State-Changed-When: Thu Jul 8 12:33:48 UTC 2010 
State-Changed-Why:  
Fixed in releng/8. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=147798 
>Unformatted:
