From owner-freebsd-net@FreeBSD.ORG Sun Feb 27 11:08:50 2011 Return-Path: Delivered-To: net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 410C1106566C for ; Sun, 27 Feb 2011 11:08:50 +0000 (UTC) (envelope-from egrosbein@rdtc.ru) Received: from eg.sd.rdtc.ru (eg.sd.rdtc.ru [62.231.161.221]) by mx1.freebsd.org (Postfix) with ESMTP id 884E88FC08 for ; Sun, 27 Feb 2011 11:08:48 +0000 (UTC) Received: from eg.sd.rdtc.ru (localhost [127.0.0.1]) by eg.sd.rdtc.ru (8.14.4/8.14.4) with ESMTP id p1RB8iJw016569 for ; Sun, 27 Feb 2011 17:08:45 +0600 (NOVT) (envelope-from egrosbein@rdtc.ru) Message-ID: <4D6A30B7.2010001@rdtc.ru> Date: Sun, 27 Feb 2011 17:08:39 +0600 From: Eugene Grosbein User-Agent: Mozilla/5.0 (X11; U; FreeBSD i386; ru-RU; rv:1.9.2.13) Gecko/20110112 Thunderbird/3.1.7 MIME-Version: 1.0 To: "net@freebsd.org" Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Cc: Subject: ipfw nat and dual-homed box X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 27 Feb 2011 11:08:50 -0000 Hi! Consider LAN using private IP addresses and NAT box with two uplinks to distinct internet providers each of which supplies us with one public IP only. With natd's "multiple instances" feature it's easy to setup dual-homed NAT box correctly, so that replies for incoming packets get translated right, no matter what routing table thinks about outgoing interface for such reply. ipfw configuration: divert 8668 ip from any to any in recv $if0 # Deal with incoming packets. divert 8669 ip from any to any in recv $if1 divert 8000 ip from any to any out xmit $if0 # For outgoing packets, first try to find existing divert 8000 ip from any to any out xmit $if1 # translation table entry in all NAT instances and use it. divert 8668 ip from any to any out xmit $if0 # Create new translation entry only if it was found nowhere. divert 8669 ip from any to any out xmit $if1 fwd $if0_gate ip from $if0_ip to any out xmit $if1 # Force packet go out right interface. fwd $if1_gate ip from $if1_ip to any out xmit $if0 Corresponding natd configuration file: instance default port 8668 interface $if0 unregistered_only yes instance second port 8669 interface $if1 unregistered_only yes globalport 8000 #EOF For performance reasons, I need to create similar setup using in-kernel "ipfw nat" what does not have such "multiple instances" feature but has its own "keep-state" mechanics: nat config if $if0 unreg_only nat config if $if1 unreg_only nat 123 ip from any to any via $if0 keep-state # For incoming packets create dynamic rule. nat 124 ip from any to any via $if1 keep-state # For outgoing packet use corresponding NAT instance. fwd $if0_gate ip from $if0_ip to any out xmit $if1 # Force packet go out right interface. fwd $if1_gate ip from $if1_ip to any out xmit $if0 This works just fine if we do not try to use ipfw nat's port forwarding. Here it breaks because "keep-state" creates dynamic rule for incoming connections before translation's done, so it records external IP of the box as destination IP. Hence, replies will be translated using wrong NAT instance when routing table chooses wrong outgoing interface - replies won't match ipfw's dynamic rules. I think this is a bug in 8.2-STABLE. Am I right? Or, perhaps, there is another way to setup ipfw nat for dual-homed LAN? Eugene Grosbein