# NAT64 with ipfw issues



## Stardco (Apr 10, 2019)

Hello,

I'm tying to build a gateway between a full ipv6 network to a ipv4 network. I choose to test at first ipfw (i will test taiga next). 
My lab is based on BSDRP (1.92) systems inspired by "https://bsdrp.net/documentation/examples/nat64#r21". It is not exactly the same but the idea stay.

Unless I do not success...
I have a workstation in IPv6 connected to an IPv6 interface on a router and a workstation IPv4 connected to the ipv4 interface on the same router.
The pings work to the router from the workstations but not the 6 to 4 NAT between workstations.

When I look at the ipfw0 interface, I do not see any packet but the ipfw counter is incremented. I see the input traffic on the interface but nothing on the output.

This is my ipfw rules file :


```
#!/bin/sh
fwcmd="/sbin/ipfw"
kldstat -q -m ipfw_nat64 || kldload ipfw_nat64
${fwcmd} -f flush
${fwcmd} nat64lsn NAT64 create prefix4 10.0.148.64/26
${fwcmd} add allow log icmp6 from any to any icmp6types 135,136
${fwcmd} add nat64lsn NAT64 ip from 2001:db8:12::/64 to 64:ff9b::/96 in
${fwcmd} add nat64lsn NAT64 ip from any to 10.0.148.64/26 in
${fwcmd} add allow log ip from any to any
```

this is the rules counters :

```
[root@rTST64]~# ipfw -a list
00100  120  8168 allow log ipv6-icmp from any to any icmp6types 135,136
00200 1009 56504 nat64lsn NAT64 ip from 2001:db8:12::/64 to 64:ff9b::/96 in
00300    0     0 nat64lsn NAT64 ip from any to 10.0.148.64/26 in
00400  109 12216 allow log ip from any to any
65535    0     0 deny ip from any to any
```

and on the statistics :


```
[root@rTST64]~# ipfw nat64lsn NAT64 stats
nat64lsn NAT64
        0 packets translated from IPv6 to IPv4
        0 packets translated from IPv4 to IPv6
        0 IPv6 fragments created
        0 IPv4 fragments received
        0 output packets dropped due to no bufs, etc.
        0 output packets discarded due to no IPv4 route
        0 output packets discarded due to no IPv6 route
        0 packets discarded due to unsupported protocol
        0 packets discarded due to memory allocation problems
        1009 packets discarded due to some errors
        0 packets not matched with IPv4 prefix
        1 mbufs queued for post processing
        2 times the job queue was processed
        2 job requests queued
        0 job requests queue limit reached
        0 job requests failed due to memory allocation problems
        1 hosts allocated
        1 hosts requested
        0 host requests failed
        0 portgroups requested
        1 portgroups allocated
        2 portgroups deleted
        0 portgroup requests failed
        0 portgroups allocated for TCP
        0 portgroups allocated for UDP
        0 portgroups allocated for ICMP
        0 states created
        0 states deleted
```

I do not know why the packets are discarded and what is the error.

Somebody have an idea what I missed ? How can I check what happened in ipfw ?

Regards,


----------



## SirDice (Apr 10, 2019)

What version of FreeBSD are you using?


----------



## Stardco (Apr 11, 2019)

It is the 12.0-STABLE.

It was just trying with 12.0-RELEASE-p3. I have the same result


----------



## Stardco (Apr 11, 2019)

Ok, for information, I resolved one part of the issue.

I saw in the RFC6052 (thanks to the tayga man page) that the ipv4 destination network MUST NOT be include in the RFC1918 range. So when I replaced it, I received my translated packet on my IPv4 workstation, I saw the ipv4 answer but... not the ipv6 answer back to the ipv6 workstation.


```
root@rFreeBSD:~ # ipfw nat64lsn all list states
2001:db8:12::1  10.0.148.78     ICMPv6          0       11.0.23.3
2001:db8:12::1  10.0.148.78     ICMPv6          4       11.0.23.3
```


```
root@rFreeBSD:~ # ipfw nat64lsn NAT64 stats
nat64lsn NAT64
        879 packets translated from IPv6 to IPv4
        879 packets translated from IPv4 to IPv6
        0 IPv6 fragments created
        0 IPv4 fragments received
        0 output packets dropped due to no bufs, etc.
        0 output packets discarded due to no IPv4 route
        0 output packets discarded due to no IPv6 route
        0 packets discarded due to unsupported protocol
        0 packets discarded due to memory allocation problems
        0 packets discarded due to some errors
        0 packets not matched with IPv4 prefix
        1 mbufs queued for post processing
        1 times the job queue was processed
        1 job requests queued
        0 job requests queue limit reached
        0 job requests failed due to memory allocation problems
        1 hosts allocated
        1 hosts requested
        0 host requests failed
        0 portgroups requested
        1 portgroups allocated
        0 portgroups deleted
        0 portgroup requests failed
        0 portgroups allocated for TCP
        0 portgroups allocated for UDP
        1 portgroups allocated for ICMP
        3 states created
        2 states deleted
```


----------



## Stardco (Apr 29, 2019)

I find a way... a strange way but a way 

The system works only if I use the same interface to do the NAT64. As a picture is better than a talk I made two schemes 








Th ipfw rules are the same :


```
00100 allow ipv6-icmp from any to any ip6 icmp6types 135,136
00200 nat64lsn NAT64 ip from 2a01:db7:12::/64 to 64:ff9b::/96 in
00300 nat64lsn NAT64 ip from any to 11.0.148.64/26 in
00500 allow log ip from any to any
00501 allow log ip6 from any to any
65535 deny ip from any to any
```

It seems the nat64 through ipfw does not route the icmp reply (the 4 to 6) from an interface to another or I missed something in the ipfw configuration...
What do you think about this ?


----------



## olivier (Jun 4, 2019)

Hi sir Stardco,
Because your lab are based on BSDRP 1.92, this mean you are using a FreeBSD 12-stable and there are some change here regarding NAT64.
cf the man page for man page of ipfw for 12-stable, section "IPv6/IPv4 NETWORK ADDRESS AND PROTOCOL TRANSLATION" mention this change:

```
After translation NAT64 translator by default sends packets through cor-
responding netisr queue. Thus translator host should be configured as
IPv4 and IPv6 router. Also this means, that a packet is handled by fire-
wall twice. First time an original packet is handled and consumed by
translator, and then it is handled again as translated packet. This
behavior can be changed by sysctl variable
net.inet.ip.fw.nat64_direct_output.
```

So the last rule "allow log ip from any to any" should be matched during the second pass, but there is a bug on 12-stable.
This mean that these old example can't work anymore but you can fix this by a simple:
`sysctl net.inet.ip.fw.nat64_direct_output=1
echo "sysctl net.inet.ip.fw.nat64_direct_output=1" >> /etc/sysctl.conf`

Or you can complexity the rules by using tag.


----------

