Creating Bridges for ContikiOS Minimal-net (for Linux)

Minimal-net helps us runing ContikiOS as a normal application. Consequently, making it easier to debug especially in case of segmentation faults. However, to setup a minimal-net, we need to do some networking tricks. There is a nice tutorial on RPL network setup on minimal-net for windows OS but none for linux. Here, I will try to explain the linux case.

As I am working on DTLS, my example setup has two nodes, a client and a server. Each of the nodes will be in different tap interfaces. So we also need to bridge them. Though, bridging them is enough for connecting the two nodes, we need a few further steps for a connection to the outside world.

Creation of TAP interfaces

When you compile and run your code with minimal-net, a tap0 interface is created and deployed for you. However, the second tap interface is not deployed, since the name of tap0 is hardcoded. So we will make a tiny change to the code, contiki/cpu/native/net/tapdev6.c. We will use ifr.ifr_name to choose the right interface to deploy (line 22):

tapdev6.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
void
tapdev_init(void)
{
  char buf[1024];

  fd = open(DEVTAP, O_RDWR);
  if(fd == -1) {
    perror("tapdev: tapdev_init: open");
    return;
  }

#ifdef linux
  {
    struct ifreq ifr;

    memset(&ifr, 0, sizeof(ifr));
    ifr.ifr_flags = IFF_TAP|IFF_NO_PI;
    if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) {
      perror(buf);
      exit(1);
    }
    snprintf(buf, sizeof(buf), "ifconfig %s up",ifr.ifr_name);
    system(buf);
    printf("%s\n", buf);
  }
#endif /* Linux */
....

With the above code each time a new tap interface with a new name will be deployed (eg., tap0, tap1).

Let’s bridge the tap interfaces

The two (or more) tap interfaces are disjoint, so we need to connect them to each other. I prefer connecting them in the link layer (ie., MAC, switch) so I will use a bridge. I will use brctl command which can be installed easily via your favorite packet manager.

1
sudo brctl addbr br0

Then, we should add our interfaces and deploy the bridge:

1
2
3
sudo brctl addif br0 tap0
sudo brctl addif br0 tap1
sudo ifconfig br0 up

Done. Now the client and the server node can communicate.

Reaching from the outside world

In order to reach these nodes from the outside world, we also need to add eth0 or wlan0 interface (whatever you want). But this time, as an additional step we should add routes too. First, let’s update our bridge.

1
2
3
sudo ifconfig br0 down
sudo brctl addif br0 eth0
sudo ifconfig br0 up

Now we have a nice bridge that connects our nodes to the outer world. However, we should also show the route to our nodes. In TinyDTLS, aaaa::ff:fe02:232 and aaaa::ff:fe02:230 ipv6 addresses are hardcoded in the client and server. So our bridge address space should involve both of them.

1
2
3
sudo ifconfig br0 down
sudo ip -6 address add aaaa::1/128 dev br0
sudo ifconfig br0 up

Done. Now you can ping your nodes (ie., ping6 aaaa::ff:fe02:232).

Comments