Thread Border Router - IPv6 Multicast

1. Introduction

608c4c35050eb280.png

What is Thread?

Thread is an IP-based low-power wireless mesh networking protocol that enables secure device-to-device and device-to-cloud communications. Thread networks can adapt to topology changes to avoid single-point failures.

What is OpenThread?

OpenThread released by Google is an open-source implementation of Thread®.

What is an OpenThread Border Router?

OpenThread Border Router (OTBR) released by Google is an open-source implementation of the Thread Border Router.

IPv6 Multicast

Thread defines a series of features to support multicast across a heterogeneous network (Thread and Wi-Fi/Ethernet Network segments) for multicast addresses with scope larger than realm local.

A Thread Border Router registers its Backbone Router (BBR) Dataset, and the selected BBR service is the Primary Backbone Router (PBBR), which is responsible for the multicast inbounding/outbounding forward.

A Thread Device sends a CoAP message to register the multicast address to the PBBR (Multicast Listener Registration, MLR for short) if the address is larger than realm local. PBBR uses MLDv2 on its External Interface to communicate to the wider IPv6 LAN/WAN about IPv6 multicast groups it needs to listen to, on behalf of its local Thread Network. And PBBR only forwards multicast traffic into the Thread Network if the destination is subscribed to by at least one Thread device.

For Thread Minimal End Devices, they may depend on their parent to aggregate the multicast address and do MLR on their behalf, or register themselves if their parent is of Thread 1.1.

For more details, please refer to Thread Specification.

What you will build

In this codelab, you're going to set up a Thread Border Router and two Thread devices, then enable and verify Multicast features on Thread devices and Wi-Fi devices.

What you will learn

  • How to build nRF52840 firmware with support for IPv6 Multicast.
  • How to subscribe to IPv6 multicast addresses on Thread devices.

What you will need

  • A Linux workstation, for building and flashing a Thread RCP, the OpenThread CLI, and testing IPv6 multicast.
  • A Raspberry Pi for the Thread border router.
  • 2 Nordic Semiconductor nRF52840 USB Dongles (one for the RCP and two for Thread end devices).

2. Setup OTBR

The quickest way to set up an OTBR is by following the OTBR Setup Guide.

After OTBR setup is complete, use ot-ctl to validate that the OTBR became the Primary Backbone Router within seconds.

> bbr state
Primary
Done
> bbr
BBR Primary:
server16: 0xF800
seqno:    21
delay:    5 secs
timeout:  3600 secs
Done

3. Build and Flash Thread devices

Build the Thread CLI application with Multicast and flash the two nRF52840 DK boards.

Build nRF52840 DK firmware

Follow instructions to clone the project and build nRF52840 firmware.

$ cd ~/src/ot-nrf528xx
$ rm -rf build
$ script/build nrf52840 USB_trans -DOT_MLR=ON

Continue with the Build a Thread network with nRF52840 boards and OpenThread codelab as written. After the end device is flashed with the CLI image, follow Join the second node to the Thread network to add the Thread device to the Thread network. Repeat for the second Thread end device.

4. Subscribe to the IPv6 multicast address

Subscribe to ff05::abcd on nRF52840 End Device 1:

> ipmaddr add ff05::abcd
Done

Verify ff05::abcd is successfully subscribed:

> ipmaddr
ff05:0:0:0:0:0:0:abcd            <--- ff05::abcd subscribed
ff33:40:fdde:ad00:beef:0:0:1
ff32:40:fdde:ad00:beef:0:0:1
ff02:0:0:0:0:0:0:2
ff03:0:0:0:0:0:0:2
ff02:0:0:0:0:0:0:1
ff03:0:0:0:0:0:0:1
ff03:0:0:0:0:0:0:fc
Done

Subscribe to ff05::abcd on the Laptop:

We need a Python script subscribe6.py to subscribe to a multicast address on the Laptop.

Copy the code below and save it as subscribe6.py:

import ctypes
import ctypes.util
import socket
import struct
import sys

libc = ctypes.CDLL(ctypes.util.find_library('c'))
ifname, group = sys.argv[1:]
addrinfo = socket.getaddrinfo(group, None)[0]
assert addrinfo[0] == socket.AF_INET6
s = socket.socket(addrinfo[0], socket.SOCK_DGRAM)
group_bin = socket.inet_pton(addrinfo[0], addrinfo[4][0])
interface_index = libc.if_nametoindex(ifname.encode('ascii'))
mreq = group_bin + struct.pack('@I', interface_index)
s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq)
print("Subscribed %s on interface %s." % (group, ifname))
input('Press ENTER to quit.')

Run subscribe6.py to subscribe ff05::abcd on the Wi-Fi network interface (e.g. wlan0):

$ sudo python3 subscribe6.py wlan0 ff05::abcd
Subscribed ff05::abcd on interface wlan0.
Press ENTER to quit.

The final network topology with multicast subscriptions are shown below:

b118448c98b2d583.png

Now that we have subscribed the IPv6 multicast address on both the nRF52840 End Device 1 in Thread network and the Laptop in the Wi-Fi network, we are going to verify bi-directional IPv6 multicast reachability in the following sections.

5. Verify Inbound IPv6 Multicast

Now, we should be able to reach both nRF52840 End Device 1 in the Thread network and the Laptop using IPv6 multicast address ff05::abcd from the Wi-Fi network.

Ping ff05::abcd on OTBR via the Wi-Fi interface:

$ ping -6 -b -t 5 -I wlan0 ff05::abcd
PING ff05::abcd(ff05::abcd) from 2401:fa00:41:801:83c1:a67:ae22:5346 wlan0: 56 data bytes
64 bytes from fdb5:8d36:6af9:7669:e43b:8e1b:6f2a:b8fa: icmp_seq=1 ttl=64 time=57.4 ms
64 bytes from 2401:fa00:41:801:8c09:1765:4ba8:48e8: icmp_seq=1 ttl=64 time=84.9 ms (DUP!)
64 bytes from fdb5:8d36:6af9:7669:e43b:8e1b:6f2a:b8fa: icmp_seq=2 ttl=64 time=54.8 ms
64 bytes from 2401:fa00:41:801:8c09:1765:4ba8:48e8: icmp_seq=2 ttl=64 time=319 ms (DUP!)
64 bytes from fdb5:8d36:6af9:7669:e43b:8e1b:6f2a:b8fa: icmp_seq=3 ttl=64 time=57.5 ms
64 bytes from 2401:fa00:41:801:8c09:1765:4ba8:48e8: icmp_seq=3 ttl=64 time=239 ms (DUP!)

# If using MacOS, use this command. The interface is typically not "wlan0" for Mac.
$ ping6 -h 5 -I wlan0 ff05::abcd

We can see that OTBR can receive two ping replies from both the nRF52840 End Device 1 and the Laptop because they both have subscribed to ff05::abcd. This shows that the OTBR can forward the IPv6 Ping Request multicast packets from the Wi-Fi network to the Thread network.

6. Verify Outbound IPv6 Multicast

Ping ff05::abcd on nRF52840 End Device 2:

> ping ff05::abcd 100 10 1
108 bytes from fdb5:8d36:6af9:7669:e43b:8e1b:6f2a:b8fa: icmp_seq=12 hlim=64 time=297ms
108 bytes from 2401:fa00:41:801:64cb:6305:7c3a:d704: icmp_seq=12 hlim=63 time=432ms
108 bytes from fdb5:8d36:6af9:7669:e43b:8e1b:6f2a:b8fa: icmp_seq=13 hlim=64 time=193ms
108 bytes from 2401:fa00:41:801:64cb:6305:7c3a:d704: icmp_seq=13 hlim=63 time=306ms
108 bytes from fdb5:8d36:6af9:7669:e43b:8e1b:6f2a:b8fa: icmp_seq=14 hlim=64 time=230ms
108 bytes from 2401:fa00:41:801:64cb:6305:7c3a:d704: icmp_seq=14 hlim=63 time=279ms

nRF52840 End Device 2 can receive ping replies from both the nRF52840 End Device 1 and the Laptop. This shows that the OTBR can forward the IPv6 Ping Reply multicast packages from the Thread network to the Wi-Fi network.

7. Congratulations

Congratulations, you've successfully set up a Thread Border Router and verified bi-directional IPv6 multicast!

For more on OpenThread, visit openthread.io.

Reference docs: