跳到主要内容

5. 主机的概念模型

虽然并不要求实现必须符合某个特定的主机概念模型, 本节描述了一个可供主机用来理解 Neighbor Discovery 的概念模型. 从概念上说, 主机会维护若干数据结构:

Neighbor Cache - 一组关于各个邻居的条目, 这些邻居是近期曾被发送过流量的对象. 条目以邻居的链路上单播 IP 地址作为键, 并包含其链路层地址, 一个指示该邻居是路由器还是主机的标志 (本文称为 IsRouter), 指向等待地址解析完成的所有排队报文的指针, 等等. Neighbor Cache 条目还包含 Neighbor Unreachability Detection 算法使用的信息, 包括可达性状态, 未应答探测的数量, 以及下一次 Neighbor Unreachability Detection 事件计划发生的时间.

Destination Cache - 一组关于近期曾被发送过流量的目的地的条目. Destination Cache 包括链路上目的地和链路外目的地, 并提供到 Neighbor Cache 的一层间接映射; Destination Cache 将目的地 IP 地址映射到下一跳邻居的 IP 地址. 不同于 Neighbor Cache, Destination Cache 同时包含链路上和链路外目的地的条目. 将 Destination Cache 与 Neighbor Cache 分开维护有多个目的. 首先, Destination Cache 可以包含并非链路相邻节点的目的地条目. 其次, Destination Cache 可以包含受 Path MTU Discovery, Redirect 消息等影响的条目.

Prefix List - 定义一组链路上地址的前缀列表. Prefix List 条目根据 Router Advertisement 中接收的信息创建. 每个条目都有一个关联的失效定时器值 (从通告中提取), 用于使前缀过期. Prefix List 条目还包含一个标志, 指示该前缀是否可按 [ADDRCONF] 的规定用于链路上判断和/或地址自动配置.

Default Router List - 可向其发送报文的路由器列表. Default Router List 条目指向 Neighbor Cache 中的条目; 选择默认路由器的算法会优先选择已知可达的路由器, 而不是可达性可疑的路由器. 每个条目也都有一个关联的失效定时器值 (从 Router Advertisement 中提取), 用于删除不再被通告的条目.

上述概念数据结构在功能上彼此独立; 实现可以按照最方便的方式合并其中的一部分或全部. 使用上述数据结构并配合后续各节中的伪代码, 可以直接满足本协议的要求. 但是, 只要实现的外部行为保持不变, 实现也可以使用其他数据结构.

5.1. 概念数据结构

虽然主机并非必须维护下文描述的所有数据结构, 本节描述的一组数据结构足以实现 Neighbor Discovery.

5.2. 概念发送算法

当节点有报文要发送时, 它首先检查 Destination Cache. 如果目的地没有对应条目, 节点会创建一个条目, 并通过调用下一跳确定算法 (Section 5.2) 初始化其下一跳地址. 创建 Destination Cache 条目后, 节点随后检查下一跳对应 Neighbor Cache 条目的状态.

Neighbor Cache 条目可以处于五种状态之一:

INCOMPLETE - 正在对该条目执行地址解析. 具体来说, 已经向目标的 solicited-node 多播地址发送了 Neighbor Solicitation, 但尚未收到对应的 Neighbor Advertisement.

REACHABLE - 已知该条目最近是可达的 (几十秒以内). 在最近 ReachableTime 毫秒内收到了正向确认, 表明到该邻居的前向路径工作正常. 处于 REACHABLE 状态时, 发送报文不会触发特殊动作.

STALE - 已知该条目最近是可达的, 但最近未收到确认. 处于 STALE 状态时, 在发送报文之前不执行任何动作. 发送报文时, 节点会根据实现将该条目转换为 DELAY 或 PROBE.

DELAY - 已知该条目最近是可达的, 并且在最近 DELAY_FIRST_PROBE_TIME 秒内发送过报文. 如果进入 DELAY 状态后的 DELAY_FIRST_PROBE_TIME 秒内没有收到可达性确认, 则发送 Neighbor Solicitation 并将状态改为 PROBE. 延迟发送探测报文可以给上层协议提供可达性确认的机会.

PROBE - 通过每隔 RetransTimer 毫秒重传 Neighbor Solicitation 主动寻求可达性确认, 直到收到可达性确认为止.

Neighbor Cache 还保存运行 Neighbor Unreachability Detection 算法所需的信息, 包括各种定时器, 计数器等.

向邻居发送报文时, 节点使用 Neighbor Cache 条目中包含的状态信息来确定在向该邻居发送流量之前是否需要执行任何操作. 下面的伪代码说明了发送算法:

if (Destination Cache entry exists) {
next hop = Destination Cache next_hop;
} else {
next hop = Next-hop determination (Section 5.2);
create Destination Cache entry;
}

if (Neighbor Cache entry exists for next hop) {
if (Neighbor Cache entry state == INCOMPLETE) {
queue packet on Neighbor Cache entry;
/* Address resolution already in progress */
}
if (Neighbor Cache entry state == REACHABLE) {
send packet;
}
if (Neighbor Cache entry state == STALE) {
send packet;
set Neighbor Cache entry state to DELAY;
set Neighbor Cache entry timer to DELAY_FIRST_PROBE_TIME;
}
if (Neighbor Cache entry state == DELAY) {
send packet;
/* timer is already set */
}
if (Neighbor Cache entry state == PROBE) {
send packet;
/* Neighbor Unreachability Detection is in progress */
}
} else {
create Neighbor Cache entry;
set Neighbor Cache entry state to INCOMPLETE;
if (link layer address is readily available) {
set link-layer address;
set Neighbor Cache entry state to STALE;
send packet;
} else {
queue packet on Neighbor Cache entry;
start address resolution;
}
}

5.3. 垃圾回收和超时要求

Neighbor Cache, Destination Cache 和 Prefix List 必须进行垃圾回收并设置超时. 但是, 本规范有意不规定具体的超时时间. 超时时间必须在维护陈旧信息和更新该信息的成本之间取得合理平衡. 一般来说, 超时时间应足够宽裕, 以避免缓存内容反复抖动, 但也要足够短, 以避免长期陈旧.

概念性实现可以使用以下规则:

  • Neighbor Cache 条目在转换到 STALE 状态后, 应至少保留 ReachableTime 指定的一段时间. 但是, 如果实现使用某种垃圾回收算法来回收条目, 它们可以保留更长时间. INCOMPLETE 状态的条目不需要保留这么长的时间.

  • Destination Cache 条目应尽可能长时间地保留在缓存中 (即无限期). 但是, 具体时长取决于实现. 如果收到指定到某个目的地存在更优路由的 Redirect 消息, 实现应该使对应 Destination Cache 条目失效.

  • Prefix List 中的条目按照 Router Advertisement 中指定的生命周期超时. 当新的 Router Advertisement 到达时, 条目的生命周期会被更新.

  • Default Router List 中的条目按照 Router Advertisement 中指定的 Router Lifetime 超时. 收到 Router Lifetime 为零的 Router Advertisement 表示应立即从 Default Router List 中移除该路由器.