Hi Pablo / NFT-dev, >> 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 } \ > > So, you would consolidate this in one single rule? So there is one > single lookup to obtain the IP address and the destination port for > the stateless packet mangling. It already is a single rule, but a single mapping, or one that appears like one. In reality, I use dynamic map @refs, of course. A single lookup would avoid the problem that the key has changed in the second lookup. I played around, trying if I could "ip6 daddr . tcp dport set" and perhaps have a map with elements like "{ $PREFIX::64:75 . 8080 : $PREFIX::100:20 . 80 }" but did not find a syntax. [I've been missing a formal syntax, it's all examples so I wasn't sure if this was possible at all.] It'd look like new_nft add rule ip6 raw prerouting \ ip6 daddr . tcp dport set \ ip6 daddr . tcp dport \ map { $PREFIX::64:75 . 8080 : $PREFIX::100:20 . 80 } >> 0. Is there a way to use maps as atomic setter for (daddr,dport)? > > Not yet. Ah, you spotted the problem too. No surprise ;-) >> 1. Can I reach back to the original value of a just-modified value? > > You mean, the original header field that was just mangled? Like > matching on the former IP address before the mangling? Yes, exactly. That way, I can use two maps but find the right combination of addr/port without intermediate key changes. >> 2. Is there a variable, or stack, to prepare with the old value? > > But this is to achieve the atomic mangling that you describe above or > you have something else in mind? You would like to store the former IP > daddr in some scratchpad area that can be accessed later on, right? It is another possible way to get to the old value so I can make the same mapping. I could imagine storing the old daddr in daddr2 then mapping daddr and using daddr2 in the second map looking to find the matching port. That might look like new_nft add rule ip6 raw prerouting \ rulevar set ip6 daddr \ ip6 daddr set \ ip6 daddr . tcp dport \ map { $PREFIX::64:75 . 8080 : $PREFIX::100:20 } \ tcp dport set \ rulevar . tcp dport \ map { $PREFIX::100:20 . 8080 : 80 } \ If the language internally uses a stack, I could imagine pushing the old value(s) to prepare for the second map, then perform the first map and continue with the second. That might look like new_nft add rule ip6 raw prerouting \ ip6 daddr push \ ip6 daddr set \ ip6 daddr . tcp dport \ map { $PREFIX::64:75 . 8080 : $PREFIX::100:20 } \ tcp dport set \ pop . tcp dport \ map { $PREFIX::100:20 . 8080 : 80 } \ The examples are just three syntaxes I can think of. Thanks, -Rick