Links Load balancing
Prerequisites :
Netfilter :
- CONNMARK
- nth (or statistic module)
- condition (for failover)
- Iproute2
System :
Linux gw
2 links (what ever techno) :
- Link 1 : BP 1500 – fraction 3
- Link 2 : BP 500 – fraction 1
ratio between the 2 link 1/4 3/4
Goal :
have a load-balancing failover betwwen two link at connection level. Setup is here for a
nated LAN.
Algorithm :
Mark system :
We build a mark system on PREROUTING using MARK and we use CONNMARK to restore the mark
on prerouting use nth to build a pool :
mark 1 for LINK 1 outgoing
mark 2 for link 2 outgoing
In our exemple nth of 4 :
1 : mark 1
2 : mark 2
3 : mark 1
4 : mark 1
See connmark for marking
iptables -A PREROUTING -t mangle -j CONNMARK --restore-mark iptables -A PREROUTING -t mangle -m mark --mark 0x0 -m nth --counter 1 \ --every 4 --packet 1 -j MARK --set-mark 1 iptables -A PREROUTING -t mangle -m mark --mark 0x0 -m nth --counter 1 \ --every 4 --packet 2 -j MARK --set-mark 2 iptables -A PREROUTING -t mangle -m mark --mark 0x0 -m nth --counter 1 \ --every 4 --packet 3 -j MARK --set-mark 1 iptables -A PREROUTING -t mangle -m mark --mark 0x0 -m nth --counter 1 \ --every 4 --packet 4 -j MARK --set-mark 1 iptables -A POSTROUTING -j CONNMARK --save-mark
The syntax is different nn recent kernel (at least 2.6.24 and over):
iptables -A PREROUTING -t mangle -m mark --mark 0x0 -m statistic \ --mode nth --every 4 --packet 0 -j MARK --set-mark 1 ...
The mark system is modified to have fail-over. We have two lines for each item of the nth pool :
exemple for item 1 :
-m condition -condition LINK1 UP -j mark 1
-m condition -condition LINK1 DOWN -j mark 2
Thus when link 1 is down packet get mark 2 and get out via LINK2
this gives :
iptables -N MARKING iptables -A PREROUTING -t mangle -j CONNMARK --restore-mark iptables -A PREROUTING -t mangle -m mark --mark 0x0 -j MARKING iptables -A MARKING -t mangle -m condition --condition link1_up \ -m nth --counter 1 --every 4 --packet 1 -j MARK --set-mark 1 iptables -A MARKING -t mangle -m condition ! --condition link1_up \ -m nth --counter 1 --every 4 --packet 1 -j MARK --set-mark 1 iptables -A MARKING -t mangle -m condition --condition link2_up -m nth --counter 1 --every 4 --packet 2 -j MARK --set-mark 2 iptables -A MARKING -t mangle -m condition ! --condition link2_up -m nth --counter 1 --every 4 --packet 2 -j MARK --set-mark 1 iptables -A MARKING -t mangle -m condition --condition link1_up \ -m nth --counter 1 --every 4 --packet 3 -j MARK --set-mark 1 iptables -A MARKING -t mangle -m condition ! --condition link1_up \ -m nth --counter 1 --every 4 --packet 3 -j MARK --set-mark 2 iptables -A MARKING -t mangle -m condition --condition link1_up \ -m nth --counter 1 --every 4 --packet 4 -j MARK --set-mark 1 iptables -A MARKING -t mangle -m condition ! --condition link1_up \ -m nth --counter 1 --every 4 --packet 4 -j MARK --set-mark 2 iptables -A POSTROUTING -j CONNMARK --save-mark
IProute :
Route packet with mark 1 to a table having default gw via LINK1
Route packet with mark 2 to a table having default gw via LINK1
ip route add default gw GW_LINK1 table LINK1 ip route add default gw GW_LINK2 table LINK2 ip rule add fwmark 1 lookup table LINK1 ip rule add fwmark 2 lookup table LINK2
NAT :
in POSTROUTING packets :
with mark 1 get IP of link 1.
with mark 2 get IP of link 1.
