5.9 路由协议
本文为 Thread 路由协议相关规范,翻译自Thread Specification->5.9 Routing Protocol,作为理论储备。这里未做任何解释,接下来会结合其他系列文档从抓包、代码实现结合协议规范去理解该路由协议。
本节描述了 Thread 网络中使用的路由协议。Thread 路由协议是一个简单的距离向量路由协议。协议的主要目标是最大化地可以在单个消息中传输的路由信息量。因此,该协议限制了包含最多 MAX_ROUTERS 或更少路由器的网络。
注意:可以使用超过 MAX_ROUTERS 的路由地址,以便在重新使用路由器地址之前等待超时。
路由器定期向 Thread 网络分区中的所有其他路由器广播其路由成本以及与邻居之间的单跳链路质量。到达特定目的地的路由成本是所有邻居对该目的地广播的成本中的最小值加上到该邻居的成本。 Advertisement 发送的速率由 Trickle 算法的一个实例确定RFC 6206。
提示:Trickle 算法是一种用于网络协议中的算法,旨在有效地维护和更新网络中的信息。它通常用于自组织网络(例如传感器网络)中,以确保网络中的路由信息、邻居信息或其他状态信息得到及时更新,同时尽量减少网络中的控制消息的数量。
Trickle 算法的核心思想是在保持低开销的同时,仍然能够快速地传播重要的变更。该算法通过引入慢速的消息传播机制和快速的消息传播机制来实现这一目标。具体来说,Trickle 算法的工作方式如下:
- 慢速传播: 定期(例如每分钟)发送一条慢速消息,其中包含节点当前的信息。这有助于保持网络中的信息更新。
- 快速传播: 在检测到信息变更时,立即发送一条快速消息。这有助于迅速传播关键信息。
- 定时器机制: 每个节点都维护一个定时器,定期触发慢速消息的发送。当接收到慢速或快速消息时,可以重置定时器。
Trickle 算法通过这种方式实现了一种自适应机制,可以根据网络的实际变化来动态调整消息的传播频率。这有助于在网络拓扑结构变化较小的情况下,降低消息传播的开销,提高网络的效率。 Trickle 算法在许多自组织网络协议中都得到了应用,例如RPL(适用于低功耗和有限能量的网络中的IPv6路由协议)。
I. 5.9.1 路由数据库
路由器维护一个路由数据库,记录使用 Thread 距离向量路由的每个单独接口的信息。这些数据库包含以下各小节中描述的数据集。
5.9.1.1 路由器 ID 集
接口的路由器 ID 集包含两个值:
- ID_set 是当前有效路由器 ID 的集合。
- ID_sequence_number 是分配给当前 ID_set 的序列号。
5.9.1.2 链路集
接口的链路集记录了与该接口上的其他路由器是或曾是邻居的信息。路由器为与每个邻居的链接维护一个元组,如下所示:
(L_router_id, L_link_margin, L_incoming_quality, L_outgoing_quality, L_age)
其中:
- L_router_id 是分配给该邻居的路由器 ID。
- L_link_margin 是从该邻居接收到的消息的测得链路余量。
- L_incoming_quality 是根据 L_link_margin 计算得到的传入链路质量度量。
- L_outgoing_quality 是由该邻居报告的从本路由器发送消息的传出链路质量度量。
- L_age 是自上次从该邻居接收到 MLE Advertisement 以来经过的时间。
5.9.2 路由集
接口的路由集记录了关于其他路由器的路由成本和下一跳信息,这些路由器是从该路由器出发可达(具有有限路由成本)的或最近可达的。路由器为每个可达路由器维护一个元组,如下所示:
(R_destination, R_next_hop, R_route_cost)
其中:
- R_destination 是该路由的目的地分配的路由器 ID。
- R_next_hop 是沿路由的下一跳分配的路由器 ID。
- R_route_cost 是由 R_next_hop 报告给 R_destination 的路由成本。
5.9.3 Leader 数据库
作为 Leader 的路由器维护一个额外的数据库,用于跟踪路由器 ID 的分配情况。与路由数据库类似,Leader 为设备作为 Leader 的每个接口维护一个单独的 Leader 数据库。
5.9.3.1 ID 分配集
接口的分配集记录了每个路由器 ID 的状态。
Leader 为每个路由器 ID 维护一个元组,如下所示:
(ID_id, ID_owner, ID_reuse_time)
其中:
- ID_id 是一个路由器 ID。
- ID_owner 是当前分配给该路由器 ID 的 IEEE 802.15.4 扩展地址,或者如果未分配,则是最近分配给它的路由器的 IEEE 802.15.4 扩展地址。
- ID_reuse_time 是可以重新分配此路由器 ID 的时间,如果它当前未分配。
Leader 记录一个路由器 ID 是否当前分配在路由器 ID 集中。
5.9.3.2 Leader 数据库丢失
在重置事件中, Leader 可能会丢失其 Leader 数据库、路由集和路由数据库的信息。如果 Leader 在重置前确定其 Thread 分区仍然处于活动状态,就必须按以下描述重新构建 Leader 数据库、路由集和路由数据库的丢失状态,并继续作为该 Thread 分区的 Leader 运行。详细信息请参阅第4章第4.7.1.3节《重置后的路由器同步》以确定这一点。
- 路由数据库(第5.9.1节,路由数据库)和路由集(第5.9.2节,路由集)通过整合收到的相邻路由器的 MLE Link Accept、MLE Link Accept 和 Request 以及 MLE Advertisement 消息的信息进行重建。具体而言,ID_sequence_number 是通过选择具有最新 ID Sequence 值的入站 MLE Route64 TLV 并使用其中的 ID Sequence 值来重建的。然后,Router ID Set 是根据在所选的 MLE Route64 TLV 中指示的活动 Router IDs 进行重建。详细的 MLE Route64 TLV 处理细节请参阅第5.9.8节《处理 Route64 TLVs》。
- 在 Leader 数据库 ID 分配集中,对于收到的 Route64 TLVs 中指示的每个活动 Router ID,创建一个元组,并将 ID_id 设置为 Router ID。
- 对于无法确定 MAC 扩展地址的 Router IDs,元组的 ID_owner 字段设置为“invalid”(或“unknown”)。
- 对于所有相邻路由器,可以通过接收的 MLE 消息的 link-local IPv6 源地址确定 MAC 扩展地址。ID_owner 字段将设置为相应的 MAC 扩展地址。
- ID_reuse_time 字段不设置,因为当前未激活的 Router IDs 不会创建元组。
5.9.4 链路裕量和链路指标
L_link_margin 值是来自相邻路由器的接收相对信号强度的运行平均值。相对信号强度记录为高于本地噪声底线的 dB,称为链路裕量。平均链路裕量根据表5-5转换为单向链路质量。
表5-5 平均链路裕量转换为单向链路质量
链路裕量(Link Margin) | 链路质量(Link Quality) | 链路成本(Link Cost) |
---|---|---|
>20 dB | 3 | 1 |
>10 dB | 2 | 2 |
>2 dB | 1 | 4 |
≤ 2 dB | 0 | 无穷大 |
单向链路质量通过 MLE Advertisements 中的 Route64 TLVs 与相邻设备共享。链路成本由链路的两个单向链路质量的最小值确定。例如,一个链路在一个方向上的链路质量为2,在另一个方向上的链路质量为1,因此最小链路质量为1,因此链路成本为4。
只有四种可能的链路质量值可以最小化向相邻设备通信链路质量的开销。
链路裕量可能直接由测量传入信号强度和噪声底线确定。或者,它可以从已确定与链路裕量存在相关性的一个或多个其他链路质量测量中派生。测量和相关性取决于硬件平台。
无论链路裕量如何确定,都必须使用平均化来平滑短期波动。Thread 设备必须针对每个相邻设备维护链路裕量的指数加权移动平均值,每当从相邻设备接收到新的 MAC 帧时更新(采样),新样本值的加权为 1/8 或 1/16。这种权重选择是特定于实现的。例如,如果相邻设备的平均链路裕量为 A,并且从该相邻设备收到的链路裕量为 X,则新的平均值为 (A 7/8) + (X 1/8)。确定链路质量时还必须应用迟滞,以便接近两种质量之间边界的链路裕量不会频繁更改 L_incoming_quality。迟滞值为 2 dB,用于链路质量 1-2 和链路质量 2-3 之间的阈值。迟滞值为 1 dB,用于链路质量 0-1 之间的阈值。例如,平均链路裕量必须至少增加到 12 dB,才能将现有质量 1 的链路更改为质量 2 的链路,并且至少增加到 3 dB,才能将现有质量 0 的链路更改为质量 1 的链路。
如果路由器连续接收到特定路由器邻居的 802.15.4 状态 NO_ACK 的 FAILED_ROUTER_TRANSMISSIONS 次单播 MCPS.DATA-Requests,则必须将与该路由器邻居的链路质量设置为“0”。如第5.9.7节《发送 Advertisement 》所述,路由器随后将重置其 Trickle 计时器。请注意,由于失败的 clear channel assessments
导致的传输故障不算作未收到确认。
5.9.5 路由成本和下一跳
对于路由器 ID(R),路由成本是直接发送到 R 的成本和最小多跳路由成本中的最小值。
更具体地说,如果在 Link Set 中存在 L_router_id = R 的条目,则 Cost_direct 是与 L_incoming_quality 和 L_outgoing_quality 的最小值关联的链路成本。如果没有这样的条目,则 Cost_direct 是无穷大。
如果在 Route Set 中存在 R_destination = R 的条目,并且 R_route_cost 加上到 R_next_hop 的链路成本小于或等于 MAX_ROUTE_COST,则 Cost_multihop 就是这个总和。如果没有这样的条目,或者总和大于 MAX_ROUTE_COST,则 Cost_multihop 就是无穷大。
到达 R 的路由成本是 Cost_direct 和 Cost_multihop 的最小值。如果 Cost_direct 和 Cost_multihop 都是无穷大,则 R 是不可达的。如果 Cost_direct 是有限的且小于或等于 Cost_multihop,则路由的下一跳是 R 本身。否则,下一跳是 R_next_hop。
5.9.6 循环和循环检测
到某些目的地的路由图中存在循环会导致到达该目的地的成本高于 MAX_ROUTE_COST。
没有“分割视野”循环避免。如果路由器从邻居处收到一个数据包,而该邻居是数据包目的地的下一跳,则必须从 Route Set 中删除目的地的条目。这样可以检测并移除两跳循环。
5.9.7 发送 Advertisement
路由器按照本节描述发送 MLE Advertisement 。REED 按照第5.16.6节《子节点》的描述定期发送 MLE Advertisement 。所有 MLE Advertisement 必须发送到链路本地所有节点组播地址(FF02::1)。
发送 MLE Advertisement 的速率由使用 Trickle 算法 RFC 6206 确定,使用 ADVERTISEMENT_I_MIN 和 ADVERTISEMENT_I_MAX 作为参数 I_MIN 和 I_MAX。Trickle 参数 k 设置为无穷大。 Advertisement 没有一致性检查。
当报告的到一个或多个目的地的路由成本(在 Route64 TLV 中)变为或从无穷大(表示为值“0”)时,Trickle 计时器将被重置。如果删除具有非零成本的路由器 ID,则还应将其重置。
在发送 Advertisement 时,路由器在 Route64 TLV 中包括 L_incoming_quality、L_outgoing_quality 和其 ID_set 中每个路由器 ID 的路由成本。如果到一个路由器 ID 的路由成本小于 MAX_ROUTE_COST,则 Route 值是该成本。否则,Route 值为无穷大(表示为值“0”)。
5.9.8 处理 Route64 TLVs
处理传入的 Route64 TLV 的第一步是将其路由器 ID 序列号与 ID_sequence_number 进行比较。如果 Route64 TLV 的序列号较高,则必须用 Route64 TLV 的序列号和 ID 集合替换 ID_sequence_number 和 ID_set 的值。若 Route64 TLV 的序列号比 ID_sequence_number 相同或更低,则 ID_sequence_number 和 ID_set 必须保持不变。如果接收设备具有路由器 ID,并且 MLE Advertisement 包括该 ID 的入链路质量,则发件者的 L_outgoing_quality 必须设置为该入链路质量。
最后,对于除发件者 ID 或接收者 ID 外出现在 ID_set 和 Route64 TLV 的已分配路由器 ID 掩码中的每个路由器 ID(R),设 Cost_reported 为 Route64 TLV 中 R 的路由成本。随后:
- 如果 Cost_reported = 0 且 R_next_hop == TLV 发件者 ID,则从路由器集合中删除 R。
否则,如果 Cost_reported > 0 并且以下条件满足之一:
- 路由器集合中没有路由器 ID R 的条目
- R_next_hop == TLV 发件者 ID
- 发件者链接成本 + Cost_reported < R_next_hop 链接成本 + R_route_cost 则通过将 R_next_hop 设置为发件者 ID 并将 R_route_cost 设置为 Cost_reported,添加或更新 R 条目。
REED 必须处理 Route64 TLVs,以获取 Thread 网络上的路由器数量,用于确定是否成为活跃路由器(参见第 5.9.9 节,路由器 ID 管理)。它还必须从父节点的 Route64 TLV 中获取到 Leader 的成本。如果此成本为无穷大,则子设备设置一个计时器,时间为 PARENT_ROUTE_TO_LEADER_TIMEOUT 秒。如果在计时器到期时未从父节点收到新的 Route64 TLV,则它尝试寻找并连接到具有有限 Leader 成本的新父节点。
5.9.9 路由器 ID 管理
Leader 负责管理路由器 ID。与所有路由器一样,Leader 维护一个显示已分配路由器 ID 的 ID_set。与其他路由器不同,Leader 还维护一个 ID_Assignment_Set,其中包含具有已分配 ID 的每个设备的 IEEE 802.15.4 扩展地址,对于当前未分配的 ID,则包含可以重新分配 ID 的时间。每当 Leader 分配或取消分配路由器 ID 时,它会更改其 ID_set,递增其 ID_sequence_number,并更新 ID_Assignment_Set 中路由器 ID 的条目。为了回收未使用的 ID,当 ID_sequence_number 在 ID_SEQUENCE_PERIOD 秒内保持不变时,Leader 还会递增 ID_sequence_number。如果一个路由器在 NETWORK_ID_TIMEOUT 秒内未从邻居处收到新的 ID_sequence_number,则它必须视为与 Leader 断开连接,并停止使用其当前的路由器 ID。
Leader 可以随时取消分配路由器 ID。如果路由器 ID 的路由成本已达到 INFINITE_COST_TIMEOUT,则 Leader 应该取消分配路由器 ID。当 Leader 取消分配路由器 ID 时,它会从其 ID_set 中删除该 ID,递增 ID_sequence_number,并将路由器 ID 的 Reuse_Time 设置为当前时间加上 ID_REUSE_DELAY。Leader 不应在至少 ID_REUSE_DELAY 秒内重新分配路由器 ID。
如果一个路由器根据新的网络数据确定其路由器 ID 已经取消分配,则它必须假定已与 Leader 断开连接,并按第 5.16.1 节“失去连接”的描述进行处理。
如果 Thread 网络中分区的活跃路由器数量少于 ROUTER_UPGRADE_THRESHOLD(邻近节点 Route64 TLV 报告的),REED 必须等待从检测到条件开始到 ROUTER_SELECTION_JITTER 秒之间的随机时间,然后如果条件仍然满足,则必须尝试通过向 Leader 请求路由器 ID 来成为活跃路由器。这有助于防止许多子设备同时请求路由器 ID。
如果 Thread 网络分区中的活跃路由器数量至少为 ROUTER_UPGRADE_THRESHOLD,低于 MAX_ROUTERS,并且最多有一个具有外部连接性的边界路由器在路由器角色中发挥作用,那么具有外部连接性的边界路由器应该尝试成为活跃路由器,方法是使用上述包括随机性的过程。这种方法通过边界路由器更好地连接到边网主机。
如果网络中活跃路由器的数量超过 ROUTER_DOWNGRADE_THRESHOLD,则符合以下所有条件的活跃路由器必须尝试释放其路由器 ID 并成为 REED。让 M 为满足以下条件的路由器集合的邻居路由器:
- 在 M 集合中至少有 MIN_DOWNGRADE_NEIGHBORS 个邻居。
- 至少有一个邻居与 M 集合中所有路由器具有至少与 D 本身的质量相同的更好质量的链接。
- 拥有的子设备数量少于三倍的多余路由器数量。换句话说,如果有 N 个活跃路由器且路由器有 C 个子设备,则 C < 3 *(N - ROUTER_DOWNGRADE_THRESHOLD)。
- 不是 Leader。
- 不是特定 Provisioning Domain(参见第 5.13.7 节“配置域”)的唯一边界路由器。如果多个边界路由器符合降级条件,则它们可以使用某种外部机制来选择是否进行降级。
如果成为子设备的决定是由路由器数量增加触发的,设备必须首先在检测到增加后延迟随机时间,时间为 ROUTER_SELECTION_JITTER 秒,然后重新检查总路由器数量和上述标准。这有助于防止许多路由器同时成为子设备。
5.9.10 路由器 ID 分配
想要成为路由器的 REED 必须发送地址请求消息以请求 Leader 分配一个路由器 ID。Leader 的路由器 ID 是从共享的 Thread 网络数据中获取的。
5.9.10.1 ADDR_SOL.req – 地址请求
地址请求消息定义如下:
CoAP 请求 URI
- coap://[
]:MM/a/as
交易模式
- Req+Rsp_Piggybacked 或 Req+Rsp_Separate(请求部分)
CoAP 载荷
- MAC 扩展地址 TLV
- [RLOC16 TLV]
- 状态 TLV
MAC 扩展地址 TLV 包括以便 Leader 可以跟踪 Thread 设备和 RLOC16 之间的映射关系。状态 TLV 包含表 5-10 的状态值之一,并指示发送请求的原因。如果原因是活动路由器数量少于 ROUTER_UPGRADE_THRESHOLD,则包含 TOO_FEW_ROUTERS。如果原因是发送者收到 MLE Child ID 请求消息(参见第 4.7.1 节“附着到父节点”),则包含 HAVE_CHILD_ID_REQUEST。如果一个拥有子设备的路由器移动到不同分区(参见第 5.16.4 节“重置 Thread 网络分区数据”),则包含 PARENT_PARTITION_CHANGE。如果发送者是希望通过成为路由器来提供与边网主机更好连接性的边界路由器,则包含 BORDER_ROUTER_REQUEST。
如果先前具有状态 BORDER_ROUTER_REQUEST 的请求不成功,发送者可以使用不同的状态值 HAVE_CHILD_ID_REQUEST 重复请求(在应用抖动后)。但前提是在发送请求时,边界路由器确定当前具有外部连接性的边界路由器最多只有一个是活动路由器。
RLOC16 TLV 仅在发送者先前是路由器,可能在另一个分区内,并希望保留其原始路由器 ID 时包含。Leader 不得为多个由 MAC 扩展地址标识的设备分配 RLOC16。如果状态是 HAVE_CHILD_ID_REQUEST 或 PARENT_PARTITION_CHANGE,则 Leader 为 REED 分配路由器 ID(如果有可用的)。如果状态是 BORDER_ROUTER_REQUEST,则 Leader 分配路由器 ID(如果有可用的),并且以下至少满足一个条件:
- 当前具有外部连接性的边界路由器中最多有一个是活动路由器(如 Thread 网络数据所示)。
- 路由器数量低于 ROUTER_UPGRADE_THRESHOLD。 注意:外部连接性的确定在第 5.9.9 节“路由器 ID 管理”中定义。
如果状态是 TOO_FEW_ROUTERS,则 Leader 为 REED 分配路由器 ID(如果活动路由器数量少于 ROUTER_UPGRADE_THRESHOLD)。如果状态是未分配的编号或在请求中没有意义的状态编号,则 Leader 发送包含状态 UNRECOGNIZED_STATUS 的地址请求响应。如果 REED 请求了特定的路由器 ID 并且该路由器 ID 可用,则选择该路由器 ID。如果无法为分配使用或者由于请求原因无法分配路由器 ID,则 Leader 发送包含状态 'No Address Available' 的地址请求响应。如果分配了路由器 ID,则 Leader 发送包含状态 'Success' 的响应。
5.9.10.2 ADDR_SOL.rsp – 地址请求响应
地址请求响应消息格式如下:
CoAP 响应代码
- 2.04 Changed
交易模式
- Req+Rsp_Piggybacked 或 Req+Rsp_Separate(响应部分)
CoAP 载荷
- 状态 TLV
- [RLOC16 TLV]
- [路由器掩码 TLV]
状态 TLV 包含表 5-10 中标记为有效的状态值,标记为 ADDR_SOL.rsp。RLOC16 TLV 包含分配的 RLOC16。路由器掩码 TLV 包含反映新 ID 分配的更新当前 ID 序列和路由器 ID 掩码。仅当状态为 'Success' 时才包含 RLOC16 TLV 和路由器掩码 TLV。
如果一个路由器希望返回成为子设备,它必须首先作为子设备重新连接到网络,然后必须向 Leader 发送一个包含不再使用的路由器 ID 的地址释放通知消息。在释放之前重新连接避免了与 Leader 的争用,因为 Leader 需要同时标记路由器 ID 为未分配并将其用于发送响应。
5.9.10.3 ADDR_REL.ntf – 地址释放通知
地址释放通知消息是可靠通知,格式如下:
- CoAP 请求
- URI coap://[
]:MM/a/ar
交易模式
- Ntf/Qry/Ans_CON
CoAP载荷
- MAC 扩展地址 TLV
- RLOC16 TLV
如果一个路由器希望返回成为子设备,它必须首先作为子设备重新连接到网络,然后必须向 Leader 发送一个 ADDR_REL.ntf,其中包含它不再使用的 RLOC16 路由器地址。
5.9.11 在链路超时之前发送链路请求
路由器必须监视 Link Set 中每个路由器链路的 L_age 值。如果对于给定邻居,此值增加到超过 3 * ADVERTISEMENT_I_MAX,则至少有三个连续的 MLE Advertisement 消息被丢失。在这种情况下,路由器必须向邻居路由器的链路本地地址发送 MLE 链路请求单播消息。该 MLE 链路请求消息必须延迟最多 MLE_MAX_REACTION_TIME,以毫秒为分辨率。该 MLE 链路请求消息必须包含一个 TLV 请求 TLV,用于 Route64 TLV。如果从邻居路由器收到包含 Route64 TLV 的相应 Link Accept 消息,则 Link Set 中该链路的 L_age 值应设置为 '0'。
5.10 单播数据包转发
Thread 规范支持以下类型的单播和组播数据包转发:
- 同属于 Thread 网络的源设备和目的设备之间的单播数据包转发。
- 源设备或目的设备位于 Thread 网络之外的单播数据包转发。当目的设备位于 Thread 网络之外且被用任播 IPv6 地址寻址时,也包括任播数据包转发。
- 同属于 Thread 网络的源设备和目的设备之间使用任播定位器(ALOC)目的地址的任播数据包转发。
II. 5.10.1 Thread 网络内的单播数据包转发
在同一时间内,最多会有 MAX_ROUTERS 个路由器共享其路由信息,正如 5.9 节中描述的路由协议。在 Thread 网络内,只有路由器可以执行多跳数据包转发。
5.10.1.1 完整 Thread 设备转发
在 Thread 网络内部,只使用 RLOC 进行路由。Thread 内部的多跳数据包转发使用 6LoWPAN Mesh Header 和 RLOC16 在链路层进行。FTD 需要解析 EID 到 RLOC 地址映射并维护 EID 到 RLOC 映射缓存。FTD 还直接响应 EID 到 RLOC 映射查询。FTD 执行 IPv6 数据包转发的步骤如下:
- 获取 IPv6 目的地的 RLOC。如果 IPv6 目的地址是 RLOC,则设备使用 IPv6 目的地址直接进行路由。如果 IPv6 目的地址是 ALOC,则设备使用第 5.10.3 节“Thread 网络内部的任播数据包转发”中定义的该类型 ALOC 的查找方法来确定适当的目的地的 RLOC,然后转发消息。如果 IPv6 目的地址在网内但不是 RLOC,则设备应检查其邻居表和 EID 到 RLOC 映射缓存,看看是否已知 RLOC。如果 RLOC 尚未知晓,则设备发起 EID 到 RLOC 查询,使用地址查询以获取 IPv6 目的地地址的 RLOC。如果 IPv6 目的地址在网外,则使用第 5.10.2 节“Thread 网络外的单播数据包转发”的规则确定适当的出口边界路由器的 RLOC。
- 确定 RLOC 是否属于相邻设备。如果 RLOC 属于相邻设备,则 6LoWPAN 层使用 RLOC16 编码 6LoWPAN 帧,而无需使用 6LoWPAN Mesh Header,并设置 IEEE 802.15.4 目的地址为 RLOC16。
- 如果 RLOC 不属于相邻设备,则 6LoWPAN 层使用 6LoWPAN Mesh Header 编码 6LoWPAN 帧,将 V 和 F 位设置为“1”,将 Originator Address 字段使用本地 RLOC16,将 Final Address 字段使用目的地的 RLOC16。
6LoWPAN Mesh Header 中的 hopsLft 字段必须设置为大于到达目的地的路由成本。如果设备不是活跃路由器,则 hopsLft 字段必须增加一;如果目标 RLOC16 不是活跃路由器的 RLOC16,则 hopsLft 字段也必须增加一。请注意,将 hopsLft 字段设置为 14 或更小的值会减小 6LoWPAN Mesh Header 的大小。
接着,设备使用路由集确定下一跳的 RLOC,并设置 IEEE 802.15.4 目的地址为下一跳的 RLOC16。
- 接收到数据包的下一跳设备会查找路由集/邻居表中的下一跳,减少 6LoWPAN Mesh Header 中的跳数计数,然后将数据包发送给下一跳,作为 IEEE 802.15.4 目的地址。
5.10.1.2 简化 Thread 设备转发
MTD 作为仅操作主机设备,将所有 IPv6 数据包转发到其父级,而无需使用 6LoWPAN Mesh Header。因此,父级执行 IPv6 转发(而不是 6LoWPAN 网格转发)来处理来自 MTD 子级的数据包。 具体来说,MTD 不解析 EID 到 RLOC,并依赖其 FTD 父级来执行查询并在 6LoWPAN Mesh Header 中包括 RLOC16。对于具有网外目的地的数据包,MTD 不选择边界路由器,并依赖其 FTD 父级选择适当的边界路由器。MTD 也不选择特定的 DHCPv6 代理,而是使用 DHCPv6 代理 ALOC,并依赖其 FTD 父级将数据包传递给适当的 DHCPv6 代理。MTD 不选择特定的服务器,而是使用适当服务类型 ID 的服务 ALOC,并依赖其 FTD 父级将数据包传递给适当的服务器。MTD 也可以以类似的方式使用其他 ALOC 类型。
5.10.1.3 使用 Mesh Address Headers 转发数据包
RFC 4944 的第 11 节描述了如何使用“链路层路由表”中的信息转发带有 Mesh Addressing headers 的数据包。在 Thread 网络中,该表将 Mesh Addressing 头中的目标 RLOC16 映射到到达目的地的下一跳的 RLOC16。在活跃路由器上,此表格如下填充:
- 如果有到路由器 R 的路由,则链路层路由表具有 R 的 RLOC16 条目和对应于 R 的潜在子级的 RLOC16。这些条目的下一跳是到达 R 的路由的下一跳。
- 对于 Mode 位 D=1 的每个此路由器的子级,有一个将子级的 RLOC16 映射到子级本身的条目。此类条目的下一跳是子级。
- 对于 Mode 位 D=0 的每个此路由器的子级,有一个将子级的 RLOC16 映射到路由器本身的条目。此类条目没有下一跳。路由器移除 Mesh Header,并根据第 5.10.1.1 节“完整 Thread 设备转发”的规定将数据包传递给子级。 请注意:以上规则意味着父级将指示其 Mode 位 D=0 子级的 mesh 目的地视为自己的 RLOC16。 一旦带有 6LoWPAN Mesh Header 的数据包到达 Mesh Header 指示的路由器,该路由器会移除 Mesh Header 并根据第 5.10.1.1 节“完整 Thread 设备转发”的规定将数据包传递给自身或子级。 对于 REEDs 和 FEDs,所有 RLOC16 的下一跳是父级。MTD 不接收或处理 mesh header,并且没有链路层路由表。
III. 5.10.2 在 Thread 网络之外的单播数据包转发
Thread 边界路由器必须在 Thread 接口和其他接口之间实现 IP 层的数据包转发,以确保与外部网络或互联网的通信。Thread 边界路由器向 Leader 提供关于它们提供的有效前缀集合的默认路由以及对于给定有效前缀提供的任何其他特定路由的信息。Leader 聚合边界路由器信息,并在整个 Thread 网络分区中传播此信息。Thread 网络数据使用 RLOC16 识别边界路由器。
从 Thread 网络发出的消息在链路层使用 6LoWPAN Mesh Header 从发起节点根据以下规则转发到适当的边界路由器,然后由边界路由器将数据包转发到其他接口。有关此转发的详细信息请参阅第 9.3.2 节,在第 9 章边界路由器中内部和外部接口之间的数据包转发。
如果 IPv6 目标地址不在网内,则路由器使用 IPv6 源地址确定提供与 IPv6 源地址的前缀相同的 Provisioning Domain 的边界路由器集合。
在该集合中,路由器按以下方式找到最佳的出口边界路由器:
- 查找与 IPv6 目标地址具有最长前缀匹配的 External Route Set 前缀。
- 如果有多个 External Route 前缀匹配,选择具有更高优先级(R_preference)的前缀。
- 如果没有 External Route 前缀匹配,则选择提供默认路由的边界路由器。
- 如果有多个边界路由器提供默认路由,则选择具有更高优先级(P_preference)的边界路由器。
- 如果有两个或更多优先级相同的边界路由器,则选择具有最低网格路径成本的边界路由器。
- 最后,如果没有边界路由器提供默认路由,则路由此数据包失败。路由器应按照第 5.8 节 ICMPv6 中指定的方式向数据包的 IPv6 源发送 ICMPv6 Destination Unreachable 消息,其中 ICMPv6 Code 为 0。
Thread 网络的传入消息基于 GUA 或补充 ULA 地址,边界路由器使用其内部地址表或地址查询来识别最终目的地的 RLOC。提供用于 SLAAC 或 DHCPv6 地址配置的前缀的边界路由器可以为网内或网外使用该前缀发送地址查询(有关更多信息,请参阅第 9 章边界路由器中的第 9.2.3 节全局地址和第 9.2.4 节补充唯一本地地址)。完成此步骤后,边界路由器根据第 5.10.1 节中描述的算法将数据包转发到网格目的地。
IV. 5.10.3 Thread 网络内的任播数据包转发
使用 ALOC 目标的 IPv6 数据包的路由由 FTDs 完成,如第 5.10.1.1 节“完整 Thread 设备转发”所定义,使用本节为每种 ALOC 类型定义的特定查询方法。
在以下子部分中,“传递到此 ALOC 失败” 表示路由器必须返回数据包的 IPv6 源,使用 ICMPv6 Destination Unreachable 消息,并将 ICMPv6 Code 设置为“0”(无法到达目的地)。ICMPv6 消息负载必须至少包含原始消息的完整 IPv6 头。
5.10.3.1 Leader ALOC
Leader ALOC 解析为 Leader Data 中 Leader Router ID 字段中的 RLOC。
5.10.3.2 DHCPv6 Agent ALOC
如果 IPv6 目标地址是 DHCPv6 代理 ALOC,则路由器使用 ALOC 中编码的上下文 ID 来确定相关前缀。对于此前缀,它考虑提供该服务的 DHCPv6 代理集合(即,提供该前缀且 P_dhcp = true 的边界路由器)。在该集合中,路由器按以下方式找到“最近”的 DHCPv6 代理:
- 如果集合中有多个 DHCPv6 代理,则选择具有最低网格路径成本的代理。
- 如果集合中没有 DHCPv6 代理,则传递到此 ALOC 失败。
5.10.3.3 Service ALOC
如果 IPv6 目标地址是 Service ALOC,则路由器使用服务类型 ID 查找 Thread 网络数据中提供该服务类型的服务器集合。然后选择具有最低网格路径成本的服务器作为目的地 RLOC。如果没有具有该服务类型 ID 的服务器,则传递到此 ALOC 失败。
5.10.3.4 Commissioner ALOC
如果 IPv6 目标地址是 Commissioner ALOC,则路由器将此 ALOC 中编码的值 N 与当前 Commissioner 会话 ID 进行比较(从 Commissioner Dataset 获取)。如果相等,则将 ALOC 解析为 Commissioner Dataset 中的 Border Agent Locator RLOC16 字段。在其他情况下,传递到此 ALOC 失败。
5.10.3.5 Neighbor Discovery Agent ALOC
如果 IPv6 目标地址是 Neighbor Discovery Agent ALOC,则路由器使用 ALOC 中编码的上下文 ID 来确定相关前缀。对于此前缀,它考虑提供该服务的 Neighbor Discovery Agent 集合(即,提供该前缀且 P_nd = true 的边界路由器)。在该集合中,路由器按以下方式找到“最近”的 ND 代理:
- 如果集合中有多个 ND 代理,则选择具有最低网格路径成本的代理。
- 如果集合中没有 ND 代理,则传递到此 ALOC 失败。
5.10.3.6 Primary Backbone Router ALOC
如果 IPv6 目标地址是 Primary Backbone Router ALOC(PBBR ALOC),则路由器首先选择使用以下算法的 Primary BBR 的 Server TLV。将 S 初始化为 BBR Dataset 中所有 Server TLV 的集合。然后:
- 如果 S 为空,则选择无,并完成此算法。
- 如果 S 的大小为一个,则选择该集合成员并完成此算法。
选择具有最高优先级的 S 中成员,规则如下:
- 规则 1:Leader 的 Server TLV 优先级高于非 Leader 的 Server TLV。
- 规则 2:前述规则相同时,具有更高 BBR Sequence Number 的 Server TLV 优先级高。
- 规则 3:前述规则相同时,具有更高 RLOC16 值的 Server TLV 优先级高。 最后,如果选择了 Server TLV,则使用该 Server TLV 中的 RLOC16 作为目的地。否则,传递到此 ALOC 失败。
V. 5.10.4 链路层目的地地址的选择
发送到 rx-off-when-idle 子设备的单播数据包的链路层目的地可以是该子设备的 RLOC16,而不管 IP 目标如何,并且消息必须使用适当的链路层单播传输发送。
如果 IP 目标是链路本地单播地址,则链路层目的地是相应的 MAC 扩展地址,由 IP 目标的 64 位 IID 和通用/本地位取反而得。请注意,Thread 设备不根据其 16 位 MAC 地址配置链路本地地址。
在所有其他情况下,数据包的下一跳是一个 RLOC。如果数据包有网格头,则 RLOC 是通向网格头目的地的下一跳。否则,它是由上述第 5.10.1.1 至 5.10.1.3 节中定义的单播/任播转发规则确定的。
还不快抢沙发