NDP协议
基本内容
IPv6邻居发现(Neighbor Discovery,ND)协议使用五种类型的ICMPv6消息,实现下面一些功能:地址解析、验证邻居是否可达、重复地址检测、路由器发现/前缀发现、地址自动配置和重定向等功能。 ND协议通常与ARP协议共同写成ARP/ND,因此可以从此知道,它实际上可以理解为IPV6中的ARP协议,实现了ARP的功能,此外进行扩展。
邻居请求消息NS(Neighbor Solicitation) | ||
邻居通告消息NA(Neighbor Advertisement) | ||
路由器通告消息RA(Router Advertisement) | ||
重定向消息(Redirect) |
NS/NA报文功能
如上表中所示,NS/NA报文的功能实际上和IPv4中的ARP协议报文很类似,包括地址冲突检测、ip/mac表项生成等,并额外扩展了一个邻居可达性探测的功能。
地址解析
获取同一链路上邻居节点的链路层地址(与IPv4的ARP功能相同),通过邻居请求消息NS和邻居通告消息NA实现。以下图为例,A获取B的链路层地址过程如下:
(1) 节点A以组播方式发送NS消息。NS消息的源地址是节点A的接口IPv6地址,目的地址是节点B的被请求节点组播地址,消息内容中包含了节点A的链路层地址和请求的目标地址。
(2) 节点B收到NS消息后,判断报文的目标地址是否为自己的IPv6地址。如果是,则节点B可以学习到节点A的链路层地址,并以单播方式返回NA消息,其中包含了自己的链路层地址。
(3) 节点A从收到的NA消息中就可获取到节点B的链路层地址。
验证邻居是否可达
在获取到邻居节点的链路层地址后,通过邻居请求消息NS和邻居通告消息NA可以验证邻居节点是否可达。
(1) 节点发送NS消息,其中目的地址是邻居节点的IPv6地址。
(2) 如果收到邻居节点的确认报文,则认为邻居可达;否则,认为邻居不可达。
重复地址检测
当节点获取到一个IPv6地址后,需要使用重复地址检测功能确定该地址是否已被其他节点使用(与IPv4的免费ARP功能相似)。如图所示,通过NS和NA实现重复地址检测的过程为:
(1) 节点A发送NS消息,NS消息的源地址是未指定地址::
,目的地址是待检测的IPv6地址对应的被请求节点组播地址,消息内容中包含了待检测的IPv6地址。
(2) 如果节点B已经使用这个IPv6地址,则会返回NA消息。其中包含了自己的IPv6地址。
(3) 节点A收到节点B发来的NA消息,就知道该IPv6地址已被使用。反之,则说明该地址未被使用,节点A就可使用此IPv6地址。
实验抓包分析
下面以一个实验来对NS/NA报文交互过程及其功能进行分析验证
- 实验拓扑
- 报文交互过程(NA/NS)
- PC生成了本地链路地址,发送NS报文进行重复地址检测,目的地址为生成的本地链路地址对应的被请求节点组播地址
- 同时,PC会在链路本地范围上发送NA报文,告诉链路范围上的设备自己的链路层地址,类似于免费arp
- PC通过RA报文(后续会提到)获取到了地址前缀(2001:: /64),根据EUI-64生成了全球单播唯一地址(2001::353f:47d6:cabd:3f25),仍然首先进行地址冲突检测(第一、二步),接着当PC ping SW,则PC会请求SW的链路层地址
PC发送NS报文请求SW地址(2001::1)的链路层地址,其中报文源IP为PC生成的IPv6全球单播地址,目的IP为2001::1对应的组播地址ff02::1:ff00:1
,并且报文中携带Target Address(2001::1),避免不同ipv6地址对应同一个组播地址的问题。
- SW收到NS报文后,会首先检查
Target Address
字段是否是自己的IPv6地址,如果是,则接收并单播回应NA报文。如果该字段的地址不是自己的IPv6地址,则丢弃。
- 对于H3C设备,可以使用
display ipv6 neighbors all
查看ipv6邻居状态,在邻居状态变化时(如由Reachable–>Stale–>Probe)会发送NS/NA报文,对邻居可达性进行探测
< admonition note “NA/NS报文字段含义” false >}}
NA报文:
字段 | 长度 | 含义 |
---|---|---|
Type | 1字节 | 消息类型,此处值为136。 |
Code | 1字节 | 该ICMPv6差错报文的始发者必须将该字段置为0,且接收端忽略该字段。 |
Checksum | 2字节 | 用来在ICMPv6报文中检验数据和部分IPv6首部的完整性。 |
R | 1比特 | 路由器标记。当置1时,R位指出发送者是路由器。R位由Neighbor Unreachability Detection使用,用于检测改变为主机的路由器。 |
S | 1比特 | 请求标记。当置1时,S位指出通告被发送以响应来自目的地地址的Neighbor Solicitation。S位用作Neighbor Unreachability Detection的可达性确认。在多播通告和非请求单播通告中置0。 |
O | 1比特 | 替代标记。替代标志,1表示通告中的信息替代缓存,如更新链路层地址时,对于任播的回应则不应置位。在针对任播地址的请求通告中,以及在请求的前缀通告中它不能被置1。在其他请求通告中和在非请求通告中它应当被置1。 |
Reserved | 29比特 | 29位未使用字段。它必须由发送者初始化为0,接收者必须忽略它。 |
Target Address | 16字节 | 对于请求的通告,是在Neighbor Solicitation消息(该消息催促这个通告)中的Target Address字段。对于非请求通告,是其链路层地址已经改变的地址。Target Address必须不是多播地址。 |
Options | 可变 | 选项: Target link-layer address: 目标的链路层地址,即,通告发送者。当响应多播请求时,在有地址的链路层上必须包括此选项。当响应单播Neighbor Solicitation时应当包括此选项。 当对端节点由于没有缓存条目从而不能返回一个Neighbor Advertisements消息时,为了避免无休止的Neighbor Solicitation“递归”,对于多播请求必须包括 此选项。当响应单播请求时,可忽略此选项,因为请求的发送者有正确的链路层地址;其他情况,此选项不能在第一位置发送单播请求。然而,在此情况,包括链路层地址仅增加了少许开销,却消除了潜在的竞争条件,那里在收到对先前的请求的响应之前,发送者删除缓存的链路层地址。 为TLV格式: Type: =2,字段长度为1字节。 Length: 1字节,表示选项的长度(包括类型字段和长度字段),以8字节为单位计算。例如,IEEE802 地址的长度是1。 Link-Layer Address: 可变长度的链路层地址。此字段的内容和形式(包括字节和比特顺序)一般由描述IPv6在不同链路层上如何运行的特定文件中规定。 |
NS报文:
字段 | 长度 | 含义 |
---|---|---|
Type | 1字节 | 消息类型,此处值为135。 |
Code | 1字节 | 该ICMPv6差错报文的始发者必须将该字段置为0,且接收端忽略该字段。 |
Checksum | 2字节 | 用来在ICMPv6报文中检验数据和部分IPv6首部的完整性。 |
Reserved | 4字节 | 此字段不使用。它必须由发送者初始化为0,接收者必须忽略它。 |
Target Address | 16字节 | 请求的目标的IP地址。它必须不是多播地址。 |
Options | 可变 | 选项: Source link-layer address源链路层地址:发送者的链路层地址,如果知道。如果Source Address是未指定地址,必须不包括在内。否则,有地址的链路层上应当包括源链路层地址。 为TLV格式: Type: 1字节,取值为1。 Length: 1字节,表示选项的长度(包括类型字段和长度字段),以8字节为单位计算。例如,IEEE802 地址的长度是1。 Link-Layer Address: 可变长度的链路层地址。此字段的内容和形式(包括字节和比特顺序)一般由描述IPv6在不同链路层上如何运行的特定文件中规定。 |
< /admonition >}}
邻居状态变化
在前面的抓包分析中,提到了ipv6邻居状态,共有五种状态,下图是邻居状态机迁移过程
A先发送NS报文,并生成缓存条目,此时,邻居状态为Incomplete。
若B回复NA报文,则邻居状态由Incomplete变为Reachable,否则固定时间后邻居状态由Incomplete变为Empty,即删除表项。
经过邻居可达时间,邻居状态由Reachable(H3C中邻居可达状态时间默认为1200000ms,即20min)变为Stale,即未知是否可达。
邻居可达状态时间修改H3C设备中,可用ipv6 nd nud reachable-time time,取值范围为1~3600000,单位为毫秒。如果在Reachable状态,A收到B的非请求NA报文(MAC地址修改),且报文中携带的B的链路层地址和表项中不同,则邻居状态马上变为Stale。
在Stale状态若A要向B发送数据,则邻居状态由Stale变为Delay,并发送NS请求。若无发送数据的需求,则会在Stale状态超时后(H3C中默认为240min),进入Delay状态
邻居可达状态时间修改H3C设备中,分为系统视图下配置和接口视图下配置,接口视图下的配置优先级高于系统视图下的配置。 系统视图:
ipv6 neighbor stale-aging { aging-minutes | second aging-seconds } 缺省情况下,STALE状态ND表项的老化时间为240分钟。
接口视图
ipv6 neighbor timer stale-aging { aging-minutes | second aging-seconds }
在经过一段固定时间后,邻居状态由Delay(默认5s)变为Probe(每隔1s发送一次NS报文,连续发送3次),其间若有NA应答,则邻居状态由Delay变为Reachable。
在Probe状态,A每隔一定时间间隔z(1s)发送单播NS,发送固定次数(3)后,有应答则邻居状态变为Reachable,否则邻居状态变为Empty,即删除表项。
下图是Reach–>Stale–>Delay–>Probe–>Reach的过程(已经将Stale状态超时时间改为60s)
RS/RA报文功能
在NS/NA实验中,提到RS/RA获取地址前缀,接口根据该前缀生成全球唯一单播地址,这个功能即IPv6的无状态自动配置功能。RS/RA报文实现的功能是路由器发现/前缀发现及地址无状态自动配置、重定向功能。
无状态自动配置
路由器发现/前缀发现是指节点从收到的RA消息中获取邻居路由器及所在网络的前缀,以及其他配置参数。
地址无状态自动配置是指节点根据路由器发现/前缀发现所获取的信息,自动配置IPv6地址。
路由器发现/前缀发现通过路由器请求消息RS和路由器通告消息RA来实现,具体过程如下:
(1) 节点启动时,通过RS消息向路由器发出请求,请求前缀和其他配置信息,以便用于节点的配置。
(2) 路由器返回RA消息,其中包括前缀信息选项(路由器也会周期性地发布RA消息)。
(3) 节点利用路由器返回的RA消息中的地址前缀及其他配置参数,自动配置接口的IPv6地址及其他信息。
前缀信息选项中不仅包括地址前缀的信息,还包括该地址前缀的首选生命期(preferred lifetime)和有效生命期(valid lifetime)。节点收到周期性发送的RA消息后,会根据该消息更新前缀的首选生命期和有效生命期。
· 有效生命期:表示前缀有效期。在有效生命期内,通过该前缀自动生成的地址可以正常使用;有效生命期过期后,通过该前缀自动生成的地址变为无效,将被删除。
· 首选生命期:表示首选通过该前缀无状态自动配置地址的时间。首选生命期过期后,节点通过该前缀自动配置的地址将被废止。节点不能使用被废止的地址建立新的连接,但是仍可以接收目的地址为被废止地址的报文。首选生命期必须小于或等于有效生命期。
抓包分析
- 发送RS请求
- 配置了非抑制RA报文的交换机发送RA报文回应,报文中包含了几个option字段,如该报文中,包含了交换机的mac地址、ipv6地址前缀、MTU
RS报文:
字段 | 长度 | 含义 |
---|---|---|
Type | 1字节 | 消息类型,此处值为133。 |
Code | 1字节 | 该ICMPv6差错报文的始发者必须将该字段置为0,且接收端忽略该字段。 |
Checksum | 2字节 | 用来在ICMPv6报文中检验数据和部分IPv6首部的完整性。 |
Reserved | 4字节 | 此字段不使用。它必须由发送者初始化为0,接收者必须忽略它。 |
Options | 可变 | 选项 源链路层地址:发送者的链路层地址,如果知道。如果Source Address是未指定地址,必须不 包括在内。否则,有地址的链路层上应当包括源链路层地址。 为TLV格式,各字段含义如下: Type: = 1,长度是1字节。 Length: 1字节,标识选项的长度(包括类型字段和长度字段)以8字节为单位计算。例如,IEEE802 地址的长度是1。Length值最少为1,0为非法值,须丢弃。 Link-Layer Address: 可变长度的链路层地址。此字段的内容和形式(包括字节和比特顺序)一般由描述IPv6在不同链路层上如何运行的特定文件中规定。 |
RA报文:
字段 | 长度 | 含义 |
---|---|---|
Type | 1字节 | 消息类型,此处值为134。 |
Code | 1字节 | 该ICMPv6差错报文的始发者必须将该字段置为0,且接收端忽略该字段。 |
Checksum | 2字节 | 用来在ICMPv6报文中检验数据和部分IPv6首部的完整性。 |
Cur Hop Limit | 1字节 | 8位无符号整数。默认值应当放置在发出IP分组的IP首部的Hop Count字段中。 取0值意味着未(由该路由器)规定。 |
M | 1比特 | 1位“管理地址配置”标记。当置1时,它指出地址可通过Dynamic Host Configuration协议获得。 如果M标记置1,则O标记为冗余,可以忽略,因为DHCPv6将返回所有可用配置信息。 |
O | 1比特 | 1位“其他配置”标记。 当M=0且O=1时,指示其他配置信息可通过DHCPv6获得。例如,这类信息包括DNS相关信息或关于网络内其他服务器的信息。 如果M=0且O=0,指示没有信息可通过DHCPv6获得。 |
Reserved | 6比特 | 6位未使用字段。它必须由发送者初始化为0,接收者必须忽略它。 |
Router Lifetime | 2字节 | 16位无符号整数。与默认路由器关联的生存期,以秒为单位。最大值18.2小时。取0值的Lifetime指出路由器不是默认路由器并且不应当出现在默认路由器列表中。Router Lifetime仅适用于作为默认路由器的路由器应用;对包括在其他消息字段或选项中的信息不适用。需要对它们的信息规定时间限制的选项有它们自己的生存期字段。 |
Reachable Time | 4字节 | 32位无符号整数。此时间以毫秒计,在收到可达性确认后节点假定该邻居是可到达的。它由Neighbor Unreachability Detection算法使用(参阅第7-3节)。此值为0意味着没有(由此路由器)作出规定。 |
Retrans Timer | 4字节 | 32位无符号整数。重发的Neighbor Solicitation消息间隔时间,以毫秒计。由地址解析和Neighbor Unreachability Detection算法使用。此值为0意味着没有(由此路由器)作出规定。 |
Options | 可变 | 选项 - Source link-layer address:源链路层地址,发出Router Advertisement的接口的链路层地址。仅在有地址的链路层上使用。路由器可以忽略此选项,以便能够使入境负载跨多个链路层地址共享。 为TLV格式,各字段含义如下: - Type: = 1,长度是1字节。 - Length: 1字节,选项的长度(包括类型字段和长度字段),以8字节为单位计算。例如,IEEE802 地址的长度是1。 - Link-Layer Address: 可变长度的链路层地址。此字段的内容和形式(包括字节和比特顺序)一般由描述IPv6在不同链路层上如何运行的特定文件中规定。 - MTU:在有可变MTU的链路上应当按此发送流量(正如在描述特定链路类型上如何 运行IP的文件中规定的)。可以按此在其他链路上发送流量。 MTU格式: - Type = 5 - Length = 1 - Reserved: 此字段未使用。它必须被发送者初始化为0,接收者必须忽略它。 - MTU: 32位无符号整数。是为此链路推荐的MTU。 - Prefix Information:这些选项规定了前缀,这些前缀是on-link的,和/或被用于地址自动配置。路由器应当包括所有它的on-link前缀(链路本地前缀除外),所以多归属第主机有完整的前缀信息,这些前缀是关于主机们附着的链路的on-link目的地的。如果缺乏完整信息,当发送流量到它的邻居们时,多归属地主机或许不能够选择正确的出接口。 格式如下: - Type: = 3 - Length: = 4 - Prefix Length: 8位无符号整数。在合法前缀中领先比特的数目。其值范围是0到128。前缀长度字段为on-link确定提供必须的信息(当与前缀信息选项中L标记相结合时)。它也帮助实现地址自动配置,对此存在更多关于前缀长度的限制。 - L: 1位on-link标记。当置1时,指出此前缀可用于on-link确定。当没有置1时,通告对此前缀的on-link或off-link性质没有说明。换句话讲,如果L标记没有置1,主机不能推断出从该前缀引申出的地址是off-link。即,主机不能更新先前关于地址是on-link的指示。 - A: 1位自动地址配置标记。当置1时,指出此前缀可用于无状态地址自动配置。 - Reserved1: 6位未使用字段。必须被发送者初始化为0,接收者必须忽略它。 - Valid Lifetime: 32位无符号整数。时间长度以秒为单位(相对于分组被发送的时间),在此时间内此前缀对于on-link确定来说是合法的。全1比特值(0xffffffff)表示无限。 - Preferred Lifetime: 32位无符号整数。时间长度以秒为单位(相对于分组被发送的时间)。在此时间 内经无状态地址自动配置,根据此前缀生成的地址保有优先权[ADDRCONF]。全1比特值(0xffffffff)表示无限。注意,此字段的值不能超过Valid Lifetime字段的值,以避免优先的地址不再合法。 - Reserved2: 此字段未使用。它必须被发送者初始化为0,接收者必须忽略它。 - Prefix: IP地址或IP地址的前缀。Prefix Length字段包含此前缀中有效领先比特的数目。在前缀中,在前缀长度之后的这些位被保留,并且必须被发送者初始化为0,接收者必须忽略它们。路由器不应当发送链路本地前缀的前缀选项,主机应当忽略这种前缀选项。 |
重定向
当主机启动时,它的路由表中可能只有一条到缺省网关的缺省路由。当满足一定的条件时,缺省网关会向源主机发送ICMPv6重定向消息,通知主机选择更好的下一跳进行后续报文的发送(与IPv4的ICMP重定向消息的功能相同)。重定向报文也承载在ICMPv6报文中,其Type字段值为137.
同时满足下列条件时,设备会发送ICMPv6重定向报文:
· 接收和转发数据报文的接口是同一接口;
· 被选择的路由本身没有被ICMPv6重定向报文创建或修改过;
· 被选择的路由不是设备的缺省路由;
· 被转发的IPv6数据报文中不包含路由扩展头。
参考文章
https://www.h3c.com/cn/d_201905/1185794_30005_0.htm#_Toc8828150
https://cshihong.github.io/2018/01/29/IPv6%E9%82%BB%E5%B1%85%E5%8F%91%E7%8E%B0%E5%8D%8F%E8%AE%AE/