Wi-SUN Multicast#

Silicon Labs Wi-SUN stack implements Multicast Protocol for Low-Power and Lossy Networks (MPL) as described in RFC7731, to support multicast packets messaging specified in the Wi-SUN FAN Technical Profile Specification version 1.1v06.

This page goes over the different aspects of Wi-SUN multicast aspects to allow users sending multicast messages over their Wi-SUN Network.

Wi-SUN Multicast Scopes#

A scope zone as described by [RFC 4007] is a topological span within which the address may be used as a unique identifier for an interface or set of interfaces.

The Wi-SUN FAN Specification requires subscription to a couple of multicast addresses which covers two different scopes:

  • The Link Local scope (FF02::): which includes all neighbors in the limit of 1 hop.

  • The Realm Local scope (FF03::): which includes all the network nodes at any limit of hops.

With the Silicon Labs Wi-SUN FAN Stack, FFNs are able to originate multicast messages destined for the required scopes listed above or any other scope. They are also able to forward multicast messages, whether they originate from the same PAN or from another host.

As the figure below shows, other hosts can send multicast packets destined to multicast groups to which PAN nodes are subscribed. The border router must join those multicast groups to enable forwarding the multicast packets of other hosts into the PAN.

Wi-SUN Required Scopes

Wi-SUN Multicast Addresses#

By default, all the Wi-SUN devices subscribe to the ALL_MPL_FORWARDERS address with a realm-local scope: FF03::FC as shown in the figure below.

In addition to the ALL_MPL_FORWARDERS address, the Border Router and the FFNs join their FAN interface to several predefined IPv6 multicast groups by default:

  • ff02::1 : targets all the nodes in the link local scope.

  • ff02::2 : targets all the routers in the link local scope.

  • ff03::1 : targets all the nodes in a Realm local scope.

  • ff03::2 : targets all the routers in a Realm local scope.

The Border Router and FFNs are also able to join other specific Multicast groups different than the ones joined by default.

Sending a Multicast Packet in Wi-SUN Network#

This section explains how to send a multicast message from the Wi-SUN Linux Border Router (wsbrd) to the FFN nodes, using a socket created by the python script at the end of this section.

Setting Up The Nodes#

  1. Run the Wi_SUN - SoC CLI example sample application on your nodes.

  2. Start a UDP server on the nodes.

        wisun  udp_server 1234

For multicast addresses other than the default ones listed in the section Wi-Sun Multicast Addresses, run the command below to join a multicast group.

    wisun socket_set_option [socket id] join_multicast_group [multicast address]

Setting Up The Border Router#

For multicast addresses other than the default ones listed in the section Wi-Sun Multicast Addresses, run the command below to join a multicast group (eg: ff03::db8:0:0). Check D-Bus API documentation for more information.

sudo busctl --system call com.silabs.Wisun.BorderRouter /com/silabs/Wisun/BorderRouter com.silabs.Wisun.BorderRouter JoinMulticastGroup "ay" 16 0xff 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0d 0xb8 0x00 0x00 0x00 0x00

The multicast socket must be bound to the wsbrd interface in order to reach the Wi-SUN PAN. The script used in this document binds the socket to interface tun0 using the socket option SO_BINDTODEVICE.

Send the Multicast Message#

Run the following command to send a message to all the routers in the Realm Local scope of the Border Router using the script multicast_packet_send.py.

python3 multicast_packet_send.py ff03::2 1234 "Hello World!!"

The script sets the socket limit to 10 hops being that the default value on Linux is 1 hop. The number of hops can be changed by setting the socket option IPV6_MULTICAST_HOPS to a different value.

multicast_packet_send.py#

import socket
import sys
import time

if len(sys.argv) != 3:
    print(
        'Usage: python3 multicast_packet_send.py [dest IPv6] [dest port] [message]' )
    exit(1)

sock = socket.socket(socket.AddressFamily.AF_INET6,
                     socket.SocketKind.SOCK_DGRAM)
sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS, 10)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BINDTODEVICE, bytes("tun0", 'ascii'))
sock.sendto(sys.argv[3], (sys.argv[1], int(sys.argv[2])))

print('packet sent')