Documentation > Basic Tutorials > Stateful NAT64

Stateful NAT64 Run


  1. Introduction
  2. Sample Network
  3. Jool
  4. Testing
  5. Stopping Jool
  6. Afterwords


This document explains how to run Jool in Stateful NAT64 mode.

Sample Network

Figure 1 - Sample Network

All the remarks in the first document’s Sample Network section apply here.

Nodes A through E:

user@A:~# service network-manager stop
user@A:~# /sbin/ip link set eth0 up
user@A:~# # Replace "::8" depending on which node you're on.
user@A:~# /sbin/ip address add 2001:db8::8/96 dev eth0
user@A:~# /sbin/ip route add default via 2001:db8::1

Nodes V through Z:

user@V:~# service network-manager stop
user@V:~# /sbin/ip link set eth0 up
user@V:~# # Replace ".16" depending on which node you're on.
user@V:~# /sbin/ip address add dev eth0

Notice these nodes do not need a default route. This is a consequence of them being in the same network as the NAT64; T will be masking the IPv6 nodes, so V through Z think they’re talking directly to it.

Node T:

user@T:~# service network-manager stop
user@T:~# /sbin/ip link set eth0 up
user@T:~# /sbin/ip address add 2001:db8::1/96 dev eth0
user@T:~# /sbin/ip link set eth1 up
user@T:~# /sbin/ip address add dev eth1
user@T:~# sysctl -w net.ipv4.conf.all.forwarding=1
user@T:~# sysctl -w net.ipv6.conf.all.forwarding=1

Note! In previous versions of Jool, T used to need two or more IPv4 addresses. Because pool4 now stores port ranges, this is no longer the case.

Remember you might want to cross-ping T vs everything before continuing.


Even though they share a lot of code, because of kernel quirks, the NAT64 module is separate from the SIIT one. The name of the NAT64 module is jool.

Most Distros OpenWRT
user@T:~# /sbin/modprobe jool
user@T:~# insmod jool

Though the meaning of pool6 is slightly different than in SIIT, the instance configuration looks pretty much the same:

iptables Jool Netfilter Jool
user@T:~# jool instance add "example" --iptables  --pool6 64:ff9b::/96
user@T:~# ip6tables -t mangle -A PREROUTING \
>		-d 64:ff9b::/96 \
>		-j JOOL --instance "example"
user@T:~# iptables  -t mangle -A PREROUTING \
>		-d -p tcp --dport 61001:65535 \
>		-j JOOL --instance "example"
user@T:~# iptables  -t mangle -A PREROUTING \
>		-d -p udp --dport 61001:65535 \
>		-j JOOL --instance "example"
user@T:~# iptables  -t mangle -A PREROUTING \
>		-d -p icmp \
>		-j JOOL --instance "example"
user@T:~# jool instance add "example" --netfilter --pool6 64:ff9b::/96

The iptables configuration, on the other hand, needs to use the JOOL target and match more specific transport addresses in the IPv4 side. Ports 61001-65535 of T’s owned IPv4 addresses are Jool’s default reserved mask range. More information can be found in pool4.

../images/bulb.svg About those iptables rules:

As far as transport protocols are concerned, NAT64 Jool knows how to handle TCP and UDP (as well as ICMP if you count it). Because of the large transport header hacking that is required by a stateful translator, NAT64 Jool cannot translate unknown transport protocols like SIIT Jool. That, on top of the fact that iptables Jool drops traffic when it finds itself unable to translate it, is why it’s better not to default --protocol (-p) to all, and instead declare a dedicated rule for each one.

../images/warning.svg And again: Please remember that a suitable ICMP-matching rule is not optional on a healthy network.


If something doesn’t work, try the FAQ.

Test by sending requests from the IPv6 network:

user@C:~$ ping6 64:ff9b::
PING 64:ff9b:: 56 data bytes
64 bytes from 64:ff9b::cb00:7110: icmp_seq=1 ttl=63 time=1.13 ms
64 bytes from 64:ff9b::cb00:7110: icmp_seq=2 ttl=63 time=4.48 ms
64 bytes from 64:ff9b::cb00:7110: icmp_seq=3 ttl=63 time=15.6 ms
64 bytes from 64:ff9b::cb00:7110: icmp_seq=4 ttl=63 time=4.89 ms
--- 64:ff9b:: ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 1.136/6.528/15.603/5.438 ms

Figure 1 - IPv4 TCP from an IPv6 node

Note! Obviously, users should not need to be aware of IP addresses, much less know they need to append a prefix whenever they need to speak to IPv4. The DNS64 document will tell you how to make the prefix-address-hack transparent to users.

Note! Because a NAT64 is stateful, only IPv6-started tests can be run at this point. See port forwarding if 4-to-6 translation is relevant for you.

Stopping Jool

Most Distros OpenWRT
user@T:~# ip6tables -t mangle -F    # Meh, whatever
user@T:~# iptables  -t mangle -F
user@T:~# jool instance remove "example"
user@T:~# /sbin/modprobe -r jool
user@T:~# ip6tables -t mangle -F    # Meh, whatever
user@T:~# iptables  -t mangle -F
user@T:~# jool instance remove "example"
user@T:~# rmmod jool


  1. More complex setups might require you to consider the MTU notes.
  2. Please note that none of what was done in this tutorial survives reboots! Documentation on persistence will be released in the future.

The next tutorial explains DNS64.