From root@s0.m0n0.ch  Wed Jan 21 12:04:08 2004
Return-Path: <root@s0.m0n0.ch>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 1FBA916A4CE
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 21 Jan 2004 12:04:08 -0800 (PST)
Received: from s0.m0n0.ch (s0.m0n0.ch [80.238.135.125])
	by mx1.FreeBSD.org (Postfix) with SMTP id 25E4843D82
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 21 Jan 2004 12:03:21 -0800 (PST)
	(envelope-from root@s0.m0n0.ch)
Received: (qmail 10829 invoked by uid 0); 21 Jan 2004 20:03:16 -0000
Message-Id: <20040121200316.10828.qmail@s0.m0n0.ch>
Date: 21 Jan 2004 20:03:16 -0000
From: Manuel Kasper <mk@neon1.net>
Reply-To: Manuel Kasper <mk@neon1.net>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: [patch] ipnat + dummynet on same interface broken
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         61685
>Category:       kern
>Synopsis:       [patch] ipnat + dummynet on same interface broken
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    andre
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jan 21 12:10:10 PST 2004
>Closed-Date:    Wed Sep 14 15:32:43 GMT 2005
>Last-Modified:  Wed Sep 14 15:32:43 GMT 2005
>Originator:     Manuel Kasper <mk@neon1.net>
>Release:        FreeBSD 4.9-RELEASE i386
>Organization:
>Environment:
System: FreeBSD nb.neon1.net 4.9-RELEASE FreeBSD 4.9-RELEASE #0: Thu Oct 30 20:20:56 CET 2003 root@nb.neon1.net:/usr/src/sys/compile/EVON600 i386

with ipfilter, ipfw and dummynet compiled into the kernel

>Description:
If ipfilter with ipnat is active on a particular interface and the ipfw
ruleset contains rules that send inbound packets on the same interface to
dummynet, they actually pass through ipnat twice, creating a bogus NAT table
entry, which later causes all outbound packets belonging to the same
connection to leave that interface effectively un-NATed (in the common case
of that interface being the external interface of a firewall with NAT, they
leave it with a private source IP address).

>How-To-Repeat:
Try to setup a firewall using ipfilter/ipnat and ipfw with dummynet rules
for inbound packets on the external interface at the same time. Create an
ipnat rdr rule to redirect traffic on some port on the external interface to
a host on the internal network. Notice that you cannot establish any
connection to it from the outside. If you have a look with tcpdump, you will
find that the internal host's reply packets (e.g. TCP SYNACK) leave the
external interface with an internal (i.e. un-NATed) source IP address.

>Fix:
Packets that enter ip_input() in sys/netinet/ip_input.c are first passed
through ipfilter (and NATed) before they reach ipfw. If a packet is sent to
dummynet, it later re-enters ip_input(), where it is decided right at the
beginning that this packet has come from dummynet. Execution then jumps to
the label "iphack:", which is right before the ipfilter section, so the
packet is NATed for the second time on the same interface. Fix: jump after
the ipfilter section instead of in front of it.

The following patch seems to fix the problem:


--- ip_input.c.patch begins here ---
--- sys/netinet/ip_input.c.orig	Tue Jan 20 20:53:51 2004
+++ sys/netinet/ip_input.c	Tue Jan 20 21:00:59 2004
@@ -340,7 +340,7 @@
 	if (args.rule) {	/* dummynet already filtered us */
 		ip = mtod(m, struct ip *);
 		hlen = IP_VHL_HL(ip->ip_vhl) << 2;
-		goto iphack ;
+		goto ipfw;	/* skip ipfilter now (already passed it)! */
 	}
 
 	ipstat.ips_total++;
@@ -451,7 +451,6 @@
 	 * - Encapsulate: put it in another IP and send out. <unimp.>
  	 */
 
-iphack:
 	/*
 	 * Check if we want to allow this packet to be processed.
 	 * Consider it to be bad if not.
@@ -463,6 +462,7 @@
 			return;
 		ip = mtod(m = m1, struct ip *);
 	}
+ipfw:
 	if (fw_enable && IPFW_LOADED) {
 		/*
 		 * If we've been forwarded from the output side, then
--- ip_input.c.patch ends here ---


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->andre 
Responsible-Changed-By: andre 
Responsible-Changed-When: Thu Nov 4 14:10:38 GMT 2004 
Responsible-Changed-Why:  
Take over. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=61685 
State-Changed-From-To: open->feedback 
State-Changed-By: andre 
State-Changed-When: Wed Sep 14 15:30:00 GMT 2005 
State-Changed-Why:  
This issue won't be fixed in RELENG_4 anymore.  For > 5.4R it behaves 
correctly since the conversion of ipfw to use pfil_hooks. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=61685 
State-Changed-From-To: feedback->closed 
State-Changed-By: andre 
State-Changed-When: Wed Sep 14 15:32:15 GMT 2005 
State-Changed-Why:  
Close case for reason stated in previous update. 

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