Today I received a question about how to distribute the outgoing connections between several IP addresses attached to an interface. Suppose that you have 3 IPs in the eth0 interface and you want to do round robin between that IPs for outgoing connections. With regular iproute commands you can’t. Doing some tricks with fwmarks, ip rule and ip route neither.
The only way that I’ve found to it is using SNAT and statistics to get a real Round Robin balance:
iptables -t nat -A POSTROUTING -m statistic --mode nth --every 3 -j SNAT --to 192.168.1.201
iptables -t nat -A POSTROUTING -m statistic --mode nth --every 2 -j SNAT --to 192.168.1.202
iptables -t nat -A POSTROUTING -m statistic --mode nth --every 1 -j SNAT --to 192.168.1.203
The IPs described in the example should be local IPs.
Four years ago I had nothing to do and started to read some pieces of the kernel code. I read about the BLK, a feature that kernel developers have been trying to remove the last years (I’m not sure if they have finished). My small contribution to that task was this two patches that I sent at the end of 2007. It’s not a big thing but it required some understanding of the kernel internals or I would have broken something 🙂
BLK or the Big Kernel Lock is a basic locking mechanism introduced in the kernel when SMP support was included. It’s a global lock, lock_kernel() and unlock_kernel() are the functions to use it. This lock is bad because is global, if the networking code wants to protect something calls it. If the filesystem code wants to protect other fs related data calls it too. Two unrelated data structures are protected and two code paths are blocked without any sense. Was an easy implementation in the first years of SMP support, but it had been spreading without control. In the last years, kernel developers have been trying to remove it. New kernel code has independent locks and block the data structures, so unrelated code paths are not blocked.