8. Redirect 功能
Redirect 消息由路由器用于告知主机某个目的地存在更好的第一跳. 路由器只会针对由该路由器转发的报文发送 Redirect 消息. 主机必须静默丢弃任何不满足 Section 8.1 中全部有效性检查的已接收 Redirect 消息.
8.1. Redirect 消息的验证
主机必须静默丢弃任何不满足以下全部有效性检查的已接收 Redirect 消息:
-
Redirect 的 IP 源地址与指定 ICMP Destination Address 的当前第一跳路由器相同.
-
IP Hop Limit 字段的值为 255, 即该报文不可能已被路由器转发.
-
ICMP Checksum 有效.
-
ICMP Code 为 0.
-
ICMP 长度 (从 IP 长度推导) 为 40 个或更多八位组.
-
Redirect 的 IP 源地址是链路本地地址. 路由器必须使用其链路本地地址作为 Redirect 消息的源地址, 以便主机能够唯一识别路由器.
-
redirect 消息中的 ICMP Destination Address 字段不包含多播地址.
-
ICMP Target Address 要么是链路本地地址 (当重定向到路由器时), 要么与 ICMP Destination Address 相同 (当重定向到链路上目的地时).
-
所有包含的选项长度均大于零.
Reserved 字段以及任何无法识别的选项的内容必须被忽略. 将来对协议进行向后兼容的更改时, 可以规定 Reserved 字段的内容或添加新选项; 向后不兼容的更改可以使用不同的 Code 值.
任何已定义但未被规定可用于 Redirect 消息的选项的内容必须被忽略, 并且报文按正常方式处理. 唯一可能出现的已定义选项是 Target Link-Layer Address 和 Redirected Header 选项.
8.2. 路由器规范
在受速率限制约束的情况下, 每当路由器转发一个并非明确发往自身的报文, 且满足以下条件时, 路由器应该发送 Redirect 消息:
-
该报文的 Source Address 字段标识一个邻居, 并且
-
对于该报文的 Destination Address, 路由器确定在与发送节点相同的链路上存在更好的第一跳节点, 并且
-
该报文的 Destination Address 不是多播地址.
发送的 Redirect 消息包含:
-
在 Target Address 字段中: 后续发往该目的地的报文应发送到的地址. 如果目标是路由器,必须使用该路由器的链路本地地址. 如果目标是主机, Target Address 字段必须设置为与触发该 Redirect 的 IP 报文的 Destination Address 相同的值.
-
在 Destination Address 字段中: 触发该 Redirect 的 IP 报文的目的地地址.
-
在选项中:
-
Target Link-Layer Address option: 目标的链路层地址. 如果已知,应该包含该选项. 注意, 在 NBMA 链路上, 主机可能没有链路层地址, 在这种情况下不能包含该选项.
-
Redirected Header: 在不使 redirect 报文超过 [IPv6] 规定的支持 IPv6 所需最小 MTU 的前提下, 尽可能多地包含被转发报文的内容.
-
路由器必须限制 Redirect 消息的发送速率, 以便在源节点未正确响应 Redirect 时限制 Redirect 消息造成的带宽和处理成本. 有关 ICMP 错误消息速率限制的更多细节可见 [ICMPv6].
8.3. 主机规范
接收 Redirect 的主机会检查报文并执行以下有效性检查. 如果任何检查失败, 主机必须静默丢弃该 Redirect 消息.
主机确认 Redirect 消息有效后, 按如下方式处理该消息:
-
如果 Target Address 与 Destination Address 不同, 主机会将其 Destination Cache 中 Destination Address 的当前条目替换为一个指向 Target Address 的条目. 对于 Path MTU 信息和 Neighbor Unreachability Detection 状态, 新条目应继承旧条目的状态. 当主机创建新的 Destination Cache 条目时, 该条目按 Section 5.2 中的说明初始化.
-
如果 Target Address 与 Destination Address 相同, 接收主机会对该目的地对应的 Prefix List 条目执行以下操作:
- 如果不存在条目, 主机将该目的地作为链路上目的地加入其 Prefix List.
- 如果 Prefix List 中已经存在该目的地的条目, 主机会更新该条目, 指示该目的地位于链路上.
对于这两种情况, 主机都会更新该目的地的 Destination Cache 条目, 使其指向 Target Address. 如果 Destination Cache 条目不存在, 主机会创建一个新条目. 即使主机已经有一个指定不同第一跳邻居的缓存条目, 也应该更新该条目, 因为路由器更适合确定正确的第一跳邻居.
如果 redirect 包含 Target Link-Layer Address 选项, 主机会为目标创建或更新 Neighbor Cache 条目. 在这两种情况下, 都会使用该选项中的 Link-Layer Address. 目标的 Neighbor Cache 条目被设置为 STALE 状态. 如果为目标创建了 Neighbor Cache 条目, 其可达性状态必须按 Section 7.3.3 的规定设置为 STALE. 如果缓存条目已经存在并使用不同的链路层地址进行了更新, 其可达性状态也必须设置为 STALE.
主机必须将 Target Address 添加到 Destination Cache. 该条目的下一跳地址设置为 Redirect 的 Target Address. 如果该目的地的 Destination Cache 条目已经存在, 则更新该条目以使用 Target Address 作为其下一跳. 注意, 主机不会验证目标是否可达; Redirect 消息的有效性由路由器负责.
路由器应该针对其转发的报文发送 Redirect 消息, 条件是该报文中的 Source Address 字段标识一个邻居, 且路由器确定存在一个更适合该目的地的第一跳节点. 路由器发送 Redirect 的速率必须受到限制, 以防止广播风暴或针对主机的拒绝服务攻击.
8.4. 示例
考虑这样一种情况: 主机通过默认路由器 R1 向某个目的地发送报文, 但同一链路上的另一个路由器 R2 是到该目的地更好的第一跳. R1 转发该报文时, 会向主机发送 Redirect, 告知其 R2 是更好的选择. 该 Redirect 包含 R2 的链路本地地址.
+------+
| Host |
+------+
|
| (1) Packet to Dest
|
v
+----+ +----+
| R1 | ---------> | R2 |
+----+ Redirect +----+
| |
| |
+------------------+
Link
- Host 通过 R1 (其默认路由器) 向目的地发送报文
- R1 转发报文并向 Host 发送 Redirect, 指示 R2 更合适
- Host 更新其 Destination Cache, 对该目的地使用 R2
- 后续发往该目的地的报文会直接发送到 R2
8.5. Redirect 环路预防
如果链路上的多个路由器对某个目的地的最佳第一跳存在分歧, Redirect 机制可能产生 redirect 环路. 但是, 此类环路通常是短暂的, 原因如下:
-
路由器只会针对其转发的报文发送 Redirect. 如果路由器收到一个自己就是最佳第一跳的报文, 它不会发送 Redirect.
-
主机收到针对同一目的地但指向不同路由器的多个 Redirect 时, 会使用最近收到的 Redirect. 随着时间推移, 系统应收敛到稳定状态.
-
Neighbor Unreachability Detection 算法最终会检测到路由器是否不可达, 从而使主机回退到另一个路由器.
尽管有这些缓解措施, 实现仍应意识到 redirect 环路的可能性, 并可以实现额外保护措施, 例如限制响应 Redirect 而更新 Destination Cache 条目的速率.