Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> wrote: > > Sorry, I don't see the usecase for different deltas. > > Then, users will more than one single rule for different port-shift > mappings? Hmm, why? Can't the variable offset be stored in the map itself (instead of the new dport value)? so assuming a map that has typeof ip saddr . ip daddr : ip daddr . tcp dport ... but the map content stores the delta to use, e.g. { 192.168.7.1 . 10.2.2.2 : 10.2.2.1 . 10000 } ... where 10000 isn't the new dport but a delta that has to be added. [ payload load 4b @ network header + 12 => reg 1 ] # saddr [ payload load 4b @ network header + 16 => reg 9 ] # daddr [ lookup reg 1 set m dreg 1 0x0 ] # now we have reg1: dnat addr, reg 9: delta to add [ payload load 2b @ transport header + 2 => reg 10 ] [ math add reg 9 + reg 10 => reg 9 ] # real port value from packet added with delta [ nat dnat ip addr_min reg 1 addr_max reg 1 proto_min reg 9 proto_max reg 9 flags 0x3 ] add operation should probably also take a modulus (fixed immediate value) so we can make a defined result for things like: 65532 + 10000 ... without a need to wrap implicitly back to "0 + remainder". > In my proposal, kernel would take the delta from register, the flag > tells the nat core how to interpret this. Yep, understood. This is mapping the existing iptables approach, but using register instead of immediate to pass data. > > So we need an 'add' operation in kernel to compute > > This is an 'add' operation built-in into the NAT engine. > > How would a generic 'add' operation in the kernel will work with > concatenations? Its not needed for concatentation case, the port value (in packet) is always a fixed value, so it can be (re)loaded at runtime. But maybe i'm missing something that the nat engone is already offering that this approach can't handle, or some other limitation.