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...
NAT64STL
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.
NAT64LSN
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().