Router - Linux upload bonding using policy routing
I'm using PPP on the Linux box - in my case via a Solos ADSL card, but this will also work using PPPoE.
First, for convenience, name your extra routing tables by editing /etc/iproute2/rt_tables:
1 ppp0 2 ppp1
Add a script in /etc/ppp/ip-up.d and in /etc/ppp/ipv6-up.d to put the routes in the per-interface tables:
#!/bin/bash # ip-up.d/set-routes ip route replace default dev ${PPP_IFACE} table ${PPP_IFACE}
#!/bin/bash # ipv6-up.d/set-routes ip -6 route replace default dev ${PPP_IFACE} table ${PPP_IFACE}
Add a script in /etc/ppp/ip-down.d and in /etc/ppp/ipv6-down.d to remove the per-interface routes when the PPP link goes down:
#!/bin/bash # ip-down.d/remove-routes ip route flush table ${PPP_IFACE}
#!/bin/bash # ipv6-down.d/remove-routes ip -6 route flush table ${PPP_IFACE}
Run the following script on boot:
#!/bin/bash # fwmark 1 is line 1 ip rule add fwmark 1 table ppp0 prio 40000 ip -6 rule add fwmark 1 table ppp0 prio 40000 # fwmark 2 is line 2 ip rule add fwmark 2 table ppp1 prio 40001 ip -6 rule add fwmark 2 table ppp1 prio 40001 # unmarked prefers line 1, then does line 2 if line 1 is not possible ip rule add from all table ppp0 prio 50000 ip -6 rule add from all table ppp0 prio 50000 ip rule add from all table ppp1 prio 50001 ip -6 rule add from all table ppp1 prio 50001
This uses iproute2's ip command to set up policy routing rules; the first set give you a firewall mark per line. (rules at prio 40000 and 40001). The last block (rules at 50000 and 50001) serves two purposes:
- It ensures that packets that are marked for routing via a dead line are passed onto the other line
- It provides a fallback if you forget to add firewall marks in PREROUTING for some packets.
Finally, apply firewall marks in PREROUTING to choose your load balancing policy. For example:
for IPT in iptables ip6tables do $IPT -A PREROUTING ! -i ppp+ -m statistic --mode nth --every 2 --packet 0 -j MARK --set-mark 1 $IPT -A PREROUTING ! -i ppp+ -m statistic --mode nth --every 2 --packet 1 -j MARK --set-mark 2 done
simply load balances by alternating packets on each line.