Intro

I do tech for NrVissing.Net, we are a very small community owned WISP. We have been using 2.4 GHz (802.11g) equipment for the last 4 years, but as everybody got APs of their own contention grew to the point where the 50+ APs in town virtually silence our traffic because of noise and CSMA-backoff. The solution to a croweded spectrum is to stop using it, so I have been on the hunt for cheap 5GHz (802.11a) CPE for a while, happily Ubuiquity has come out with a very nice solution for us: The NanoStation5 and NanoStation5 LOCO, this page is contains my thoughts on these units, but it's not a technical reference or a sales pitch so I'll try not to repeat anything that can be found elsewhere.

Price

We buy our Ubiquiti gear from Wifi-stock or interprojekt and I'm happy to report that both companies are nice to deal with and that the Ubiquiti "Crazy Lo-Cost" claim holds over to their prices, with VAT (18%/22%) and other fees the price of a NS5 LOCO is only 79.8 USD, which is quite a good price.

Hardware

The good points are many:

There aren't many problems with the hardware and they are relatively minor:

Power requirements

The datasheets are curiously vague on the voltage range and power requirements of the devices, so I'm doing my own measurements, my results are:

DeviceMin VMax VIdle WBusy W
NSL54241.82.8
B5 4.5241.92.9
NS5 4242.65.0

The NS5 is a little different than the others, if the voltage is too low and it raises slowly then the PSU will lock up and the unit will never boot, but if power raises quickly then the NS5 will power on with as little as 3.5 V.

The max voltage is not measured (increase voltate to just before the smoke comes out), but Ubiquiti were nice enough to print DC power 24V Max on the Bullet5 and the 36 V capacitor in the PSU section of the NSL board also seems to suggest that 24 V is safe.

I have found two NS5s (out of 15) that stop working when fed more than 22 V, it seems to be a problem with the power supply, the units come to life again when the voltage is back under 22 V, so nothing is getting fried.

Firmware: AirOS

The firmware on the ns5 is the first I've seen on such a device that didn't give me an immediate urge to claw my eyes out and replace it with something else, in other words: It's really quite good.

AirOS is Ubiquitis flavor of Linux and almost all features including user passwords are set via the web interface and can easily be exported to a simple configuration file, which is quite handy as there is a very nice upload configuration option that makes provisioning new units a breeze.

AirOS lacks only very few features that I've been able to find while working with it:

Configuration

All options supported by the firmware are exported in a simple configuration file, this is absolutely brilliant as it makes automated configurations very easy, this is the procedure I used:

  1. Configure a unit as I normally would with all the needed features turned on.
  2. Export configuration to a file.
  3. Generate a new configuration based on the exported one using a small script that calculates or looks up the values that should be changed.
  4. Use another script to upload the specialized configuration to a factory fresh unit.

The units have a reset button that loads the factory default config, this means that any unit can be recycled just by resetting it and going though the provisioning procedure as I would with a brand new unit.

Range Performance

This table shows the expected worst case signal margin for different combinations of Ubiquiti gear at 54 Mb/s with a huge margin of 13 dBm, iow, when the values in the table says 0 that means that the received signal strength is at least -59.5 dBm or 20 times higher than needed for 54 Mb/s operation.

Each number in the bottom part of the table is calculated as rxsignal - margin - sensitivity, so zero means that there is exactly 13 dBm more signal than the receiver sensitivity limit at 54 Mb/s.

Both sensitivity and transmit power are the datasheet values @ 54 Mb/s, I've substracted 1.5 dBm from sensitivity to account for the the tolerance of +/- 1.5 dBm of both these values.

The results from this table seem to hold up pretty well with real-world experiments, if you'ld like to mess about with the numbers take a look at the spreadsheet: ubiquity-link-budget-v3.ods [36K].

Automated firmware upgrades and configuration

I have automated the firmware upgrade and configuration of our Ubiquiti units via the web interface.

The firmware upgrade script I use is part of this package: ubnt-scipting.tar.gz [20K], it upgrades the firmware on the ns5/ps5/b5 unit with the default address and default username/password, this ensures that I don't accidently upgrade a unit which is in production.

Upgrading takes about 130 seconds and is completely automatic. The script has only been tested on Kubuntu 8.10, but it should work unmodified on any Linux and with slight modification on any other OS.

The scripting package content

The IP allocation and configuration

The scripting package assumes that you have a maximum of 15 APs pr. tower/switch, a maximum of 15 stations on each AP and a maximum of 253 clients on the wired side of each station, if those constraints bother you then you have to dig into the code to make it work the way you want.

Wired PoP net

The layout of addresses is: pop: Point of presence id. (100..253), ap: Access point 1..15

Wireles AP net

For each AP there is a wireless network: wl = ap << 4;

Wired Station net

Each station provides access to the customer network, sta: station id (1..15), un = ap << 4 + sta

License

You are free to use the scripting package for whatever you want under the GPL, if you do something interesting with it, please let me know.

Compiling the firmware

The NS-type (aka XS) devices do not allow you to change the files in the filesystem, so to add any software you need to build and install a completely new firmware image.

Ubiquiti has wisely chosen to release an SDK package that allows customers to modify and compile most of the software in the XS devices, all that's needed is a bog-standard 32 bit Ubuntu 8.10 or 8.04 machine with the mips toolchain installed, a 64 bit machine can also be used by applying enough force when installing the toolchain.

Ubuntu doesn't have a mips toolchain, but Ubiquiti supplies one on their AirOS support page along with binary firmware and source (aka SDK) downloads.

Compiling the firmware is a simple matter, but there is one small problem with the firmware tools that fail to include limits.h, Ubnt has fixed the issue in the next version of the firmware, but until then my basic fixes are contained in this diff: SDK.UBNT.v3.3.2.4257-compilefixes.diff [12K].

Adding Quagga, aka. OSPF support

Once your network starts growing you quickly run into trouble with maintainance of the routing tables throughout the network, OSPF allows the routers to figure out the routes from their own static routes and by talking to their neighbors. OSPF responds to dynamic changes, like the downing of an interface or a router and within seconds the routing tables are updated throughtout the network, possibly routing around the problem entirely, if there are redundant links available.

Quagga seems to be the best Free OSPF implementation at the moment, and it was very easy to configure in my kvm lab, so it was my choice from the beginning.

AirOS doesn't come with Quagga or any other OSPF support so I went to UBNTs excellent forum to see if anyone else had solved that particular problem, while looking though the forum I ran into Jeff Wishnie from Inveneo, do watch the 9 minute CNN documentaty from that last link, I'll wait.

Jeff has added Quagga to AirOS, so all I needed to do was to apply his Quagga changes to the latest released AirOS version and get it compiled.

What I did was basically to unpack the SDK, patch it to fix the compile problems and then run:

svn merge -r27:HEAD http://svn.inveneo.org/repos/ubnt/branches/ubnt-lsX-SDK-v3.2.3743

Verifying the SDK source

The firmware image that is generated using the SDK ought to be exactly the same as the one that UBNT ships, otherwise there are no guarantee that my toolchain is correct or that it's actually the correct source we have, so I was quite unappy that the generated firmware image ended up at 2816498 bytes vs. the 3014926 bytes of the official firmware.

To figure out what the difference is it's necessary to do a bit of reverse engineering.

Splitting the original and the SDK generated firmware using the fwsplit utility from the SDK yields the following files:

File name SizeSize in SDK output Comment
XS5.ar2313.v3.3.2.4257.090214.1458.txt 299198 Map of the image, with the same numbers except for the bootloader that's not in the SDK version.
XS5.ar2313.v3.3.2.4257.090214.1458.RedBoot181960- The bootloader which is missing from the SDK, fine with me as not overwriting the bootloader is what will keep clumsy SDK users from bricking their units back to the stage where only several hours with JTAG can save it.
XS5.ar2313.v3.3.2.4257.090214.1458.kernel 497774497754 The Linux kernel lzma compressed, the only differences in the uncompressed files are timestamps and paths.
XS5.ar2313.v3.3.2.4257.090214.1458.cramfs 23347202318336 The actual file system, with 16384 bytes missing, not a whole lot, but it still might be bad so it warrants more detailed investigation.

It's slightly interesting to notice that the ubnt kernel was built on a machine called devint (development integration perhaps?) in a directory called /home/ubnt/build/litestation-3.3.1 (the XS series started out with the litestation line, so that makes sense) at Sat Feb 14 15:00:57 EET 2009, the timestamp and the build directory seem to indicate that the kernel was built for the previous release, so the 3.3.2 release was probably a minimal bugfix release where only the fixed binaries were updated, leaving the kernel as it was.

The contents of the cramfs image had some differences as expected from the differing sizes:

The mysterious devint module

The file called /lib/modules/devint.o exists in the official UBNT firmware, but not in the SDK, running strings on it, yields:

kernel_version=2.4.27-ubnt0
author=kaleda. UAB "DevInt"
license=GPL
description=Provides /dev/int interface
device=/dev/int
Greetings from /dev/int crew!
You have found us :)
<4>You betta don't do it!
<3>failed to register /dev/int

It seems this module is an easter egg from the developers at UBNT that simply outputs Greetings from /dev/int crew! You have found us :) to people who read /dev/int

A quick look at the disassembly of the module reveals that it doesn't seem to call into any kernel functions at all, so when UBNT says it's harmless, I'm inclined to trust them on that.

What to do about the differences

All the differences in the SDK generated binaries and the binary firmware are explainable by the slight difference in build hosts used and will probably not mean anything in real-world use.

However it's still different enough to make me skittish about doing a large deployment with modified firmware built this way.

The only way I could feel safe doing deployments is to modify the SDK to be able to do bit-perfect builds and only then start adding my own changes on top of that.

My approach will be to use the SDK to build the entire firmware, but in stead of building a firmware image from the SDK as intended by UBNT, I'll unpack the original firmware and add in only the files I know I need to change, that way my changes will be truely minimal. With any luck I can apply my changes to an updated binary firmware image even before the SDK for that firmware is available.

Patching the firmware

This is my super-conservative firmware building procedure:

  1. Follow the UBNT instructions on setting up a build environment (install Ubuntu 8.04 or 8.10, install the mips toolchain they provide)
  2. Download the original XS5 firmware binary and the SDK from The UBNT AirOS support page
  3. Apply the compile fixes SDK.UBNT.v3.3.2.4257-compilefixes.diff [12K] in case you are running a newer host OS than Ubuntu 8.04.
  4. Build the firmware from the SDK by cd'ing to the directory and typing: make xs5
  5. Download and unpack my firmware tools package in the parent directory of the SDK directory: airos-fw-tools.tar.gz [12K]
  6. Copy the mkfwimage and fwsplit executeables into the same directory: cp SDK.UBNT.*/tools/bin/*fw* .
  7. Edit the patch-fw script, it's important that you understand the first 45 lines and adapt them to your needs.
  8. Run patch-fw

The patch-fw script will unpack the original firmware image, then copy over just the needed files from your SDK directory and finally create a new firmware image, this ensures that the difference between the UBNT firmware and your patched firmware are well-known and minimal.

This procedure is not really needed once you are confident that your build environment is sane, but it could be helpful in the situation where Ubnt has come out with a version of the firmware, but not yet released the SDK.

Scripting batch operations

I have written a few scripts for scripting batch operations on AirOs, they are all licensed under GPL and available here: airos-scripts.tar.gz [12K]

To run the scripts you need perl with WWW::Mechanize, on Debian like OS'es like (k)ubuntu simply run: sudo apt-get install libwww-mechanize-perl, it's a little harder on Windows where you first have to download and install ActivePerl from ActiveState and then run ppm to install the WWW::Mechanize module.

If you found something on this page useful then please buy me a book from my Amazon wishlist.

© Flemming Frandsen