IPFW IPFW Kernel NAT is not working

Please help.
I have version 10.2-RELEASE with kernel NAT configured.
Ping request pass to external adapter, but don't route back to internal.

Internal (ue1):
Code:
# tcpdump -ni ue1 | grep 5.255.255.5
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ue1, link-type EN10MB (Ethernet), capture size 65535 bytes
11:56:38.974346 IP 169.254.138.12 > 5.255.255.5: ICMP echo request, id 35751, seq 1132, length 64
11:56:39.974337 IP 169.254.138.12 > 5.255.255.5: ICMP echo request, id 35751, seq 1133, length 64
11:56:40.974338 IP 169.254.138.12 > 5.255.255.5: ICMP echo request, id 35751, seq 1134, length 64
11:56:41.974378 IP 169.254.138.12 > 5.255.255.5: ICMP echo request, id 35751, seq 1135, length 64
11:56:42.984345 IP 169.254.138.12 > 5.255.255.5: ICMP echo request, id 35751, seq 1136, length 64
11:56:43.984368 IP 169.254.138.12 > 5.255.255.5: ICMP echo request, id 35751, seq 1137, length 64

External (ue0):
Code:
tcpdump -ni ue0 | grep 5.255.255.5
# tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ue0, link-type EN10MB (Ethernet), capture size 65535 bytes
11:57:22.074659 IP 192.168.1.113 > 5.255.255.5: ICMP echo request, id 35751, seq 1175, length 64
11:57:22.084355 IP 5.255.255.5 > 192.168.1.113: ICMP echo reply, id 35751, seq 1175, length 64
11:57:23.074586 IP 192.168.1.113 > 5.255.255.5: ICMP echo request, id 35751, seq 1176, length 64
11:57:23.084768 IP 5.255.255.5 > 192.168.1.113: ICMP echo reply, id 35751, seq 1176, length 64
11:57:24.074717 IP 192.168.1.113 > 5.255.255.5: ICMP echo request, id 35751, seq 1177, length 64

Configs:
Code:
# ifconfig
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6>
inet6 ::1 prefixlen 128
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1
inet 127.0.0.1 netmask 0xff000000
nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
ue0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=80001<RXCSUM,LINKSTATE>
ether b8:27:eb:37:b1:2f
inet 192.168.1.113 netmask 0xffffff00 broadcast 192.168.1.255
media: Ethernet autoselect (100baseTX <full-duplex>)
status: active
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
ue1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=8000b<RXCSUM,TXCSUM,VLAN_MTU,LINKSTATE>
ether 9c:eb:e8:06:c2:df
inet 169.254.138.1 netmask 0xffffff00 broadcast 169.254.138.255
media: Ethernet autoselect (100baseTX <full-duplex>)
status: active
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>

Code:
# netstat -rn
Routing tables
Internet:
Destination        Gateway            Flags      Netif Expire
default            192.168.1.1        UGS         ue0
127.0.0.1          link#1             UH          lo0
169.254.138.0/24   link#3             U           ue1
169.254.138.1      link#3             UHS         lo0
192.168.1.0/24     link#2             U           ue0
192.168.1.113      link#2             UHS         lo0
Code:
# cat /boot/loader.conf
ipdivert_load="YES"
ipfw_load="YES"
ipfw_nat_load="YES"
libalias_load="YES"
Code:
# cat /etc/rc.conf
hostname="router"
gateway_enable="YES"
defaultrouter="192.168.1.1"
ifconfig_ue0="inet 192.168.1.113 netmask 255.255.255.0"
ifconfig_ue1="inet 169.254.138.1 netmask 255.255.255.0"
firewall_enable="YES"
firewall_type="OPEN"
firewall_script="/etc/ipfw.rules"
firewall_logging="YES"
firewall_nat_enable="YES"
firewall_nat_interface="ue0"
sshd_enable="YES"
sendmail_enable="NONE"
sendmail_submit_enable="NO"
sendmail_outbound_enable="NO"
sendmail_msp_queue_enable="NO"
growfs_enable="YES"
Code:
# cat /etc/ipfw.rules
ipfw -q -f flush
cmd="ipfw -q add"
$cmd 00010 allow all from any to any via lo0
ipfw nat 1 config log if ue0 same_ports reset
$cmd 00020 nat 1 all from any to any via ue0
$cmd 00030 allow all from any to any
Code:
# cat /etc/sysctl.conf
net.inet.ip.fw.one_pass=1
net.inet.ip.fw.verbose=1
net.init.ip.fw.verbose_limit=5

Thanks!
 
A wild guess. ue0 and ue1 are USB ethernet adapters, correct? Without taking a special measure, these are activated late in the boot sequence, and it may happen later than ipfw gets set up. Try again after adding the following to /boot/loader.conf:
Code:
...
uether_load="YES"
if_axe_load="YES"
I got an ethernet adapter which is driven by axe(4). You need to find out the correct USB driver for your interfaces and replace if_axe_load with the respective directive.
 
Thanks for the answer
Yes, internal adapter is USB based on AX88772B chip, so driver is also AXE.
I have tried to add driver to boot config, but there is some problem, NAT still not working.
 
Is there any reason you can't use PF for the same task? With PF your NAT would be simply:

Code:
ext_if=ue0

nat on $ext_if inet from ! ($ext_if) to any -> ($ext_if)

Add static-port at the end if you need the port numbers to stay the same.
 
Is there any reason you can't use PF for the same task? With PF your NAT would be simply:

Code:
ext_if=ue0

nat on $ext_if inet from ! ($ext_if) to any -> ($ext_if)

Add static-port at the end if you need the port numbers to stay the same.
I going to try PF if there is no way to fix IPFW NAT
 
Please show the output of the following command:
# ipfw show
Code:
 # ipfw show

00020   0     0 allow ip from any to any via lo0

00020 120 15866 nat 1 ip from any to any via ue0

00030   0     0 allow ip from any to any

65535   0     0 deny ip from any to any
 
Code:
# ipfw show
00020   0     0 allow ip from any to any via lo0
00020 120 15866 nat 1 ip from any to any via ue0
00030   0     0 allow ip from any to any
65535   0     0 deny ip from any to any

Looks OK so far. I tested exactly your firewall script on my machine, and a ping from an internal client to the IP of the external interface did simply work -- as expected. Only difference, my internal network interface is re0, but the external network interface is ue0 as well.

Code:
# ifconfig
re0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
    options=8209b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
    ether 00:27:0e:08:c1:61
    inet 192.168.1.1 netmask 0xffffff00 broadcast 192.168.1.255 
    inet6 fe80::227:eff:fe08:c161%re0 prefixlen 64 scopeid 0x1 
    nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
    media: Ethernet autoselect (100baseTX <full-duplex>)
    status: active
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
    options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6>
    inet6 ::1 prefixlen 128 
    inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2 
    inet 127.0.0.1 netmask 0xff000000 
    nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
ue0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
    options=8000b<RXCSUM,TXCSUM,VLAN_MTU,LINKSTATE>
    ether 00:13:3b:85:09:3a
    inet 100.0.0.1 netmask 0xffffff00 broadcast 100.0.0.255 
    nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
    media: Ethernet autoselect (100baseTX <full-duplex>)
    status: active
 
I see 2 rules numbered 00020. Might have no impact at all. But I had the impression that rule numbers should be unique. Looks like traffic hits the NAT rule, but no counters tallied for either deny or accept rules. The log directive should put some helpful info in /var/log/security.
 
I see 2 rules numbered 00020. Might have no impact at all. But I had the impression that rule numbers should be unique. Looks like traffic hits the NAT rule, but no counters tallied for either deny or accept rules. The log directive should put some helpful info in /var/log/security.

When using in-kernel NAT and one_pass=1, the nat rule allows the traffic as well. Thus, rule 30 will never match anything as rule 20 matches everything. You can actually delete rule 30 as it's superfluous and just wastes CPU cycles to check it.
 
Back
Top