Zbr's days.

About :: TODO :: Blog :: RSS :: Old blog :: Projects :: GIT :: Gallery :: Notes

Tue, 12 Dec 2006

Network address translation (NAT) over netchannels.


Netchannels itself work - one can configure either userspace netchannels or kernel ones, which are processed by kernel threads.

NAT is special and thus interesting case - packets must be mangled and resent upto two times - when packet is received from one network (before changes), then it should be changed, sent to likely other network, reply received, changed and sent back to original host.
There are at least two types of rules in such scenario.
One type contains NAT rules which are created by system administrator, another one is per connection rule, which includes real manipulation data. At minimum it contains two routes - to original host and to remote host. Main mangling rule setup by administrator, for example 192.168.0.0/255.255.0.0 convert to look like source is 1.0.0.1, can contains several different networks, which are connected through different network adapters, so input routes are essentially per-connection, the same applies to destination routes.

So, what is the logic behind NAT in case of netchannels or netfilter?
I will describe how netchannel implementation will work.
When packet first time enters network stack and it hits NAT netchannel, it will be queued for processing in special thread, where new netchannel with exact source/destination parameters will be created, including routes for input and output directions (actually they are both output directions for NAT server (or only one direction, if connection is to/from NAT server itself), but one of them is input and other is output from the initial packet point of view, so I will call it that way), then packet will be changed and sent to appropriate destination. When next packet or reply will enter the stack, it will be caught by that new netchannel, since its priority is higher, and eventually packet will be changed and resent in special thread. Each new netchannel, created by NAT system, will have either kernel timer attached or special state machine will be created to track too old netchannels which potentially can be freed (i.e. some kind of garbage collection).
Since each new netchannel, created by NAT system, has always exact parameters without wildcards, it would be possible to put them not into trie, but into special binary tree with faster search time, but such tree must be put into main NAT netchannel to not mess with other rules, which were setup in trie, so actually there will be even more lookups than in case when new netchannels are put directly into the same trie - one lookup for main NAT netchannel and then additional tree search for subnetchannel (lets give such a name to netchannels created by NAT system).
In theory it is possible to not create new subnetchannel for each new connection - system can take an advantage of the fact, that several dataflows (potentially mapped to individual netchannels) can use the same routes, so they could share the same subnetchannel, but in practice there is no way to select set of addresses which contain the same route, only possible to get route by addresses.
This rises a question actually, since I want to use exactly one netchannel for server-like scenarious, when there is only one listening netchannel, which transfers data to/from userspace, which handles protocol itself. I will think about posible good implementation of such a feture, but until it is done, new netchannel must be created for each new connection.

Netfilter NAT work essentially the same.
It is based on famous connection tracking subsystem - each packet, when it enters the stack, will get connection tracking entry attached to it, when packet within the same connection (i.e. source/destination parameters) enters the stack, it will be changed according to that connection tracking entry. Connection tracking entries live in own cache independent on NAT, but called from NAT rule - so we have exactly two lookups which I decided to avoid in described above netchannel scheme. Netfilter/connection tracking lookups are perfomed in fixed-sized hash tables, contained linked lists, which does not scale neither with number of packets, nor with number of rules.

/devel/networking :: Link / Comments ()