IPv6 邻居发现协议详解
在局域网中,当主机或其他网络设备有数据要发送给另一个主机或设备时,它必须知道对方的网络层地址(即 IPv6 地址)。但是仅有 IPv6 地址是不够的,因为 IPv6 数据报文必须封装成帧才能通过物理网络发送,因此发送方还必须有接收方的链路层地址(MAC 地址),所以需要一个从 IPv6 地址到链路层地址的映射,保证数据报文的传送能够顺利进行。ND(Neighbor Discovery,邻居发现)用来实现网络层 IPv6 地址与链路层 MAC 地址之间的映射,是以太网通信的基础。
NDP(Neighbor Discovery Protocol,邻居发现协议)是 IPv6 协议体系中一个重要的基础协议。NDP 替代了 IPv4 的 ARP 和 ICMP 路由器发现功能,它定义了使用 ICMPv6 报文实现地址解析、邻居不可达检测、重复地址检测、路由器发现、重定向等功能。
1、地址解析
在 IPv4 中,当主机需要和目标主机通信时,必须先通过 ARP 获得目的主机的链路层地址。在 IPv6 中,同样需要从 IP 地址解析出链路层地址的功能。NDP 实现了这个功能。
ARP 报文是直接封装在以太网报文中的,以太网协议类型为 0x0806,普遍观点认为 ARP 的定位为 2.5 层协议。NDP 本身基于 ICMPv6 实现,以太网协议类型为 0x86DD(IPv6 报文),IPv6 的 Next Header 字段值为 58,表示 ICMPv6 报文,由于 NDP 使用的所有报文均封装在 ICMPv6 报文中,一般来说, NDP 被看作三层协议。在三层完成地址解析,主要有以下几个好处。
地址解析在三层完成,不同的二层介质可以采用相同的地址解析协议。
可以使用三层的安全机制避免地址解析攻击。
使用组播方式发送请求报文,减少了对二层网络性能的压力。
地址解析过程中使用了两种 ICMPv6 报文:NS(Neighbor Solicitation,邻居请求)报文和 NA(Neighbor Advertisement,邻居通告)报文。
NS 报文:Type 字段值为 135,Code 字段值为 0,在地址解析中的作用类似于 IPv4 中的 ARP 请求报文。
NA 报文:Type 字段值为 136,Code 字段值为 0,在地址解析中的作用类似于 IPv4 中的 ARP 应答报文。
IPv6 地址解析的过程如图:
Host A 在向 Host B 发送报文之前必须要解析出 Host B 的链路层地址,所以首先 Host A 会发送一个 NS 报文,其中源地址为 Host A 的 IPv6 地址,目的地址为 Host B 的被请求节点组播地址,需要解析的目标 IP 为 Host B 的 IPv6 地址,这就表示 Host A 想要知道 Host B 的链路层地址。同时需要指出的是,在 NS 报文的 Options 字段中还携带了 Host A 的链路层地址。
当 Host B 接收到了 NS 报文之后,就会回应 NA 报文,其中源地址为 Host B 的 IPv6 地址,目的地址为 Host A 的 IPv6 地址(使用 NS 报文中的 Host A 的链路层地址进行单播),Host B 的链路层地址被放在 Options 字段中。这样就完成了一个地址解析的过程。
2、邻居不可达检测
与邻居之间的通信会因各种原因而中断,包括硬件故障、接口卡的热插拔等。如果目的地失效,则不可能恢复,通信失败;如果路径失效,则可能恢复。因此节点需要维护一张邻居表,每个邻居都有相应的状态,状态之间可以迁移。
邻居状态有 5 种,分别是 Incomplete(未完成)、Reachable(可达)、Stale (过时)、Delay(延迟)、Probe(探查)。
邻居状态之间具体的迁移过程如图,其中 Empty 表示邻居表项为空。
下面以 A、B 两个邻居节点之间相互通信过程中 A 节点的邻居状态变化为例(假设 A、B 之前从未通信),说明邻居状态迁移的过程。
A 先发送 NS 报文,并生成缓存条目,此时,邻居状态为 Incomplete。
若 B 回复 NA 报文,则邻居状态由 Incomplete 变为 Reachable,否则在固定的一段时间后,邻居状态由 Incomplete 变为 Empty,即删除表项。
经过邻居可达时间,邻居状态由 Reachable 变为 Stale,即未知是否可达。
如果在 Reachable 状态下,A 收到 B 的非请求 NA 报文,且报文中携带的 B 的链路层地址和表项中不同,则邻居状态马上变为 Stale。
在 Stale 状态下,若 A 要向 B 发送数据,则邻居状态由 Stale 变为 Delay,并发送 NS 请求。
在经过一段固定的时间后,邻居状态由 Delay 变为 Probe,其间若有 NA 应答,则邻居状态由 Delay 变为 Reachable。
在 Probe 状态,A 每隔一段时间发送单播 NS,发送固定次数后,有应答则邻居状态变为 Reachable,否则邻居状态变为 Empty,即删除表项。
3、重复地址检测
DAD(Duplicate Address Detect,重复地址检测)是在接口使用某个 IPv6 单播地址之前进行的,主要是为了探测是否有其他的节点使用了该地址。在地址自动配置的时候进行 DAD 检测很有必要。一个 IPv6 单播地址在分配给一个接口之后、通过重复地址检测之前被称为 Tentative Address (试验地址)。此时该接口不能使用这个试验地址进行单播通信,但是仍然会加入两个组播组:All-Node 组播组和试验地址所对应的 Solicited-Node 组播组。
IPv6 重复地址检测技术和 IPv4 中的免费 ARP(Gratuitous ARP)类似:节点向试验地址所对应的 Solicited-Node 组播组发送 NS 报文。NS 报文中目标地址即为该试验地址。如果收到某个其他站点回应的 NA 报文,就证明该地址已被使用,节点将不能使用该试验地址通信。
重复地址检测的原理如图
Host A 的 IPv6 地址 FC00::1 为新配置地址,即 FC00::1 为 Host A 的试验地址。Host A 向 FC00::1 的 Solicited-Node 组播组发送一个以 FC00::1 为请求的目标地址的 NS 报文,进行重复地址检测,由于 FC00::1 并未正式指定,所以 NS 报文的源地址为未指定地址。当 Host B 收到该 NS 报文后,有两种处理方法。
如果 Host B 发现 FC00::1 是自身的一个试验地址,则 Host B 放弃使用这个地址作为接口地址,并且不会发送 NA 报文。
如果 Host B 发现 FC00::1 是一个已经正常使用的地址,Host B 会向 FF02::1 发送一个 NA 报文,该消息中会包含 FC00::1。这样,Host A 收到这个消息后就会发现自身的试验地址是重复的。在 Host A 上,该试验地址不生效,被标识为 Duplicated 状态。
4、路由发现
路由器发现功能用来发现与本地链路相连的设备,并获取与地址自动配置相关的前缀和其他配置参数。在 IPv6 中,IPv6 地址可以支持无状态的自动配置,即主机通过某种机制获取网络前缀信息,然后主机自己生成地址的接口标识部分。路由器发现功能是 IPv6 地址自动配置功能的基础,主要通过以下两种报文实现该功能。
RA(Router Advertisement,路由器通告)报文:每台设备为了让二层网络上的主机和设备知道自己的存在,都会定时以组播形式发送 RA 报文,RA 报文中会带有网络前缀信息和其他一些标志位信息。RA 报文的 Type 字段值为 134。
RS(Router Solicitation,路由器请求)报文:很多情况下主机接入网络后希望尽快获取网络前缀进行通信,此时主机可以立刻发送 RS 报文,网络上的设备将回应 RA 报文。RS 报文的 Type 字段值为 133。
IPv6 主机无状态自动配置的过程为:根据接口标识获得链路本地地址;发出邻居请求,进行重复地址检测;如地址冲突,则停止自动配置,需要手工配置;如不冲突,链路本地地址生效,节点具备本地链路通信能力;主机会发送 RS 报文,请求设备回复 RA 报文(或接收到设备定期发送的 RA 报文);根据 RA 报文中的前缀信息和接口标识获得 IPv6 地址。
当主机所在的链路中存在多个设备时,主机需要根据报文的目的地址选择转发设备。在这种情况下,设备通过向主机发布默认路由优先级和特定路由信息,提高主机根据不同的目的地选择合适的转发设备的能力。
在 RA 报文中,定义了默认路由优先级和路由信息这两个字段,帮助主机在发送报文时选择合适的转发设备。主机收到包含路由信息的 RA 报文后,会更新自己的路由表。当主机向其他设备发送报文时,通过查询路由表,向合适的路由器发送报文。
主机收到包含默认路由优先级信息的 RA 报文后,会更新自己的默认路由列表。当主机向其他设备发送报文时,如果没有路由可选,则首先查询该列表,然后向本链路内优先级最高的设备发送报文;如果该设备发生故障,主机根据优先级从高到低的顺序,依次选择其他设备。
5、重定向
当网关设备发现报文从其他网关设备转发更好时,它就会发送重定向报文告知报文的发送者,让报文发送者选择另一个网关设备。重定向报文对应的 ICMPv6 的 Type 字段值为 137,报文中会携带更好的路由下一跳地址和需要被重定向的报文的目的地址等信息。
Host1 需要和 Host2 通信,Host1 的默认网关设备是 R1,当 Host1 向 Host2 发送报文时报文会被送到 R1。R1 接收到 Host1 发送的报文以后,会发现实际上 Host1 直接发送给 R2 更好,它将发送一个重定向报文给 Host1,其中报文中更好的路由下一跳地址为 R2,目的地址为 Host2。Host1 接收到了重定向报文之后,会在默认路由表中添加一个主机路由,以后发往 Host2 的报文就直接发送给 R2。
当设备收到一个报文后,只有在满足以下全部条件时,设备才会向报文发送者发送重定向报文。• 报文的目的地址不是一个组播地址。
报文并非通过路由转发给设备。
经过路由计算后,路由的下一跳出接口是接收报文的接口。
设备发现报文的最佳下一跳 IP 地址和报文的源 IP 地址处于同一网段。
设备检查报文的源地址,发现自身的邻居表项中有用该地址作为全球单播地址或链路本地地址的邻居存在。
如果通信目标是一台主机,则主机的 IPv6 地址就是重定向报文的目的地址。如果该重定向报文含有选项字段,则选项字段中含有目标主机的链路层地址。
版权声明: 本文为 InfoQ 作者【穿过生命散发芬芳】的原创文章。
原文链接:【http://xie.infoq.cn/article/5dffa00aa0900ade7ccc26a23】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论