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

この Codelab について
schedule17 分
subject最終更新: 2025年5月5日
account_circle作成者: Simon Lin, Jonathan Hui

1. はじめに

608c4c35050eb280.png

Thread とは何ですか?

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

OpenThread とは

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

OpenThread ボーダー ルーターとは

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

IPv6 マルチキャスト

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

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

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

Thread 最小エンドデバイスの場合、親に依存してマルチキャスト アドレスを集約し、代わりに MLR を実行することも、親が Thread 1.1 の場合に自身を登録することもできます。

詳しくは、スレッドの仕様をご覧ください。

作業内容

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

学習内容

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

必要なもの

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

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 マルチキャストを確認する

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

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

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

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 レスポンス マルチキャスト パッケージを Thread ネットワークから Wi-Fi ネットワークに転送できることを示しています。

7. 完了

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

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

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