Skip to content

Tutorial: RIOT and Multi Hop Routing with RPL

Cenk Gündoğan edited this page Sep 26, 2015 · 15 revisions

Table of Contents

  1. Prerequisites
  2. Preparation
  3. Tutorials
    1. Routing with RPL using Native
    2. Routing with RPL using the IoT-Lab Testbed

Prerequisites

Please have a look at the Quick-Start-Guide and Creating-your-first-RIOT-project.

Preparation

For routing capabilities it is necessary that the RPL implementation is compiled into your RIOT application. This can be achieved by adding gnrc_rpl to the USEMODULE variable in your application's Makefile. You can consult this Makefile for a complete example.

Tutorials

For the following tutorials the gnrc_networking example will be used. All commands listed here will be issued from within the examples/gnrc_networking directory. You may use your own application after adjusting the Makefile accordingly as described in the Preparation.

Routing with RPL using Native

Information about the native port of RIOT can be found in Family:-native and Board:-native

Downside

Because all nodes are connected via the tapbr0 bridge, all nodes are reachable to each other within a single hop. Therefore, it is not possible to test real multi-hop communication with this method. Virtual-riot-network describes how native nodes can be deployed with a virtualized network topology using tap interfaces. However, currently it is not possible to use RIOT together with desvirt. See RIOT#3908 and desvirt#17 for more information.

Creating Tap Interfaces

The native RIOT instances communicate through tap interfaces. We provide a script that supports the setup and cleanup of such interfaces.

To setup tap interfaces and a bridge that connects each tap interface:

$ ../../dist/tools/tapsetup/tapsetup -c 4

With the -c parameter you can specify how many tap interfaces you want to create (default 2). To delete all tap interface you can execute:

$ ../../dist/tools/tapsetup/tapsetup -d

See the help for further information about additional parameters:

$ ../../dist/tools/tapsetup/tapsetup -h

You can verify that the tap interfaces have been created successfully by looking at the output of ip l. This list should include the new interfaces tapbr0, tap0, tap1, tap2 and tap3.

Compiling for Native

$ make clean all

Starting the RIOT

Type the following command in three different terminals, by using tap0, tap1 and tap2 respectively.

$ make term PORT=tap{0,1,2}
RIOT native interrupts/signals initialized.
LED_GREEN_OFF
LED_RED_ON
RIOT native board initialized.
RIOT native hardware initialization complete.

main(): This is RIOT! (Version: XXX)
RIOT network stack example application
All up, running the shell now
>

You will be greeted by RIOT's shell in all three terminals.

Initializing RPL

In order to use RPL we have to choose a RPL root node. I will choose the node that is using the tap0 interface as RPL root.

With the ifconfig command we can get the configured interfaces for a particular RIOT node. On my system the output is as follows for the node on tap0.

> ifconfig
Iface  6   HWaddr: d2:61:59:ce:b3:5d
           MTU:1280
           Source address length: 6
           Link type: wired
           inet6 addr: ff02::1/128  scope: local [multicast]
           inet6 addr: fe80::d061:59ff:fece:b35d/64  scope: local
           inet6 addr: ff02::1:ffce:b35d/128  scope: local [multicast]
           inet6 addr: ff02::2/128  scope: local [multicast]

At first, we need to configure a global IPv6 address for the root node

> ifconfig 6 add 2001:db8::1
success: added 2001:db8::1/64 to interface 6

> ifconfig
Iface  6   HWaddr: d2:61:59:ce:b3:5d
           MTU:1280
           Source address length: 6
           Link type: wired
           inet6 addr: ff02::1/128  scope: local [multicast]
           inet6 addr: fe80::d061:59ff:fece:b35d/64  scope: local
           inet6 addr: ff02::1:ffce:b35d/128  scope: local [multicast]
           inet6 addr: ff02::2/128  scope: local [multicast]
           inet6 addr: 2001:db8::1/64  scope: global
           inet6 addr: ff02::1:ff00:1/128  scope: local [multicast]

Now, RPL must be initialized on that particular interface for all nodes (tap0-3):

> rpl init 6
successfully initialized RPL on interface 6

Starting RPL

On the root node (tap0 in this tutorial), type:

> rpl root 1 2001:db8::1
successfully added a new RPL DODAG

Note however, that the DODAG ID 2001:db8::1 matches a global IPv6 address configured on an interface, like it was done in [Initializing RPL](### Initializing RPL). The 1 before 2001:db8::1 is the Instance ID and can be adjusted if so desired.

To see the RPL status, type rpl.

> rpl
instance table: [X]     [ ]
dodag table:    [X]     [ ]     [ ]     [ ]
parent table:   [ ]     [ ]     [ ]     [ ]     [ ]     [ ]

instance [1 | mop: 2 | ocp: 0 | mhri: 256 | mri 0]
        dodag [2001:db8::1 | R: 256 | CL: 0s | TR(I=[8,20], k=10, c=0, TC=3s, TI=4s)]

The root node has a rank of R: 256.

Now type rpl in the other terminals (here an example for tap1):


> rpl
instance table: [X]     [ ]
dodag table:    [X]     [ ]     [ ]     [ ]
parent table:   [X]     [ ]     [ ]     [ ]     [ ]     [ ]

instance [1 | mop: 2 | ocp: 0 | mhri: 256 | mri 0]
        dodag [2001:db8::1 | R: 512 | CL: 0s | TR(I=[8,20], k=10, c=0, TC=2s, TI=4s)]
                parent [addr: fe80::d069:49ff:fede:b38c | rank: 256 | lifetime: 118s]

This node is part of the RPL-DODAG with the DODAG-ID 2001:db8::1 and Instance Id 1. Furthermore, this node's rank is R: 512, and the preferred parent has the link-local IPv6 address fe80::d069:49ff:fede:b38c. This parent's rank is rank: 256, therefore we know that this must be the root of this RPL-DODAG.

Note that all participating nodes in the RPL-DODAG have configured automatically a global IPv6 address matching the prefix from the DODAG-ID. Verify with ifconfig.

RPL should now start to fill the FIB (Forwarding Information Base) table, which is consulted when forwarding packets. On the root node (tap0):

> fibroute
Destination                   Flags  Next Hop                      Flags  Expires     Interface
2001:db8::1063:a9ff:fe84:34ac 0x0003 fe80::1063:a9ff:fe84:34ac     0x0003 68.6131236

and on the participating node (tap1):

> fibroute
Destination                   Flags  Next Hop                      Flags  Expires     Interface
::                            0x0003 fe80::d069:49ff:fede:b38c     0x0003 68.6874646

Routing with RPL using the IoT-Lab Testbed

Basic information about the IoT-Lab Testbed can be found in their wiki. This tutorial will cover only the iotlab-m3 nodes, but the following commands should also be applicable for the wsn430 nodes.

Compiling for the iotlab-m3 Nodes

To compile the gnrc_networking example for the iotlab-m3, the following command can be executed.

$ BOARD=iotlab-m3 make all

Starting an Experiment

An experiment can be started either by using the IoT-Lab dashboard or by using a Makefile that is provided by RIOT. In this tutorial the Makefile method will be used.

To start an experiment execute:

$ IOTLAB_USER=<iotlab_user> IOTLAB_PHY_NODES=1-3+6-9 IOTLAB_EXP_NAME=test IOTLAB_DURATION=60 BOARD=iotlab-m3 make -B clean iotlab-exp -I ../../dist/testbed-support

This command may prompt for a password to authenticate your IoT-Lab account. You will need to use the same password, which you would use for the IoT-Lab dashboard.

Parameter Description
IOTLAB_USER Specify your Iot-Lab account name. The same name used for the dashboard
IOTLAB_PHY_NODES Choose the nodes for the experiment. If a node is not available, the Makefile will return with an error specifying which nodes are busy
IOTLAB_EXP_NAME Name of the experiment
IOTLAB_DURATION Duration in minutes
BOARD The board to use: iotlab-m3
More information and further parameters can be found in the Readme.

The iotlab-exp target builds the application, starts an experiment at the testbed and uploads the binary to all nodes allocated for this experiment.

Assuming the experiment started successfully, you can then communicate with the nodes directly from the command line like this:

$ IOTLAB_USER=<iotlab_user> BOARD=iotlab-m3 make iotlab-term -I ../../dist/testbed-support

This command may prompt you for a password if your SSH key that you uploaded to the IoT-Lab Testbed for SSH usage is password protected.

Once you are connected, the serial aggregator of the iot-lab testbed will be started and you have a console from where you can control every node.

Starting RPL

Each command issued in the serial aggregator will be transmitted to all nodes used for the current experiment. In order to direct a command specifically to a single node, the node id must be prepended to this command.

Before starting RPL, a global IPv6 address must be configured for the root node. In this tutorial, node 1 will be used as the RPL root.

m3-1;ifconfig 7 add 2001:db8::1
1443297528.351524;m3-1;> ifconfig 7 add 2001:db8::1
1443297528.352779;m3-1;success: added 2001:db8::1/64 to interface 7

Afterwards, RPL must be started on interface 7 for all nodes:

rpl init 7
1443297759.620212;m3-1;> rpl init 7
1443297759.620212;m3-1;successfully initialized RPL on interface 7
1443297759.620212;m3-2;> rpl init 7
1443297759.620212;m3-2;successfully initialized RPL on interface 7
1443297759.620212;m3-3;> rpl init 7
1443297759.620212;m3-3;successfully initialized RPL on interface 7
1443297759.620212;m3-6;> rpl init 7
1443297759.620212;m3-6;successfully initialized RPL on interface 7
1443297759.620212;m3-7;> rpl init 7
1443297759.620212;m3-7;successfully initialized RPL on interface 7
1443297759.620212;m3-8;> rpl init 7
1443297759.620212;m3-8;successfully initialized RPL on interface 7
1443297759.620212;m3-9;> rpl init 7
1443297759.620212;m3-9;successfully initialized RPL on interface 7

Now, a DODAG can be started on the root node with the following command:

m3-1;rpl root 1 2001:db8::1
1443297984.009225;m3-1;> rpl root 1 2001:db8::1
1443297984.010086;m3-1;successfully added a new RPL DODAG

To see more information about the state of RPL, the rpl command can be used. Here is an example output of the rpl command invoked on the root node:

1443298078.165285;m3-1;> rpl
1443298078.166202;m3-1;instance table: [X]     [ ]
1443298078.167158;m3-1;dodag table:    [X]     [ ]     [ ]     [ ]
1443298078.167273;m3-1;parent table:   [ ]     [ ]     [ ]     [ ]     [ ]     [ ]
1443298078.168186;m3-1;
1443298078.168186;m3-1;instance [1 | mop: 2 | ocp: 0 | mhri: 256 | mri 0]
1443298078.170135;m3-1;        dodag [2001:db8::1 | R: 256 | CL: 0s | TR(I=[8,20], k=10, c=0, TC=lus, TI=lus)]

And here is an example output of rpl invoked on a node that participates in the DODAG:

1443298350.449564;m3-2;> rpl
1443298350.450321;m3-2;instance table: [X]     [ ]
1443298350.451315;m3-2;dodag table:    [X]     [ ]     [ ]     [ ]
1443298350.451427;m3-2;parent table:   [X]     [ ]     [ ]     [ ]     [ ]     [ ]
1443298350.451550;m3-2;
1443298350.452254;m3-2;instance [1 | mop: 2 | ocp: 0 | mhri: 256 | mri 0]
1443298350.454278;m3-2;        dodag [2001:db8::1 | R: 512 | CL: 0s | TR(I=[8,20], k=10, c=0, TC=lus, TI=lus)]
1443298350.456276;m3-2;                parent [addr: fe80::3432:4833:46de:7d02 | rank: 256 | lifetime: lus]

Within a couple of seconds, all nodes should have correctly configured routes and you should be able to ping or send udp packets from one node to any other node that participates in the RPL dodag. The fibroute command can be used to dump the dynamically configured routes.

Clone this wiki locally