Life with two PPP links

By Abhijit Menon-Sen <ams@toroid.org>

2009-07-13

We have DSL service from two ISPs: MTNL (purchased in 2006, when they were the only provider in the area) and Airtel (purchased in 2009 during a week-long outage on the MTNL line). By coincidence, both ISPs gave us UT Starcom UT-304R2 modems (but with different packaging and firmware); these are configured as bridges, and I have two PPPoE interfaces set up on my Linux gateway.

I used to let pppd set a default route through whichever link happened to come up first at boot, and would switch the route by hand when that link went down. That strategy proved remarkably short-sighted when I found myself unable to access my home network from the outside because the gateway lacked a functioning default route. Last weekend, I spent a few minutes making sure I wouldn't be left stranded ever again. Here's a quick summary.

When a PPP link is established, I want to add a default route through it if there isn't a default route already. When a link goes down and takes the default route with it, I want to switch the route to the other link. (If both links are down, there's nothing to do but wait for one to come up and establish a new default route). In both cases, I want to do a dynamic DNS update when I add a new default route. To this end, I created a /etc/ppp/defaultroute script.

#!/bin/bash

IF=$1

# If there's a default route, exit.
/sbin/ip route list|grep -q "^default " && exit

# If we can't establish a new default route, exit.
/sbin/ip route add default dev $IF || exit

/etc/ppp/dynamic-dns $IF

On my Ubuntu system, pppd(8) runs /etc/ppp/ip-up and /etc/ppp/ip-down after a PPP link is brought up or torn down and they, in turn, run the scripts in /etc/ppp/ip-up.d and /etc/ppp/ip-down.d respectively, with the interface name as the first argument. I told pppd to keep its hands off the default route ("nodefaultroute" in /etc/ppp/options) and created /etc/ppp/ip-up.d/00link and /etc/ppp/ip-down.d/00link to call my script.

#!/bin/sh
/etc/ppp/defaultroute $1
#!/bin/sh

if [ $1 = "ppp0" ]; then
    OF=ppp1
else
    OF=ppp0
fi

/etc/ppp/defaultroute $OF

(It's worth noting that ip-down.d/00link is called when the interface is already down, so no "does the default route point to us?" test is necessary. If it did, the route went down with the interface.)

Someday I will set up policy routing so that I can use both links together. But, for now, I am satisfied with having the correct default route set without my intervention.