IPv6 寻址

View source on GitHub

让我们来看一下 Thread 如何识别网络中的每个设备,以及设备间用何种类型的地址进行相互通信。

域

OT Scopes

Thread 网络中有三种域用于单播寻址:

  • Link-Local — 所有通过单次射频传输可访问的接口
  • Mesh-Local — 所有在同一 Thread 网络中可访问的接口
  • Global — 所有从 Thread 网络外部可以访问的接口

前两个域与 Thread 网络指定的 Prefix(前缀)相对应。Link-Local 的 Prefix 为 fe80::/16,Mesh-Local 的 Prefix 为 fd00::/8。

单播

单个 Thread 设备可以通过多种 IPv6 单播地址来进行标识。每种地址都有不同的功能(基于域和用例)。

在介绍每种类型之前,让我们先了解一个共同的概念,它叫作 RLOC(Routing Locator)。RLOC 根据 Thread 接口在网络拓扑中的位置来对其进行标识。

如何生成 RLOC

所有设备都获得一个 Router ID 和一个 Child ID。每个 Router 维护一个包含其所有子节点的表,两个 ID 的组合唯一地标识拓扑中的设备。例如,请参考以下拓扑中高亮的节点,其中 Router(五边形)中的数字是 Router ID,End Device(圆形)中的数字是 Child ID:

OT RLOC Topology

每个子节点的 Router ID 对应于它的父节点(Router)。因为 Router 不会是子节点,所以 Router 的 Child ID 始终为 0。这些值对于 Thread 网络中的每个设备都是唯一的,并用于创建 RLOC16(代表 RLOC 的后 16 位)。

例如,以下是左上节点(Router ID = 1,Child ID = 1)的 RLOC16 的计算方法:

OT RLOC16

RLOC16 是 IID(Interface Identifier)的一部分,IID 对应的是 IPv6 地址的后 64 位。一些 IID 可用于标识某些类型的 Thread 接口。例如,RLOC 的 IID 始终为 0000:00ff:fe00:RLOC16 的形式。

RLOC 由 Mesh-Local Prefix 和 IID 组成。例如,如果 Mesh-Local Prefix 是 fde5:8dba:82e1:1::/64,RLOC16 = 0x401,那么该节点的 RLOC 就是:

OT RLOC

可以使用相同的逻辑来确定以上示例拓扑中所有高亮的节点的 RLOC:

OT Topology w/ Address

但是,因为 RLOC 是基于节点在拓扑中的位置的,所以节点的 RLOC 会随着拓扑的变化而改变。

例如,如果 Thread 网络中的 0x400 节点离开了网络,那么它的子节点 0x401 和 0x402 会与其它的 Router 建立新连接,从而获得新的 RLOC16 和 RLOC:

OT Topology after Change

单播地址类型

RLOC 只是 Thread 设备可以获得的多种 IPv6 单播地址之一。另一类用于在 Thread 网络分区内标识唯一的 Thread 接口的地址称为 EID(Endpoint Identifier)。EID 与 Thread 网络拓扑无关。

常见的单播类型如下。

一种用于标识单次射频传输可访问的 Thread 接口的 EID。
示例fe80::54db:881c:3845:57f4
IID基于 802.15.4 Extended Address
域Link-Local
详情
  • 用于发现邻居、配置链路和交换路由信息
  • 非可路由地址
  • 总是带 fe80::/16 Prefix

Mesh-Local EID (ML-EID)

一种用于标识 Thread 接口的 EID,其与网络拓扑无关。用于访问同一 Thread 分区内的 Thread 接口。也称为 ULA(Unique Local Address)。
示例fde5:8dba:82e1:1:416:993c:8399:35ab
IID在 commissioning 完成后随机生成
域Mesh-Local
详情
  • 不会随拓扑变化而变化
  • 应由应用程序使用
  • 总是带 fd00::/8 Prefix

Routing Locator (RLOC)

根据 Thread 接口在网络拓扑中的位置来对其进行标识。
示例fde5:8dba:82e1:1::ff:fe00:1001
IID0000:00ff:fe00:RLOC16
域Mesh-Local
详情
  • 在设备连接到网络后生成
  • 用于在 Thread 网络中传递 IPv6 数据报
  • 随拓扑变化而变化
  • 通常不会由应用程序使用

Anycast Locator (ALOC)

用于标识 Thread 网络分区中一个或多个 Thread 接口的位置。如果始发者不知道目的地的 RLOC,则使用 ALOC 进行查找。
示例fde5:8dba:82e1:1::ff:fe00:fc01
IID0000:00ff:fe00:fcXX
域Mesh-Local
详情
  • fcXX = ALOC 目的地址,用于查询对应的 RLOC
  • 通常不会由应用程序使用

Global Unicast Address (GUA)

一个EID,用于标识除 Thread 网络外的全局范围内的 Thread 接口。
示例2000::54db:881c:3845:57f4
IID
  • SLAAC — 由设备自身随机分配
  • DHCP — 由 DHCPv6 服务器分配
  • Manual — 由应用层分配
域Global
详情
  • 一个公开的 IPv6 地址
  • 总是带 2000::/3 Prefix

多播

多播用于一次将信息传达给多个设备。Thread 网络中保留了特定的地址,以提供给不同分组的设备在多播时使用。

IPv6 地址 域 传递给
ff02::1 Link-Local 所有 FTD 和 MED
ff02::2 Link-Local 所有 FTD
ff03::1 Mesh-Local 所有 FTD 和 MED
ff03::2 Mesh-Local 所有 FTD

你可能会注意到,上面的多播表中没有将 SED 作为接收者包括在内。Thread 为所有 Thread 节点(包括 SED)定义了(link-local 和 realm-local 域)基于单播 prefix 的 IPv6 多播地址。这些多播地址基于单播 Mesh-Local prefix 构成,因 Thread 网络而异。(有关基于单播 prefix 的 IPv6 多播地址的详情,请参阅 RFC 3306)。

Thread 设备还支持除表中所列举域之外的任意域。

任播

当目的地的 RLOC 未知时,可以使用任播将流量路由到 Thread 接口。ALOC(Anycast Locator)标识 Thread 分区内多个接口的位置。ALOC 的后 16 位,称为 ALOC16,其格式为 0xfcXX,表示 ALOC 的类型。

例如,0xfc01 和 0xfc0f 之间的 ALOC16 保留给了 DHCPv6 Agent。如果特定的 DHCPv6 Agent RLOC 是未知的(可能是因为网络拓扑已更改),则可以将消息发送到 DHCPv6 Agent ALOC 以获取 RLOC。

Thread 定义了以下 ALOC16 值:

ALOC16 类型
0xfc00 Leader
0xfc01 – 0xfc0f DHCPv6 Agent
0xfc10 – 0xfc2f Service
0xfc30 – 0xfc37 Commissioner
0xfc40 – 0xfc4e Neighbor Discovery Agent
0xfc38 – 0xfc3f
0xfc4f – 0xfcff
Reserved

回顾

你应该学到了:

  • Thread 网络包含三个域:Link-Local、Mesh-Local 和 Global
  • Thread 设备具有多种单播 IPv6 地址
  • RLOC 表示设备在 Thread 网络中的位置
  • ML-EID 对于分区内的 Thread 设备是唯一的,并且应由应用程序使用
  • Thread 使用多播将数据转发到节点组和 Router 组
  • 当目的地的 RLOC 未知时,Thread 可以使用任播

要了解有关 Thread 的 IPv6 寻址的更多信息,请参阅 Thread Specification 的 5.2 和 5.3 节。