6. 路由器和前缀发现
本节描述路由器发现和前缀发现. Router Discovery 是主机定位位于所连接链路上的路由器的过程. Prefix Discovery 是主机发现一组地址前缀的过程, 这些前缀定义了对于某条连接链路而言哪些目的地位于链路上.
主机使用通告的链路上前缀来构建和维护一个列表, 该列表用于判断报文的目的地是在链路上, 还是需要经过路由器. 默认情况下, 主机会从 Router Advertisement 中学习所有链路上前缀. 但是, 路由器可以被配置为在 Router Advertisement 中省略部分或全部前缀. 在这种情况下, 主机会假定目的地位于链路外, 并将流量发送给路由器. 路由器随后可以按需要发出 redirect.
6.1. 消息验证
6.1.1. Router Solicitation 消息的验证
主机必须静默丢弃任何收到的 Router Solicitation 消息.
路由器必须静默丢弃任何不满足以下所有有效性检查的已接收 Router Solicitation 消息:
-
IP Source Address 是链路本地地址. 如果 solicitation 的源地址是未指定地址, 路由器不得向多播地址 (all-nodes 多播地址除外) 发送 Router Advertisement. 此限制用于防止恶意节点发起拒绝服务攻击.
-
IP Hop Limit 字段的值为 255, 即该报文不可能已被路由器转发.
-
ICMP Checksum 有效.
-
ICMP Code 为 0.
-
ICMP 长度 (从 IP 长度推导) 为 8 个或更多八位组.
-
所有包含的选项长度均大于零.
如果在某个接口上接收到根据上述检查有效的 Router Solicitation, 且该接口是 advertising interface, 则路由器可以按下文所述以多播 Router Advertisement 响应, 或以目的地为请求节点地址的单播 Router Advertisement 响应. 如果 Router Solicitation 是从单播地址发送的, 路由器应以单播 Router Advertisement 响应; 如果 Router Solicitation 是从未指定地址发送的, 则应以多播 Router Advertisement 响应.
6.1.2. Router Advertisement 消息的验证
节点必须静默丢弃任何不满足以下所有有效性检查的已接收 Router Advertisement 消息:
-
IP Source Address 是链路本地地址. 路由器必须使用其链路本地地址作为 Router Advertisement 和 Redirect 消息的源地址, 以便主机能够唯一识别路由器.
-
IP Hop Limit 字段的值为 255, 即该报文不可能已被路由器转发.
-
ICMP Checksum 有效.
-
ICMP Code 为 0.
-
ICMP 长度 (从 IP 长度推导) 为 16 个或更多八位组.
-
所有包含的选项长度均大于零.
Reserved 字段以及任何无法识别的选项的内容必须被忽略. 将来对协议进行向后兼容的更改时, 可以规定 Reserved 字段的内容或添加新选项; 向后不兼容的更改可以使用不同的 Code 值.
任何已定义但未被规定可用于 Router Advertisement 消息的选项的内容必须被忽略, 并且报文按正常方式处理. 唯一可能出现的已定义选项是 Source Link-Layer Address, MTU 和 Prefix Information 选项.
通过有效性检查的 Router Advertisement 称为 "valid Router Advertisement".
6.2. 路由器规范
6.2.1. 路由器配置变量
对于每个 advertising interface, 路由器必须允许系统管理配置以下概念变量:
MaxRtrAdvInterval - 从该接口发送非请求多播 Router Advertisement 之间允许的最大时间, 单位为秒.必须不小于 4 秒且不大于 1800 秒.
Default: 600 秒
MinRtrAdvInterval - 从该接口发送非请求多播 Router Advertisement 之间允许的最小时间, 单位为秒.必须不小于 3 秒且不大于 .75 * MaxRtrAdvInterval.
Default: 0.33 * MaxRtrAdvInterval
AdvManagedFlag - 放入 Router Advertisement 中 "Managed address configuration" 标志的值. 参见 [ADDRCONF].
Default: FALSE
AdvOtherConfigFlag - 放入 Router Advertisement 中 "Other configuration" 标志的值. 参见 [ADDRCONF].
Default: FALSE
AdvLinkMTU - 放入路由器发送的 MTU 选项中的值. 值为零表示不发送 MTU 选项.
Default: 0
AdvReachableTime - 放入路由器发送的 Router Advertisement 消息的 Reachable Time 字段中的值. 值为零表示 (由该路由器) 未指定.必须不大于 3,600,000 毫秒 (1 小时).
Default: 0
AdvRetransTimer - 放入路由器发送的 Router Advertisement 消息的 Retrans Timer 字段中的值. 值为零表示 (由该路由器) 未指定.
Default: 0
AdvCurHopLimit - 放入路由器发送的 Router Advertisement 消息的 Cur Hop Limit 字段中的值. 该值应设置为当前 Internet 的直径. 值为零表示 (由该路由器) 未指定.
Default: 实现时有效的 "Assigned Numbers" [ASSIGNED] 中指定的值.
AdvDefaultLifetime - 放入从该接口发送的 Router Advertisement 的 Router Lifetime 字段中的值, 单位为秒.必须为零, 或者位于 MaxRtrAdvInterval 与 9000 秒之间. 值为零表示该路由器不应被用作默认路由器. 描述 IPv6 如何在不同链路层上运行的特定文档可以覆盖这些限制. 例如, 在点到点链路中, 对端可能已经充分了解另一端设备的数量和状态, 因而不需要通告.
Default: 3 * MaxRtrAdvInterval
AdvPrefixList - 要放入从该接口发送的 Router Advertisement 消息中的 Prefix Information 选项的前缀列表.
Default: 路由器通过路由协议通告为从发送该通告的接口看是链路上的所有前缀.
对于在 Prefix Information 选项中通告的每个前缀, 路由器必须还允许配置以下变量:
AdvValidLifetime - 放入 Prefix Information 选项中 Valid Lifetime 的值, 单位为秒. 指定值全 1 (0xffffffff) 表示无限.
Default: 2592000 秒 (30 天), 固定值 (即在连续通告中保持不变).
AdvOnLinkFlag - 放入 Prefix Information 选项中 on-link flag ("L-bit") 字段的值.
Default: TRUE
AdvPreferredLifetime - 放入 Prefix Information 选项中 Preferred Lifetime 的值, 单位为秒. 指定值全 1 (0xffffffff) 表示无限.
Default: 604800 秒 (7 天), 固定值 (即在连续通告中保持不变).
AdvAutonomousFlag - 放入 Prefix Information 选项中 Autonomous Flag 字段的值.
Default: TRUE
6.2.2. 成为 Advertising Interface
术语 "advertising interface" 指路由器在其上定期发送 Router Advertisement 的任何接口. 路由器必须允许系统管理员将某个接口设为 advertising interface.
接口可以在任何时候成为 advertising interface. 当它成为 advertising interface 时, 路由器:
-
按 [ADDRCONF] 中的说明初始化该接口.
-
调度从该接口发送第一条 Router Advertisement. 发送时间的选择应使该通告在 0 到 MAX_INITIAL_RTR_ADVERT_INTERVAL 之间均匀分布的某个时间发送.
6.2.3. Router Advertisement 消息内容
路由器会从其 advertising interface 发送周期性以及被请求的 Router Advertisement. 发出的 Router Advertisement 按 Section 4.2 给出的消息格式填入以下值:
-
在 Router Lifetime 字段中: 接口配置的 AdvDefaultLifetime.
-
在 M 和 O 标志中: 分别为接口配置的 AdvManagedFlag 和 AdvOtherConfigFlag.
-
在 Cur Hop Limit 字段中: 接口配置的 CurHopLimit.
-
在 Reachable Time 字段中: 接口配置的 AdvReachableTime.
-
在 Retrans Timer 字段中: 接口配置的 AdvRetransTimer.
-
在选项中:
-
Source Link-Layer Address option: 接口的链路层地址. 此选项应该被包含, 但在没有地址的链路上可以省略.
-
MTU option: 如果接口配置的 AdvLinkMTU 值非零, 则为该值. 如果 AdvLinkMTU 为零, 则不发送 MTU 选项.
-
Prefix Information options: AdvPrefixList 中列出的每个前缀对应一个 Prefix Information 选项. 每个 Prefix Information 选项包含以下字段:
- 在 "on-link" 标志中: AdvOnLinkFlag
- 在 Valid Lifetime 字段中: AdvValidLifetime
- 在 "autonomous address-configuration" 标志中: AdvAutonomousFlag
- 在 Preferred Lifetime 字段中: AdvPreferredLifetime
- 在 Prefix 中: 被通告的前缀
-
路由器可以包含除上述选项以外的选项.
6.2.4. 发送非请求 Router Advertisement
路由器发送非请求 Router Advertisement 来宣告其存在, 并通告各种链路和 Internet 参数. 对于每个 advertising interface, 路由器会向 all-nodes 多播地址周期性发送多播 Router Advertisement.
Router Advertisement 的发送速率由路由器的配置变量 MaxRtrAdvInterval 和 MinRtrAdvInterval 控制. 当接口成为 advertising interface 时, 路由器会在该接口上初始化一个定时器, 该定时器在发送第一条通告后到期. 定时器被设置为在 0 到 MAX_INITIAL_RTR_ADVERT_INTERVAL 之间均匀分布的某个时间到期.
第一条通告之后, 后续 Router Advertisement 会在定时器到期时发送. 每当定时器到期时, 它会被重置为 MinRtrAdvInterval 与 MaxRtrAdvInterval 之间均匀分布的某个值.
6.2.5. 停止作为 Advertising Interface
接口可以在任何时候停止作为 advertising interface. 例如, 正在关闭的路由器或正在禁用的接口可以停止作为 advertising interface. 在这种情况下, 路由器应该在该接口上发送一个或多个 (但不超过 MAX_FINAL_RTR_ADVERTISEMENTS 个) 最终多播 Router Advertisement, 其 Router Lifetime 字段为零. 对于正在关闭的路由器,应该先声明该接口停止作为 advertising interface, 然后发送最终 Router Advertisement. 如果路由器知道某个接口可能会有一段时间不可用 (例如由于即将断电), 路由器可以以更快的速率发送最终 Router Advertisement (即比每 MinRtrAdvInterval 一次更频繁).
6.2.6. 处理 Router Solicitation
主机必须静默丢弃任何收到的 Router Solicitation 消息.
除了发送周期性的非请求通告以外, 路由器还会响应在 advertising interface 上收到的有效 Router Solicitation 而发送 Router Advertisement. 路由器可以选择将响应单播直接发送到请求主机的地址 (如果 solicitation 的源地址不是未指定地址), 但通常情况是将响应多播到 all-nodes 组. 在后一种情况下, 接口的间隔定时器会被重置为一个新的随机值, 就像已经发送了一条非请求通告一样 (参见 Section 6.2.4).
在所有情况下, 响应 Router Solicitation 而发送的 Router Advertisement 必须延迟一个介于 0 和 MAX_RA_DELAY_TIME 秒之间的随机时间. (如果单条通告是为响应多个 solicitation 而发送, 该延迟相对于第一个 solicitation 计算.) 此外, 连续发送到 all-nodes 多播地址的 Router Advertisement 必须受到速率限制, 不得超过每 MIN_DELAY_BETWEEN_RAS 秒一条通告.
如果路由器的配置表明不应在该接口上发送 Router Advertisement, 路由器可以选择忽略 Router Solicitation.
6.2.7. Router Advertisement 一致性
为最大程度降低错误配置的可能性, 路由器应该在其通告的值上保持一致. 也就是说, 同一链路上的路由器应该为 AdvCurHopLimit, AdvManagedFlag, AdvOtherConfigFlag, AdvLinkMTU, AdvReachableTime 和 AdvRetransTimer 通告相同的值. 但是, 并不要求这种一致性, 如果路由器通告不同的值, 系统仍应工作, 尽管可能不如一致时工作得好.
如果链路上的路由器为 AdvCurHopLimit 通告不同的值, 主机会使用最近学习到的通告值. 如果 AdvCurHopLimit 发生变化, 部分主机可能使用一个值, 而其他主机可能使用另一个值, 直到所有主机都收到通告新值的 Router Advertisement.
如果路由器为 AdvReachableTime 或 AdvRetransTimer 通告不同的值, 主机会按 Section 6.3.2 中的说明计算自己的值.
如果路由器为 AdvDefaultLifetime 通告不同的值, 主机会优先选择通告最大值的路由器.
6.3. 主机规范
6.3.1. 主机配置变量
对于每个接口, 主机应该允许系统管理配置以下变量:
DupAddrDetectTransmits - 在对 tentative address 执行 Duplicate Address Detection 时连续发送的 Neighbor Solicitation 消息数量. 值为零表示不对 tentative address 执行 Duplicate Address Detection. 值为一表示只发送一次, 不进行后续重传.
Default: 1, 但可以由覆盖特定链路类型上运行 IP 的文档中的链路类型专用值覆盖.
6.3.2. 主机变量
主机按每个接口维护以下变量:
RouterList - 默认路由器列表, 如 Section 5 中所定义.
PrefixList - 前缀列表, 如 Section 5 中所定义.
LinkMTU - 链路的 MTU 值. 使用链路层提供的 linkmtu 值初始化.
CurHopLimit - 放入外发 IP 报文 IP 头部 Hop Count 字段的默认值. 初始化为 "IPv6 Assigned Numbers" 文档 [ASSIGNED] 中指定的值.
BaseReachableTime - 用于计算随机 ReachableTime 值的基础值. 初始化为 REACHABLE_TIME.
ReachableTime - 在收到可达性确认后, 邻居被认为可达的时间. ReachableTime 由 Neighbor Unreachability Detection 算法使用 (参见 Section 7.3). 它从 Router Advertisement 中学习, 或设置为默认值. 它是在 MIN_RANDOM_FACTOR 和 MAX_RANDOM_FACTOR 倍 BaseReachableTime 之间均匀分布的随机值. 当 BaseReachableTime 发生变化时 (由于 Router Advertisement), 或者即使没有收到 Router Advertisement 也至少每隔数小时, 都应计算一个新的随机值.
RetransTimer - 在解析地址或探测邻居可达性时, 向邻居重传 Neighbor Solicitation 消息之间的时间. 也用于 Duplicate Address Detection 期间 (参见 [ADDRCONF]). RetransTimer 从 Router Advertisement 中学习, 或设置为默认值.
6.3.3. 接口初始化
主机在所有支持多播的接口上加入 all-nodes 多播地址.
6.3.4. 处理接收的 Router Advertisement
收到有效 Router Advertisement 时, 主机会提取报文的源地址并执行以下操作:
-
如果该地址尚未出现在主机的 Default Router List 中, 且该通告的 Router Lifetime 非零, 则在列表中创建新条目, 并使用该通告的 Router Lifetime 字段初始化其失效定时器值.
-
如果由于之前收到的通告, 该地址已经出现在主机的 Default Router List 中, 则将其失效定时器重置为新收到通告中的 Router Lifetime 值.
-
如果该地址已经出现在主机的 Default Router List 中, 且收到的 Router Lifetime 值为零, 则按 Section 6.3.5 的规定立即使该条目超时.
Router Advertisement 字段 (例如 Cur Hop Limit, Reachable Time 和 Retrans Timer) 可以包含表示未指定的值. 在这种情况下, 应忽略该参数, 主机应继续使用其已经在使用的值.
如果收到的 Cur Hop Limit 值非零, 主机应该将其 CurHopLimit 变量设置为收到的值.
如果收到的 Reachable Time 值非零, 主机应该将其 BaseReachableTime 变量设置为收到的值. 如果新值不同于之前的值, 主机应该重新计算一个新的随机 ReachableTime 值.
如果收到的 Retrans Timer 值非零, 主机应该将其 RetransTimer 变量设置为收到的值.
如果存在 MTU 选项, 只要该值大于或等于最小链路 MTU [IPv6], 且不超过链路类型专用文档中指定的默认 LinkMTU 值 (例如 [IPv6-ETHER]), 主机应该将该选项的值复制到 LinkMTU.
设置了 "on-link" (L) 标志的 Prefix Information 选项表示一个前缀, 该前缀标识一段应被认为位于链路上的地址范围. 但是请注意, on-link 标志设置为零的 Prefix Information 选项不传达任何关于链路上判断的信息, 并且不得被解释为该前缀覆盖的地址位于链路外. 禁用先前已通告前缀的唯一方法是以 Valid Lifetime 设置为零的方式通告该前缀. (参见 Section 6.3.5).
对于每个设置了 on-link 标志的 Prefix Information 选项, 主机会执行以下操作:
-
如果该前缀尚未出现在 Prefix List 中, 且 Prefix Information 选项的 Valid Lifetime 字段非零, 则为该前缀创建新条目, 并将其失效定时器初始化为 Prefix Information 选项中的 Valid Lifetime 值.
-
如果由于之前收到的通告, 该前缀已经出现在主机的 Prefix List 中, 则将其失效定时器重置为 Prefix Information 选项中的 Valid Lifetime 值. 如果新的 Lifetime 值为零, 则立即使该前缀超时 (参见 Section 6.3.5).
-
如果 Prefix Information 选项的 Valid Lifetime 字段为零, 且该前缀不存在于主机的 Prefix List 中, 则静默忽略该选项.
autonomous address-configuration 标志 (A-flag) 指示该前缀是否可用于无状态地址自动配置. A-flag 的处理在 [ADDRCONF] 中规定.
6.3.5. 前缀和默认路由器超时
当前缀的 Valid Lifetime 到期时, 该前缀会从 Prefix List 中移除. 前缀在其 Valid Lifetime 到期时失效.
每当 Default Router List 中某个条目的失效定时器到期时, 该条目会被丢弃. 从 Default Router List 中移除路由器时, 节点必须更新 Destination Cache, 使所有使用该路由器的条目重新执行下一跳确定, 而不是继续向 (已删除的) 路由器发送流量.
6.3.6. 默认路由器选择
选择默认路由器的算法取决于 Host 的策略. 该算法可以是移动性解决方案的一部分.
以下规则表示在没有更好算法时应该使用的 Default Router Selection 算法.
-
可达或可能可达的路由器 (即处于 INCOMPLETE 以外的任何状态) 应该优先于可达性未知或可疑的路由器 (即处于 INCOMPLETE 状态的路由器). 实现可以选择始终返回同一路由器, 或以 round-robin 方式在路由器列表中轮转, 只要在存在可达路由器时始终返回可达路由器即可.
-
当列表中没有已知可达或可能可达的路由器时,应该以 round-robin 方式选择路由器, 这样后续默认路由器请求在所有其他路由器都被选择过之前不会返回同一路由器.
在这种情况下遍历路由器列表, 可确保在没有已知可达路由器时主动测试所有可用路由器的可达性.
6.3.7. 发送 Router Solicitation
当接口变为 enabled 时, 主机可以发送最多 MAX_RTR_SOLICITATIONS 条 Router Solicitation 消息. 但是, 在不预期收到 unsolicited Router Advertisement 的接口上 (例如 host-only 链路, 或主机已配置默认路由器的链路), 不需要发送 Router Solicitation.
主机向 all-routers multicast address 发送 Router Solicitation.
主机应该发送最多 MAX_RTR_SOLICITATIONS 条 Router Solicitation 消息, 每条之间至少间隔 RTR_SOLICITATION_INTERVAL 秒. 但是, 为避免网络拥塞, 第一次发送前的延迟应该是 0 到 MAX_RTR_SOLICITATION_DELAY 之间均匀分布的随机值. 此延迟确保不同主机的 Router Solicitation 不会同步.
在发送 MAX_RTR_SOLICITATIONS 条 solicitation 后, 主机将收到 Router Advertisement, 或得出链路上没有路由器的结论. 一旦主机已发送 MAX_RTR_SOLICITATIONS 条 solicitation, 它应该继续接收和处理在其停止发送 Router Solicitation 后可能到达的 Router Advertisement.