Thread ボーダー ルーター - IPv6 マルチキャスト

1. はじめに

608c4c35050eb280.png

Thread とは何ですか?

Thread は、デバイス間およびデバイスとクラウド間の安全な通信を可能にする、IP ベースの低消費電力ワイヤレス メッシュ ネットワーキング プロトコルです。Thread ネットワークは、トポロジの変更に適応して単一障害点を回避できます。

OpenThread とは

Google がリリースした OpenThread は、Thread® のオープンソース実装です。

OpenThread ボーダー ルーターとは

Google がリリースした OpenThread Border Router(OTBR)は、Thread ボーダー ルーターのオープンソース実装です。

IPv6 マルチキャスト

Thread は、レルム ローカルよりもスコープの大きいマルチキャスト アドレスについて、異種混在ネットワーク(Thread ネットワーク セグメントと Wi-Fi/イーサネット ネットワーク セグメント)全体でマルチキャストをサポートする一連の機能を定義します。

Thread ボーダー ルーターはバックボーン ルーター(BBR)データセットを登録し、選択された BBR サービスはプライマリ バックボーン ルーター(PBBR)となります。PBBR は、マルチキャストのインバウンド/アウトバウンド転送を担当します。

アドレスが realm local より大きい場合、Thread デバイスは CoAP メッセージを送信して、マルチキャスト アドレスを PBBR(マルチキャスト リスナー登録、MLR)に登録します。PBBR は、外部インターフェースで MLDv2 を使用して、ローカル Thread ネットワークに代わってリッスンする必要がある IPv6 マルチキャスト グループについて、より広範な IPv6 LAN/WAN と通信します。また、PBBR は、宛先が 1 つ以上の Thread デバイスによって登録されている場合にのみ、マルチキャスト トラフィックを Thread ネットワークに転送します。

Thread Minimal End Device の場合、親デバイスに依存してマルチキャスト アドレスを集約し、MLR を代行してもらうか、親デバイスが Thread 1.1 の場合は自身で登録します。

詳しくは、Thread 仕様を参照してください。

作成するアプリの概要

この Codelab では、Thread ボーダー ルーターと 2 つの Thread デバイスを設定し、Thread デバイスと Wi-Fi デバイスでマルチキャスト機能を有効にして確認します。

学習内容

  • IPv6 マルチキャストをサポートする nRF52840 ファームウェアをビルドする方法。
  • Thread デバイスで IPv6 マルチキャスト アドレスをサブスクライブする方法。

必要なもの

  • Thread RCP、OpenThread CLI のビルドとフラッシュ、IPv6 マルチキャストのテストに使用する Linux ワークステーション。
  • Thread ボーダー ルーター用の Raspberry Pi。
  • 2 個の Nordic Semiconductor nRF52840 USB ドングル(1 個は RCP 用、2 個は Thread エンドデバイス用)。

2. OTBR をセットアップする

OTBR を設定する最も簡単な方法は、OTBR 設定ガイドに沿って操作することです。

OTBR の設定が完了したら、ot-ctl を使用して、OTBR が数秒以内にプライマリ バックボーン ルーターになったことを確認します。

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

3. Thread デバイスをビルドしてフラッシュする

マルチキャストを使用して Thread CLI アプリケーションをビルドし、2 つの nRF52840 DK ボードをフラッシュします。

nRF52840 DK ファームウェアをビルドする

手順に沿ってプロジェクトを複製し、nRF52840 ファームウェアをビルドします。

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

記載されているとおり、nRF52840 ボードと OpenThread を使用して Thread ネットワークを構築する Codelab を続行します。エンドデバイスに CLI イメージを書き込んだら、2 番目のノードを Thread ネットワークに参加させるに沿って、Thread デバイスを Thread ネットワークに追加します。2 つ目の Thread エンドデバイスについても同様に操作します。

4. IPv6 マルチキャスト アドレスをサブスクライブする

nRF52840 エンドデバイス 1 で ff05::abcd をサブスクライブします。

> ipmaddr add ff05::abcd
Done

ff05::abcd が正常にサブスクライブされていることを確認します。

> 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

ノートパソコンで ff05::abcd に登録します。

ノートパソコンでマルチキャスト アドレスを登録するには、Python スクリプト subscribe6.py が必要です。

次のコードをコピーして、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.')

subscribe6.py を実行して、Wi-Fi ネットワーク インターフェース(wlan0 など)で ff05::abcd をサブスクライブします。

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

マルチキャスト サブスクリプションを含む最終的なネットワーク トポロジは次のとおりです。

b118448c98b2d583.png

Thread ネットワークの nRF52840 エンドデバイス 1 と Wi-Fi ネットワークのノートパソコンの両方で IPv6 マルチキャスト アドレスをサブスクライブしたので、次のセクションで双方向の IPv6 マルチキャスト到達可能性を確認します。

5. インバウンド IPv6 マルチキャストを確認する

これで、Wi-Fi ネットワークから IPv6 マルチキャスト アドレス ff05::abcd を使用して、Thread ネットワーク内の nRF52840 エンドデバイス 1 とノートパソコンの両方にアクセスできるようになります。

Wi-Fi インターフェース経由で OTBR の ff05::abcd に ping を送信します。

$ 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

nRF52840 エンドデバイス 1 とノートパソコンの両方が ff05::abcd をサブスクライブしているため、OTBR は両方から 2 つの ping 応答を受信できます。これは、OTBR が Wi-Fi ネットワークから Thread ネットワークに IPv6 Ping リクエスト マルチキャスト パケットを転送できることを示しています。

6. アウトバウンド IPv6 マルチキャストを検証する

nRF52840 エンドデバイス 2 で ff05::abcd に ping を送信します。

> 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 エンドデバイス 2 は、nRF52840 エンドデバイス 1 とノートパソコンの両方から ping 応答を受信できます。これは、OTBR が IPv6 Ping Reply マルチキャスト パッケージを Thread ネットワークから Wi-Fi ネットワークに転送できることを示しています。

7. 完了

お疲れさまでした。これで、Thread ボーダー ルーターを正常にセットアップし、双方向 IPv6 マルチキャストを確認できました。

OpenThread の詳細については、openthread.io をご覧ください。

リファレンス ドキュメント: