Skip to main content

5. Protocol Specification (协议规范)

自动配置在支持组播的接口上以每个接口为基础执行. 对于多宿主机, 自动配置在每个接口上独立执行. 自动配置主要适用于主机, 但有两个例外. 预计路由器将使用下面概述的程序生成链路本地地址. 此外, 路由器在将所有地址分配给接口之前对所有地址执行重复地址检测.

5.1. Node Configuration Variables (节点配置变量)

节点必须 (MUST) 允许为每个支持组播的接口通过系统管理配置以下自动配置相关变量:

DupAddrDetectTransmits - 在暂定地址上执行重复地址检测时发送的连续邻居请求消息的数量. 值为零表示不在暂定地址上执行重复地址检测. 值为一表示单次传输, 没有后续重传.

默认值: 1, 但可以被特定链路类型文档中的链路类型特定值覆盖, 该文档涵盖与在特定链路类型上传输IP相关的问题 (例如, [RFC2464]).

自动配置还假设存在[RFC4861]中定义的变量RetransTimer. 对于自动配置目的, RetransTimer指定在重复地址检测期间执行的连续邻居请求传输之间的延迟 (如果DupAddrDetectTransmits大于1), 以及节点在发送最后一个邻居请求后在结束重复地址检测过程之前等待的时间.

除了形成链路本地地址和使用重复地址检测之外, 路由器如何 (自动) 配置其接口超出了本文档的范围.

主机维护地址列表及其相应的生命周期. 地址列表包含自动配置的地址和手动配置的地址.

每当接口被启用时, 节点就形成链路本地地址. 接口可以在以下任何事件之后被启用:

  • 接口在系统启动时初始化.
  • 接口在临时接口故障后或被系统管理临时禁用后重新初始化.
  • 接口首次连接到链路. 这包括由于无线网络接入点的变化而动态更改连接链路的情况.
  • 接口在被管理禁用后被系统管理启用.

链路本地地址是通过将众所周知的链路本地前缀FE80::0 [RFC4291] (适当长度) 与接口标识符组合而形成的, 如下所示:

  1. 地址的最左侧'前缀长度'位是链路本地前缀的位.
  2. 地址中链路本地前缀右侧的位都设置为零.
  3. 如果接口标识符的长度是N位, 则地址的最右侧N位被接口标识符替换.

如果链路本地前缀长度和N的总和大于128, 则自动配置失败, 并且需要手动配置. 接口标识符的长度在单独的特定链路类型文档中定义, 该文档也应与地址架构[RFC4291]一致 (参见第2节). 这些文档将仔细定义长度, 以便可以在链路上自动配置链路本地地址.

链路本地地址具有无限的首选和有效生命周期; 它永远不会超时.

5.4. Duplicate Address Detection (重复地址检测)

必须 (MUST) 在将所有单播地址分配给接口之前对其执行重复地址检测, 无论它们是通过无状态自动配置, DHCPv6还是手动配置获得的, 但有以下例外:

  • DupAddrDetectTransmits变量设置为零的接口不执行重复地址检测.
  • 禁止 (MUST NOT) 在任播地址上执行重复地址检测 (请注意, 任播地址在语法上无法与单播地址区分).
  • 应该 (SHOULD) 测试每个单独的单播地址的唯一性. 请注意, 已部署的实现仅对链路本地地址执行重复地址检测, 并跳过对使用与链路本地地址相同的接口标识符的全球地址的测试. 虽然本文档不会使这些实现无效, 但不推荐 (NOT RECOMMENDED) 这种"优化", 并且新实现禁止 (MUST NOT) 进行该优化. 这种优化来自所有接口地址都是从相同标识符生成的假设. 然而, 该假设实际上并不成立; 已经引入了新类型的地址, 其中单个接口上的所有单播地址的接口标识符不一定相同[RFC4941] [RFC3972]. 要求对所有单播地址执行重复地址检测将使算法对当前和未来的特殊接口标识符具有鲁棒性.

用于检测重复地址的程序使用邻居请求和通告消息, 如下所述. 如果在程序期间发现重复地址, 则无法将地址分配给接口. 如果地址是从接口标识符派生的, 则需要为接口分配新标识符, 或者需要手动配置接口的所有IP地址. 请注意, 检测重复地址的方法并不完全可靠, 并且可能仍然存在重复地址 (例如, 如果在执行重复地址检测时链路被分区).

应用重复地址检测程序的地址在程序成功完成之前被称为暂定地址. 暂定地址不被认为以传统意义"分配给接口". 也就是说, 接口必须接受目标地址字段中包含暂定地址的邻居请求和通告消息, 但对这些数据包的处理方式与目标地址与分配给接口的地址匹配的数据包不同. 应该静默丢弃发送到暂定地址的其他数据包. 请注意, "其他数据包"包括将暂定 (即单播) 地址作为IP目标地址并且在目标地址字段中包含暂定地址的邻居请求和通告消息. 但是, 这种情况在正常操作中不应该发生, 因为这些消息在重复地址检测程序中是组播的.

还应注意, 必须在将地址分配给接口之前执行重复地址检测, 以防止多个节点同时使用相同地址. 如果节点在执行重复地址检测的同时开始使用地址, 并且另一个节点已经在使用该地址, 则执行重复地址检测的节点将错误地处理发送给其他节点的流量, 导致诸如重置打开的TCP连接之类的可能负面后果.

以下小节描述了节点执行的特定测试以验证地址的唯一性. 如果在发送DupAddrDetectTransmits个邻居请求后的RetransTimer毫秒内没有任何测试指示重复地址的存在, 则认为地址是唯一的. 一旦确定地址是唯一的, 就可以将其分配给接口.

5.4.1. Message Validation (消息验证)

节点必须 (MUST) 静默丢弃任何未通过[RFC4861]中指定的有效性检查的邻居请求或通告消息. 通过这些有效性检查的邻居请求或通告消息分别称为有效请求或有效通告.

5.4.2. Sending Neighbor Solicitation Messages (发送邻居请求消息)

在发送邻居请求之前, 接口必须 (MUST) 加入全节点组播地址和暂定地址的请求节点组播地址. 前者确保节点从已经使用该地址的其他节点接收邻居通告; 后者确保同时尝试使用相同地址的两个节点应该检测到彼此的存在.

为了检查地址, 节点发送DupAddrDetectTransmits个邻居请求, 每个间隔RetransTimer毫秒. 请求的目标地址设置为正在检查的地址, IP源地址设置为未指定地址, IP目标地址设置为目标地址的请求节点组播地址.

如果邻居请求将是接口 (重新) 初始化后从接口发送的第一条消息, 则节点应该 (SHOULD) 通过[RFC4861]中指定的0到MAX_RTR_SOLICITATION_DELAY之间的随机延迟延迟加入请求节点组播地址. 这有助于在许多节点同时在链路上启动时 (例如在电源故障后) 缓解拥塞, 并且可能有助于避免当多个节点同时尝试请求相同地址时的竞争条件.

即使邻居请求不是第一条要发送的消息, 如果正在检查的地址是由发送到组播地址的路由器通告消息配置的, 则节点应该 (SHOULD) 通过0到MAX_RTR_SOLICITATION_DELAY之间的随机延迟延迟加入请求节点组播地址. 延迟将避免在多个节点通过接收相同的单个组播路由器通告来配置地址时的类似拥塞.

请注意, 当节点加入组播地址时, 它通常会为组播地址发送组播侦听器发现 (MLD) 报告消息[RFC2710] [RFC3810]. 在重复地址检测的情况下, 需要MLD报告消息以通知MLD侦听交换机 (而不是路由器) 转发组播数据包. 在上述描述中, 加入组播地址的延迟因此意味着延迟传输相应的MLD报告消息. 由于MLD规范不要求随机延迟以避免竞争条件, 仅延迟邻居请求将导致MLD报告消息的拥塞. 然后, 拥塞将阻止MLD侦听交换机正常工作, 从而阻止重复地址检测工作. 在这种情况下包括MLD报告延迟的要求避免了这种情况. [RFC3590]还讨论了重复地址检测和MLD之间的一些交互问题, 并指定在这种情况下应该为MLD报告使用哪个源地址.

为了提高重复地址检测算法的鲁棒性, 接口必须 (MUST) 在延迟期间接收和处理发送到全节点组播地址或暂定地址的请求节点组播地址的数据报. 这不一定与必须延迟加入组播组的要求冲突. 实际上, 在某些情况下, 节点可以在MLD报告传输之前的延迟期间开始侦听组. 但是, 应该注意的是, 在某些链路层环境中, 特别是对于MLD侦听交换机, 在发送MLD报告之前将无法接收组播.

5.4.3. Receiving Neighbor Solicitation Messages (接收邻居请求消息)

在接口上接收到有效的邻居请求消息时, 节点行为取决于目标地址是否是暂定的. 如果目标地址不是暂定的 (即, 它已分配给接收接口), 则按照[RFC4861]中所述处理请求. 如果目标地址是暂定的, 并且源地址是单播地址, 则请求的发送者正在对目标执行地址解析; 应该静默忽略请求. 否则, 按照下面描述的进行处理. 在所有情况下, 节点禁止 (MUST NOT) 响应暂定地址的邻居请求.

如果邻居请求的源地址是未指定地址, 则请求来自执行重复地址检测的节点. 如果请求来自另一个节点, 则暂定地址是重复的, 不应使用 (由任一节点). 如果请求来自节点本身 (因为节点循环回组播数据包), 则请求不表示重复地址的存在.

实现者注意: 许多接口提供了一种方式, 供上层选择性地启用和禁用组播数据包的循环回. 实现这种设施的详细信息可能会阻止重复地址检测正常工作. 有关进一步讨论, 请参见附录A.

以下测试识别暂定地址不唯一的条件:

  • 如果在发送暂定地址的邻居请求之前接收到该地址的邻居请求, 则暂定地址是重复的. 当两个节点同时运行重复地址检测但在不同时间传输初始请求时 (例如, 通过在加入请求节点组播地址和传输初始请求之前选择不同的随机延迟值), 会发生这种情况.
  • 如果接收到的邻居请求的实际数量超过基于环回语义预期的数量 (例如, 接口不循环回数据包, 但接收到一个或多个请求), 则暂定地址是重复的. 当两个节点同时运行重复地址检测并且大约在同一时间传输请求时, 会发生这种情况.

5.4.4. Receiving Neighbor Advertisement Messages (接收邻居通告消息)

在接口上接收到有效的邻居通告消息时, 节点行为取决于目标地址是暂定的还是与分配给接口的单播或任播地址匹配:

  1. 如果目标地址是暂定的, 则暂定地址不唯一.
  2. 如果目标地址与分配给接收接口的单播地址匹配, 则可能表示地址是重复的, 但未被重复地址检测程序检测到 (回想一下重复地址检测并不完全可靠). 如何处理这种情况超出了本文档的范围.
  3. 否则, 按照[RFC4861]中所述处理通告.

5.4.5. When Duplicate Address Detection Fails (当重复地址检测失败时)

如上所述确定为重复的暂定地址禁止 (MUST NOT) 分配给接口, 并且节点应该 (SHOULD) 记录系统管理错误.

如果地址是基于硬件地址 (应该是唯一分配的, 例如, 以太网接口的EUI-64) 的接口标识符形成的链路本地地址, 则应该 (SHOULD) 禁用接口上的IP操作. 通过禁用IP操作, 节点将:

  • 不从接口发送任何IP数据包,
  • 静默丢弃在接口上接收的任何IP数据包, 以及
  • 不将任何IP数据包转发到接口 (当充当路由器或处理带有路由标头的数据包时).

在这种情况下, IP地址重复可能意味着正在使用重复的硬件地址, 并且尝试通过配置另一个IP地址来恢复不会导致可用的网络. 实际上, 它可能通过创建比仅禁用接口上的网络操作更难诊断的问题而使情况变得更糟; 用户将看到一个部分工作的网络, 其中一些事情有效, 而其他事情无效.

另一方面, 如果重复的链路本地地址不是基于应该是唯一分配的硬件地址的接口标识符形成的, 则可以 (MAY) 继续接口上的IP操作.

注意: 如第2节所述, "IP"在上述描述中意味着"IPv6". 虽然关于硬件地址的背景原理独立于特定网络协议, 但其对其他协议的影响超出了本文档的范围.

5.5. Creation of Global Addresses (全球地址的创建)

全球地址是通过将接口标识符附加到适当长度的前缀而形成的. 前缀从路由器通告中包含的前缀信息选项获得. 本节中描述的全球地址的创建应该 (SHOULD) 是本地可配置的. 但是, 下面描述的处理必须 (MUST) 默认启用.

5.5.1. Soliciting Router Advertisements (请求路由器通告)

路由器通告定期发送到全节点组播地址. 为了快速获得通告, 主机发送路由器请求, 如[RFC4861]中所述.

5.5.2. Absence of Router Advertisements (缺少路由器通告)

即使链路上没有路由器, 获取地址的DHCPv6服务仍然可用, 并且主机可能希望使用该服务. 从自动配置的角度来看, 如果在发送少量路由器请求后没有接收到路由器通告 (如[RFC4861]中所述), 则链路上没有路由器.

请注意, 在这个意义上, 链路上可能没有路由器, 但有一个具有转发数据包能力的节点. 在这种情况下, 必须在主机中手动配置转发节点的地址才能发送链路外数据包, 因为自动配置默认路由器地址的唯一机制是使用路由器通告的机制.

5.5.3. Router Advertisement Processing (路由器通告处理)

对于路由器通告中的每个前缀信息选项:

a) 如果未设置自治标志, 则静默忽略前缀信息选项.

b) 如果前缀是链路本地前缀, 则静默忽略前缀信息选项.

c) 如果首选生命周期大于有效生命周期, 则静默忽略前缀信息选项. 在这种情况下, 节点可以 (MAY) 希望记录系统管理错误.

d) 如果通告的前缀不等于已经在与接口关联的地址列表中的无状态自动配置地址的前缀 (其中"等于"意味着两个前缀长度相同, 并且前缀的前缀长度位相同), 并且如果有效生命周期不为0, 则通过将通告的前缀与链路的接口标识符组合来形成地址 (并将其添加到列表), 如下所示:

|            128 - N bits               |       N bits           |
+---------------------------------------+------------------------+
| link prefix | interface identifier |
+----------------------------------------------------------------+

如果前缀长度和接口标识符长度的总和不等于128位, 则必须 (MUST) 忽略前缀信息选项. 在这种情况下, 实现可以 (MAY) 希望记录系统管理错误. 接口标识符的长度在单独的特定链路类型文档中定义, 该文档也应与地址架构[RFC4291]一致 (参见第2节).

系统管理员有责任确保路由器通告中包含的前缀的长度与该链路类型的接口标识符的长度一致. 但是, 应该注意的是, 这并不意味着通告的前缀长度是无意义的. 实际上, 通告的长度对[RFC4861]中的链路上确定具有非平凡的意义, 其中前缀长度和接口标识符长度的总和可能不等于128. 因此, 在这里验证通告的前缀长度应该是安全的, 以便在地址自动配置的上下文中检测和避免指定无效前缀长度的配置错误.

请注意, 地址架构[RFC4291]的未来版本和未来的特定链路类型文档 (仍将相互一致) 可能允许除当前文档中定义的值以外长度的接口标识符. 因此, 实现不应假设特定常量. 相反, 它应该期望任何长度的接口标识符.

如果成功形成地址并且地址尚未在列表中, 则主机将其添加到分配给接口的地址列表中, 从前缀信息选项初始化其首选和有效生命周期值. 请注意, 在此步骤开始时对前缀执行的检查并不总是能检测到列表中的地址冲突. 可能是列表中已经存在的地址 (通过手动配置或DHCPv6配置) 恰好与新创建的地址相同, 而这种情况应该是非典型的.

e) 如果通告的前缀等于列表中通过无状态自动配置配置的地址的前缀, 则地址的首选生命周期重置为接收通告中的首选生命周期. 对地址的有效生命周期执行的特定操作取决于接收通告中的有效生命周期和先前自动配置的地址的有效生命周期到期的剩余时间. 在以下讨论中, 我们将剩余时间称为"RemainingLifetime":

  1. 如果接收的有效生命周期大于2小时或大于RemainingLifetime, 则将相应地址的有效生命周期设置为通告的有效生命周期.
  2. 如果RemainingLifetime小于或等于2小时, 则忽略关于有效生命周期的前缀信息选项, 除非从中获得此选项的路由器通告已被认证 (例如, 通过安全邻居发现[RFC3971]). 如果路由器通告已认证, 则应将相应地址的有效生命周期设置为接收选项中的有效生命周期.
  3. 否则, 将相应地址的有效生命周期重置为2小时.

上述规则解决了特定的拒绝服务攻击, 其中伪造的通告可能包含具有非常短的有效生命周期的前缀. 如果没有上述规则, 包含具有短有效生命周期的伪造前缀信息选项的单个未认证通告可能导致节点的所有地址过早到期. 上述规则确保合法通告 (定期发送) 将在短有效生命周期实际生效之前"取消"它们.

请注意, 相应地址的首选生命周期总是重置为接收的前缀信息选项中的首选生命周期, 无论有效生命周期是重置还是被忽略. 差异来自对首选生命周期的可能攻击相对较小的事实. 此外, 当有效管理员希望通过发送短首选生命周期来弃用特定地址时 (并且有效生命周期被意外忽略), 忽略首选生命周期甚至是不可取的.

5.5.4. Address Lifetime Expiry (地址生命周期到期)

当首选地址的首选生命周期到期时, 首选地址变为已弃用. 已弃用的地址应该 (SHOULD) 继续用作现有通信中的源地址, 但如果可以轻松使用足够范围的备用 (非已弃用) 地址, 则不应该 (SHOULD NOT) 用于发起新通信.

请注意, 使用非已弃用地址发起新通信的可行性可能是特定于应用程序的决定, 因为只有应用程序可能知道 (现在) 已弃用的地址是否 (或仍然) 正在被应用程序使用. 例如, 如果应用程序明确指定协议栈使用已弃用的地址作为源地址, 协议栈必须接受; 应用程序可能请求它, 因为该IP地址用于更高级别的通信, 并且可能要求此类分组中的多个连接使用相同的IP地址对.

IP和更高层 (例如, TCP, UDP) 必须 (MUST) 继续接受和处理发送到已弃用地址的数据报, 因为已弃用的地址仍然是接口的有效地址. 在TCP的情况下, 这意味着使用已弃用的地址作为相应SYN-ACK中的源地址来响应发送到已弃用地址的TCP SYN段 (如果该连接将被允许).

实现可以 (MAY) 阻止任何新通信使用已弃用的地址, 但系统管理必须 (MUST) 有能力禁用这种设施, 并且该设施必须 (MUST) 默认禁用.

还应注意源地址选择的其他微妙情况. 例如, 上述描述没有阐明在已弃用的较小范围地址和非已弃用的足够范围地址之间应该使用哪个地址. 包括此情况的地址选择的详细信息在[RFC3484]中描述, 并超出了本文档的范围.

当地址 (及其与接口的关联) 的有效生命周期到期时, 地址变为无效. 无效地址禁止 (MUST NOT) 用作出站通信中的源地址, 并且禁止 (MUST NOT) 在接收接口上被识别为目标.

5.6. Configuration Consistency (配置一致性)

主机可以同时使用无状态自动配置和DHCPv6获取地址信息, 因为两者可以同时启用. 其他配置参数 (如MTU大小和跳数限制) 的值也可能从路由器通告和DHCPv6学习. 如果相同的配置信息由多个源提供, 则此信息的值应该是一致的. 但是, 如果从多个源接收的信息不一致, 则不被认为是致命错误. 主机接受通过邻居发现和DHCPv6接收的所有信息的并集.

如果从不同来源获知不一致的信息, 实现可能希望优先考虑安全获知的信息而不是没有保护获知的信息. 例如, [RFC3971]的第8节讨论了如何处理通过安全邻居发现获知的信息与通过普通邻居发现获知的信息冲突. 相同的讨论可以适用于通过普通邻居发现获知的信息与通过安全DHCPv6获知的信息之间的偏好, 等等.

在任何情况下, 如果没有安全性差异, 最近获得的值应该 (SHOULD) 优先于较早获知的信息.

5.7. Retaining Configured Addresses for Stability (保留已配置地址以保持稳定性)

具有稳定存储的实现可能希望在使用无状态地址自动配置获取地址时在存储中保留地址. 假设使用的生命周期是合理的, 这种技术意味着路由器的临时中断 (少于有效生命周期) 永远不会导致丢失节点的全球地址, 即使节点要重新启动. 使用这种技术时, 还应该注意必须保留首选和有效生命周期的到期时间, 以防止在地址变为已弃用或无效后使用地址.

关于这种扩展的更多详细信息超出了本文档的范围.