Routing for multiple ISP links on Linux

Many of us have multiple ISP uplinks for different reasons like reliability, download limit, etc. but there is no clear guide [at least, I couldn’t find any] on routing for multiple links.

I came across the same problem — I got a new fiber connection, but it is a capped one and I have a slow ADSL link which is not capped. So I obviously would want to use the ADSL link for low priority downloads while fiber for browsing.
After a lot of researching around, I found the solution. Probably a specific case, since my computer has just one Ethernet card and I want to use both the links simultaneously on the same computer.

The network setup scenario:

  • There’s a main router (NAT, DHCP Enabled), which has WAN port, WiFi and LAN ports with IP Address 192.168.0.1
  • There’s another WiFi router (which is used in WDS Bridge mode) with IP Address 192.168.0.2
  • The ADSL Router (NAT Enabled, DHCP disabled) has IP Address 192.168.0.3  and is connected to main router’s LAN port, since fiber must be connected to WAN port for PPPoE connection.
  • An Ethernet Switch is wired to the second WiFi router.
  • The Linux box is connected to the Ethernet Switch.

I setup two IP Addresses on the Linux box: 192.168.0.4 and 192.168.0.5 as follows:

# ifconfig eth0 192.168.0.4
# ifconfig eth0:1 192.168.0.5

Now, I want to route all traffic originating from 192.168.0.4 (the default IP Address for eth0) via fiber, and all traffic originating from 192.168.0.5 via ADSL Router.
To accomplish this, I use policy based routing (CONFIG_ADVANCED_ROUTER must be enabled in kernel configuration) using iproute2.

Routing:

We need to create a new table which will be looked up if traffic is from the second IP and otherwise use the default route.
And then the policy routing rule which specifies that if traffic is from second IP, lookup the other table.

# echo 10 adsl >> /etc/iproute2/rt_tables
# ip route add default via 192.168.0.1
# ip route add default via 192.168.0.3 table adsl
# ip rule add from 192.168.0.5 table adsl

And you’re done. Traffic from applications using 192.168.0.4 (it will be used as default, if you don’t specify anything) will get routed through 192.168.0.1 and those who use 192.168.0.5 will get routed through 192.168.0.3.
As a simple test, you can do this:

$ curl text.whatisyourip.org
$ curl --interface 192.168.0.5 text.whatisyourip.org

That should give you two different IP Address, the first one your Fiber’s public address and the second one your ADSL’s public address.
If that works, you can add the routing code to run at startup or may be even in system network configuration. Every Linux distribution has it’s own way of doing that, so I won’t cover that. If you’re a Gentoo user, you can add it in /etc/conf.d/net as follows:

config_eth0="192.168.0.4/24 192.168.0.5/24"
dns_servers_eth0="192.168.0.1"
routes_eth0="default via 192.168.0.1
default via 192.168.0.3 table adsl"

postup() {
        if [ "${IFACE}" == "eth0" ]; then
                ip rule | grep 192.168.0.5 &> /dev/null
                [ $? -ne 0 ] && ip rule add from 192.168.0.5 table adsl
        fi
}

Now, many applications like Firefox, Chrome, etc. don’t support listening/using to a specific interface/IP Address. There’s a simple solution for the problem I found on Daniel Lange’s Blog.
All you have to do is, download this libc wrapper and compile it as follows:

$ gcc -nostartfiles -fpic -shared bind.c -o bind.so -ldl -D_GNU_SOURCE

Once you have done that, you can use it as follows:

$ LD_PRELOAD=bind.so BIND_ADDR=192.168.0.5 firefox

If you visit text.whatisyourip.org from there, you should see your ADSL public IP. For applications which support binding to a specific address, just configure it do so.

3 Comments on “Routing for multiple ISP links on Linux”

  1. Instead of doing all this manually, you can also use ISP Unity.

    isp-unity which is a gem for managing multiple heterogeneous (broadband, wifi, lease line, data-card etc) connections from multiple internet providers. This also has advanced features like quality of service (QoS) for scheduling, prioritizing of traffic and managing bandwidth.

    http://rubygems.org/gems/ispunity

    Like

Leave a Reply to Chaitanya Parekh Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: