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)路由器请求(RouterSolicitation):当接口工作时,主机发送路由器请求消息,要求路由器立即产生路由器通告消息,而不必等待下一个预定时间。
(2)路由器通告(RouterAdvertisement):路由器周期性地通告它的存在以及配置的链路和网络参数,或者对路由器请求消息作出响应。路由器通告消息包含在连接(on-link)确定、地址配置的前缀和跳数限制值等。
(3)邻居请求(NeighborSolicitation):节点发送邻居请求消息来请求邻居的链路层地址,以验证它先前所获得并保存在缓存中的邻居链路层地址的可达性,或者验证它自己的地址在本地链路上是否是惟一的。
(4)邻居通告(NeighborAdvertisement):邻居请求消息的响应。节点也可以发送非请求邻居通告来指示链路层地址的变化。
(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)路由器和前缀发现
路由器必须无条件丢弃不满足有效性检查的路由器请求和路由器通告消息。
路由器发现功能用来标识与给定链路相连的路由器,并获取与地址自动配置相关的前缀和配置参数。
作为对请求消息的响应,路由器应周期地发送组播路由器通告消息,来通告链路上节点的可达性。每个主机从链路上相连的路由器上接收路由器通告消息,并建立默认路由器列表(当到达目的地的路径不可知时所使用的路由器)。如果路由器很频繁地产生路由器通告消息,那么主机就能在几分钟内学习到路由器的存在,否则就要使用邻居不可达检测。
路由器通告消息应包含用来确定在连接可达性的前缀列表。主机通过使用从路由器通告消息中提取的前缀,来确定目的地是否在连接,能否直接可达,或者是否非连接,还是仅通过一个路由器就可达。目的地是在连接的,但这个目的地没有被路由器通告消息学到的前缀覆盖,在这种情况下,主机认为目的地是非连接的,路由器发送重定向消息给发送者。
路由器通告消息应包含一些标志位,这些标志位通知主机怎样执行地址的自动配置,例如路由器能指定主机是使用有状态地址配置还是无状态地址配置。
另外,路由器通告消息中还应包含简化网络集中管理的参数,例如主机产生的数据包中使用的跳数限制参数的缺省值,或链路MTU值。
当主机向路由器发出路由器请求消息时,路由器应立刻发送路由器通告消息,通过这种方式能加速节点的配置过程。
(2)地址解析
IPv6节点通过邻居请求和邻居通告消息将IPv6地址解析成链路层地址,对组播地址不执行地址解析。
节点通过组播邻居请求消息来激活地址解析过程,邻居请求消息用来请求目标路由器返回它的链路层地址。源路由器在邻居请求消息中包含了它的链路层地址,并将邻居请求消息组播到与目标地址相关的请求节点组播地址,目标路由器在单播的邻居通告消息中返回它的链路层地址。这一对消息使源和目标路由器能解析出相互的链路层地址。
(3)重定向功能
当包必须发送到一个非连接的目的地时,需要选择转发包的路由器。当选择的路由器作为消息传送的下一跳并不是最好的下一跳时,路由器需产生重定向消息,通知源节点到达目的地存在一个更佳的下一跳路由器。
路由器必须能够确定每个邻居路由器的本地链路(1ink-local)地址,以保证重定向消息里的目标地址根据本地链路地址来识别邻居路由器。
在源端没有正确应答重定向消息,或者源端选择忽略没有被验证的重定向消息的情况下,为了节省频带和处理的费用,路由器必须限定发送重定向消息的速率。
在收到重定向消息时,路由器不能更新路由表。
(4)邻居不可达检测
任何时候通过邻居或到达邻居的通信,会因各种原因而中断,包括硬件故障、接口卡的热插入等。如果目的地失效,则恢复是不可能的,通信失败;如果路径失效,则恢复是可能的。因此节点应该主动跟踪数据包发向邻居的可达性状态。
主机与邻居节点之间所有路径都应进行邻居不可达性检测,包括主机到主机、主机到路由器以及路由器到主机之间的通信,也可用于路由器之间,以检测邻居或邻居前向路径发生的故障。
如果路由器最近收到确认,邻居的IP层已经收到最近发送到它的数据包,那么该邻居是可达的。邻居不可达检测使用两种方法进行确认:一种是从上层协议来的提示,提供“连接正在处理”的确认;另一种是路由器发送单播邻居请求消息,收到了应答的邻居通告消息。为了减少不必要的网络流量,探测消息仅发送到邻居。
邻居不可达性检测与向邻居发送数据包同时进行。在邻居可达性确认期间,路由器继续向缓存链路层地址的邻居发送数据包;如果没有数据包发向邻居,则不发送检测。
6、邻居发现协议与ARP的比较
邻居发现协议比IPv4协议的相应部分在许多方面有了更大的改善。
在IPv4中,由IP层到链路层地址的解析(ARP)是基于链路层的广播机制来实现的,数据包由LLC网桥进行转发,在一个比较大的站点范围内会占用大量的带宽,有时还会引起“广播风暴”。而在IPv6中,这一过程是基于IP层的组播机制实现的,这样,在地址解析的过程中受到地址解析发送包影响的节点数大大减少,而且非IPv6节点根本不受影响。
另外,IPv6的邻居发现协议中路由器通告消息会带着自己的链路层地址,还会带着本地链路的前缀,从而避免了每个节点配置自己的子网掩码。
IPv4的ARP是不安全的,无法保证回应ARP探测消息的节点是需要的节点,这样会导致发往一个节点的数据包被另一个节点窃听到。而邻居发现协议运行在IPv6之上,它属于网络层协议,它的安全性可由IPv6的安全性来保证。
IPv4的ARP运行在数据链路层,不同的网络介质需要有不同的ARP协议,例如EthernetARP与FDDIARP就不完全相同。而邻居发现协议运行在网络层,与介质无关,任何网络媒介都可以运行相同的邻居发现协议。
与IPv4协议不同,通过邻居发现协议得到的各种地址信息都有一定的生存期,这些生存期由这些信息的发送者规定。路由器能够通知主机如何执行地址配置,例如路由器能指示主机是使用状态地址配置还是使用无状态地址配置。路由器能够通告链路的最大传输单元信息(MTU),以使同一链路上的所有节点使用相同的MTU值。对于无状态地址自动配置来说,邻居发现协议能够提供主机进行无状态地址自动配置所需要的全部信息。
在IPv4到IPv6的早期过渡阶段,所有实现IPv6的节点都应该被配制成一种双栈结构。双栈结构使节点能够与IPv4保持兼容,因此现存的IPv4协议层应该被一种既支持IPv4又支持IPv6的协议层所取代,而且TCP和UDP层应该被升级支持IPv6。支持两个版本的IP协议的最大困难在于同时处理两种不同结构的地址,邻居发现中的邻居自动发现功能可以很容易地处理这种功能。
7、结束语
自从IETF在1998年12月制定了邻居发现协议的标准文本RFC2461后,邻居发现就成为IPv6节点使用的重要协议,它解决了连接在同一条链路上的所有节点之间的互操作问题。
虽然目前IPv6的标准已经比较稳定,国内外厂商研制的相关产品和设备也已经成熟,但由于IPv6技术在我国的市场需求还不是很明朗,因此IPv6技术在我国还处于试验网的实践和运行阶段。随着IPv6网络应用商业化进程的加快,邻居发现协议的使用将会越来越广泛。