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:

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.

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:

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:

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:

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

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.

  • Ershad K

    Informative. Thanks, Nilesh!

  • http://twitter.com/gaurish Gaurish Sharma

    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