-
Notifications
You must be signed in to change notification settings - Fork 2k
Tutorial: RIOT and Multi Hop Routing with RPL
Please have a look at the Quick-Start-Guide and Creating-your-first-RIOT-project.
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.
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.
Information about the native port of RIOT can be found in Family:-native and Board:-native
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.
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
.
$ make clean all
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.
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
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
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.
To compile the gnrc_networking
example for the iotlab-m3
, the following command can be executed.
$ BOARD=iotlab-m3 make all
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.
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.