Some years ago, when I worked at the Hospital of Pediatric Specialties in Maracaibo, I did a project that would update routing for our multi-link internet connection when there was a DHCP event. I decided to redo the whole thing using a simpler approach plus I would release the code without asking for permission (as it's mine now) under Affero GPLv3.
So, you have read lartc's guide on 'Routing for multiple uplinks/providers' and it all makes sense (and does work). However, there's a catch for you: Instead of having static network configurations, your ISPs use DHCP to set your network connections and you don't intend to sit all day long waiting for DHCP event to happen to reconfigure the whole thing, do you? That's what I thought.
In order to solve the problem I just described I created dhcp-lb. It's a python script that, once configured and linked as a dhclient exit hook, can listen to dhcp events and reconfigure networking accordingly.
What I need
You need python, dhclient, iproute2 (that I think will come by default in almost every distro) and a multipath-enabled kernel (check for CONFIG_IP_ROUTE_MULTIPATH, I think).
How to get it?
Right now, the only way to get it is through bazaar from launchpad's branch I set for it. I have created a PPA, but I have to learn how to use it so be patient (maybe someone can help me in this journey). If you want it but don't want to use bazaar to get it, email me and I'll gladly send you a tgz with it.
Configuring it is fairly simple. You need to create a file called /etc/dhcp-lb with the configuration of each link involved in the multilink default route. Each line has the configuration of each link and it has four fields (so far):
- Network Interface
- Routing Table for that interface
- Routing Table ID (numeric, less than 255... check /etc/iproute2/rt_tables)
- Weight (numeric, more than 0)
All 4 fields have to be separated by exactly a single white space at this time. One example /etc/dhcp-lb file would look like this:
# interface routing-table table-id weight
eth0 table-eth0 200 1
wlan0 table-wlan0 201 2
In this example I set wlan0 to have twice the routing weight of eth0 (for example, eth0 is 512 kbps and wlan0 is 1 mbps). Also, if the routing tables are not set in /etc/iproute2/rt_tables, dhcp-lb will take care to add them to that file, so no need to change rt_tables beforehand.
After you have done that, all you need to do is link /usr/bin/dhcp-lb into the exit hooks directory (/etc/dhcp3/dhclient-exit-hooks.d in my case) and you are done. Restart the network service and it should start working right away.
Keep in mind
dhcp-lb only configures routing with multiple uplinks and it doesn't correct any of the shortcomings that come along having multiple uplinks. It only reconfigures routing with dhcp events. What are the shortcomings? That would require a blog posting of its own, but this is the most noticeable (at least, to me):
- Balancing works beautifully for multiple short connections from your LAN. Few long connections? It won't look like it's balancing at all. It's because of the way routing works. The kernel doesn't make a routing decision for every packet that goes out of a box. Instead, it uses a routing cache to associate a target IP with the network interface it chose to use to get to it so it doesn't have to make a routing decision again... and the cache lasts for a few minutes (run this command: ip route show cache to take a look at the actual cache). After a while, it can decide to send packets to that same host through another network interface possibly breaking connections established to that host cause the other host will start receiving packets from a different address.
I hope this project helps you. However, this project is (as you can see from the logs) very young so expect it to have some problems (that I'll be working to solve). Have patches for it? Please, send them without hesitation. I'm open to suggestions and donations if you consider I deserve any.
I just released dhcp-lb 0.02 (sep 9th 2009). Check this post to learn more about it.