Maps are yet another interesting feature that has been in nftables since the very beginning. You can use a map to look up for data based on some specific key that is used as input. Maps internally use the generic set infrastructure.

Literal maps

The following example shows how the destination TCP port selects the destination IP address to DNAT the packet:

% nft add rule ip nat prerouting dnat tcp dport map { 80 :, 8888 : }

This is how you can express a classical port redirection when the real server are actually located behind the firewall. This can be read as it follows:

  • If the TCP destination port is 80, then the packet is DNAT'ed to
  • If the TCP destination port is 8888, then the packet is DNAT'ed to

Map declarations

You can also declare maps that you can populate in a dynamic fashion, eg.

% nft add map nat porttoip  { type inet_service: ipv4_addr\; }
% nft add element nat porttoip { 80 :, 8888 : }

The example above shows that the porttoip map maintains the corresponde between Internet services (which is the datatype of a TCP destination port) and IP addresses. Then, you can use it from a rule like:

% nft add rule ip nat postrouting snat tcp dport map @porttoip

This rules tells that the source IP address that is used for SNAT depends on TCP destination port. The content of the map can be dynamically updated by adding new elements.