Background

Ubiquiti makes a line of highly integrated routers that are basically small, outdoor Linux machines with an 802.11a/n radio and a wired nic, some also come with a built in antenna, which makes setting up a long-distance outdoor network really easy and cheaply.

At NrVissing.Net which I do tech for we now have 15 Access points and 60 CPEs, all of them Ubiquiti NanoStation 5, Loco 5 or Bullet 5. The APs are placed at 4 different physical locations and linked via 802.11a.

The problem that OSPF solves

The Ubiquiti gear works really well, but there's no redundancy, which means that I'm only one breakdown away from having 60 angry, Internet deprived neighbors. Another problem is that maintaining the routing is quickly becoming harder as more bits of network appears. The solution, as you might have guessed is called OSPF.

OSPF allows routers to figure out which links exist in the network topology for them selves and set up several routes that allow the kernel to balance the traffic between several routes and take down routes that have failed.

Implementing OSPF on Linux with Quagga

For Linux there is a popular package called Quagga, which has already been ported to openwrt, which AirOS V is based on, so adding it to the AirOS SDK was easy enough.

Inveneo did much the same work for the older non-openwrt-based AirOS, so for the older AirOS versions I've been using a solution based on their work.

Implementing OSPF on Linux with BIRD

Some people swear by BIRD, so I thought I'd take a stab at using it on AirOS, some random thoughts in this regard:

It's really sad that there's no multipath support, but I left the BIRD package in for when someone implements multipath support or in case somebody else can do without multipath.

Dealing with the existing non-OSPF routers: CARP

I don't expect to be able to replace all the existing non-OSPF APs all at once, but I'd still like them to keep working if their default gateway goes down, for this I'm using CARP as implemented by the portable UCARP daemon to automatically switch the default gateway IP from one of the OSPF-enabled uplinks to another. Nobody has ported and published an openwrt port of ucarp before me, so for this bit I had to start from scratch.

Contents

What you get with my firmware mod are the following ingredients:

ComponentVersionWhat it is
AirOS 5.1 or 5.1.2 SDKExact version downloaded directly from ubnt.com
Quagga 0.99.15-19137Revision 19137 of quagga-unstable is checked out from openwrt via svn
UCARP 1.5.1Exact version downloaded directly from the main ucarp site and checked
BIRD 1.2.1Exact version downloaded directly from the bird site and checked.
saveconfign/aA small script that does: 'cfgmtd -w -p /etc/'.
Patches 2010-02-23Patches to build and hook into the ubnt init.

Releases

VersionChanges
2010-01-30Initial release.
2010-02-10Configured Linux with multipath (aka. ECMP) support, without it routes would disappear if Quagga could see more than one route.
2010-02-14Ported BIRD 1.2.1 and added saveconfig.
2010-02-21Disabled the buggy and OOPSy CONFIG_IP_ROUTE_MULTIPATH_CACHED kernel option, multipath routing now works correctly.
2010-02-23Updated to SDK 5.1.2 and added a README file, no other changes.

Getting and building the firmware

Rather than do all the work and distribute the resulting image, I'm publishing a small perl script which will do all the downloading, patching and building needed to get the finished image in about half an hour on a reasonable 64bit ubunutu 9.10 machine. Distributing the modification this way allows anybody to modify the parts they need and as it's a fairly minimal set of diffs, it allows me to upgrade the solution to a newer version of AirOS much easier.

  1. Download airos-plus.tar.bz2 [12K]
  2. Unpack the tarball by running something like: tar xfv airos-plus.tar.bz2
  3. cd to the created directory: cd airos-plus/5.1.2
  4. If you have already downloaded the SDK run: ./plus path/to/SDK.UBNT.v5.1.2.tar.bz2
  5. If you don't have the SDK just run: ./plus get
  6. If you are missing any of the OS tools you need to build the firmware, the script will try to use sudo apt-get install ... to install the packages.
  7. Wait while the firmware is built.
  8. If all goes well you will end up with a new firmware file called something like: XM.ar7240.v5.1.plus-2010-02-10.3635.100210.2039.bin that you can update your M-series Ubiquiti router with.

Configuring Quagga

Once the firmware has been installed you need to configure at least Quagga, without it the daemons will not be started. The two files zebra.conf and quagga.conf mentioned in the Quagga documentation must be placed in /etc/persistent rather than /etc/quagga and once they've been written, the files need to be written to flash using: cfgmtd -w -p /etc/ saveconfig

Quagga will start at boot when the /etc/persistent/zebra.conf and /etc/persistent/ospfd.conf files exist, but it can also be stopped and started using the quagga.init script.

Getting AirOS routes out of the way

No routes should be configured in AirOS, not even the default route, because those routes will not be distributed by OSPF and they will interfere, to get AirOS to stop creating any routes, set:

route.1.gw=
route.1.status=disabled

Example zebra.conf

This is the zebra.conf file from one of my backbone routers that provides access to some non-OSPF enabled routers, once all the routers are running OSPF, these static routes can go away:

password zebra
access-list vty permit 127.0.0.0/8
access-list vty deny any
line vty
 access-class vty

ip route 10.102.1.0/20 10.102.0.1
ip route 10.102.32.0/20 10.102.0.2
ip route 10.102.48.0/20 10.102.0.3
ip route 10.102.64.0/20 10.102.0.4
ip route 10.102.80.0/20 10.102.0.5
ip route 10.104.0.0/16 10.102.0.1
ip route 10.105.0.0/16 10.102.0.2

Example ospfd.conf

This is the ospfd.conf file from one of my backbone routers, it's actually the same on all the Ubiquiti routers.

password zebra
access-list vty permit 127.0.0.0/8
access-list vty deny any

line vty
 access-class vty

router ospf
 network 10.100.0.0/16 area 0
 network 10.102.0.0/24 area 0
 network 10.103.0.0/24 area 0
 redistribute connected
 redistribute static

area 0 authentication

interface eth0
 ip ospf authentication-key love
 ip ospf dead-interval 5
 ip ospf hello-interval 1

interface ath0
 ip ospf authentication-key love
 ip ospf dead-interval 10
 ip ospf hello-interval 1

log syslog

This ospfd.conf works, but it's cobbled together from several incomplete pieces of documentation and unexplained examples, so I can't figure out why the ospf authentication-key statement has to be part of the interface section, when the password is area specific.

Configuring BIRD

BIRD will only be started if /etc/persistent/bird4.conf exists, upload your config file with scp or edit it in-place with vi, run saveconfig and start bird with bird.init start. Notice that BIRD is not built by default, so you must use make menuconfig to turn it on in the openwrt directory.

Configuring UCARP

UCARP is configured by a simple shell script named /etc/persistent/ucarp.conf, there is an example version of this file located in SDK.UBNT.v5.1.2/openwrt/package/ucarp/files/ucarp.conf once the script has patched it into the SDK. This is the example file:

# Usage for AirOS: 
# 1) Edit this file and copy it to /etc/persistent/ucarp.conf
# 2) Run: ucarp.init test
# 3) Run: cfgmtd -w -p /etc/ && reboot

# Interface to run CARP on
IF=br0

# Virtual IP shared with the other system
VIP=10.0.0.117

# Size of the network mask for the virtual IP
VMASK=24

# Real, static IP of this host
MYIP=192.168.1.20

# Password shared with the other system
PASSWORD=love

# IP addresses to arping after taking over the shared IP,
# you should list all known systems, those not listed can
# take up to a minute to notice the change.
PINGIP="10.0.0.1 10.0.0.20"

Tip jar?

I don't have a tip jar, but if you found something on this page useful then feel free to buy me a book from my Amazon wishlist.

© Flemming Frandsen - Worst viewed with MSIE, because it sucks. - Firefox is ok though. - stopsoftwarepatents.eu petition banner