From razor@ldc.ro  Wed Feb 26 14:42:57 2003
Return-Path: <razor@ldc.ro>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 6AEA037B401
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 26 Feb 2003 14:42:57 -0800 (PST)
Received: from ldc.ro (ldc-gw.rdsnet.ro [213.157.163.8])
	by mx1.FreeBSD.org (Postfix) with SMTP id 99CA643F3F
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 26 Feb 2003 14:42:55 -0800 (PST)
	(envelope-from razor@ldc.ro)
Received: (qmail 69478 invoked by uid 666); 26 Feb 2003 22:42:54 -0000
Message-Id: <20030226224254.69475.qmail@ldc.ro>
Date: 26 Feb 2003 22:42:54 -0000
From: Alex Popa <razor@ldc.ro>
Reply-To: Alex Popa <razor@ldc.ro>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: ipfw2 probability is wrong 
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         48717
>Category:       kern
>Synopsis:       ipfw2 probability is wrong
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    maxim
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Feb 26 14:50:06 PST 2003
>Closed-Date:    Wed Mar 05 03:27:09 PST 2003
>Last-Modified:  Wed Mar 05 03:27:09 PST 2003
>Originator:     Alex Popa
>Release:        FreeBSD 4.8-PRERELEASE i386
>Organization:
>Environment:
System:	 FreeBSD ric.interactive.ro 4.8-PRERELEASE FreeBSD 4.8-PRERELEASE #0: Wed Feb 19 23:21:16 EET 2003 root@ric.interactive.ro:/usr/obj/usr/src/sys/RIC i386


>Description:
ipfw2 uses an inverted probability while trying to match rules.

It seems this behaviour is wrongly inherited from ipfw1.  The ipfw1
userland program uses "1-d" for the probability calculation, and the
kernel uses "random() < f->dont_match_prob" as a condition to *NOT*
matching the packet.  However, the ipfw2 kernel part uses a very similar
condition for *matching* the packet.

>How-To-Repeat:
Use a simple firewall, like this (note only on a test machine!):

ipfw add 1 drop prob 0.99 ip from any to any out
ipfw add 2 permit all from any to any

Then ping some host on the local network.  Instead of a 99% loss rate,
you get a 1% loss.

>Fix:

Apply the following patch to /usr/src/sys/netinet/ip_fw2.c:

--- ip_fw2.c.orig	Thu Feb 27 00:29:33 2003
+++ ip_fw2.c	Thu Feb 27 00:29:58 2003
@@ -1747,7 +1747,7 @@
 				break;
 
 			case O_PROB:
-				match = (random()<((ipfw_insn_u32 *)cmd)->d[0]);
+				match = !(random()<((ipfw_insn_u32 *)cmd)->d[0]);
 				break;
 
 			/*

>Release-Note:
>Audit-Trail:

From: Maxim Konovalov <maxim@macomnet.ru>
To: Alex Popa <razor@ldc.ro>
Cc: bug-followup@freebsd.org
Subject: Re: kern/48717: ipfw2 probability is wrong 
Date: Thu, 27 Feb 2003 16:53:05 +0300 (MSK)

 Please try a patch below instead.
 
 Index: ipfw/ipfw2.c
 ===================================================================
 RCS file: /home/ncvs/src/sbin/ipfw/ipfw2.c,v
 retrieving revision 1.4.2.10
 diff -u -r1.4.2.10 ipfw2.c
 --- ipfw/ipfw2.c	14 Jan 2003 19:15:59 -0000	1.4.2.10
 +++ ipfw/ipfw2.c	27 Feb 2003 13:47:57 -0000
 @@ -865,7 +865,7 @@
  			ipfw_insn_u32 *p = (ipfw_insn_u32 *)cmd;
  			double d = 1.0 * p->d[0];
 
 -			d = 1 - (d / 0x7fffffff);
 +			d = d / 0x7fffffff;
  			printf("prob %f ", d);
  		    }
  			break;
 @@ -2521,8 +2521,7 @@
  		if (d != 1) { /* 1 means always match */
  			action->opcode = O_PROB;
  			action->len = 2;
 -			*((int32_t *)(action+1)) =
 -				(int32_t)((1 - d) * 0x7fffffff);
 +			*((int32_t *)(action+1)) = (int32_t)(d * 0x7fffffff);
  			action += action->len;
  		}
  		av += 2; ac -= 2;
 
 %%%
 
 -- 
 Maxim Konovalov, maxim@macomnet.ru, maxim@FreeBSD.org

From: Alex Popa <razor@ldc.ro>
To: Maxim Konovalov <maxim@macomnet.ru>
Cc: bug-followup@freebsd.org
Subject: Re: kern/48717: ipfw2 probability is wrong
Date: Fri, 28 Feb 2003 00:49:41 +0200

 This solves the issue I am seeing.  Thank you.
 
 Alex
 
 On Thu, Feb 27, 2003 at 04:53:05PM +0300, Maxim Konovalov wrote:
 > 
 > Please try a patch below instead.
 > 
 > Index: ipfw/ipfw2.c
 > ===================================================================
 > RCS file: /home/ncvs/src/sbin/ipfw/ipfw2.c,v
 > retrieving revision 1.4.2.10
 > diff -u -r1.4.2.10 ipfw2.c
 > --- ipfw/ipfw2.c	14 Jan 2003 19:15:59 -0000	1.4.2.10
 > +++ ipfw/ipfw2.c	27 Feb 2003 13:47:57 -0000
 > @@ -865,7 +865,7 @@
 >  			ipfw_insn_u32 *p = (ipfw_insn_u32 *)cmd;
 >  			double d = 1.0 * p->d[0];
 > 
 > -			d = 1 - (d / 0x7fffffff);
 > +			d = d / 0x7fffffff;
 >  			printf("prob %f ", d);
 >  		    }
 >  			break;
 > @@ -2521,8 +2521,7 @@
 >  		if (d != 1) { /* 1 means always match */
 >  			action->opcode = O_PROB;
 >  			action->len = 2;
 > -			*((int32_t *)(action+1)) =
 > -				(int32_t)((1 - d) * 0x7fffffff);
 > +			*((int32_t *)(action+1)) = (int32_t)(d * 0x7fffffff);
 >  			action += action->len;
 >  		}
 >  		av += 2; ac -= 2;
 > 
 > %%%
 > 
 > -- 
 > Maxim Konovalov, maxim@macomnet.ru, maxim@FreeBSD.org
 ------------+-------------------------------------------------------
 Alex Popa,  |  "Computer science is no more about computers than
 razor@ldc.ro|     astronomy is about telescopes" -- E. W. Dijkstra
 ------------+------------------------------------------------------
State-Changed-From-To: open->patched 
State-Changed-By: maxim 
State-Changed-When: Fri Feb 28 00:18:39 PST 2003 
State-Changed-Why:  
Fixed in rev. 1.17 src/sbin/ipfw/ipfw2.c in -CURRENT several months ago. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=48717 
State-Changed-From-To: patched->closed 
State-Changed-By: maxim 
State-Changed-When: Wed Mar 5 03:23:37 PST 2003 
State-Changed-Why:  
Fixed in rev. 1.4.2.11 src/sbin/ipfw/ipfw2.c in -STABLE. 


Responsible-Changed-From-To: freebsd-bugs->maxim 
Responsible-Changed-By: maxim 
Responsible-Changed-When: Wed Mar 5 03:23:37 PST 2003 
Responsible-Changed-Why:  
Feedbacks trap. 

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