本文档规范了一种针对互联网社区的互联网标准跟踪协议。欢迎就改进提出建议并进行讨论。请参阅“Internet Official Protocol Standards”(STD 1)的最新版本,以验证本协议的标准化状态和当前状态。本备忘录可以无限制地分发。
本文档详细说明了针对IP协议版本6(IPv6)设计的邻居发现(Neighbor Discovery,ND)协议。ND协议对于同一网络段内的IPv6节点识别彼此、确定彼此的链路层地址、发现路由器并维护关于到活动邻居节点的路径可达性信息至关重要。
Table of Contents
本规范定义了针对IPv6的邻居发现(Neighbor Discovery,ND)协议。节点(主机和路由器)使用邻居发现来确定已知于连接的邻居节点的链路层地址,并快速清除无效的缓存值。主机还使用邻居发现来寻找愿意代表其转发数据包的邻近路由器。最后,节点使用该协议主动跟踪哪些邻居节点是可达的、哪些是不可达的,并检测链路层地址的更改。当路由器或到路由器的路径发生故障时,主机会主动搜索功能正常的替代路径。
除非另有规定(在覆盖特定链路类型的IP操作的文档中),否则本文档适用于所有链路类型。但是,由于邻居发现对于某些服务使用链路层的多播,因此在某些链路类型(例如,非广播多点接入(NBMA)链路)上,可能会指定替代协议或机制来实现这些服务(在覆盖特定链路类型的IP操作的适当文档中)。本文档描述的不直接依赖于多播的服务,例如重定向(Redirects)、下一跳确定(Next-hop determination)、邻居不可达性检测(Neighbor Unreachability Detection)等,预计将按照本文档的规范提供。关于在NBMA链路上使用ND的详细信息,已在[IPv6-NBMA]中进行了解释。此外,[IPv6-3GPP]和[IPv6-CELL]讨论了该协议在某些蜂窝链路上的使用情况,这些是NBMA链路的示例。
IP:IPv6(Internet Protocol Version 6)。仅在必要时为避免歧义使用IPv4和IPv6这两个术语。
ICMP:用于IPv6的Internet控制消息协议。仅在必要时为避免歧义使用ICMPv4和ICMPv6这两个术语。
node:实现IP的设备。
router:转发不是明确寻址给自身的IP数据包的节点。
host:任何不是路由器的节点。
upper layer:紧接在IP上方的协议层。例如,传输协议(如TCP和UDP)、控制协议(如ICMP)、路由协议(如OSPF),以及作为IP“隧道”(即封装在IP中)的互联网层(或更低层)的协议。
link:节点可以在其上进行链路层通信的通信设施或介质,即紧接在IP下层之上的层。例如,以太网(简单或桥接)、PPP链路、X.25、帧中继或ATM网络,以及作为互联网层(或更高层)“隧道”的协议,如在IPv4或IPv6本身上的隧道。
interface:节点连接到链路的接口。
neighbors:连接到相同链路的节点。
address:接口或一组接口的IP层标识符。
anycast address:一组接口的标识符(通常属于不同的节点)。发送到单播地址的数据包将被传递到由该地址标识的接口之一(根据路由协议测量的“最近”接口)。参见[ADDR-ARCH]。
prefix:由某个地址的一些初始位构成的位字符串。
link-layer address:接口的链路层标识符。例如,以太网链路的IEEE 802地址。
on-link:分配给指定链路上的接口的地址。如果满足以下条件之一,节点将认为地址在链路上:
off-link:与“在链路上”相反,指在指定链路上未分配给任何接口的地址。
longest prefix match:确定一组前缀中哪个(如果有)覆盖目标地址的过程。如果前缀的所有位都与目标地址的最左边的位匹配,则目标地址由前缀覆盖。当多个前缀覆盖一个地址时,最长前缀是匹配的前缀。
reachability:指向邻居的单向“前进”路径是否正常运行。特别是指发送到邻居的数据包是否到达了邻居机器上的IP层,并且是否被接收IP层正确处理。对于相邻的路由器,可达性意味着由节点的IP层发送的数据包被传递到路由器的IP层,并且路由器确实转发数据包(即,它被配置为路由器而不是主机)。对于主机,可达性意味着节点的IP层发送的数据包已被传递到相邻主机的IP层。
packet:IP头部加上有效负载。
link MTU:链路上传输单个传输单元的最大传输单元,即以字节为单位的最大数据包大小。
target:寻求地址解析信息的地址,或者是被重定向时的新的下一跳地址。
proxy:代表另一个节点响应邻居发现查询消息的节点。作为一个例子,充当已经移出链路的移动节点的代理的路由器可能潜在地充当移动节点的代理。
ICMP destination unreachable indication:对于无法传递的数据包,返回给原始发送者的错误指示,原因见[ICMPv6]。如果错误发生在除了源节点之外的节点上,则会生成一个ICMP错误消息。如果错误发生在发起节点上,实现不需要真正创建并发送ICMP错误数据包到源地址,只要通过适当的机制(例如,从过程调用的返回值)通知上层发送者即可。但请注意,在某些情况下,实现可能会发现将错误返回给发送者是方便的,它可以采取有害的数据包,生成一个ICMP错误消息,然后通过通用的错误处理例程(在本地)传递它。
random delay:在发送消息时,有时需要延迟传输一段随机时间,以防止多个节点同时发送,或防止远程周期性传输相互同步。当需要随机组件时,节点计算实际延迟方式是使计算出的延迟形成均匀分布的随机值,该随机值落在指定的最小和最大延迟时间之间。实现者必须小心确保计算的随机分量的粒度和所使用的定时器的分辨率都足够高,以确保多个节点延迟相同的概率很小。
random delay seed:如果伪随机数生成器用于计算随机延迟组件,则在使用之前应初始化生成器。请注意,仅使用接口标识符作为种子是不够的,因为接口标识符不总是唯一的。为了减少重复接口标识符导致使用相同种子的概率,种子应从多种输入源(例如,机器组件)计算出来,即使在相同的“盒子”上也可能是不同的。例如,种子可以通过将CPU的序列号与接口标识符相结合来形成。关于随机性和随机数生成的更多信息,请参阅[RAND]。
不同的链路层有不同的特性。对邻居发现(Neighbor Discovery)而言,关注的有:
多播能力:支持通过链路层本地机制向所有邻居(即广播)或所有邻居的子集发送数据包的链路。
点对点:连接恰好两个接口的链路。点对点链路假定具有多播功能和链路本地地址。
非广播多接入(NBMA):多个接口可以连接到的链路,但不支持原生的多播或广播形式(例如X.25、ATM、帧中继等)。请注意,所有链路类型(包括NBMA)都预期为需要的应用程序提供多播服务(例如使用多播服务器)。但是,需要进一步研究的问题是,邻居发现是否应使用此类设施或提供等效多播功能的备用机制。
共享介质:允许多个节点直接通信的链路,但连接的节点配置方式使得它们对于所有在链路上的目的地并不具备完整的前缀信息。也就是说,在IP层级别,同一链路上的节点可能不知道它们是邻居;默认情况下,它们通过路由器进行通信。例如大型(交换的)公共数据网络,例如交换多兆数据服务(SMDS)和宽带综合业务数字网(B-ISDN)。也称为“大型云”。参见[SH-MEDIA]。
可变MTU:没有定义明确MTU(最大传输单元)的链路(例如IEEE 802.5令牌环)。许多链路(例如以太网)具有由链路层协议或特定描述如何在链路层上运行IP的文档定义的标准MTU。
不对称可达性:非反射性和/或非传递性可达性是正常操作的一部分的链路。(非反射性可达性意味着来自A的数据包可以到达B,但来自B的数据包却不能到达A。非传递性可达性意味着来自A的数据包可以到达B,来自B的数据包可以到达C,但来自A的数据包却不能到达C。)许多无线电链路表现出这些属性。
邻居发现(Neighbor Discovery)利用[ADDR-ARCH]中定义的多种不同地址,包括:
所有节点多播地址(all-nodes multicast address):用于到达所有节点的链路本地范围地址,为FF02::1。
所有路由器多播地址(all-routers multicast address):用于到达所有路由器的链路本地范围地址,为FF02::2。
请求节点多播地址(solicited-node multicast address):计算得到的链路本地范围的多播地址,作为被请求目标地址的函数。该函数的描述在[ADDR-ARCH]中。此函数被选中以使得仅在最高有效位不同的IP地址(例如由于与不同提供者关联的多个前缀)将映射到相同的请求节点地址,从而减少了节点必须在链路层加入的多播地址数量。
链路本地地址(link-local address):具有链路级别范围的单播地址,可用于到达邻居。路由器上的所有接口必须具有链路本地地址。此外,[ADDRCONF]要求主机上的接口具有链路本地地址。
未指定地址(unspecified address):指示缺乏地址(例如,地址未知)的保留地址值。它永远不会用作目标地址,但如果发送方(暂时)不知道自己的地址(例如,在无状态地址自动配置[ADDRCONF]期间验证地址未使用时),可能会用作源地址。未指定地址的值为0:0:0:0:0:0:0:0。
请注意,本规范不严格遵守[ADDR-SEL]中关于源地址和目标地址范围一致性的要求。在某些情况下,主机可以使用IPv6头中的源地址比目标地址的范围更大的情况。
当本文档中出现关键字“MUST”、“MUST NOT”、“REQUIRED”、“SHALL”、“SHALL NOT”、“SHOULD”、“SHOULD NOT”、“RECOMMENDED”、“MAY”和“OPTIONAL”时,其解释方式应按照[KEYWORDS]中的描述执行。
本文档还使用内部概念变量来描述协议行为,以及实现必须允许系统管理员更改的外部变量。为了展示协议行为,提供了特定的变量名称、它们的值如何变化以及它们的设置如何影响协议行为。实现不必完全按照此处描述的形式具有这些变量,只要其外部行为与本文档中描述的行为一致即可。
该协议解决了与连接到同一链路的节点之间交互相关的一系列问题。它定义了解决以下每个问题的机制:
邻居发现定义了五种不同的ICMP数据包类型:一对路由器请求和路由器通告消息,一对邻居请求和邻居通告消息,以及一条重定向消息。这些消息具有以下目的:
在支持多播的链路上,每个路由器定期多播路由器通告数据包以宣告其可用性。主机从所有路由器接收路由器通告,构建默认路由器列表。路由器生成路由器通告的频率足够主机在几分钟内就能了解其存在,但不足以依赖缺少通告来检测路由器故障;单独的邻居不可达检测算法提供了故障检测。
路由器通告包含用于本地确定和/或自治地址配置的前缀列表;与前缀相关的标志指定特定前缀的预期用途。主机使用广告的本地前缀构建和维护列表,用于决定数据包的目标是否本地或在路由器之外。请注意,即使目的地不在任何广告的本地前缀范围内,目的地仍然可能在本地。在这种情况下,路由器可以发送重定向,通知发送方目的地是一个邻居。
路由器通告(和每个前缀的标志)允许路由器通知主机如何执行地址自动配置。例如,路由器可以指定主机是否应使用DHCPv6和/或自治(无状态)地址配置。
路由器通告消息还包含主机在传出数据包中应使用的Internet参数,例如主机应使用的跳数限制,以及可选的链路参数,例如链路MTU。这有助于对关键参数进行集中管理,这些参数可以在路由器上设置并自动传播到所有附加的主机。
节点通过广播邻居请求来实现地址解析,该请求要求目标节点返回其链路层地址。邻居请求消息被广播到目标地址的预定节点多播地址。目标以单播邻居通告消息返回其链路层地址。单个请求-响应对的数据包对于初始化方和目标方解析彼此的链路层地址是足够的;初始化方在邻居请求中包含其链路层地址。
邻居请求消息也可以用于确定是否已将同一单播地址分配给多个节点。使用邻居请求消息进行重复地址检测的使用在[ADDRCONF]中指定。
邻居不可达检测用于检测邻居的故障或到达邻居的前向路径的故障。这样做需要积极确认发送到邻居的数据包实际上到达该邻居并被其IP层正确处理。邻居不可达检测使用来自两个源的确认。在可能的情况下,上层协议提供了连接正在进行“前进进展”的积极确认,即已知先前发送的数据已被正确传送(例如,最近收到了新的确认)。当不通过这些“提示”获得积极确认时,节点将单播邻居请求消息发送到下一跳,以从下一跳获取邻居通告作为可达性确认。为了减少不必要的网络流量,探测消息仅发送到节点正在积极发送数据包的邻居。
除了解决上述一般问题外,邻居发现还处理了以下情况:
IPv6邻居发现协议对应于IPv4协议地址解析协议[ARP]、ICMP路由器发现[RDISC]和ICMP重定向[ICMPv4]的组合。在IPv4中,尽管主机需求文档[HR-CL]指定了一些可能的死网关检测算法(是邻居不可达检测所处理问题的一个子集),但一般没有就邻居不可达检测达成共识的协议或机制。
邻居发现协议在IPv4协议集合方面提供了许多改进:
邻居发现协议支持具有不同属性的链路。在存在某些属性时,本文档中仅完全指定ND协议机制的子集:
点对点 - 邻居发现将处理此类链路,就像处理多播链路一样。 (点对点链路可以轻松提供多播,而且可以为接口分配链路本地地址。)
多播 - 邻居发现在多播能力链路上按本文档描述的方式运行。
非广播多接入(NBMA) - 重定向、邻居不可达检测和下一跳确定应按照本文档中描述的方式实现。在NBMA链路上未在本文档中指定地址解析和传递路由器询问和通告的机制。请注意,如果主机支持默认路由器列表的手动配置,则主机可以从重定向消息中动态获取其邻居的链路层地址。
共享媒体 - 重定向消息是根据[SH-MEDIA]中的XRedirect消息进行建模,以简化在共享媒体链路上使用该协议。本规范不涉及仅涉及路由器的共享媒体问题,例如:
可变MTU - 邻居发现允许路由器为链路指定MTU,然后所有节点使用该MTU。为了使多播正常工作,链路上的所有节点必须使用相同的MTU(或最大接收单元)。否则,在多播时,发送方无法知道哪些节点将接收数据包,因此无法确定所有接收方可以处理的最小数据包大小(或最大接收单元)。
不对称可达性 - 邻居发现检测到对称可达性的缺失;节点会避免使用与其没有对称连接的邻居的路径。邻居不可达检测通常会识别出这种半链路,并且节点将不使用它们。
该协议未来可能会扩展,以在缺乏反射性和传递性连接性的环境中找到可行的路径。
邻居发现消息用于各种功能。有几个功能旨在允许主机确定地址的所有权或链路层与IP层地址之间的映射关系。与邻居发现相关的漏洞在第11.1节中讨论。保护邻居发现的一般解决方案超出了本规范的范围,并在[SEND]中讨论。然而,第11.2节解释了如何在哪些限制下使用IPsec身份验证头(AH)或封装安全有效负载(ESP)来保护邻居发现。
本节介绍了本规范中使用的所有消息的消息格式。
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options ...
+-+-+-+-+-+-+-+-+-+-+-+-
主机发送路由器请求以促使路由器快速生成路由器通告。
IP字段:
ICMP字段:
有效选项:
未来版本的此协议可能会定义新的选项类型。接收方必须默默忽略它们不认识的任何选项,并继续处理消息。
在这里插入代码片
路由器周期性地发送路由器通告消息,或者响应路由器请求。
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Cur Hop Limit |M|O| Reserved | Router Lifetime |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Reachable Time |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Retrans Timer |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options ...
+-+-+-+-+-+-+-+-+-+-+-+-
IP字段:
ICMP字段:
可能的选项:
未来版本的此协议可能会定义新的选项类型。接收方必须默默忽略它们不认识的任何选项,并继续处理消息。
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ +
| |
+ Target Address +
| |
+ +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options ...
+-+-+-+-+-+-+-+-+-+-+-+-
节点发送邻居请求以请求目标节点的链路层地址,同时向目标提供自己的链路层地址。当节点需要解析地址时,邻居请求消息会进行多播;当节点寻求验证邻居的可达性时,则进行单播。
IP字段:
ICMP字段:
可能的选项:
未来版本的此协议可能会定义新的选项类型。接收方必须默默忽略它们不认识的任何选项,并继续处理消息。
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|R|S|O| Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ +
| |
+ Target Address +
| |
+ +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options ...
+-+-+-+-+-+-+-+-+-+-+-+-
节点响应邻居请求发送邻居广告,并且为了(不可靠地)快速传播新信息,发送未经请求的邻居广告。
IP字段:
ICMP字段:
Type:136
Code:0
Checksum:ICMP校验和,参见[ICMPv6]。
R:路由器标志。设置时,R位表示发送方是路由器。R位由邻居不可达性检测用于检测从路由器更改为主机的情况。
S:被请求标志。设置时,S位表示该广告是作为对目标地址的邻居请求的响应发送的。S位用作邻居不可达性检测的可达性确认。它不能设置在多播广告或未经请求的单播广告中。
O:覆盖标志。设置时,O位表示该广告应覆盖现有的缓存条目并更新缓存的链路层地址。当未设置时,该广告将不会更新缓存的链路层地址,尽管它将更新一个现有的邻居缓存条目,其中未知链路层地址。在对任播地址和被请求代理广告的被请求广告中,不应设置O位。在其他被请求广告和未经请求的广告中应该设置O位。
Reserved:29位未使用字段。发送方必须将其初始化为零,并且接收方必须忽略它。
Target Address:对于被请求的广告,是引发此广告的邻居请求消息中的目标地址。对于未经请求的广告,是其链路层地址发生更改的地址。目标地址不能是多播地址。
可能的选项:
未来版本的此协议可能会定义新的选项
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ +
| |
+ Target Address +
| |
+ +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ +
| |
+ Destination Address +
| |
+ +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options ...
+-+-+-+-+-+-+-+-+-+-+-+-
路由器发送重定向数据包以通知主机到达目的地的更好的第一跳节点。主机可以被重定向到更好的第一跳路由器,但也可以通过重定向得知目的地实际上是一个邻居。后者通过将 ICMP 目标地址设置为 ICMP 目的地址来实现。
IP字段:
ICMP字段:
可能的选项:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Length | ... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
~ ... ~
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
邻居发现消息包括零个或多个选项,其中某些选项可能在同一消息中出现多次。必要时应填充选项以确保它们以自然的64位边界结束。所有选项都采用以下格式:
字段:
Type:8位标识符,表示选项的类型。本文档中定义的选项包括:
选项名称 | 类型 |
---|---|
源链路层地址 | 1 |
目标链路层地址 | 2 |
前缀信息 | 3 |
重定向的头部 | 4 |
MTU | 5 |
Length:8位无符号整数。选项的长度(包括类型和长度字段),以8个八位组为单位。值为0是无效的。节点必须静默丢弃包含长度为零的选项的 ND(邻居发现)数据包。
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Length | Prefix Length |L|A| Reserved1 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Valid Lifetime |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Preferred Lifetime |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Reserved2 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ +
| |
+ Prefix +
| |
+ +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
字段:
Type:
Length:选项的长度(包括类型和长度字段),以8个八位组为单位。例如,IEEE 802地址的长度为1 [IPv6-ETHER]。
Link-Layer Address:可变长度的链路层地址。
这个字段的内容和格式(包括字节和位顺序)预计会在描述 IPv6 在不同链路层上运行的具体文档中指定。例如,[IPv6-ETHER]。
Description:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Length | Prefix Length |L|A| Reserved1 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Valid Lifetime |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Preferred Lifetime |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Reserved2 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ +
| |
+ Prefix +
| |
+ +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
字段:
类型:3
长度:4
前缀长度:8位无符号整数。前缀中有效的前导位数。取值范围从0到128。前缀长度字段提供了与 L 标志(前缀信息选项中的)相结合的联机确定所需的必要信息。它还辅助地址自动配置,如[ADDRCONF]中所指定的,对前缀长度可能有更多的限制。
L:1位联机标志。设置时表示该前缀可用于联机确定。当未设置时,该广告对前缀的联机或脱机属性不作任何说明。换句话说,如果未设置 L 标志,则主机绝不能得出源自该前缀的地址是脱机的结论。也就是说,它不能更新先前指示地址为联机的信息。
A:1位自治地址配置标志。设置时表示该前缀可用于如[ADDRCONF]中所指定的无状态地址配置。
保留1:6位未使用的字段。发送方必须将其初始化为零,接收方必须忽略它。
有效生存时间:32位无符号整数。以秒为单位的时间长度(相对于发送数据包时刻),用于联机确定前缀的有效期。全部位设置为1(0xffffffff)表示无限期。有效生存时间也被[ADDRCONF]使用。
首选生存时间:32位无符号整数。相对于发送数据包时刻,通过无状态地址自动配置生成的地址保持首选状态的时间长度[ADDRCONF]。全部位设置为1(0xffffffff)表示无限期。参见[ADDRCONF]。请注意,此字段的值不能超过有效生存时间字段,以避免偏好已不再有效的地址。
保留2:该字段未使用。发送方必须将其初始化为零,接收方必须忽略它。
前缀:一个IP地址或一个IP地址的前缀。前缀长度字段包含前缀中有效的前导位数。前缀长度后的前缀位被保留,发送方必须将其初始化为零,接收方必须忽略它。路由器不应为链路本地前缀发送前缀选项,主机应忽略这样的前缀选项。
描述:
前缀信息选项为主机提供了联机前缀和用于地址自动配置的前缀。前缀信息选项出现在路由器通告数据包中,并对其他消息必须静默忽略。
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Length | Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
~ IP header + data ~
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
字段:
类型:4
长度:以8个八位字节为单位的选项长度。
保留:这些字段未使用。发送方必须将其初始化为零,接收方必须忽略它。
IP头部 + 数据:原始数据包截断部分,以确保重定向消息的大小不超过[IPv6]规定的支持IPv6所需的最小MTU。
描述:
重定向头部选项用于重定向消息,并包含被重定向的数据包的全部或部分内容。
对于其他邻居发现消息,此选项必须被静默忽略。
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Length | Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| MTU |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
字段:
类型:5
长度:1
保留:这个字段未使用。发送方必须将其初始化为零,接收方必须忽略它。
MTU:32位无符号整数。链路推荐的MTU值。
描述:
MTU选项用于路由器通告消息中,在链路的MTU值不是十分明确时,确保链路上的所有节点使用相同的MTU值。
对于其他邻居发现消息,此选项必须被静默忽略。
在异构技术被桥接在一起的配置中,最大支持的MTU可能在不同的段中有所不同。如果桥接设备不生成ICMP“数据包太大”消息,通信节点将无法使用路径MTU动态确定每个邻居的合适MTU。在这种情况下,路由器可以被配置为使用MTU选项来指定所有段所支持的最大MTU值。
本节描述了主机(在某种程度上也包括路由器)将在与相邻节点交互时维护的一种可能的数据结构组织的概念模型。所描述的组织结构旨在便于解释邻居发现协议的行为方式。本文档不要求实现遵循此模型,只要其外部行为与本文档中描述的行为一致即可。
该模型仅涉及与邻居发现直接相关的主机行为方面。特别是,它不涉及源地址选择或多宿主主机上出口接口的选择等问题。
主机将为每个接口维护以下信息:
邻居缓存:关于最近发送流量的各个邻居的条目集合。条目以邻居的本地单播IP地址为键,并包含其链路层地址等信息,标志该邻居是路由器还是主机(在本文中称为IsRouter),指向等待地址解析完成的排队数据包的指针等。邻居缓存条目还包含邻居不可达性检测算法使用的信息,包括可达性状态、未答复探测的数量以及下一个邻居不可达性检测事件计划发生的时间。
目标缓存:关于最近发送流量的目的地的条目集合。目标缓存包括本地和非本地目的地,并提供到邻居缓存的间接引用;目标缓存将目的地IP地址映射到下一跳邻居的IP地址。此缓存根据从重定向消息中学到的信息进行更新。实现可能发现在目标缓存条目中存储一些与邻居发现无直接关系的附加信息非常方便,比如传输协议维护的路径MTU(PMTU)和往返计时器。
前缀列表:定义一组本地连接地址的前缀列表。前缀列表条目是根据接收的路由器通告中的信息创建的。每个条目都有一个关联的失效计时器值(从通告中提取),用于在前缀失效时将其过期。特殊的“无穷大”计时器值指定了前缀永远有效,除非在随后的通告中接收到新的(有限的)值。
上述概念性数据结构可以使用各种技术实现。一个可能的实现方法是对所有上述数据结构使用单一的最长匹配路由表。不管具体的实现方式如何,重要的是路由器的邻居缓存条目由使用该路由器的所有目标缓存条目共享,以防止冗余的邻居不可达性检测探测。
还要注意,其他协议(例如,Mobile IPv6)可能添加其他的概念性数据结构。实现可以自由地以任何方式实现这样的数据结构。例如,一个实现可以将所有概念性数据结构合并到单个路由表中。
邻居缓存包含由邻居不可达性检测算法维护的信息。一个关键的信息是邻居的可达性状态,有五个可能的值。以下定义是非正式的;详细的定义可以在第7.3.2节中找到。
不完整:地址解析正在进行中,尚未确定邻居的链路层地址。
可达:简单来说,已知邻居在最近(十几秒前)是可达的。
陈旧:不再知道邻居是可达的,但在发送流量到邻居之前,不应尝试验证其可达性。
延迟:不再知道邻居是可达的,并且最近已经向邻居发送了流量。然而,不要立即探测邻居,而是延迟一小段时间,以便让上层协议提供可达性确认。
探测:不再知道邻居是可达的,并且正在发送单播邻居请求探测来验证可达性。
当节点发送数据包到一个目的地时,它使用目标缓存、前缀列表和默认路由器列表的组合来确定适当的下一跳IP地址,这个操作被称为“下一跳确定”。一旦知道下一跳的IP地址,发送节点将查询邻居缓存以获取关于该邻居的链路层信息。
对于给定的单播目的地的下一跳确定操作如下。发送者根据前缀列表执行最长前缀匹配,以确定数据包的目的地是本地连接还是非本地连接。如果目的地是本地连接,下一跳地址与数据包的目的地地址相同。否则,发送者从默认路由器列表中选择一个路由器(按照第6.3.6节中描述的规则)。
出于效率原因,下一跳确定并不是对发送的每个数据包都执行。相反,下一跳确定计算的结果保存在目标缓存中(也包含从重定向消息中学到的更新)。当发送节点有数据包要发送时,它首先检查目标缓存。如果目的地没有条目,则调用下一跳确定以创建目标缓存条目。
一旦知道下一跳节点的IP地址,发送者就会在邻居缓存中检查关于该邻居的链路层信息。如果条目不存在,发送者将创建一个条目,将其状态设置为“不完整”,启动地址解析,然后将数据包排队等待地址解析完成。对于支持组播的接口,地址解析包括发送邻居请求消息并等待邻居通告。当接收到邻居通告响应时,链路层地址将输入邻居缓存条目,并传输排队的数据包。地址解析机制在第7.2节中有详细描述。
对于组播数据包,下一跳始终是(组播)目的地地址,被视为本地连接。查找与给定IP组播地址相对应的链路层地址的过程可以在涵盖特定链路类型的IP操作的单独文档中找到(例如,[IPv6-ETHER])。
每当在传输单播数据包时访问邻居缓存条目时,发送者都会根据邻居不可达性检测算法(第7.3节)检查邻居不可达性检测相关信息。这种不可达性检查可能会导致发送者发送单播邻居请求来验证邻居是否仍然可达。
下一跳确定是在第一次发送流量到目的地时完成的。只要随后与该目的地的通信成功进行,就会继续使用目标缓存条目。如果在某个时刻通信停止进行,由邻居不可达性检测算法确定,下一跳确定可能需要再次执行。例如,流量通过故障路由器应该切换到正常工作的路由器。同样,可以将流向移动节点的流量重定向到“移动代理”。
需要注意的是,当节点重新执行下一跳确定时,无需丢弃完整的目标缓存条目。事实上,通常有利于保留这样的缓存信息,例如目标缓存条目中可能保留的PMTU和往返计时器值。
路由器和多宿主主机有多个接口。本文档的其余部分假定所有发送和接收的邻居发现消息都涉及到相应上下文的接口。例如,当回应路由器请求时,相应的路由器通告将通过接收到该请求的接口发送。
上述的概念性数据结构使用不同的机制来丢弃可能过时或未使用的信息。
从正确性的角度来看,没有必要定期清除目标缓存和邻居缓存条目。虽然过时的信息可能会在缓存中无限期地保留,但邻居不可达性检测算法确保了如果实际正在使用过时的信息,那么这些信息会被迅速清除。
为了限制目标缓存和邻居缓存所需的存储空间,节点可能需要垃圾回收旧条目。但是,必须注意确保始终存在足够的空间来保存活动条目的工作集。如果缓存较小,在短时间内丢弃并快速重建条目可能会导致大量的邻居发现消息。任何基于最近最少使用(LRU)的策略,只回收一段时间未使用的条目(例如,十分钟或更长时间)应该足够清除未使用的条目。
节点应保留默认路由器列表和前缀列表中的条目直到其生存时间到期。然而,如果内存不足,节点可能会过早地清除条目。如果没有保留所有路由器在默认路由器列表上,节点应该保留至少两个条目在默认路由器列表中(最好更多),以保持离线目的地的稳健连接。
当从前缀列表中移除条目时,无需从目标缓存或邻居缓存中清除任何条目。邻居不可达性检测将高效地清除这些缓存中已失效的条目。然而,当从默认路由器列表中移除条目时,任何在目标缓存中经过该路由器的条目必须再次执行下一跳确定,以选择新的默认路由器。
本节描述了与邻居发现的路由器和主机行为相关的部分,其中路由器发现用于定位相邻路由器以及了解与无状态地址自动配置相关的前缀和配置参数。
前缀发现是主机了解存在于同链路上并且可以直接到达而无需经过路由器的 IP 地址范围的过程。路由器发送路由器通告,指示发送者是否愿意成为默认路由器。路由器通告还包含前缀信息选项,列出了标识同链路 IP 地址的前缀集合。
无状态地址自动配置还必须获取子网前缀作为配置地址的一部分。虽然用于地址自动配置的前缀在逻辑上与用于同链路确定的前缀不同,但自动配置信息被附加在路由器发现消息上,以减少网络流量。实际上,相同的前缀可以通过在前缀信息选项中指定适当的标志来用于同链路确定和地址自动配置。有关自动配置信息的处理详细信息,请参阅 [ADDRCONF]。
主机必须静默丢弃任何收到的路由器请求消息。
路由器必须静默丢弃任何未满足以下所有有效性检查的接收到的路由器请求消息:
IP跳数限制字段的值为255,即数据包不可能由路由器转发。
ICMP校验和有效。
ICMP代码为0。
ICMP长度(从IP长度推导)为8个或更多八位字节。
所有包含的选项都具有大于零的长度。
如果IP源地址是未指定的地址,则消息中没有源链路层地址选项。
保留字段的内容和任何未识别的选项的内容必须被忽略。未来对协议的向后兼容更改可能会指定保留字段的内容或添加新选项;不兼容的更改可能会使用不同的代码值。
未指定用于路由器请求消息的已定义选项的内容必须被忽略,并且数据包将按照正常进行处理。唯一可能出现的定义选项是源链路层地址选项。
通过有效性检查的solicitation称为“有效的solicitation”。
节点必须静默丢弃任何不满足以下所有有效性检查的接收到的路由器通告消息:
IP源地址是链路本地地址。路由器必须使用它们的链路本地地址作为路由器通告和重定向消息的源地址,以便主机可以唯一地识别路由器。
IP跳数限制字段的值为255,即数据包不可能由路由器转发。
ICMP校验和有效。
ICMP代码为0。
ICMP长度(从IP长度推导)为16个或更多八位字节。
所有包含的选项都具有大于零的长度。
保留字段的内容和任何未识别选项的内容必须被忽略。未来对协议的向后兼容更改可能会指定保留字段的内容或添加新选项;不兼容的更改可能会使用不同的代码值。
必须忽略未指定用于路由器通告消息的已定义选项的内容,并且数据包将按照正常进行处理。唯一可能出现的定义选项是源链路层地址、前缀信息和MTU选项。
通过有效性检查的通告称为“有效的通告”。
路由器必须允许由系统管理配置以下概念变量。特定变量名称仅用于演示目的,实现不必拥有它们,只要其外部行为与本文档中描述的一致即可。默认值是为了简化通常情况下的配置。
下面列出的某些变量的默认值可以被描述不同链路层上IPv6操作的具体文档所覆盖。此规则简化了在具有性能差异的链路类型上配置Neighbor Discovery。
对于每个接口:
IsRouter:指示此接口是否启用路由。在接口上启用路由将意味着路由器可以转发到或从接口转发数据包。
AdvSendAdvertisements:指示路由器是否定期发送路由广告并响应路由器请求。
MaxRtrAdvInterval:从接口发送未经请求的多播路由广告之间允许的最长时间,以秒为单位。必须不少于4秒,不大于1800秒。
MinRtrAdvInterval:从接口发送未经请求的多播路由广告之间允许的最短时间,以秒为单位。必须不少于3秒,不大于0.75 * MaxRtrAdvInterval。
AdvManagedFlag:要放置在路由器广告中“管理地址配置”标志字段中的TRUE/FALSE值。参见[ADDRCONF]。
AdvOtherConfigFlag:要放置在路由器广告中“其他配置”标志字段中的TRUE/FALSE值。参见[ADDRCONF]。
AdvLinkMTU:由路由器发送的MTU选项中的值。零值表示不发送MTU选项。
AdvReachableTime:在路由器发送的路由广告消息中要放置的可达时间字段的值。零值表示未指定(由此路由器)。必须不大于3,600,000毫秒(1小时)。
AdvRetransTimer:在路由器发送的路由广告消息中要放置的重传定时器字段的值。零值表示未指定(由此路由器)。
AdvCurHopLimit:路由器发送的路由广告消息中要放置的当前跳限制字段的默认值。该值应设置为Internet的当前直径。零值表示未指定(由此路由器)。
AdvDefaultLifetime:从接口发送的路由器广告的路由器生存期字段的值,以秒为单位。必须为零或在MaxRtrAdvInterval和9000秒之间。零值表示该路由器不用作默认路由器。这些限制可以被描述不同链路层上IPv6操作的具体文档所覆盖。例如,在点对点链接中,对等体可能对另一端设备的数量和状态有足够的信息,以便更少地需要广告。
AdvPrefixList:要放置在从接口发送的路由广告消息中的前缀信息选项中的前缀列表。
默认值:路由器通过路由协议广告为该接口的on-link前缀。不应将链路本地前缀包含在广告前缀列表中。
每个前缀都有一个相关的:
AdvValidLifetime:在前缀信息选项的有效生存期中放置的值,以秒为单位。所有1的指定值(0xffffffff)表示无穷大。实现可以允许以两种方式指定AdvValidLifetime:
实时递减的时间,即将在将来的某个指定时间导致生存期为零,或者
在连续广告中保持不变的固定时间。
默认值:2592000秒(30天),固定(即在连续广告中保持不变)。
AdvOnLinkFlag:要放置在前缀信息选项中的on-link标志(“L位”)字段中的值。
[ADDRCONF]中的无状态地址配置定义了与每个前缀相关的其他信息:
AdvPreferredLifetime:在前缀信息选项的首选生存期中放置的值,以秒为单位。所有1的指定值(0xffffffff)表示无穷大。有关此值的使用详见[ADDRCONF]。实现可以允许以两种方式指定AdvPreferredLifetime:
实时递减的时间,即将在将来的某个指定时间导致生存期为零,或者
在连续广告中保持不变的固定时间。
默认值:604800秒(7天),固定(即在连续广告中保持不变)。此值不得大于AdvValidLifetime。
AdvAutonomousFlag:要放置在前缀信息选项中的自动标志字段中的值。参见[ADDRCONF]。
上述变量包含要放置在发出的路由器广告消息中的信息。主机使用接收到的信息来初始化一组类似的变量,以控制它们的外部行为(参见第6.3.2节)。其中一些主机变量(例如CurHopLimit、RetransTimer和ReachableTime)适用于所有节点,包括路由器。在实践中,这些变量可能实际上并不存在于路由器上,因为它们的内容可以从上述描述的变量派生出来。然而,外部路由器行为必须与这些变量相同。特别是,这包括根据第6.3.2节中描述的方式偶尔对ReachableTime值进行随机化。
协议常量在第10节中定义。
术语“广告接口”指的是任何功能正常且已启用至少一个单播IP地址的接口,并且其对应的AdvSendAdvertisements标志为TRUE。路由器不得向任何非广告接口发送路由广告。
接口可能在系统启动之外的时间成为广告接口。例如:
路由器必须在广告接口上加入所有路由器的多播地址。路由器响应发送到所有路由器地址的路由器请求,并验证相邻路由器发送的路由器广告的一致性。
路由器通过其广告接口定期发送以及被请求的路由器广告。出站路由器广告填充以下数值,与第4.2节中给出的消息格式一致:
在路由器生存期字段中:接口配置的AdvDefaultLifetime。
在M和O标志中:分别是接口配置的AdvManagedFlag和AdvOtherConfigFlag。
在当前跳限制字段中:接口配置的CurHopLimit。
在可达时间字段中:接口配置的AdvReachableTime。
在重传定时器字段中:接口配置的AdvRetransTimer。
在选项中:
源链路层地址选项:发送接口的链路层地址。为了便于入站负载平衡复制接口,此选项可以省略。
MTU选项:如果AdvLinkMTU值为非零,则是接口配置的AdvLinkMTU值。如果AdvLinkMTU为零,则不发送MTU选项。
前缀信息选项:对于AdvPrefixList中列出的每个前缀,一个前缀信息选项,选项字段设置为AdvPrefixList条目中的信息,如下所示:
路由器可能希望发送不作为默认路由器进行广告的路由器广告。例如,路由器可能会为无状态地址自动配置广告前缀,而不希望转发数据包。此类路由器将出站广告中的路由器生存期字段设置为零。
路由器可以选择在发送未经请求的路由器广告时不包括某些或所有选项。例如,如果前缀生存期比AdvDefaultLifetime长得多,那么每隔几次广告包含它们可能就足够了。但是,在响应路由器请求或发送前几个初始未经请求的广告时,路由器应包含所有选项,以便在系统初始化期间快速传播所有信息(例如前缀)。
如果包含所有选项导致广告的大小超过链路MTU,可以发送多个广告,每个广告包含选项的子集。
主机绝不能在任何时候发送路由器广告消息。
未经请求的路由器广告不是严格周期性的:连续传输之间的间隔是随机的,以减少与同一链路上其他路由器的广告同步的概率[SYNC]。每个广告接口都有自己的定时器。每当从接口发送组播广告时,定时器将被重置为介于接口配置的MinRtrAdvInterval和MaxRtrAdvInterval之间的均匀分布的随机值;定时器到期将导致发送下一个广告和选择新的随机值。
对于成为广告接口时发送的前几个广告(最多MAX_INITIAL_RTR_ADVERTISEMENTS),如果随机选择的间隔大于MAX_INITIAL_RTR_ADVERT_INTERVAL,则定时器应设置为MAX_INITIAL_RTR_ADVERT_INTERVAL。在初始广告中使用较小的间隔增加了在路由器第一次可用时快速发现路由器的可能性,在可能存在数据包丢失的情况下。
路由器广告中包含的信息可能会通过系统管理的操作而更改。例如,广告前缀的生存期可能会更改,可以添加新前缀,路由器可能停止作为路由器(即,从路由器切换为主机),等等。在这种情况下,路由器可以发送多达MAX_INITIAL_RTR_ADVERTISEMENTS个未经请求的广告,使用与接口成为广告接口时相同的规则。
接口可能通过系统管理的操作停止成为广告接口,例如:
在这种情况下,路由器应在接口上发送一个或多个(但不超过MAX_FINAL_RTR_ADVERTISEMENTS)带有零路由器生存期字段的最终多播路由器广告。对于路由器变为主机的情况,系统还应该在路由器支持IP组播的所有接口上(无论它们是否已成为广告接口)退出所有路由器IP多播组。此外,主机必须确保从接口发送的随后的邻居广告消息的路由器标志设置为零。
请注意,系统管理可能会禁用路由器的IP转发功能(即,将系统从路由器更改为主机),这并不一定意味着路由器的接口停止成为广告接口。在这种情况下,后续的路由器广告必须将路由器生存期字段设置为零。
主机必须默默地丢弃任何收到的路由器请求消息。
除了定期、未经请求地发送广告外,路由器还会响应在广告接口上收到的有效请求而发送广告。路由器可以选择直接向请求主机的地址单播响应(如果请求的源地址不是未指定地址),但通常情况是将响应组播到所有节点组。在后一种情况下,接口的间隔计时器将被重置为一个新的随机值,就好像刚刚发送了一个未经请求的广告(请参阅第6.2.4节)。
在所有情况下,对路由器请求发送的路由器广告必须延迟发送,延迟时间在0到MAX_RA_DELAY_TIME秒之间。(如果对多个请求只发送单个广告,则延迟时间是相对于第一个请求的。)此外,连续发送到所有节点多播地址的路由器广告必须按照每MIN_DELAY_BETWEEN_RAS秒不超过一个广告的速率进行限制。
路由器可能如下处理路由器请求:
收到路由器请求后,计算0到MAX_RA_DELAY_TIME范围内的随机延迟。如果计算出的值对应于下一个多播路由器广告预定发送的时间,则忽略随机延迟,并在已计划的时间发送广告。
如果路由器在最近的MIN_DELAY_BETWEEN_RAS秒内(包括已发出的请求或未经请求的多播路由器广告),安排广告在上一个广告发送后的MIN_DELAY_BETWEEN_RAS加上随机值的时间发送。这样可以确保多播路由器广告受到速率限制。
否则,安排在随机值给定的时间发送路由器广告。
请注意,路由器允许比MinRtrAdvInterval配置变量指示的频率更频繁地发送多播路由器广告,只要更频繁的广告是对路由器请求的响应即可。然而,在任何情况下,未经请求的多播广告不得频率高于MinRtrAdvInterval指示的频率。
路由器请求中的源地址是未指定地址的,不得更新路由器的邻居缓存;带有正确源地址的请求如下更新邻居缓存。如果路由器已经有了请求发送者的邻居缓存条目,而且请求包含源链路层地址选项,并且接收到的链路层地址与缓存中已有的不同,那么链路层地址应该更新到适当的邻居缓存条目中,并且其可达性状态也必须设置为STALE。如果对于请求的发送者没有现有的邻居缓存条目,路由器会创建一个,安装链路层地址,并按照第7.3.3节的规定将其可达性状态设置为STALE。如果不存在现有的邻居缓存条目,并且在请求中没有提供源链路层地址选项,则路由器可以用多播路由器广告或单播路由器广告作出响应。无论是否提供源链路层地址选项,如果邻居缓存条目存在(或已创建),条目的IsRouter标志必须设置为FALSE。
路由器应该检查其他路由器发送的有效路由器广告,并验证路由器在链路上广告一致的信息。检测到的不一致性表明一个或多个路由器可能配置错误,并应记录到系统或网络管理中。要检查的最小信息集包括:
注意,不同的路由器广告不同的前缀集合并不是错误。此外,一些路由器可能将一些字段留空,即,值为零,而其他路由器指定值。错误的记录应该限制在引起主机在每次接收到广告时从一个值切换到另一个值的冲突信息上。
对于路由器接收到的路由器广告消息的任何其他操作超出了本文档的范围。
路由器上的链路本地地址应该很少甚至不会更改。接收到邻居发现消息的节点使用源地址来识别发送者。如果来自同一路由器的多个数据包包含不同的源地址,节点将假定它们来自不同的路由器,导致不良行为。例如,一个节点将忽略由当前第一跳路由器以外的路由器发送的重定向消息。因此,特定路由器发送的路由器广告中使用的源地址必须与重定向到该路由器时的目标地址相同。
使用链路本地地址在链路上唯一标识路由器的好处是,当站点重新编号时,路由器所知的地址不应更改。
如果路由器更改其一个接口的链路本地地址,应通知主机这种更改。路由器应该从旧的链路本地地址多播几个路由器广告,路由器生存时间字段设置为零,也应该从新的链路本地地址多播几个路由器广告。总体效果应该与一个接口停止成为广告接口,另一个接口开始成为广告接口一样。
无。
除了第5.1节中定义的数据结构外,主机还维护一些与邻居发现相关的变量。特定的变量名称仅用于演示目的,实现不必有这些变量,只要其外部行为与本文档中描述的行为一致即可。
这些变量具有默认值,这些默认值将被路由器广告消息中接收的信息所覆盖。当链路上没有路由器或者接收到的所有路由器广告都将特定值未指定时,将使用默认值。
本规范中的默认值可以被描述了不同链路层上的IP操作的具体文档所覆盖。这一规则允许邻居发现在性能特征差异很大的链路上运行。
对于每个接口:
LinkMTU:链路的最大传输单元。
默认值:特定文档中描述的IPv6在特定链路层上的操作值(例如,[IPv6-ETHER])。
CurHopLimit:发送IP数据包时要使用的默认跳限。
默认值:在实施时生效的“已分配号码”[ASSIGNED]中指定的值。
BaseReachableTime:用于计算随机ReachableTime值的基本值。
默认值:REACHABLE_TIME毫秒。
ReachableTime:在收到可达性确认后,邻居被视为可达的时间。
此值应该是 MIN_RANDOM_FACTOR 和 MAX_RANDOM_FACTOR 倍的 BaseReachableTime 毫秒之间的均匀分布的随机值。当 BaseReachableTime 更改(由于路由器广告)或者即使没有收到路由器广告也应至少每几个小时计算一次新的随机值。
RetransTimer:解析地址或探测邻居可达性时向邻居重发邻居请求消息之间的时间间隔。
默认值:RETRANS_TIMER毫秒。
当存在多个路由器时,所有路由器共同广告的信息可能是单个路由器通告中包含信息的超集。此外,信息也可以通过其他动态方式(如DHCPv6)获得。主机接受所有接收到的信息;接收到路由器通告不得使先前从另一广告或其他来源接收到的所有信息无效。但是,当接收到特定参数(例如,链路MTU)或选项(例如,特定前缀的生存期)的信息与先前接收到的信息不同时,并且该参数/选项只能具有一个值时,应将最近接收到的信息视为权威信息。
路由器通告字段(例如,Cur Hop Limit,Reachable Time和Retrans Timer)可能包含一个表示未指定的值。在这种情况下,应忽略该参数,并且主机应继续使用其已使用的任何值。特别地,主机不得将未指定的值解释为恢复到在接收到第一个路由器通告之前使用的默认值。此规则防止主机在一个路由器广告特定值的情况下不断更改内部变量,而其他路由器广告未指定值。
收到有效路由器通告后,主机提取数据包的源地址,并执行以下操作:
为了限制默认路由器列表所需的存储空间,主机可以选择不存储通过广告发现的所有路由器地址。但是,主机必须保留至少两个路由器地址,并应保留更多。默认路由器的选择是在通信到目的地似乎失败时进行的。因此,列表上有更多路由器时,更有可能快速找到备用工作路由器(例如,无需等待下一个广告到达)。
如果收到的Cur Hop Limit值非零,则主机应将其CurHopLimit变量设置为接收到的值。
如果收到的Reachable Time值非零,则主机应将其BaseReachableTime变量设置为接收到的值。如果新值与先前值不同,则主机应重新计算新的随机ReachableTime值。ReachableTime计算为在BaseReachableTime的MIN_RANDOM_FACTOR和MAX_RANDOM_FACTOR倍之间的均匀分布的随机值。使用随机组件可消除邻居不可达检测消息相互同步的可能性。
在大多数情况下,广告的Reachable Time值将在连续的路由器通告中保持不变,并且主机的BaseReachableTime很少更改。在这种情况下,实现应确保至少每隔几个小时重新计算一次新的随机值。
如果接收到的Retrans Timer值非零,则应将RetransTimer变量从Retrans Timer字段复制过来。
从路由器通告的固定部分提取信息后,应扫描广告以查找有效的选项。如果广告包含源链路层地址选项,则应将链接层地址记录在路由器的邻居缓存条目中(必要时创建条目),并且邻居缓存条目中的IsRouter标志必须设置为TRUE。如果未包含源链路层地址,但存在相应的邻居缓存条目,则其IsRouter标志必须设置为TRUE。IsRouter标志用于邻居不可达检测以确定路由器何时更改为主机(即,无法再转发数据包)。如果为路由器创建了邻居缓存条目,则其可达性状态必须根据第7.3.3节中规定的设置为STALE。如果已经存在的缓存条目并使用不同的链路层地址进行更新,则其可达性状态也必须设置为STALE。
如果存在MTU选项,则主机应将该选项的值复制到LinkMTU中,只要该值大于或等于最小链路MTU[IPv6]并且不超过链路类型特定文档(例如[IPv6-ETHER])中指定的最大LinkMTU值。
具有设置为“on-link”(L)标志的前缀信息选项表示识别应视为on-link的地址范围的前缀。但是,请注意,设置为零的前缀信息选项的on-link标志不传达有关on-link确定的任何信息,并且不得被解释为表示由前缀覆盖的地址是off-link的。取消先前on-link指示的唯一方法是使用设置了L位并且生存期设置为零的前缀来广告该前缀。在向地址发送的数据包没有关于地址的on-link状态的任何信息时,默认行为(见第5.2节)是将数据包转发到默认路由器;设置为零的“on-link”(L)标志的前缀信息选项不会更改此行为。有关将地址视为on-link的原因在第2.1节中的“on-link”的定义中指定。通常,设置为零的on-link标志的前缀具有自主标志并由[ADDRCONF]使用。
对于每个设置了on-link标志的前缀信息选项,主机执行以下操作:
无状态地址自动配置[ADDRCONF]在某些情况下可能使用前缀的更大有效生存期或完全忽略它,以防止特定的拒绝服务攻击。但是,由于以同样的拒绝服务针对on-link前缀列表的效果并不灾难性(主机将向默认路由器发送数据包并接收重定向,而不是直接向邻居发送数据包),因此邻居发现协议不对前缀生存期值施加此类检查。同样,[ADDRCONF]可能对地址配置目的施加某些前缀长度的限制。因此,前缀可能会被主机中的[ADDRCONF]实现拒绝。但是,与前缀选项中的其他标志结合使用时,前缀长度仍然对于on-link确定是有效的。
注意: 实现可以选择单独处理前缀的on-link方面和前缀的无状态地址自动配置方面,例如,将每个有效路由器通告消息的副本传递给“on-link”和“addrconf”函数。然后,每个函数可以独立操作具有适当标志集的前缀。
每当前缀列表条目的失效定时器到期时,该条目将被丢弃。但是,无需更新现有的目的地缓存条目。如果现有邻居缓存条目出现可达性问题,则邻居不可达检测将执行任何必要的恢复操作。
每当默认路由器列表中条目的生存期到期时,该条目将被丢弃。在删除默认路由器时,节点必须以这样的方式更新目的地缓存,以便所有使用该路由器的条目再次执行下一跳确定,而不是继续向(已删除的)路由器发送流量。
选择路由器的算法部分取决于路由器是否已知可达性。关于节点如何跟踪邻居可达性状态的确切细节在第7.3节中有所涵盖。选择默认路由器的算法在下一跳确定时被调用,当对于某个离开链接的目的地不存在目的地缓存条目时,或者通过现有路由器进行的通信似乎出现故障时。在正常情况下,首次发送到目的地的流量将选择路由器,随后针对该目的地的流量将使用与目的地缓存指示的相同路由器,模除由重定向消息引起的目的地缓存的任何更改。
从默认路由器列表中选择路由器的策略如下:
可达或可能可达的路由器(即,处于除INCOMPLETE以外的任何状态)应优先于其可达性未知或可疑的路由器(即,处于INCOMPLETE状态,或者不存在邻居缓存条目)。有关在有多个等效路由器可用时的默认路由器选择的进一步实现提示详见[LD-SHRE]。
当列表上没有已知可达或可能可达的路由器时,路由器应以循环轮询的方式进行选择,以便后续对默认路由器的请求不会返回相同的路由器,直到选择了所有其他路由器。
在这种情况下循环遍历路由器列表,以确保邻居不可达检测算法主动探测所有可用的路由器。对默认路由器的请求与向路由器发送数据包同时进行,并且所选的路由器将作为副作用被探测其可达性。
6.3.7. 发送路由器请求
当接口启用时,主机可能不愿意等待下一个未经请求的路由器通告以定位默认路由器或学习前缀。为了快速获取路由器通告,主机SHOULD发送最多 MAX_RTR_SOLICITATIONS 条路由器请求消息,每条消息之间至少间隔 RTR_SOLICITATION_INTERVAL 秒。可以在以下任何事件后发送路由器请求:
系统启动时初始化接口。
在临时接口故障或被系统管理暂时禁用后重新初始化接口。
通过系统管理关闭 IP 转发能力,使系统从路由器变为主机。
主机首次连接到链路。
主机在一段时间后重新连接到链路。
主机将路由器请求发送到全路由器组播地址。IP 源地址设置为接口的单播地址之一或未指定地址。如果 IP 源地址不是未指定地址,则SHOULD将“源链路层地址”选项设置为主机的链路层地址。
在主机发送初始请求之前,SHOULD将传输延迟一段随机时间,介于 0 和 MAX_RTR_SOLICITATION_DELAY 之间。这有助于减轻同时在同一链路上启动多个主机时可能发生的拥塞,例如从电源故障恢复后可能发生的情况。如果主机自接口(重新)启用以来已经执行了随机延迟(例如,作为“重复地址检测 [ADDRCONF]”的一部分),则在发送第一条路由器请求消息之前无需再次延迟。
在某些情况下,如果需要,可以省略随机延迟。例如,使用 [MIPv6] 的移动节点移动到新链路时需要尽快发现此移动,以最小化由其拓扑移动引起的数据包丢失量。路由器请求对于在 Mobile IPv6 中进行移动检测提供了一个有用的工具,因为它们允许移动节点确定移动到新链路。因此,如果移动节点收到链路层信息表明可能发生了移动,它可以立即发送路由器请求,而无需进行随机延迟。此类指示的强度应该由移动节点的实现根据链路层提示的确定程度进行评估,这超出了本规范的范围。请注意,不恰当地使用此机制(例如,基于弱或短暂的指示)可能导致路由器请求风暴。此外,大量使用此机制的大量移动节点的同时移动可能导致大量同时发送的请求。
一旦主机发送了路由器请求,并收到了有效的路由器通告并具有非零的路由器生存期,则主机必须停止在该接口上发送额外的请求,直到下次发生上述事件之一。此外,如果在发送请求之前收到通告,则应至少发送一次请求。对于受请求的通告的响应可能包含比未经请求的通告更多的信息。
如果主机发送了 MAX_RTR_SOLICITATIONS 条请求,并在发送最后一条请求后等待了 MAX_RTR_SOLICITATION_DELAY 秒后没有收到路由器通告,则主机得出结论认为链路上没有路由器用于[ADDRCONF]的目的。但是,如果路由器出现在链路上,则主机会继续接收和处理路由器通告消息。
本节描述了与邻居请求(Neighbor Solicitation)和邻居通告(Neighbor Advertisement)消息相关的功能,并包括地址解析和邻居不可达检测算法的描述。
邻居请求和邻居通告消息也用于如[ADDRCONF]所规定的重复地址检测。特别是,重复地址检测使用了具有未指定源地址的邻居请求消息,针对其自己的“暂时”地址。这些消息会触发已经使用该地址的节点以组播邻居通告的方式响应,表明该地址已被使用。
节点必须默默丢弃任何未满足以下所有有效性检查的接收到的邻居请求消息:
- IP Hop Limit 字段的值为 255,即数据包不可能被路由器转发。
- ICMP 校验和是有效的。
- ICMP Code 为 0。
- ICMP长度(根据IP长度导出)为24个或更多八位组。
- 目标地址不是多播地址。
- 所有包含的选项的长度大于零。
- 如果IP源地址是未指定地址,则IP目的地址是一个所请求的节点组播地址。
- 如果IP源地址是未指定地址,则消息中没有源链路层地址选项。
必须忽略保留字段的内容和任何未识别的选项。未来对协议的向后兼容的更改可能会指定保留字段的内容或添加新选项;向后不兼容的更改可能会使用不同的 Code 值。未指定用于邻居请求消息的已定义选项的内容必须被忽略,并且数据包应按正常方式处理。唯一可能出现的已定义选项是源链路层地址选项。
经过有效性检查的邻居请求称为“有效请求”。
节点必须默默丢弃任何未满足以下所有有效性检查的接收到的邻居通告消息:
- IP Hop Limit 字段的值为 255,即数据包不可能被路由器转发。
- ICMP 校验和是有效的。
- ICMP Code 为 0。
- ICMP长度(根据IP长度导出)为24个或更多八位组。
- 目标地址不是多播地址。
- 如果IP目的地址是一个多播地址,则所请求的标志位为零。
- 所有包含的选项的长度大于零。
必须忽略保留字段的内容和任何未识别的选项。未来对协议的向后兼容的更改可能会指定保留字段的内容或添加新选项;向后不兼容的更改可能会使用不同的 Code 值。
经过有效性检查的邻居通告称为“有效通告”。
地址解析是节点仅凭其 IP 地址确定邻居的链路层地址的过程。地址解析仅针对被确定为在链路上的地址进行,并且发送方不知道相应链路层地址(参见第5.2节)。地址解析永远不会针对多播地址执行。
主机有可能收到不包括链路层地址选项的请求、路由器通告或重定向消息。除了 IsRouter 标志(如第6.3.4节和第7.2.5节所述)以外,这些消息不得创建或更新邻居缓存条目。如果对于此类消息的源不存在邻居缓存条目,则在可以开始与该地址的单播通信之前,将需要进行地址解析。对于对请求的单播响应而言,需要额外的数据包交换以传递通告,这点特别重要。
当支持多播的接口启用时,节点必须加入该接口的全节点多播地址,以及与该接口分配的每个IP地址对应的所请求节点多播地址。
分配给接口的地址集可能随时间变化。可能添加新地址并删除旧地址 [ADDRCONF]。在这种情况下,节点必须加入和离开分别对应新地址和旧地址的所请求节点多播地址。加入所请求节点多播地址是通过使用类似 [MLD] 或 [MLDv2] 协议的多播监听器发现来完成的。请注意,多个单播地址可能映射到同一个所请求节点多播地址;节点不得在与该多播地址对应的所有分配地址已被删除之前离开所请求节点多播组。
当节点有一个单播数据包要发送到一个邻居,但不知道邻居的链路层地址时,它会执行地址解析。对于支持多播的接口,这涉及创建一个处于 INCOMPLETE 状态的邻居缓存条目,并传输一个针对该邻居的邻居请求消息。该请求消息发送到与目标地址对应的所请求节点多播地址。
如果触发请求的数据包的源地址与出站接口分配的地址之一相同,则应该将该地址放置在传出请求的 IP 源地址中。否则,应该使用接口分配的任何一个地址。在可能的情况下使用触发数据包的源地址可以确保邻居请求的接收者在其邻居缓存中安装高度可能在属于触发数据包“连接”的后续返回流量中使用的 IP 地址。
如果该请求发送到所请求节点多播地址,则发送者必须将其链路层地址(如果有)作为源链路层地址选项包括在内。否则,发送者应该将其链路层地址(如果有)作为源链路层地址选项包括在内。在多播请求中包括源链路层地址是必需的,以便目标有一个地址可以用来发送邻居通告。在单播请求中,实现可以省略源链路层地址选项。这里的假设是,如果发送者在其缓存中具有对等方的链路层地址,则对等方很可能也会在其缓存中具有发送者的条目。因此,不需要发送。
在等待地址解析完成时,对于每个邻居,发送者必须保留一个小的等待地址解析完成的数据包队列。该队列必须持有至少一个数据包,可能包含更多。但是,每个邻居的排队数据包数量应该限制在一些小的值。当队列溢出时,新到达的数据包应该替换最旧的条目。一旦地址解析完成,节点会传输任何排队的数据包。
在等待响应时,发送者应该大约每个 RetransTimer 毫秒重新传输一次邻居请求消息,即使没有额外的流量发送到邻居也是如此。重传必须受到限制,至多每个邻居每个 RetransTimer 毫秒一个请求。
如果在发送 MAX_MULTICAST_SOLICIT 个请求后没有接收到邻居通告,则地址解析失败。发送者必须对等待地址解析的每个数据包返回 ICMP 目标不可达指示,代码为 3(地址不可达)。
一个有效的邻居请求如果不满足以下任何一个要求,则必须被静默丢弃:
- 目标地址是分配给接收接口的“有效”单播或任播地址 [ADDRCONF],
- 目标地址是节点提供代理服务的单播或任播地址,或者
- 目标地址是正在进行重复地址检测的“临时”地址 [ADDRCONF]。
如果目标地址是临时的,则应该按照 [ADDRCONF] 中描述的方式处理邻居请求。否则,以下描述适用。如果源地址不是未指定地址,并且在具有地址的链路层上,请求包含源链路层地址选项,则接收者应该为邻居请求的 IP 源地址创建或更新邻居缓存条目。如果条目不存在,则节点应该创建一个新条目,并根据第 7.3.3 节的规定将其可达性状态设置为 STALE。如果条目已经存在,并且缓存的链路层地址与接收到的源链路层选项中的地址不同,则应该用接收到的地址替换缓存地址,并且条目的可达性状态必须设置为 STALE。
如果创建了一个邻居缓存条目,则 IsRouter 标志应该设置为 FALSE。即使邻居请求是由路由器发送的,这也是这样,因为邻居请求消息不包含发送者是否为路由器的指示。如果发送者是路由器,在随后的邻居通告或路由器通告消息中将设置正确的 IsRouter 值。如果邻居缓存条目已经存在,则其 IsRouter 标志不得被修改。
如果源地址是未指定地址,则节点不能创建或更新邻居缓存条目。
在邻居缓存的任何更新之后,节点将作为下一节中描述的邻居通告响应发送邻居通告。
节点对一个有效的邻居请求进行邻居通告的响应,该邻居请求针对节点的一个分配地址。通告的目标地址从邻居请求的目标地址复制而来。如果邻居请求的 IP 目的地址不是一个多播地址,则可以省略目标链路层地址选项;对于已经接收到邻居请求的邻居节点来说,其缓存的值必须是当前的。如果邻居请求的 IP 目的地址是一个多播地址,则必须在通告中包含目标链路层选项。此外,如果节点是路由器,则必须将 Router 标志设置为 1;否则,必须将该标志设置为 0。
如果目标地址是任播地址或节点正在提供代理服务的单播地址,或者目标链路层地址选项未包含,则应该将 Override 标志设置为 0。否则,应该将 Override 标志设置为 1。正确设置 Override 标志确保节点优先考虑非代理通告,即使在代理通告之后接收到,也确保任播地址的第一个通告“获胜”。
如果邻居请求的源地址是未指定地址,则节点必须将 Solicited 标志设置为 0,并将通告多播到全节点地址。否则,节点必须将 Solicited 标志设置为 1,并将通告单播到邻居请求的源地址。
如果目标地址是一个任播地址,则发送者应该延迟在 0 到 MAX_ANYCAST_DELAY_TIME 秒之间的随机时间发送响应。
因为单播邻居请求不需要包含源链路层地址,所以发送所请求的邻居通告时,节点可能没有其邻居的相应链路层地址存在于其邻居缓存中。在这种情况下,节点首先必须使用邻居发现来确定其邻居的链路层地址(即发送一个多播邻居请求)。
当接收到有效的邻居通告(被请求或未请求的)时,会在邻居缓存中查找目标的条目。如果没有条目存在,则应该静默丢弃该通告。因为接收方显然没有与目标发起任何通信,所以不需要创建条目。
一旦找到适当的邻居缓存条目,所采取的具体操作取决于邻居缓存条目的状态、通告中的标志以及实际提供的链路层地址。
如果在接收到通告时目标的邻居缓存条目处于 INCOMPLETE 状态,则会发生以下两种情况之一。如果链路层有地址且未包含目标链路层地址选项,则接收节点应该静默丢弃接收到的通告。否则,接收节点执行以下步骤:
请注意,如果条目处于 INCOMPLETE 状态,则忽略 Override 标志。
如果在接收到通告时目标的邻居缓存条目处于除 INCOMPLETE 以外的任何状态,则执行以下操作:
I. 如果 Override 标志未设置且提供的链路层地址与缓存中的地址不同,则执行以下两种操作之一:
a. 如果条目的状态为 REACHABLE,则将其设置为 STALE,但不对条目进行其他更新。
b. 否则,应该忽略接收到的通告,不能更新缓存。
II. 如果 Override 标志已设置,或提供的链路层地址与缓存中的地址相同,或未提供目标链路层地址选项,则接收到的通告必须按以下方式更新邻居缓存条目:
- 必须在缓存中插入目标链路层地址选项中的链路层地址(如果提供的地址与已记录的地址不同)。
- 如果 Solicited 标志被设置,则条目的状态必须设置为 REACHABLE。如果 Solicited 标志为零并且链路层地址已更新为不同的地址,则状态必须设置为 STALE。否则,条目的状态保持不变。
- 如果通告的 Solicited 标志被设置,这只能说明该通告是对邻居请求的响应。因为邻居不可达性检测请求是发送到缓存的链路层地址的,所以收到请求的响应表明正常的前向路径已经生效。但是,收到未被请求的邻居通告可能表示邻居有紧急信息要通告(例如,更改了链路层地址)。如果紧急信息表明与节点当前使用的内容有所不同,则节点在发送下一个数据包时应该验证路径的可达性。对于未更改缓存内容的未经请求的通告,无需更新状态。
- 根据接收到的通告中的 Router 标志设置邻居缓存条目的 IsRouter 标志。对于因此更新而从 TRUE 更改为 FALSE 的情况,节点必须从默认路由器列表中移除该路由器,并根据第 7.3.3 节的规定更新使用该邻居作为路由器的所有目的地缓存条目。这是为了检测节点作为路由器停止转发数据包的情况。
上述规则确保在邻居通告优先时更新缓存(即设置了 Override 标志)或邻居通告引用了当前在缓存中记录的相同链路层地址时更新。如果上述情况都不适用,则通告通过更改缓存条目中的状态来引发未来的邻居不可达性检测(如果尚未进行)。
在某些情况下,节点可能能够确定其链路层地址已更改(例如,接口卡的热插拔),并希望快速通知其邻居新的链路层地址。在这种情况下,节点可以向全节点多播地址发送多达 MAX_NEIGHBOR_ADVERTISEMENT 个未请求的邻居通告消息。这些通告必须至少间隔 RetransTimer 秒。
未请求通告中的目标地址字段设置为接口的 IP 地址,并且目标链路层地址选项填充有新的链路层地址。Solicited 标志必须设置为零,以避免混淆邻居不可达性检测算法。如果节点是路由器,则必须将 Router 标志设置为一;否则,必须设置为零。Override 标志可以设置为零或一。在任何情况下,相邻节点将立即将其针对目标地址的邻居缓存条目状态更改为 STALE,促使它们验证可达性路径。如果 Override 标志设置为一,相邻节点将在其缓存中安装新的链路层地址。否则,它们将忽略新的链路层地址,选择探测已缓存的地址。
对于接口上分配了多个 IP 地址的节点,可以针对每个地址多播单独的邻居通告。在这种情况下,节点应该在发送每个通告之间引入小的延迟,以降低因拥塞导致通告丢失的概率。
当其链路层地址更改或被配置为代理地址(通过系统管理或其他机制)时,代理可以多播邻居通告。如果有多个节点为相同一组地址提供代理服务,则代理应该提供一种机制,防止多个代理为任何一个地址多播通告,以减少多播流量过多的风险。这是需要使用邻居通告的其他协议的要求。执行代理通告的节点示例是[MIPv6]中指定的Home Agent。
此外,属于任播地址的节点在其链路层地址更改时,可以针对该任播地址多播未请求的邻居通告。
请注意,由于未请求的邻居通告并不能可靠地更新所有节点的缓存(通告可能未被所有节点接收),因此它们只应被视为一种性能优化,以快速更新大多数邻居的缓存。邻居不可达性检测算法确保所有节点获得可达的链路层地址,尽管延迟可能略长。
从邻居发现的角度来看,任播地址在大多数情况下与单播地址一样对待。由于任播地址在语法上与单播地址相同,执行地址解析或邻居不可达性检测的节点将其视为单播地址。不会发生特殊处理。
将任播地址分配给接口的节点将其视为具有两个例外的单播地址。首先,作为对邻居请求的响应发送的邻居通告应该通过在0到 MAX_ANYCAST_DELAY_TIME 之间的随机时间延迟,以减少网络拥塞的概率。其次,在邻居通告中,Override 标志应该设置为 0,以便在收到多个通告时使用首个收到的通告,而不是最近收到的通告。
与单播地址一样,邻居不可达性检测确保节点快速检测到当前任播地址的绑定何时变得无效。
在有限的情况下,路由器可以为一个或多个其他节点代理,也就是说,通过邻居通告表明它愿意接受未明确寻址给自己的数据包。例如,路由器可能代表移动节点接受数据包,该移动节点已经移出链路。代理使用的机制基本上与任播地址使用的机制相同。
代理必须加入对应于它代理的节点分配的 IP 地址的被请求节点组播地址。这应该使用多播监听发现协议,如 [MLD] 或 [MLDv2] 来完成。
所有被请求的代理邻居通告消息必须将 Override 标志设置为零。这确保如果节点本身存在于链路上,它的邻居通告(带有 Override 标志设置为 1)将优先于从代理接收的任何通告。代理可以像第 7.2.6 节所述一样发送 Override 标志设置为 1 的非请求通告,但这样做可能会导致代理通告覆盖节点本身创建的有效条目。
最后,当作为对邻居请求的响应发送代理通告时,发送方应该通过在 0 到 MAX_ANYCAST_DELAY_TIME 秒之间的随机时间延迟响应,以避免由几个代理发送的多个响应造成的冲突。但是,在某些情况下(例如,Mobile IPv6),仅存在一个代理,这样的延迟是不必要的。
与邻居的通信可能在任何时间因各种原因而失败,包括硬件故障、接口卡热插拔等。如果目标已经失败,则无法恢复通信。另一方面,如果是路径失败,可能可以恢复。因此,节点积极跟踪它发送数据包的邻居的可达性“状态”。
邻居不可达性检测用于主机和邻居节点之间的所有路径,包括主机到主机、主机到路由器和路由器到主机的通信。邻居不可达性检测也可能在路由器之间使用,但如果有等效的机制可用,例如作为路由协议的一部分,则不需要。
当到邻居的路径似乎失败时,特定的恢复过程取决于邻居的使用方式。例如,如果邻居是最终目的地,则应再次执行地址解析。然而,如果邻居是路由器,则尝试切换到另一个路由器可能是适当的。具体的恢复过程包括在下一跳确定下; 邻居不可达性检测通过删除邻居缓存条目来表示需要下一跳确定。
邻居不可达性检测仅针对发送到单播数据包的邻居执行;发送到多播地址时不使用它。
如果节点最近接收到确认最近发送给邻居的数据包已被其 IP 层接收,则认为邻居是可达的。积极的确认可以通过两种方式获得:来自上层协议的提示,指示连接正在进行“前进”,或接收到作为邻居请求的响应的邻居通告消息。
如果连接正在进行“前进”,则说明从远程对等方接收到的数据包只有在最近发送到该对等方的数据包实际到达时才能到达。例如,在 TCP 中,接收到(新的)确认表示先前发送的数据到达了对等方。同样,新数据(非重复数据)的到达表示先前的确认正在传递给远程对等方。如果数据包已到达对等方,则它们也必定到达了发送方的下一跳邻居;因此,“前进”表示下一跳邻居是可达的。对于离链路的目的地,前进意味着第一跳路由器是可达的。可用时,应使用此上层信息。
在某些情况下(例如基于 UDP 的协议和路由器转发数据包到主机),从上层协议中可能无法轻松获取到这种可达性信息。当没有提示可用且节点正在向邻居发送数据包时,节点会主动使用单播邻居请求消息来探测邻居,以验证正向路径是否仍然有效。
收到请求的邻居通告作为可达性确认,因为将 Solicited 标志设置为 1 的通告仅作为对邻居请求的响应发送。不得将其他邻居发现消息(例如路由器通告和将 Solicited 标志设置为零的邻居通告)视为可达性确认。收到非请求的消息仅确认了从发送者到接收节点的单向路径。相比之下,邻居不可达性检测要求节点跟踪从其视角到邻居的正向路径的可达性,而不是邻居的视角。请注意,收到请求的广告表明双向路径正在工作。该邻居必须已收到请求,促使它生成一个广告。同样,收到广告表明从发送者到接收者的路径正在工作。但是,后者只有接收者知道;广告的发送方无法直接知道其发送的广告实际上已经到达邻居。从邻居不可达性检测的角度来看,只有正向路径的可达性是感兴趣的。
邻居缓存项可以处于以下五种状态之一:
INCOMPLETE 地址解析正在对该项执行。具体来说,已向目标的请求节点组多播地址发送了邻居请求,但相应的邻居通告尚未收到。
REACHABLE 在最近的 ReachableTime 毫秒内收到了正面确认,即正向路径到邻居正在正常工作。在 REACHABLE 状态下,发送数据包时不会发生特殊操作。
STALE 距离上次收到正面确认的时间已超过 ReachableTime 毫秒,正向路径正常工作。在过期状态下,直到发送数据包之前都不会发生任何操作。
接收到未经请求的邻居发现消息更新了缓存的链路层地址后,进入 STALE 状态。接收到这样的消息并不确认可达性,进入 STALE 状态可确保在实际使用该项时快速验证可达性。但是,直到实际使用该项之前,实际上并未验证可达性。
DELAY 距离上次收到正面确认的时间已超过 ReachableTime 毫秒,并且在 DELAY_FIRST_PROBE_TIME 秒内发送了数据包。如果在进入 DELAY 状态后的 DELAY_FIRST_PROBE_TIME 秒内未收到可达性确认,则发送邻居请求并将状态更改为 PROBE。
DELAY 状态是一种优化,可在上层协议提供可达性确认的情况下为 ReachableTime 毫秒后未有最近流量的情况下提供额外时间。如果没有这种优化,在流量停滞后打开 TCP 连接将会立即发起探测,尽管随后的三次握手几乎立即提供了可达性确认。
PROBE 通过每隔 RetransTimer 毫秒重新发送邻居请求来积极寻求可达性确认,直到收到可达性确认为止。
邻居不可达性检测与向邻居发送数据包并行进行。在重新确认邻居的可达性时,节点继续使用缓存的链路层地址向该邻居发送数据包。如果不向邻居发送流量,则不发送探测。
当节点需要对相邻地址执行地址解析时,在 INCOMPLETE 状态下创建一个条目,并根据第 7.2 节的规定启动地址解析。如果地址解析失败,则应删除该条目,以便随后的流量再次调用下一跳确定过程。在此时调用下一跳确定可以确保尝试备用默认路由器。
当收到可达性确认(通过上层建议或请求的邻居通告)时,条目的状态更改为 REACHABLE。唯一的例外是,上层建议对于处于 INCOMPLETE 状态的条目(例如,没有缓存链路层地址的条目)没有影响。
当达到 ReachableTime 毫秒后,自上次邻居的可达性确认后,邻居缓存条目的状态从 REACHABLE 更改为 STALE。
注意:实现实际上可以推迟从 REACHABLE 更改到 STALE 状态的转换,直到向邻居发送数据包为止,也就是说,与 ReachableTime 的到期关联的显式超时事件是没有必要的。
第一次发送数据包到一个条目为 STALE 的邻居时,发送方将其状态更改为 DELAY,并设置一个计时器,在 DELAY_FIRST_PROBE_TIME 秒后过期。如果条目在计时器到期时仍处于 DELAY 状态,则其状态更改为 PROBE。如果接收到可达性确认,则其状态更改为 REACHABLE。
进入 PROBE 状态时,节点向邻居使用缓存的链路层地址发送单播邻居请求消息。在 PROBE 状态下,节点每隔 RetransTimer 毫秒重发邻居请求消息,直到获得可达性确认为止。即使没有向邻居发送额外的数据包,探测也会被重发。如果在发送 MAX_UNICAST_SOLICIT 个请求后等待 RetransTimer 毫秒后未收到响应,则重传将停止,条目应被删除。随后的流量将重新创建条目并再次执行地址解析。
请注意,所有邻居请求都按邻居进行了速率限制。节点不能频繁于 RetransTimer 毫秒内向同一邻居发送邻居请求。
当收到不经请求的邻居通告消息(即路由器请求、路由器通告、重定向和邻居请求)而导致新建立的邻居缓存条目进入 STALE 状态时,这些数据包包含发送者或在重定向情况下是重定向目标的链路层地址。然而,接收这些链路层地址并不确认正向路径到该节点的可达性。将新建立的已知链路层地址的邻居缓存条目放置在 STALE 状态提供了快速检测路径故障的保证。此外,如果由于接收到上述消息之一而修改了缓存的链路层地址,则状态也应设置为 STALE,以便快速验证到新链路层地址的路径是否正常。
为了正确检测路由器从路由器转换为主机的情况(例如,如果其 IP 转发能力由系统管理关闭),节点必须将所有接收到的邻居通告消息中的 Router 标志字段与邻居缓存条目中记录的 IsRouter 标志进行比较。当节点检测到邻居从路由器更改为主机时,节点必须从默认路由器列表中删除该路由器,并按第 6.3.5 节描述的方式更新目的地缓存。请注意,路由器可能未列在默认路由器列表中,即使目的地缓存条目正在使用它(例如,主机被重定向到它)。在这种情况下,所有引用(先前)路由器的目的地缓存条目必须在使用该条目之前再次执行下一跳确定。
在某些情况下,链路特定信息可能表明到邻居的路径已失败(例如,虚拟电路的重置)。在这种情况下,链路特定信息可能用于在邻居不可达性检测之前清除邻居缓存条目。但是,不能使用链路特定信息来确认邻居的可达性;这种信息不提供相邻 IP 层之间的端到端确认。
本节描述了与发送和处理重定向消息相关的功能。
路由器发送重定向消息以将主机重定向到特定目的地的更好的第一跳路由器,或者通知主机目的地实际上是邻居(即,处于同一链路中)。后者通过将 ICMP 目标地址设置为等于 ICMP 目的地址来实现。
为了确保重定向消息中的目标地址通过其链路本地地址标识邻居路由器,路由器必须能够确定其每个相邻路由器的链路本地地址。对于静态路由,此要求意味着应使用路由器的链路本地地址指定下一跳路由器的地址。对于动态路由,此要求意味着所有 IPv6 路由协议必须以某种方式交换相邻路由器的链路本地地址。
主机必须静默丢弃任何未满足以下所有有效性检查的接收到的重定向消息:
- IP 源地址为链路本地地址。路由器必须使用其链路本地地址作为路由器通告和重定向消息的源地址,以便主机可以唯一地识别路由器。
- IP 跳数限制字段的值为 255,即数据包不可能由路由器转发。
- ICMP 校验和有效。
- ICMP 代码为 0。
- ICMP 长度(从 IP 长度派生)为 40 个或更多八位组。
- 重定向的 IP 源地址与指定的 ICMP 目的地址的当前第一跳路由器相同。
- 重定向消息中的 ICMP 目标地址字段不包含多播地址。
- ICMP 目标地址是链路本地地址(当重定向到路由器时),或者与 ICMP 目的地址相同(当重定向到同一链路上的目的地时)。
- 所有包含的选项长度大于零。
必须忽略保留字段的内容以及任何未识别的选项。对协议的未来向后兼容的更改可能会指定保留字段的内容或添加新选项;向后不兼容的更改可能会使用不同的代码值。
必须忽略未指定用于重定向消息的定义选项的内容,并按照正常流程处理该数据包。唯一可能出现的已定义选项是目标链路层地址选项和重定向的报头选项。
主机不得仅因为重定向的目标地址不在链路的前缀范围内而将重定向视为无效。重定向消息的语义之一是目标地址是在链路上的。
通过有效性检查的重定向称为“有效重定向”。
路由器在以下情况下(受速率限制)应发送重定向消息:
- 路由器转发的数据包不是显式地寻址给自身(即不是通过路由器进行源路由的数据包),其中数据包的源地址字段标识了一个邻居,并且
- 路由器(在本规范范围之外的方式)确定要发送到被转发数据包的目的地址的更好的第一跳节点位于与发送节点相同的链路上,且
- 数据包的目的地址不是一个多播地址。
发送的重定向数据包包含,与第 4.5 节中给出的消息格式一致:
- 在目标地址字段中:指定将来发往该目的地的后续数据包的地址。如果目标是一个路由器,则必须使用该路由器的链路本地地址。如果目标是主机,则目标地址字段必须设置为与目的地址字段相同的值。
- 在目的地址字段中:调用 IP 数据包的目的地址。
- 在选项中:
o 目标链路层地址选项:目标的链路层地址(如果已知)。
o 重定向报头:转发的数据包中尽可能包含的内容,以使重定向数据包不超过支持 IPv6 所需的最小 MTU,详见 [IPv6]。
路由器必须限制发送重定向消息的速率,以限制当源不正确地响应重定向消息或源选择忽略未经身份验证的重定向消息时,重定向消息所产生的带宽和处理成本。有关限制 ICMP 错误消息速率的更多细节可在 [ICMPv6] 中找到。
路由器在收到重定向消息时不得更新其路由表。
接收到一个有效的重定向消息的主机应相应地更新其目的地缓存(Destination Cache),以便随后的流量发送到指定的目标。如果不存在目的地的目的地缓存条目,实现应该创建这样的条目。
如果重定向消息包含目标链路层地址选项,则主机将为目标创建或更新邻居缓存(Neighbor Cache)条目。在两种情况下,缓存的链路层地址将从目标链路层地址选项中复制过来。如果为目标创建了邻居缓存条目,则其可达性状态必须根据第 7.3.3 节的规定设置为 STALE。如果已经存在缓存条目并且使用不同的链路层地址进行了更新,则其可达性状态也必须设置为 STALE。如果链路层地址与缓存中已有的地址相同,则缓存条目的状态保持不变。
如果目标地址和目的地址相同,则主机必须将目标视为在链路上(on-link)。如果目标地址与目的地址不同,则主机必须为目标设置 IsRouter 为 TRUE。然而,如果目标地址和目的地址相同,则无法可靠确定目标地址是否是路由器。因此,新创建的邻居缓存条目应将 IsRouter 标志设置为 FALSE,而现有的缓存条目应保持标志不变。如果目标是一个路由器,随后的邻居通告或路由器通告消息将相应地更新 IsRouter。
重定向消息适用于发送到特定目的地的所有流量。也就是说,在收到某个目的地的重定向消息后,所有发送到该地址的目的地缓存条目都应更新为使用指定的下一跳,而不管在重定向报头选项中出现的流标签字段的内容是什么。
主机不得发送重定向消息。
选项提供了一种对可变长度字段进行编码的机制,这些字段可能在同一数据包中出现多次,或者是一些并非在所有数据包中都出现的信息。选项还可以用于在未来版本的 ND 中添加附加功能。
为了确保未来的扩展能够与当前的实现正确地共存,所有节点必须在接收到的 ND 数据包中默默地忽略任何它们不认识的选项,并继续处理该数据包。本文档中指定的所有选项必须被识别。一个节点不得仅因为 ND 消息包含了未识别的选项而忽略有效的选项。
当前的选项集合被定义为接收方可以独立地处理同一数据包中的多个选项。为了保持这些属性,未来的选项应遵循以下简单的规则:
选项不能依赖于其他选项的存在或缺失。选项的语义应该仅依赖于 ND 数据包的固定部分中的信息以及选项本身包含的信息。
遵循以上规则有以下好处:
1) 接收方可以独立地处理不同的选项。例如,一个实现可以选择在用户空间进程中处理包含在路由器通告消息中的前缀信息选项,同时在内核中的例程中处理同一消息中的链路层地址选项。
2) 如果选项的数量导致一个数据包超出了链路的 MTU,多个数据包可以携带选项的子集,而不会改变语义。
3) 发送方可以在不同的数据包中发送选项的子集。例如,如果前缀的有效期和首选期足够长,可能不需要在每个路由器通告中包含前缀信息选项。此外,不同的路由器可能发送不同的选项集合。因此,接收方不得将特定数据包中某个选项的缺失与任何动作关联。本协议规定接收方只应根据计时器的到期和接收到的数据包中包含的信息采取行动。
ND 数据包中的选项可以以任何顺序出现;接收方必须准备好独立地处理它们,不受其顺序的影响。消息中也可以有同一选项的多个实例(例如,前缀信息选项)。
如果在路由器通告中包含的选项数量导致通告的大小超出了链路的 MTU,路由器可以发送多个单独的通告,每个通告包含选项的子集。
要包含在重定向报头选项中的数据量必须受限,以使整个重定向数据包不超过支持 IPv6 所需的最小 MTU,如 [IPv6] 中所述。
所有选项的长度都是 8 个八位字节的倍数,确保适当的对齐,而无需任何 “填充” 选项。选项中的字段(以及 ND 数据包中的字段)都定义为按其自然边界对齐(例如,16 位字段在 16 位边界上对齐),除了 128 位的 IP 地址/前缀,它们在 64 位边界上对齐。链路层地址字段包含未解释的八位字符串;它在 8 位边界上对齐。
包括 IP 头的 ND 数据包的大小限制为链路 MTU。向 ND 数据包添加选项时,节点不得超出链路 MTU。
本协议的未来版本可能会定义新的选项类型。接收方必须默默地忽略任何未识别的选项,并继续处理该消息。