Page MenuHomeFreeBSD

[RFC/RFT] NAT64 implementation for ipfw.

Authored by ae on May 18 2016, 10:56 AM.



This patch includes two NAT64 implementations in one ipfw_nat64 module - stateless nat64stl and stateful nat64lsn.
Each implementation registers in ipfw as external action and supports many instances.
The code isn't perfect, there are some hacks and simplifications, but since code slush is coming...


ipfw [set N] nat64stl NAME create table4 <name> table6 <name> prefix <prefix>
ipfw [set N] nat64stl NAME stats
ipfw [set N] nat64stl {NAME | all} destroy
ipfw [set N] nat64stl {NAME | all} {list | show}

Stateless NAT64 uses two ipfw's lookup tables to determine addresses that it should translate.
@table4 should contains IPv4->IPv6 addresses mapping.
@table6 should contains IPv6->IPv4 addresses mapping. I.e. one table contains the same adresses,
but reverse key<->value. It isn't handy, but currently it is implemented like this.

The tables should be created using such commands:

ipfw table T46 create type addr valtype ipv6
ipfw table T64 create type addr valtype ipv4

The @prefix argument currently supports only well-known prefix 64:ff9b::/96.
After nat64stl instance will be created, it can be used in rules:

ipfw nat64stl NAT64 create table4 T46 table6 T64
ipfw add allow icmp6 from any to any icmp6types 135,136
ipfw add nat64stl NAT64 ip from any to table(T46)
ipfw add nat64stl NAT64 ip6 from table(T64) to 64:ff9b::/96

The rule that handles nat64stl doesn't terminate the search if packet doesn't matched to addresses in tables.


ipfw [set N] nat64lsn NAME create ...
ipfw [set N] nat64lsn NAME stats
ipfw [set N] nat64lsn {NAME | all} destroy
ipfw [set N] nat64lsn {NAME | all} {list | show} [config | states]

Stateful NAT64 has only one option required to create an instance - prefix4.
All other options can be left with default values.

ipfw nat64lsn NAT64 create prefix4 XX.YY.148.64/26
ipfw add allow icmp6 from any to any icmp6types 135,136
ipfw add nat64lsn NAT64 ip from 2YYY:XXX::/32 to 64:ff9b::/96 in
ipfw add nat64lsn NAT64 ip from any to XX.YY.148.64/26 in

The rule that handles nat64lsn always terminates the search (may be we need to change this behaviour?).

Both implementations uses the shared code to implement translation.
After translation packet will be reinjected into corresponding NETISR queue.
Also there is code under IPFIREWALL_NAT64_DIRECT_OUTPUT ifdefs. It uses own route lookup and directly calls if_output().

Test Plan

We use only NAT64LSN for many months and seems it works very stable now. NAT64STL was very little tested.
Also I did many changes in the code (mostly renaming variables/structures/functions) before submit it,
so, some bugs could been appear.

Diff Detail

rS FreeBSD src repository - subversion
Automatic diff as part of commit; lint not applicable.
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

ae retitled this revision from to [RFC/RFT] NAT64 implementation for ipfw..
ae updated this object.
ae edited the test plan for this revision. (Show Details)
ae added reviewers: network, melifaro, hrs, bz.
hrs edited edge metadata.

I think we can go ahead with this, too.

This revision is now accepted and ready to land.Jul 15 2016, 5:23 PM
ae edited edge metadata.
This revision was automatically updated to reflect the committed changes.