802.11s Wireless Mesh Network

Overview

Originally the 802.11 WiFi standards defined two modes of operation, “ad-hoc” and “infrastructure”. The 802.11s amendment introduces another mode: mesh networks. The distinguishing feature of mesh networks is that each node is able to forward 802.11 frames to other nodes, potentially extending the range of the overall network. This is different from “infrastructure mode” where all nodes communicate via a central Access Point.

WLAN modes

Nodes in a wireless mesh network may be mobile and it is the task of a (OSI layer 2) mesh routing protocols to continuously determine the optimal path between any two mesh nodes. The 802.11s document mandates the Hybrid Wireless Mesh Protocol (HWMP) as the standard routing protocol but others can be implemented.

In this document I am going to describe how to configure a small wireless mesh network based on the open80211s implementation on a few RaspberryPi.

Hardware & Software

The following hardware and software was used for this experiment.

Configuring open80211s

In this section I am going to focus on how to get an 802.11s mesh network up and running using the open80211s software. open80211s is an open-source implementation of the recently ratified IEEE 802.11s wireless mesh standard. The project’s Wiki page provides a lot of background information about 802.11s and the steps summarised in this document are based on the Wiki page.

The 2016-05-27-raspbian-jessie-lite.img version of Raspbian serves as the base for my experiments with the open80211s software. It is good practice to update the distribution first.

$ sudo apt-get update
$ sudo apt-get dist-upgrade
$ reboot

$ uname -a
Linux yellow 4.4.13+ #894 Mon Jun 13 12:43:26 BST 2016 armv6l GNU/Linux

Kernel support

The WiPi USB WLAN adapter uses a RT5370 chip which is supported through the RT2800 driver. Most importantly is uses the mac80211 module which is a pre-requisite for open80211s to work.

$ lsusb
Bus 001 Device 005: ID 148f:5370 Ralink Technology, Corp. RT5370 Wireless Adapter
...

$ sudo modprobe rt2800usb

$ lsmod | grep 2800
rt2800usb              18877  0
rt2800lib              82155  1 rt2800usb
rt2x00usb              12680  1 rt2800usb
rt2x00lib              48998  3 rt2x00usb,rt2800lib,rt2800usb
mac80211              608549  3 rt2x00lib,rt2x00usb,rt2800lib
crc_ccitt               1732  1 rt2800lib

In my setup, the WiPi adapter appears as the wlan1 interface.

$ iwconfig
...
wlan1     IEEE 802.11bgn  ESSID:off/any
          Mode:Managed  Access Point: Not-Associated   Tx-Power=20 dBm
          Retry short limit:7   RTS thr:off   Fragment thr:off
          Power Management:off

Creating a wireless mesh network

As long as there is kernel support for the WLAN adapter, and the adapter supports ‘mesh’ mode, creating a wireless mesh is fairly straightforward. It involves the following steps.

  1. Defining a mesh interface name (mesh0 in the example below) and setting a mesh_idi. The mesh identifier has a similar purpose to the SSID in a “normal” WLAN.
  2. Setting the channel. The WiPi adapter only supports the 2.4 GHz band and after doing a site survey I decided to use channel 4.
  3. Shutting down the wlanX interface and bringing up the mesh0 interface instead.
  4. Assigning an IP address.
$ sudo iw dev wlan1 interface add mesh0 type mp mesh_id MYMESHID
$ sudo iw dev mesh0 set channel 4
$ sudo ifconfig wlan1 down
$ sudo ifconfig mesh0 up
$ sudo ip addr add 10.1.100.10/24 dev mesh0

In my lab, I created a wireless mesh network as shown below. Let’s see whether all nodes are visible.

pi@yellow$ cat /etc/hosts
127.0.0.1    localhost yellow
10.2.1.51    blue-mesh
10.2.1.52    white-mesh
10.2.1.53    yellow-mesh
10.2.1.54    red-mesh

pi@yellow$ fping white-mesh red-mesh yellow-mesh blue-mesh
white-mesh is alive
red-mesh is alive
yellow-mesh is alive
blue-mesh is alive

There are a few commands that display status information about the mesh. The station dump command displays all neighbouring mesh nodes.

pi@yellow$ sudo iw dev mesh0 station dump | grep Station
Station 40:a5:ef:0f:41:ef (on mesh0)
Station 40:a5:ef:0f:4b:e3 (on mesh0)

The output of the mpath dump command shows the current HWMP routing table. Note how node 40:a5:ef:0f:46:df is reached via 40:a5:ef:0f:41:ef as it did not show as a neighbour node in station dump.

pi@yellow$ sudo iw dev mesh0 mpath dump
DEST ADDR         NEXT HOP          IFACE    SN      METRIC  QLEN    EXPTIME         DTIM    DRET    FLAGS
40:a5:ef:0f:4b:e3 40:a5:ef:0f:4b:e3 mesh0    2       8769    0       0       0       0       0x14
40:a5:ef:0f:41:ef 40:a5:ef:0f:41:ef mesh0    5       8577    0       0       100     0       0x14
40:a5:ef:0f:46:df 40:a5:ef:0f:41:ef mesh0    11      18786   0       0       200     1       0x4

Because bitrate most links have a fairly weak signal, the bitrate is slow. This is reflected in the approximately 500 Kbits/sec bandwidth reported by iperf.

pi@yellow$ sudo iw dev mesh0 station dump | grep bitrate
     tx bitrate:     1.0 MBit/s
     rx bitrate:     1.0 MBit/s
     tx bitrate:     1.0 MBit/s
     rx bitrate:     1.0 MBit/s

Security

Note Unfortunately this currently does not work with the rt2800 driver (https://github.com/cozybit/authsae/issues/34).

Currently the released version of wpa_supplicant does not support mesh mode. 802.11s requires the “Simultaneous Authentication of Equals (SAE)” protocol with is implemented in the (https://github.com/cozybit/authsae) project. Unfortunately this package must be installed manually and has a few dependencies.

$ sudo apt-get install cmake libssl-dev libconfig-dev libnl-3-dev libnl-genl-3-dev
$ git clone https://github.com/cozybit/authsae
$ cd authsae
$ make
$ sudo make install
$ ls /usr/local/etc/authsae.cfg /usr/local/bin/meshd* /usr/local/bin/mon
/usr/local/bin/meshd
/usr/local/bin/meshd-nl80211
/usr/local/bin/mon
/usr/local/etc/authsae.cfg

The README explains the different settings in /usr/local/etc/authsae.cfg. Once configured, start meshd-nl80211 as follows:

$ sudo meshd-nl80211 -c /usr/local/etc/authsae.cfg -o /var/log/meshd.log -B

Routing between wireless mesh and LAN

A wireless mesh node that connects to a non-mesh network is called a Mesh Point Portal (MPP). Most documents describe how a Mesh Point Portal is used to bridge the mesh and the non-mesh networks. I am going to describe this in the next section. First I explain how one can make the Mesh Point Portal a router connecting both networks.

Configure VRRP on nodes yellow and white

pi@yellow$ sudo apt-get install keepalived

pi@yellow$ sudo vi /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
    state MASTER
    interface mesh0
    virtual_router_id 100
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass mypasswd
    }
    virtual_ipaddress {
        10.2.1.1
    }
}

I decided to start keepalived from the command line. After a few seconds the mesh0 interface will have been assigned the 10.2.1.1 address.

pi@yellow$ sudo systemctl stop keepalived

pi@yellow$ sudo keepalived -f /etc/keepalived/keepalived.conf --vrrp

pi@yellow$ ip add li mesh0
5: mesh0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 40:a5:ef:0f:54:5a brd ff:ff:ff:ff:ff:ff
    inet 10.2.1.53/24 scope global mesh0
       valid_lft forever preferred_lft forever
    inet 10.2.1.1/32 scope global mesh0
       valid_lft forever preferred_lft forever

The same steps must be performed on node white, with the only difference that the priority setting in the configuration file must be different.

Configure dynamic routing on nodes yellow and white

For the purpose of simplicity I’ll be configuring RIPv2 as this is the only protocol my (consumer grade) Internet Router supports.

pi@yellow$ sudo sysctl net.ipv4.ip_forward=1    # enable forwarding
pi@yellow$ sudo apt-get install quagga
pi@yellow$ sudo vi /etc/quagga/daemons
zebra=yes
...
ripd=yes

pi@yellow$ sudo vi /etc/quagga/zebra.conf
hostname yellow

pi@yellow$ sudo vi /etc/quagga/ripd.conf
router rip
  network eth0
  redistribute connected

pi@yellow$ sudo systemctl start quagga

Configure the default gateway on red and blue

This step is straightforward, e.g.

pi@blue$ sudo route add -net default gw 10.2.1.1
pi@blue$ route -n
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.2.1.1        0.0.0.0         UG    0      0        0 mesh0
10.2.1.0        0.0.0.0         255.255.255.0   U     0      0        0 mesh0

Now I can ran a full traceroute to the Internet.

pi@blue$ sudo traceroute -I 150.101.213.146
traceroute to 150.101.213.146 (150.101.213.146), 30 hops max, 60 byte packets
 1  yellow-mesh      3.668 ms   3.480 ms   3.465 ms
 2  10.1.1.1         3.430 ms   3.367 ms   3.453 ms
 3  150.101.32.128  14.801 ms  16.476 ms  17.640 ms
 4  150.101.35.165  18.812 ms  24.582 ms  24.557 ms
 5  150.101.40.134  24.444 ms  20.036 ms  19.048 ms
 6  150.101.213.146 16.619 ms  14.815 ms  14.666 ms

Initially the packets will be routed via yellow as it currently holds the VRRP address for the default gateway. If node yellow becomes unavailable, the VRRP address will move to node white.

The main disadvantage of a routed solution is that the mesh nodes will send all non-local traffic to the Portal that is currently the default gateway. It is not possible to load-balance between multiple portals. In large mesh topologies this may be a major disadvantage.

Bridging the wireless mesh and the LAN

The alternative to routing between a mesh and a non-mesh network is bridging them.

Sorry, I did not manage to make this work!

802.11s

The following links were useful sources of information.

Other Wireless Mesh Protocols

Apart from 802.11s there are a couple of alternative protocols implementing wireless mesh networks.