Thursday, April 16, 2015

Linux RPL Router - improvements

In my previous post I wrote about an experimental Linux RPL router running on RaspberryPi using RPL code from Joao Pedro Taveira's linux-rpl. I encountered some problems with using the router, and I would like to share some advice on solving these problems.

Status of current 802.15.4 development

Linux 802.15.4/6LoWPAN support has been moved again. Currently the development is happening in bluetooth-next repository. The name might be a little confusing - repo contains 6LoWPAN code for both Bluetooth and 802.15.4. In general everything that has been done in old linux-wpan-next repo still works, which is a good thing :)

I pulled RPL code from linux-wpan-next repo to a clone of bluetooth-next repo - you can download it at GitHub, branch feature-rpl. All instructions for compilation and running RPL are still valid.

Also Alex Aring gave a speech about 802.15.4 in Linux on FOSDEM in Bruxelles. You can check the video here.

Problems with ifplugd

After recent changes wpan0 interface is created automatically during system startup. If you are using RaspberryPi with Raspbian this might lead to a problem with ifplugd daemon. This program always keeps wpan0 interface up and it will prevent you from changing some interface parameters like PAN ID. To solve the problem you need to modify /etc/default/ifplugd file to look more or less like that:
# This file may be changed either manually or by running dpkg-reconfigure.
#
# N.B.: dpkg-reconfigure deletes everything from this file except for
# the assignments to variables INTERFACES, HOTPLUG_INTERFACES, ARGS and
# SUSPEND_ACTION.  When run it uses the current values of those variables
# as their default values, thus preserving the administrator's changes.
#
# This file is sourced by both the init script /etc/init.d/ifplugd and
# the udev script /lib/udev/ifplugd.agent to give default values.
# The init script starts ifplugd for all interfaces listed in
# INTERFACES, and the udev script starts ifplugd for all interfaces
# listed in HOTPLUG_INTERFACES. The special value all starts one
# ifplugd for all interfaces being present.
INTERFACES="eth0"
HOTPLUG_INTERFACES="wlan0"
ARGS="-q -f -u0 -d10 -w -I"
SUSPEND_ACTION="stop"

Multihop problems with RPL router

I tested Linux RPL router with two Atmel AVR Raven nodes running recent Contiki OS. I noticed that when both nodes are connected directly to router everything worked fine. But when one Raven was connected to the router through the other Raven, the router wasn't able to ping the non-adjacent Raven. I expected that the problem was caused by missing support for RPL option for IPv6 Hop-by-Hop header in Linux RPL router. This option is critical - if receiving node doesn't understand the RPL option, it drops the entire packet. By default Contiki nodes insert RPL option to IPv6 Hop-by-Hop header to forwarded packets only - that explains why adjacent nodes could communicate.

Dummy RPL option handler

I decided to try adding dummy RPL option handler, and check if router starts accepting packets with RPL option for IPv6 Hop-by-Hop header. I added commit to my feature-rpl branch. I repeated tests with Contiki Raven nodes. This time I could ping nodes two hops away without problems. Yay!!!

Dummy RPL option handler is not a perfect solution - contents of RPL option are ignored, and it's not compliant with RFC6550. However for a simple operation as a DODAG root, dummy handler should be sufficient for testing purposes. DODAG root can't be a part of a routing loop in normal circumstances (it has no parrents), so skipping RPL option should be safe. Contiki nodes currently accept packets with no RPL option in IPv6 header.

Conclusions

The above paragraph presents a quick hack that overcomes the biggest limitation of current RPL Linux router - lack of multihop operation. There are other problems with implementation: rpl-ctl command doesn't produce useful output, and quantity of DIO packets sent is highly suspicious.