TC-NAT(8)
๐ NAT action in tc(8) ๐
Okay bestie, this is the page for the nat action in tc(8). Its whole name is nat - stateless native address translation action ๐ฆ It's the NAT action that goes in tc, and it's stateless, which means it doesn't keep track of connections.
โจ NAME โจ
nat - stateless native address translation action ๐
๐ธ SYNOPSIS ๐ธ
tc ... action nat DIRECTION OLD NEW
DIRECTION := { ingress | egress }
OLD := IPV4_ADDR_SPEC
NEW := IPV4_ADDR_SPEC
IPV4_ADDR_SPEC := { default | any | all | in_addr[/{prefix|netmask}]
๐ง DESCRIPTION ๐ง
Okay so the nat action lets you do NAT without the overhead of conntrack ๐ That's super useful when you've got a huge number of flows or addresses to translate, bestie. Like, it's giving efficiency. ๐
It works best when you pair it with the u32 filter, because then you can look up a big pile of stateless NAT rules in constant time. Iconic. ๐ฅ
๐ OPTIONS ๐
ingressโ Translates destination addresses, aka DNAT ๐egressโ Translates source addresses, aka SNAT โจ- OLD โ Says which addresses should get translated ๐
- NEW โ Says which addresses OLD should be translated into ๐ฆ
๐ NOTES ๐
The address format for OLD and NEW is seriously flexible, no cap ๐ซถ You can use one of the keywords default, any or all, which all mean the all-zero IP address. Or you can do an IP address plus a netmask or prefix length, separated by a slash (/). Either way, the mask (or prefix length) from OLD gets used for NEW too, so you always get a one-to-one mapping of addresses. Periodt. ๐
Address translation is done with a combo of binary operations ๐ง First, the original address (source or destination) gets matched against OLD. If it fits, the new address is built by taking the leading bits from NEW (defined by the netmask of OLD) and taking the remaining bits from the original address. It's giving math magic. โจ
Heads up: there's only rudimental support for upper layer protocols, namely TCP, UDP and ICMP ๐ญ For TCP and UDP, the action only recalculates the checksum. For ICMP, it also takes care of embedded IP headers inside ICMP packets and translates the addresses in there too. ๐
๐ฆ SEE ALSO ๐ฆ
tc(8) ๐
Bye bestie, that's the whole page! ๐ซถ This one's from the iproute2 package, dated 12 Jan 2015, and it's filed under NAT action in tc(8) ๐โจ
๐ฆ where this page comes from
- alpine 3.22: iproute2-doc 6.15.0-r0 ยท GPL-2.0-or-later
- alpine 3.23: iproute2-doc 6.17.0-r0 ยท GPL-2.0-or-later
- alpine 3.24: iproute2-doc 7.0.0-r0 ยท GPL-2.0-or-later
- arch rolling: iproute2 7.2.0-1
- arch rolling: iproute2 7.3.0-1 ยท GPL-2.0-or-later
- centos-stream 10: iproute-tc 7.0.0-2.el10 ยท GPL-2.0-or-later
- centos-stream 9: iproute-tc 6.17.0-3.el9 ยท GPL-2.0-or-later
- debian bookworm: iproute2 6.1.0-3 ยท GPL-2.0-only
- debian trixie: iproute2 6.15.0-1 ยท GPL-2.0-only
- fedora 43: iproute-tc 6.14.0-2.fc43 ยท GPL-2.0-or-later
- fedora 44: iproute-tc 6.17.0-2.fc44 ยท GPL-2.0-or-later
- nixos 26.05: iproute2 7.0.0
- nixpkgs unstable: iproute2 7.2.0
- opensuse-leap 16.0: iproute2 6.12-160000.4.1 ยท GPL-2.0-only
- opensuse-leap 16.0: iproute2 6.12-160000.4.1 ยท GPL-2.0-only
- opensuse-leap 16.0: iproute2 6.12-160000.4.1 ยท GPL-2.0-only
- opensuse-leap 16.0: iproute2 6.12-160000.4.1 ยท GPL-2.0-only
- ubuntu noble: iproute2 6.1.0-1ubuntu6 ยท GPL-2.0-only
- ubuntu noble: iproute2 6.1.0-1ubuntu6.4 ยท GPL-2.0-only
- ubuntu questing: iproute2 6.16.0-1ubuntu2
- ubuntu questing: iproute2 6.16.0-1ubuntu2.1 ยท GPL-2.0-only
- ubuntu questing: iproute2 6.16.0-1ubuntu2.2
- ubuntu resolute: iproute2 6.19.0-1ubuntu1 ยท GPL-2.0-only
- ubuntu resolute: iproute2 6.19.0-1ubuntu1.1 ยท GPL-2.0-only
- ubuntu stonking: iproute2 7.2.0-1ubuntu1 ยท GPL-2.0-only
- ๐ girlified by anthropic/claude-haiku-5.5 on : a language model's rewrite of the original, under its terms