Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 26 Mar 2013 17:10:56 +0100
From:      Andrzej Tobola <ato@iem.pw.edu.pl>
To:        freebsd-ipfw@freebsd.org
Subject:   Re: kernel NAT with ipfw failing
Message-ID:  <20130326161056.GA34850@volt.iem.pw.edu.pl>
In-Reply-To: <5151BEA9.2080907@oxit.fi>
References:  <5151BEA9.2080907@oxit.fi>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, Mar 26, 2013 at 05:28:41PM +0200, Jukka Ukkonen wrote:
> 
> Hello,
> 
> Does anyone have a confirmed working example (one that is
> in daily active use) of the ipfw NAT inside the kernel?

Yes.
>From a long time. On FreeBSD 9.1-STABLE amd64.


% # ipfw -a list
 00100  21174480  25689611435 allow ip from any to any via lo0
 00200         0            0 deny ip from any to 127.0.0.0/8
 00300         0            0 deny ip from 127.0.0.0/8 to any
 00500  25956378  24125425085 nat 1 ip from any to 194.29.146.4
 00500  88469999  28195999566 nat 1 ip from any to any recv lagg0
 .............

% grep nat /etc/rc.conf
 nat_enable=YES                  # NAT (/usr/local/etc/rc.d)
 nat_LAN=lagg0                   #  LAN
 nat_IP=194.29.146.4             #  nat1

% cat /usr/local/etc/rc.d/nat

#!/bin/sh
#
# $FreeBSD: src/etc/rc.d/nat,v 0.1 2010/11/7 22:04:50 ato Exp $
#
# ato 2010

# PROVIDE: nat
# REQUIRE: NETWORKING
# REQUIRE: named
# KEYWORD: nojail

# To enable User must define:
#  nat_enable=YES
#  nat_IP= or nat_WAN=	# NATed IP (raw or DNS name) or WAN interface name
#  nat_LAN=		# LAN interface name
#			# if not specified get `route -n get -inet default | grep interface:`

. /etc/rc.subr

name=nat
rcvar=nat_enable

load_rc_config $name

: ${nat_enable:=NO}
: ${nat_CONF="reset unreg_only same_ports log"} # deny_in
: ${nat_N:=1}
: ${nat_R:=500}

#set_rcvar nat_enable NO "NAT (ipfw)" >/dev/null

start_precmd=nat_prestart
start_cmd=nat_start
required_modules="ipfw_nat.ko"	# XXX why .ko necessary ?
stop_cmd=nat_stop

extra_commands="status show dump"
status_cmd=nat_show
show_cmd=nat_show
dump_cmd=nat_dump

nat_prestart()
{
	[ "$nat_WAN$nat_IP" ] || err 1 "You must define \$nat_IP or \$nat_WAN."
	[ "$nat_LAN" ] || err 1 "You must define \$nat_LAN."
	ifconfig -l ether | grep -q $nat_LAN || err 1 "Can't find LAN interface $nat_LAN."
	if [ "$nat_IP" ]; then
		# TODO test czy IP przypisany:
		ping -q -c1 -W100 $nat_IP 2> /dev/null | grep -q '100.0% packet loss' && return 1
	else
		nat_IP=me
	fi
	return 0
}

nat_start()
{
	# XXX test if ON
	echo "Enabling NAT on $nat_LAN."
	if [ "$nat_WAN" ] ; then
		nat_CONF="if $nat_WAN $nat_CONF"
	elif [ "$nat_IP" ]; then
		nat_CONF="ip $nat_IP  $nat_CONF"
	else # no nat_WAN or nat_IP defined - get default inet gateway interface:
		nat_WAN=`route -n get -inet default | grep interface:` ; nat_WAN=${nat_WAN##*: }
		nat_CONF="if $nat_WAN $nat_CONF"
	fi
	ipfw nat $nat_N config $nat_CONF
	ipfw add $nat_R nat $nat_N all from any to $nat_IP
	ipfw add $nat_R nat $nat_N all from any to any recv $nat_LAN
	sysctl net.inet.ip.forwarding=1
	#sysctl net.inet.ip.fw.one_pass=1		# def=0 (nie wplywa?)
	#Bound dummynet to CPU0:
	#cpuset -l 0 -t $(procstat -t 0 | awk '/dummynet/ {print $2}')
}

nat_stop()
{
	echo "Disabling NAT"
	# XXX test if ON
	ipfw delete $nat_R
	kldunload $required_modules
}

nat_show()
{
	# XXX test if ON
	ipfw nat $nat_N show config
	ipfw -a list $nat_R && ipfw nat $nat_N show
	arp -ai $nat_LAN
}

nat_dump()
{
	# XXX test if ON
	sysctl net.inet.ip.fw.verbose=0
	tcpdump -i ipfw0
	sysctl net.inet.ip.fw.verbose=1
}

run_rc_command "$1"


cheers,
-a



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20130326161056.GA34850>