Hi Rick, On Mon, Jun 08, 2020 at 12:02:03PM +0200, Rick van Rein wrote: > 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. Right, one single mapping. > 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 } I see. > >> 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. OK, but you only need this "stack" idea is alternative proposal to get the "one single mapping" idea working, correct? Thanks.