Hello, I seem to be running into an expressive limitation of nft while trying to do stateless translation. I prefer statelessness because it it is clearer for bidirectionality / peering, and saves lookup times. After nat64, I have a small set of IPv6 addresses and I would like to map their (daddr,dport) or better even (daddr,proto,dport) tuples to outgoing (daddr',dport'). Effectively, port forwarding for IPv6. Individual rules work, like this one side of a bidir portmap: nft add rule ip6 raw prerouting \ ip6 daddr $PREFIX::64:75 \ tcp dport 8080 \ ip6 daddr set $PREFIX::100:20 \ tcp dport set 80 \ notrack I have problems doing this with the map construct, presumably because it does not atomically replace (daddr,dport) by (daddr',dport') but instead does two assignments with intermediate alterede state. This is bound to work in many cases, but it can give undesired crossover behaviours [namely between incoming IPs if they map to the same daddr' while coming from the same dport]: nft add rule ip6 raw prerouting \ ip6 daddr set \ ip6 daddr . tcp dport \ map { $PREFIX::64:75 . 8080 : $PREFIX::100:20 } \ tcp dport set \ ip6 daddr . tcp dport \ map { $PREFIX::100:20 . 8080 : 80 } \ notrack So now I am wondering, 0. Is there a way to use maps as atomic setter for (daddr,dport)? 1. Can I reach back to the original value of a just-modified value? 2. Is there a variable, or stack, to prepare with the old value? Without this, I need to work around an expressive limitation, * Fan out from a few IPv6 to many first to minimise rule clashes * Make separate maps and rules and maps for each of the IPv6 addresses Both sound to me like a lack of expressiveness, or that I missed how. Thanks! -Rick