1、引言
随着IP网络规模和业务的迅速发展,IP网络的用户数急剧增加,正因为如此,IP网络也暴露出越来越多的问题,如地址空间不足、QoS、安全问题等。为了解决Internet的这些问题,尤其是解决地址空间不足的问题,IETF于1992年在IPv4的基础上定义了下一代的Internet协议,被称之为“Ipng”或“IPv6”。
IPv6解决的最大问题是扩大了地址空间,另外,它与IPv4相比在其它许多方面都具有优势,例如安全性、服务质量、移动性等。IPv6的一个显著特点就是它具有“即插即用”功能。即插即用使节点直接连接到网络后,不需要经过任何人工配置就能够使用,即插即用使网络的管理和控制变得更加简单;其次,节点只需要知道自己的链路层地址及本地网络的子网前缀,就能够通过IPv6的无状态或者全状态自动配置得到惟一的IPv6地址,从而成为网络的一部分;另外,IPv6还实现了更好的对节点移动性的支持。这些功能都是通过邻居发现协议来实现的,同一个子网内的所有主机和路由器之间的交互也都是通过邻居发现协议来实现的。
2、工作原理
邻居发现协议是IPv6协议的一个基本的组成部分,它实现了在IPv4中的地址解析协议(ARP)、控制报文协议(ICMP)中的路由器发现部分、重定向协议的所有功能,并具有邻居不可达检测机制。
邻居发现协议实现了路由器和前缀发现、地址解析、下一跳地址确定、重定向、邻居不可达检测、重复地址检测等功能,可选实现链路层地址变化、输入负载均衡、泛播地址和代理通告等功能。
邻居发现协议采用5种类型的IPv6控制信息报文(ICMPv6)来实现邻居发现协议的各种功能。这5种类型消息如下。
(1)路由器请求(Router Solicitation):当接口工作时,主机发送路由器请求消息,要求路由器立即产生路由器通告消息,而不必等待下一个预定时间。
(2)路由器通告(Router Advertisement):路由器周期性地通告它的存在以及配置的链路和网络参数,或者对路由器请求消息作出响应。路由器通告消息包含在连接(on-link)确定、地址配置的前缀和跳数限制值等。
(3)邻居请求(Neighbor Solicitation):节点发送邻居请求消息来请求邻居的链路层地址,以验证它先前所获得并保存在缓存中的邻居链路层地址的可达性,或者验证它自己的地址在本地链路上是否是惟一的。
(4)邻居通告(Neighbor Advertisement):邻居请求消息的响应。节点也可以发送非请求邻居通告来指示链路层地址的变化。
(5)重定向(Redirect):路由器通过重定向消息通知主机。对于特定的目的地址,如果不是最佳的路由,则通知主机到达目的地的最佳下一跳。
3、主机的数据结构
IPv6的一个设计要求是:即使在一个有限的网络内,主机也必须正确工作,而不像路由器不能储存路由表,不能有永久的配置,因此主机必须能自动配置,必须能学到交换数据的有关目的地的最小信息。这些信息储存的存储器叫做缓存,这些数据结构是一系列记录的排列,称作表项。每个表项储存的信息有一定的有效期,需要周期性地清除缓存中的表项,以保证缓存的空间大小。
主机需要为每一接口维护以下信息。
?邻居缓存:一组有关单个邻居的表项,这些邻居接收到了最新的数据流。表项是连接单播地址的关键,它包括的信息有:其链路层地址、指示邻居是路由器还是主机的标志、指向任何排队等待完成地址解析数据包的指针等。邻居缓存表项还包括由邻居不达检测算法所使用的信息,如可达状态、探测无应答的次数以及下一次邻居不达检测发生的时间。
?目的地缓存:一组有关最近收到数据流的目的地节点表项。目的地缓存包括“在连接(on-link)”和“非连接(off-link)”目的地,并在其中提供一定程度的间接寻址。目的地缓存能把目的地IP地址映射成下一跳邻居的IP地址,该缓存通过重定向消息进行信息更新。如果在目的地缓存表项中存储与邻居发现没有直接关系的附加信息,例如路径MTU(PMTU)以及由传输协议设定的往返时间,则执行时会更加方便。
?前缀列表:规定一组“在连接(on-link)”地址的前缀组成的列表。前缀列表表项产生于路由器通告接收到的信息。每一个表项都有一个相关的失效计时器值(由通告信息确定),它用于在前缀失效时废弃这些前缀。除非在后续通告中收到了一个新的(有限)值,否则特殊的“无限”计时器值规定前缀永久有效。本地链路(1ink-local)前缀位于带有无限失效计时器的前缀列表,而不管路由器是否正在向其通告前缀。接收的路由器通告不应该修改本地链路前缀的失效计时器。
?缺省路由器列表:接收数据包的路由器列表。路由器列表的表项指向邻居缓存中的相应的表项。缺省路由器的选择算法是:选择那些已知可达的路由器,而不选择可达性还不确定的路由器。每一个表项还有一个相关的失效计时器值(从路由器通告信息中得到),它的作用是删除不再通告的表项。
上述数据结构可以用不同的方法实现。其中一种实现方法是对所有数据结构使用单个最长匹配路由表。不管采用哪种特定的实现方法,为了防止重复性的邻居不可达检测,路由器的邻居缓存表项可以由使用该路由器的所有目的地缓存表项共享。
邻居缓存包含有邻居不可达检测算法维护的信息。邻居可达性状态是最关键的信息,它的取值是下列的5个值之一。
?不完整性(INCOMPLETE):正在进行地址解析,邻居的链路层地址还没确定。
?可达性(REACHABLE):邻居在最近处于可达状态(在小于10s以前)。
?失效性(STALE):在数据流发送给该邻居以前邻居是不可达的,并无法验证其可达性。
?延迟(DELAY):邻居不再是可达的,同时数据流在最近已经发送给邻居,但不立即对该邻居进行探测,而在一个短时延后发送探测信息,这样就可以为上层协议提供可达性确认。
?探测(PROBE):邻居不再是可达的,同时发送单播邻居请求探测以验证可达性。
4、数据包的发送算法
节点向目的地发送数据包时,使用目的地缓存、前缀列表、默认路由器列表确定合适的下一跳的IP地址,然后路由器查询邻居缓存确定邻居的链路层地址。
IPv6单播地址的下一跳确定操作如下:发送者使用前缀列表中的前缀进行最长前缀匹配,确定包的目的地是在连接的还是非连接的。如果下一跳是在连接的,下一跳地址就和目的地地址相同,否则发送者从默认路由器列表中选择下一跳。如果默认路由器列表为空,则发送者认为目的地是在连接的。
下一跳确定的信息存储在目的地缓存中,下一个包可以使用这些信息。当路由器发送包时,首先检查目的地缓存,如果目的地缓存没有相关信息存在,就激活下一跳确定过程。
在学习到下一跳路由器的IPv6地址后,发送者检查邻居缓存以决定链路层地址。如果没有下一跳IPv6地址的表项存在,路由器的工作如下:
?创建一个新表项,并设置其状态为不完全。
?开始进行地址解析。
?对传送的包进行排队。
当地址解析结束时,获得链路层地址,存储在邻居缓存中。此时表项到达新的可达状态,排队的包能够传送。
对于组播包,下一跳总是认为在连接,确定组播IPv6地址的链路层地址取决于链路类型。当邻居缓存开始传送单播包时,发送者根据邻居不可达检测算法检测相关的可达性信息,验证邻居的可达性。当邻居不可达时,再次执行下一跳确定,验证到达目的地的另一条路径是否是可达的。
如果知道了下一跳节点的IP地址,发送方就检查邻居缓存中有关邻居的链路层信息。如果没有表项存在,发送方就创建一条,并设置其状态为“不完整性”,同时启动地址解析,然后对没有完成地址解析的数据包进行排队。对具有组播功能的接口来说,地址解析的过程是发送一个邻居请求信息,以及等待一个邻居通告。当收到一个邻居通告应答时,链路层地址被表项在邻居缓存中,同时发送排队的数据包。
在传输单播数据包期间每次读取邻居发现缓存的表项,发送方根据邻居不可达性检测的算法检查邻居不可达性检测的相关信息,但不可达性检测会使发送方发出单播邻居请求,以验证该邻居还是可达的。
数据流第一次送往目的地时就执行下一跳确定的操作,随后该目的地如果仍能正常通信,目的地缓存的表项就可以继续使用。如果邻居不可达算法决定在某一点终止通信,则需要重新执行下一跳确定,例如故障路由器的流量应该切换到正常工作的路由器,流向移动节点的数据流可能要重新路由到“移动代理”。
当节点重做下一跳确定时,不需要丢弃整个目的地缓存的表项,其中PMTU和往返计时器值的信息是很有用的。
5、邻居发现协议的功能
(1)路由器和前缀发现
路由器必须无条件丢弃不满足有效性检查的路由器请求和路由器通告消息。
路由器发现功能用来标识与给定链路相连的路由器,并获取与地址自动配置相关的前缀和配置参数。
作为对请求消息的响应,路由器应周期地发送组播路由器通告消息,来通告链路上节点的可达性。每个主机从链路上相连的路由器上接收路由器通告消息,并建立默认路由器列表(当到达目的地的路径不可知时所使用的路由器)。如果路由器很频繁地产生路由器通告消息,那么主机就能在几分钟内学习到路由器的存在,否则就要使用邻居不可达检测。
路由器通告消息应包含用来确定在连接可达性的前缀列表。主机通过使用从路由器通告消息中提取的前缀,来确定目的地是否在连接,能否直接可达,或者是否非连接,还是仅通过一个路由器就可达。目的地是在连接的,但这个目