Ever wanted to combine two WAN connections for faster* internet? I do, for torrenting. And I scripted it.
On the Web, you’ll easily find „tutorials“ that just give you some bash script you have to painstakingly modify for it to run. This is as simple as it gets! But see for yourself! (code at the end of this post)
Since I get a dynamic (external) IP right into my PC, that would mean, I’d have to modify that every time. So I made this small script, that only depends on iproute2
, which you’ll need anyways, and awk
and grep
, that should already be on your system.
Just run the script as root and give the network interfaces you want to balance as parameters.
~$ sudo ./load-balance.sh eth0 eth1 wlan0
In a future version, I’d like to add support for dynamically setting the weight (currently, all interfaces get the same priority).
My setup looks like this:
eth0
goes to my Uni’s Interweb (they are my ISP)eth1
is connected via a USB-Ethernet-adapter to a router with a UMTS-modemwlan0
is my Android phone in tethering modeAs you can see, it is of course necessary, that you have multiple entry points into the Internet. If you connect your PC with multiple connections to the same WAN, you won’t get any speed increase.
* Load balancing won’t work in all use cases. If you for example just stream a single video (or download a single file), only one of the balanced interfaces will be in use, and no speed increase is visible. But when you download multiple things, like the chunks of a torrent, half of the files/chunks are downloaded over the first IF, and half over the other.
#!/bin/bash
# Load balance multiple internet connections. Requires iproute2, awk and grep.
# (C) 2016 Tobias Girstmair, isticktoit.net, GPLv2
# Also useful: speedometer -l -r eth1 -t eth1 -m $(( 1024 * 1024 * 3 / 2 ))
# Not much user error checking is done - only pass working network connections
# script needs root to work and at least two connections to be useful
[ $EUID -eq 0 -a $# -ge 2 ] || {
echo "Usage (as root): $0 iface1 iface2 ..." >&2
exit 1
}
get_free_tblnum() { # http://stackoverflow.com/a/28702075
awk -v RS='\\s+' '{ a[$1] } END { for(i = 10; i in a; ++i); print i }'</etc/iproute2/rt_tables
}
loadbal() {
IFACE=$1
TABLE="${IFACE}loadbalance"
if ! grep -q -w "$TABLE" /etc/iproute2/rt_tables ; then
echo "$(get_free_tblnum) $TABLE" >> /etc/iproute2/rt_tables
fi
MY_IP=$(ip -o -4 addr show $IFACE |awk -F'(\\s|/)+' '{print $4}')
GW_IP=$(ip route show dev $IFACE | awk '/default/ {print $3}')
SUBNT=$(ip route show dev $IFACE | awk '/proto kernel/ {print $1}')
ip route add $SUBNT dev $IFACE src $MY_IP table $TABLE
ip route add default via $GW_IP table $TABLE
ip rule add from $MY_IP table $TABLE
echo nexthop via $GW_IP dev $IFACE weight 1
}
ip route add default scope global $(for IF in "$@"; do loadbal $IF; done)
Changelog: v1.01: HTML-escaped the code