IPV6除了显著增加了地址空间外,另一个最显著的特征就是它的即插即用性。
邻居发现协议(Neighbor Discovery Protocol,NDP)就是使用以下的功能实现即插即用特性的协议:
NDP定义了5种ICMPv6报文类型:
类型133 路由器请求(RS):由主机发起,用来请求一个路由器发送一个RA
类型134 路由器通告(RA):由路由器发起,通告路由器的存在和链路的细节参数(链路前缀,MTU,跳数限制等),周期性发送,也用于答RS。
类型135 邻居请求(NS):由节点主机发起,用来请求另一台主机的链路层地址,或实现地址冲突检测、邻居不可达检测。
类型136 邻居通告(NA):有节点发起用来响应NS,如果一个节点改变了他的链路层地址,那么它能够主动发送一个NA来通告这个新地址。
类型137 重定向(Redirect)
NDP消息通常在链路本地的范围内收发。
为了进一步增强安全性,承载所有NDP消息的IPV6数据包的跳数限制为255,如果收到的数据包跳数小于255的,说明该数据包最少已经经过一台路由器,因此该数据包应该被丢弃。这样可以防止NDP受到来自不与本地链路相连的源节点的攻击或欺骗。
路由器发现功能用来发现与本地链路相连的设备,并获取与地址自动配置相关的前缀和其他配置参数。
在IPv6中,IPv6地址可以支持无状态的自动配置,即主机通过某种机制获取网络前缀信息,然后主机自己生成地址的接口标识部分。路由器发现功能是IPv6地址自动配置功能的基础,主要通过以下两种报文实现:
RA报文:每台设备为了让二层网络上的主机和设备知道自己的存在,定时都会组播发送RA报文,最小缺省周期为200S,RA报文中会带有网络前缀信息,及其他一些标志位信息。未经请求的RA源地址是路由器接口的链路地址,目的地址是所有节点的多播地址(FE02::1)。
RS报文:很多情况下主机接入网络后希望尽快获取网络前缀进行通信,此时主机可以立刻发送RS报文,网络上的设备将回应RA报文。RS的源地址可以是未指定的地址(::),也可以是该主机的链路本地地址,目的地址则始终是所有路由器的多播地址(FE02::2)。
当一台主机收到一条RA时,它就会将这台路由器添加到他的缺省路由器列表中,如果存在多台路由器条目时,要么在列表中依次轮询,要么选择保持单台路由器作为缺省路由。
当一台IPV6的主机第一次连接到链路上时,他能够自我配置自己接口的链路地址:在自己接口的48位的MAC地址中间插入一个保留的16位数值0xFFFE,并把它的U/L位(第七位)翻转,这样就得到了一个64位接口ID。在接口ID前面加上链路本地前缀FE80::/10,就得到了链路本地地址
如果主机只需要和所在链路上的设备通信时,自动配置的地址已经足够,但是要和链路以外的主机通讯时,就需要更大的范围地址,通常使用以下两种方法获取地址:
当节点获取到一个新的地址时会将该地址归类位临时状态,在地址冲突检测没有完成并确认之前该地址不能被使用。
Host A的IPv6地址FC00::1为新配置地址,即FC00::1为Host A的试验地址。Host A向FC00::1的Solicited-Node组播组发送一个以FC00::1为请求的目标地址的NS报文进行重复地址检测,由于FC00::1并未正式指定,所以NS报文的源地址为未指定地址。当Host B收到该NS报文后,有两种处理方法
1.如果Host B发现FC00::1是自身的一个试验地址,则Host B放弃使用这个地址作为接口地址,并且不会发送NA报文。
2.如果Host B发现FC00::1是一个已经正常使用的地址,Host B会向FF02::1发送一个NA报文,该消息中会包含FC00::1。这样,Host A收到这个消息后就会发现自身的试验地址是重复的。Host A上该试验地址不生效,被标识为duplicated状态。
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字段中。这样就完成了一个地址解析的过程。
通过邻居或到达邻居的通信,会因各种原因而中断,包括硬件故障、接口卡的热插入等。如果目的地失效,则恢复是不可能的,通信失败;如果路径失效,则恢复是可能的。因此节点需要维护一张邻居表,每个邻居都有相应的状态,状态之间可以迁移。
RFC2461中定义了5种邻居状态,分别是:未完成(Incomplete)、可达(Reachable)、陈旧(Stale)、延迟(Delay)、探查(Probe)。
下面以A、B两个邻居节点之间相互通信过程中A节点的邻居状态变化为例(假设A、B之前从未通信),说明邻居状态迁移的过程。
A先发送NS报文,并生成缓存条目,此时,邻居状态为Incomplete。
若B回复NA报文,则邻居状态由Incomplete变为Reachable,否则固定时间后邻居状态由Incomplete变为Empty,即删除表项。
经过邻居可达时间,邻居状态由Reachable变为Stale,即不确定邻居节点的可达性。
如果在Reachable状态,A收到B的非请求NA报文,且报文中携带的B的链路层地址和表项中不同,则邻居状态马上变为Stale。
在STALE状态到达老化时间后进入Delay状态。
在经过一段固定时间(5秒)后,邻居状态由Delay变为Probe,其间若有NA应答,则邻居状态由Delay变为Reachable。
在Probe状态,A每隔一定时间间隔(1秒)发送单播NS,发送固定次数(3次)后,有应答则邻居状态变为Reachable,否则邻居状态变为Empty,即删除表项。
邻居不可达性的检测需要双向检测,所以当一个未经请求的RA或NA不能改变邻居缓存条目的状态到Reachable。