个人认为,理解报文就理解了协议。通过报文中的字段可以理解协议在交互过程中相关传递的信息,更加便于理解协议。
因此本文将以IPv6的常用协议上进行介绍,以详细介绍IPv6的相关内容。
- 关于IPv6相关内容,可参考2006年发布的RFC4291;
- 关于ICMPv6相关内容,可参考2006年发布的RFC4443;
- 关于Neighbor Discovery相关内容,可参考2007年发布的RFC4861;
- 关于Stateless Address Autoconfiguration相关内容,可参考2007年发布的RFC4862;
- 关于Duplicate Address Detection相关内容,可参考2006年发布的RFC4429和可参考2007年发布的RFC4862。(RFC4429介绍的是Optimistic DAD,RFC4862介绍了标准DAD)
推荐资料
- 关于 IPv6 协议相关内容,可参考2017年发布的RFC8200;
- 关于 IPv6 头部的相关字段,可参考IANA的Internet Protocol Version 6 (IPv6) Parameters;
- 关于 IPv6 全球单播地址的具体分类,可参考IANA的IPv6 Global Unicast Address Assignments;
- 博客 – 浅谈 Linux 上的 SLAAC;
- 博客 – IPv6动态地址分配机制详解;
- 博客 – DHCPv6-原理浅谈+报文示例+简易配置(SLAAC+DHCPv6+PD前缀代理)–RFC8415;
- 《ipv6技术精要》(CISCO出版)。
ICMPv6/ND协议较为复杂,建议详读1.3.2、3.2、4.2等章节或阅读其他资料。
另需说明的是本文档旨在介绍相关原理,对于不同设备及厂家的ND实现上不做深究。有意者建议阅读相关设备资料。
例如CISCO在ND的实现上,非请求RA的发送以600s为周期(也可调整);DAD检测默认3次。
而HW实现上,非请求RA的发送参考了RFC的随机周期,并且DAD依照RFC描述也仅进行了1次。
此外对于服务器设备的ND实现也比较复杂,有意者可查阅相关资料。
IPv6是一种新型的网络结构,并且通常与ICMPv6/Neighbor Discovery协议共生存在。本文旨在对IPv6的基础内容进行介绍。
个人能力有限,如有疑问欢迎留言指导~
目录
IPv6-ICMPv6
- 目录
- 1.IPv6基础内容
- 2.ICMPv6
- 3.Neighbor Discovery协议
- 4.ND协议的路由器和前缀发现-RS/RA报文
- 5.ND协议的地址解析和邻居不可达检测-NS/NA报文
- 6.其他IPv6基础协议
- 更新
1.IPv6基础内容
1.1.IPv6简介/分类
IPv6:
@新一代的IP用于替代IPv4的下一代IP协议
@核心解决IPv4地址不足的问题
IPv6地址:
IPv6地址共128bits,使用冒号分隔的16进制表达。128=16*8
@通用格式为X:X:X:X:X:X:X:X。X=16进制。
举例当X=2031时,
2031=0010 0000 0011 0001。
@压缩格式。
当X组中高位出现0时可进行省略,当每个X=0时,可进行”: :“缩写。但是”: :“缩写只可缩写一次。
举例,3001::1=3001:0000:0000:0000:0000:0000:0000:0001
其他还有内嵌IPv4的IPv6地址格式,暂不做介绍。
关于IPv6格式地址格式表达,可参考2010年发布的RFC5952;
IPv6分类
IPv6的地址总共可分为3类:单播地址、组播地址、任播地址。
单播地址:
全球单播地址= =2000::/3,占据IPv6的1/8。
2000::至3FFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
唯一本地单播地址= =fc00::/7,占据IPv6的1/2^7。类似IPv4的私网地址,但是可全球唯一。
FC00::至FDFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
链路本地地址= =fe80::/10,占据IPv6的1/2^10。
FE80::至FEBF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
@:在全球单播地址中,又会有一些地址有特殊用途。 比如2001:db8::/32作为保留前缀,以便在文档中使用。IANA发布IPv6 Global Unicast Address Assignments进行了详细总结,有意者可阅读相关资料。
自动换行
@:链路本地地址会在启用IPv6接口后自动生成,用于在接口链路上进行本链路上的通信和 ICMPv6 等协议交互。本链路通信指的是在链路上自动通告接口的128位IPv6路由,通过这种方式实际上可以实现同一链路两端不同网段通信的效果。
自动换行
@://链路本地地址也可手动配置,链路上的链路本地地址只有1个。自动换行
@://ping链路本地地址需要指定链路。因为只有本地链路有效(链路本地地址具有链路本地范围),这也意味着同一台设备的不同接口可以具有相同的链路本地地址。
内嵌IPv4地址= =0000::/8,可用于协议报文的源地址。
::至00FF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
未指定地址= =::/128,可用于协议报文的源地址。
内部环回地址= =::1/128。类似IPv4的127.0.0.1/32,操作系统的内部通信地址。
组播地址:
指定组播地址= =ff00::/8,占据IPv6的1/2^8。
FF00::至FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
请求节点组播地址= =FF02:1:FF00.0000/104。主要用于ICMPv6地址使用。FF02:0:0:0:0:1:FF00:0至FF02:0:0:0:0:1:FFFF:FFFF
1@:请求节点组播地址是为设备上的每个单播地址自动创建的,将请求节点组播前缀FF02:0:0:0:0:1:FF00::/104附加到单播地址的低阶24bit上即可生成请求节点组播地址。
2@:每个节点必须为分配给它的每个单播和任意播地址加入的一个组播地址,用于DAD地址重复检测和地址解析。
3@:与链路本地地址相同,只在本地链路上有效
在具体的组播地址上
Flag:4bits,目前只有0000和0001两种取值。0000表示为IANA分配的永久组播地址,0001为临时组播地址。
Scope:4bits,组播数据流在网络中发送的范围。
可参考2014年发布的RFC7346
1标识接口范围(不可传出,设备内部通信),
2标识链路本地也即仅在二层链路,
3标识区域本地范围,
4标识管理本地范围,
5标识站点本地范围,
8标识组织本地范围,
E标识全局范围等
Group ID:32bits,同IPv4组播地址。建议使用最后32bits。
常见的组播地址:
@Node-Local=
FF01::1为所有节点组播;
FF01::2为所有路由器组播
@Link-Local=
FF02::1为所有节点组播
FF02::2为所有路由器组播
FF02::5为OSPFv3路由器组播
FF02::6为OSPFv3路由器DR组播
FF02::9为RIP路由器DR组播
FF02::13为PIM路由器DR组播
任播地址:使用较少
任播地址与单播地址使用相同的地址空间;配置时须明确表明是任播地址以此区别单播和任播。可以用于距离用户最近的地址传输。例如在ospf不同区域宣告相同的任意播地址,通过cost优选可以让用户优选距离最近的节点。
IPv6组播MAC映射:
将组播IP的后32bits,叠加至33:33后形成48bits的mac地址。
1.2.IPv6报文格式/配置
关于最新的IPv6报文格式相关内容,可参考2017年发布的RFC8200。
链路层:
Ethernet Type=0x86dd
其他的Ethernet Type举例:
802.1q Ethernet Type=0x8100;
ARP Ethernet Type=0x0806;
IPv4 Ethernet Type=0x0800;
MPLS Ethernet Type=0x8847; 等
IPv6报文格式:Version:4bits,IPv6固定为6。IPv4则固定为4。
Traffic class:8bits,QOS分类。功能类似于IPv4的DSCP。
Flow Label:20bits,流标签。通常可用于区分是否是同一个流。例如TCP/UDP通过5元组确定流,而IPv6可根据该信息判断是否是同一个流。
Payload length:16bits,有效载荷的长度,单位byte字节。除去IPv6基本报文的长度,也即载荷长+IPv6扩展报文长。
Next header:8bits,下一报头。携带的上层报头的信息类型,也即扩展IPv6头部的类型或者上层协议的类型。
Hop limit:8bits,条数限制。与IPv4的TTL功能相似。
Source Address:128bits,报文的源地址。
Destination Address:128bits,报文的目的地址。
Extension Headers:IPv6的扩展头部,长度不定。IPv6使用扩展头部来扩展其他功能,扩展性好。另一个好处是只携带所使用的功能,减小IPv6报文的长。
常用扩展报头有:
1@逐跳选项报头(Hop-by-Hop Options header,Next Header=0)=该选项主要用于为在传送路径上的每跳转发指定发送参数,传送路径上的每台中间节点都要读取并处理该字段。(每台IPv6都需要处理的参数)
应用场景:用于巨型载荷;用于路由器提示;用于资源预留。
2@目的选项报头(Destination Options header,Next Header=60)=目的选项报头携带了一些只有目的节点才会处理的信息。目前,目的选项报文头主要用于移动lPv6
3@路由报头(Routing header,Next Header=43)=路由报头和IPv4的Loose Source and Record Route选项类似,该报头能够被lPv6源节点用来强制数据包经过特定的路由器。
4@分片报头(Fragment header,Next Header=44)=同IPv4一样,IPv6报文发送也受到MTU的限制。当报文长度超过MTU时就需要将报文分段发送,而在IPv6中,分段通过分段报头来实现。
5@认证报头(Authentication header,Next Header=51)=该报头由IPSec使用,提供认证、数据完整性以及重放保护。它还对IPv6基本报头中的一些字段进行保护。
6@封装安全净载报头(Encapsulating Security Payload header,Next Header=50)=该报头由IPSec使用,提供认证、数据完整性以及重放保护和IPv6数据报的保密,类似于认证报头。
自动换行
@RFC8200规定当有多个扩展报头时,必须按照如下顺序出现:IPv6 基本报头、逐跳选项扩展报头、目的选项扩展报头、路由扩展报头、分片扩展报头、授权扩展报头、封装安全净载报头、目的选项扩展报头(指那些将被分组报文的最终目的地处理的目的选项报头)、上层扩展报头。
@但是IPv6 节点必须接受并尝试以任意顺序处理扩展标头,并在同一数据包中出现任意次数。 “逐跳选项”标头除外,该标头仅限于仅紧跟在 IPv6 标头之后。 尽管如此,仍强烈建议 IPv6 数据包源遵守上述规定。
@并且,IPv6在源目的设备之间不允许分片。而是利用PMTU路径MTU检测确认链路上的允许通过的最大MTU。
IPv6的配置方式:
IPv6的一个特性是链路复用,也即一条链路上支持多个IPv6前缀。
1@手工配置:
2@EUI-64分配:
将MAC地址的第7bit置1(也有其他方案,指定第7bit进行反转),并将接口48bits的MAC地址从中间插入固定长度16bit的FFFE,共64bits。将该bits转成IPv6的格式,填充到所分配的前缀上。
对于前缀小于64,在前缀与后64bit间补0;大于64,则将冲突eui-64部分删除。
1@在单播MAC地址中,第1个Byte的第7bit是U/L(Universal/Local,也称为G/L,其中G表示Global)位,用于表示MAC地址的唯一性。如果U/L=0,则该MAC地址是全局管理地址,是由拥有OUI的厂商所分配的MAC地址;如果U/L=1,则是本地管理地址,是网络管理员基于业务目的自定义的MAC地址。
2@在单播MAC地址中,第1个Byte的第8bit决定单播和多播。
3@而在在EUI-64接口ID中,第7bit(也即IPv6地址后8个字节的第一个字节)的含义与MAC地址正好相反,0表示本地管理,1表示全球管理,所以使用EUIl-64格式的接口ID,U/L位为1,则地址是全球唯一的,如果为0,则为本地唯一。这就是为什么要反转该位。
3@IPv6 unnumbered:
一个接口如果没有IP地址就无法生成路由也就无法产生IP报文转发报文。IPv6 unnumbered 就是路由器一个接口上没有配置地址,但借用其他其他接口的地址进行报文的路由转发。
以太口不能配置成无编号(unnumbered)接口。
串口中(同步口)中,使用也受限制。比如当封装成 帧中继的时候,只有点对点
的子接口才允许配置成unnumbered。另外X.25封装也是不允许的。
自动换行
Cisco 2500系列unnumbered地址配置示例://关于本场景下的路由传递和出接口问题不做详细延申。//指定串口共用 Ethernet0 的地址。
4@SLAAC:
利用 Stateless Address Autoconfiguration 协议进行IPv6地址的动态配置。
第6章节进行相关介绍。
5@DHCPv6:
利用DHCPv6协议进行IPv6地址的动态配置
关于IPv6地址的SLACC+DHCPv6具体交互原理和使用案例介绍,可参考博客–DHCPv6-原理浅谈+报文示例+简易配置(SLAAC+DHCPv6+PD前缀代理)–RFC8415。
1.3.IPv6的扩展介绍
1.3.1.PMTU
通常情况下IPv6在源目的设备之间不允许分片。而是利用PMTU路径MTU检测确认链路上的允许通过的最大MTU。
PMTU可参考2017年发布的RFC8201,原理上利用ICMPv6的Packet Too Big (PTB)发现路径上的MTU。源节点向目的节点发送载荷不断减小的MTU值,以确认PMTU。
1@:源节点将第一跳MTU作为初始PMTU向目的节点发送ICMPv6,如果可正常通信就将该MTU作为PMTU。
2@:在中间路径上收到限制,则在中间节点返回ICMPv6的Packet Too Big (PTB)并携带正确的MTU值。源节点重新携带该MTU重复上述过程直到在整个路径上都获得通过。
3@:考虑到拓扑变化的可能,源节点周期性地增加其假设的PMTU。一般PMTU不变化,因此该周期应较大。
RFC8201规定节点收到ICMPv6的Packet Too Big (PTB)后的5min内不进行检测。建议定时器设置为10min。
4@:目的地址为组播场景下,可能有多个PMTU。此时选择该路径集中最小的PMTU值。ECMP场景下,也同样适用。
5@:节点不得收到ICMPv6的Packet Too Big (PTB)就更改PMTU,因为可能是无效的信息。这通常指的是转发的PTB报文。
6@:PMTU与到目的地址的Path相关联,因此可将该PMTU与本地目的地址相关的缓存关联起来。如果启用了IPv6的Flow字段,此时可将Flow ID作为Path的代表。也就将Flow ID和PMTU关联起来。
7@:在使用IPv6扩展报文路由报头情况下,目的地址选择的是Segment List的最后一个地址。
除此之外还有Packetization Layer Path MTU Discovery (PLPMTUD)-RFC4821,主要用于TCP等包封装协议上确认路径MTU。可以不基于ICMPv6来实现。这里不做介绍。
1.3.2.IPv6的数据结构概念
IPv6主机/节点通常会在本地为接口维护相应的表项/缓存,在此参考2007年发布的RFC4861进行介绍说明。
对于多归的出接口场景等暂不说明。并且对于移动IPv6也可能添加其他的数据结构概念。有时也可将如下概念融合到一张路由表中。
Neighbor Cache:到邻居传递数据的缓存。包括邻居在活动链路上的单播地址、邻居的链路层地址、邻居的路由标识、指向等待地址解析完成的任何排队数据包的指针,等。
在进行邻居不可达检测时,还包括使用的不可达检测算法、未应答探测的数量、下一次不可达检测的剩余时间。
Neighbor Cache支持静态配置://ipv6 neighbor用于在接口下配置静态 Neighbor Cache。
Destination Cache:到目标传递数据的缓存。包括目标的活动状态和到目标相关的下一跳邻居的 Neighbor Cache。可被ICMPv6的重定向报文更新。
Prefix List:活动链路上地址的集合。前缀列表缓存主要通过RA报文交互,并且每一条目都有对应的生存时间。
链路本地地址前缀具有无穷大的生存时间,该定时器并且不可被RA报文修改。
Default Router List:数据包被传递的路由器列表。路由器列表条目指向邻居缓存中的条目,选择算法优先选择具有良好可达性的邻居。
在实际进行数据转发时的原则可能不同。(例如可以选择最长掩码匹配)。但使用该路由器的所有 Destination Cache 条目都必须共享路由器的 Neighbor Cache 条目,以避免多余的邻居不可达性检测探测。
传递数据时的算法:节点通过 Destination Cache、Prefix List 和 Default Router List 确认到达目标的下一跳。这一动作可称为下一跳确认,并且将结果可以存储 Destination Cache 中。随后通过 Neighbor Cache 确认邻居的链路层地址。
1@:发送方根据前缀列表执行最长前缀匹配,以确定数据包的目的地是在链路上还是在链路外。在链路上将邻居地址作为目标地址,否则由 Default Router List 确认下一跳路由器。
2.1@:如果下一跳节点已知,就选择下一跳节点的链路层地址
2.2@:如果没有对应条目,就创建相应的条目并初始化为 INCOMPLETE。同时启动地址解析。在NS和NA交互完成创建Neighbor Cache条目后便可正常传递数据。
3@:组播数据包的下一跳总是组播地址,并认为其总在活动链路上。
Neighbor Cache条目的5种状态:
1@:INCOMPLETE。地址解析时所展现的状态。也即已经发出了一个发往请求节点组播地址的NS报文,但是未收到NA报文。
类似于发出了特定组播为目的IP的ARP,但未收到ARP回应。
收到地址解析NA回应时过渡到REACHABLE状态,否则之间删除条目。
2@:REACHABLE。在最后的 Reachable_Time 毫秒(节点常数30,000ms)内收到了邻居转发能力的确认。转发数据包时无特殊动作。
在最多30s前,已经确认邻居可达。如果持续流量/持续确认,则持续保持该状态。
//display ipv6 neighbor用于查看Neighbor Cache状态。
自动换行
该REACHABLE状态持续时间也可更改://ipv6 nd nud reachable-time用于配置 Neighbor Cache 的REACHABLE状态持续时间。该命令除控制本设备邻居表项的老化时间外,还可填充于RA报文中帮助主机配置邻居可达时间。
这里30s的Reachable_Time指的是REACHABLE可以维持的最大时间。(不经流量刷新/不经邻居状态检测)
3@:STALE。收到了邻居转发能力的确认。在转发数据包前无特殊动作。当接收到可更新缓存的链路层地址的非请求型ND消息时,进入STALE状态。
邻居的可达性存疑,但在发送流量前不进行可达性验证。一般nd缓存在仅在REACHABLE后的30s内没有刷新就会过渡到该状态。
处于该状态时,Neighbor Cache可正常使用但需要进行可达性检测进行验证。
4@:DELAY。自收到上一次邻居转发能力的确认,并且在最后一次DELAY_FIRST_PROBE_TIME(节点常数5s)内发送了数据包以来,已过去了超过Reachable_Time毫秒(节点常数30,000ms)。
虽然并且最近向邻居发送了流量,但是邻居的可达性仍然存疑。然而,与其立即探测邻居,不如将发送探测延迟一段时间,以便给上层协议一个不通过邻居请求就可达性确认刷新条目的机会。
收到了可达性确认就转变为REACHABLE状态。
5@:PROBE。如果在进入 DELAY 状态后的DELAY_FIRST_PROBE_TIME(节点常数5s)内未收到可达性确认,则发送邻居请求并将状态更改为 PROBE。
并每 Retrans_Timer 毫秒(节点常数1,000ms)重新发送NS,直到接收到可达性确认。也即正在进行可达性检测的状态。
邻居的可达性存疑,因此发送单播NS进行邻居探测。//在MAX_MULTICAST_SOLICIT次(节点常数,3次)的NS消息后没有收到NA报文,也即地址解析失败。此时将会删除Neighbor Cache。
注意:每次发送NS后都需要等待Retrans_Timer(节点常数,1000ms)时间才可进行判定。
2.ICMPv6
2.1.ICMPv6简介
ICMPv6是IPv6的基础协议之一,用于向源节点传递报文转发的信息或者错误,并执行其他互联网层功能。例如类似IPv4中ARP等的相关功能。
ICMPv6是IPv6的一个组成部分,是每个IPv6节点必须完全实现基本协议。
ICMPv6的基本格式:IPv6的Next Head标识58
Type:ICMPv6类型,1字节。
Code:代码,1字节。在 TYPE 字段的基础上,用来创建更详细的报文等级。
CheckSum:校验和,2字节。用于校验ICMPv6和部分IPv6扩展头。
总的来说ICMPv6可分为两大类:
差错消息error message:Type=0-127;
通知消息informational message:Type=128-255。
2.1.1.ICMPv6差错消息
2006年发布的RFC4443给出常用的ICMPv6差错类型:
这一情况不包括拥塞导致的丢包。
Type Code Description 1-不可达 0 没有路由到达目的地 1 与目的地的通信由于管理被禁止 2 超过了源地址分类的范围 3 地址不可达 4 端口不可达 5 源地址的入口/出口策略失败 6 拒绝路由到达目的地 2-包太大 0 包太大 3-超时 0 hop-limit超时 1 分片重组超时 4-参数错误 0-3 各种参数错误 127 X ICMPv6 差错报文扩展保留 IANA收集了一些ICMPv6的详细的Type字段分类,感兴趣者可以点击此处阅读查看。
ICMPv6的源目的IPv6:
与IPv4相同,ICMPv6报文必须确认源目的IPv6地址。当地址为单播地址时,无需多言。
当目的地址为组播地址/任播地址/不属于任何节点的单播地址时,回应报文必须是从属于节点的单播地址。
ICMPv6的处理规则:
1@:如果目的节点收到未知类型的差错消息包ICMPv6,必须传递至产生该数据包的上层进程。
2@:如果目的节点收到未知类型的通知消息包ICMPv6,必须静默丢弃。
3@:在传递ICMPv6差错消息时,必须在不超过MTU的情况下一次涵盖尽可能多的差错信息。
4@:在收到某些报文情况下,禁止发布ICMPv6的差错消息。
例如,ICMPv6差错消息,ICMPv6重定向消息,目的地址为组播IPv6且提示数据包太大或提示参数错误,链路组播IPv6和链路广播IPv6以及其他不属于单个节点的IPv6报文。
5@:为了防止上层程序未注意到错误,ICMPv6的差错报文的产生速率应当也受到限制。但是RFC4443并未给出明确的指导,只说明可以通过令牌桶来做限制。
2.1.2.ICMPv6通知消息
ICMPv6常用通知消息
Type | Code | Description |
---|---|---|
128 | 0 | 回显请求 |
129 | 0 | 回显应答 |
133 | X | 路由请求RS |
134 | X | 路由通告RA |
135 | X | 邻居请求NS |
136 | X | 路由通告NA |
137 | X | 重定向 |
143 | X | MLDv2 |
Type128和Type129功能与IPv4的ICMP的ping几乎完全相同。而其他类型的ICMPv6主要用于实现IPv6的邻居可达性检测、地址重复检测,等一些其他功能。
2.2.ICMPv6的其他考虑
ICMPv6的防攻击:
1@:使用IPv6的扩展头进行加密认证。
2@:IPv6的组播源应正确设置,以防止其他节点对自身的发送差错报文造成的DOS功能。
3@:ICMPv6通常要将结果上送至上层协议,例如TCP等,因此上层协议需要对ICMPv6做相应的检查以避免可能造成的TCP-Attack。
4@:ICMPv6的差错消息,在某些场景下是不会得到解决或解决时间比较长。
3.Neighbor Discovery协议
3.1.ND所涉及的基本概念
Neighbor Discovery协议的作用:
借用ICMPv6的Type133-137类型报文实现如下功能。
1@-Router Discovery:主机用来确定可为自己路由数据的相邻路由器。
2@-Prefix Discovery:节点用来确定所连接链路上为活动链路(on-link)的一系列地址前缀。
3@-Parameter Discovery:节点(主机和路由器)用来确认链路参数或网络参数。
4@-Address Autoconfiguration:节点用来无状态下的地址自动获取。
5@-Address resolution:节点用来在活动链路(on-link)给定目标地址的地址解析。
6@-Next-hop determination:节点用来映射目的IP与传递流量的目的IP。
7@-Neighbor Unreachability Detection:节点用来确定邻居是否可达,邻居的地址是否改变。
8@-Duplicate Address Detection:节点用来确定地址是否重复。
9@-Redirect:路由器通知主机一个更合适的下一跳。
所涉及到的IPv6地址:
all-nodes multicast address所有节点组播地址:ff02::1,发送给所有主机和路由器;
all-routers multicast address所有路由器组播地址:ff02::2,发送给所有路由器;
solicited-node multicast address请求节点组播地址:ff02:1:ff00.0000/104;
link-local address链路本地地址:fe80::/10,只具有链路范围的单播地址;
unspecified address未指定地址:缺少地址的保留地址,例如::/128。不可作为报文的目的地址。
所支持的链路类型:
ND协议支持多种链路类型:PtoP、组播、NBMA、shared media、可变MTU、同步可达性。
PtoP链路下的ND协议://PtoP链路下不在执行ND的地址解析。//此处直接进行NS/NA的交互。
尽管实际操作可能不同。
3.2.ND报文格式
接下来首先介绍下ND协议所涉及的5种ICMPv6报文的基本报文格式:Router Solicitation、Router Advertisement、Neighbor Solicitation、Neighbor Advertisement和Redirect。
3.2.1.RS和RA
Router Solicitation路由请求消息:
1@IP Fields:
源地址= = 发送报文的源接口地址or未指定地址,
目的地址= = all-routers multicast address=ff02::2,
Hop Limit= = 255。
2@Type:133,
3@Code:0,
4@Checksum:校验ICMPv6和部分IPv6扩展头,
5@Reserved:4字节必须置为0,
6@Valid Options:发送者的Source link-layer address Option;如果是未指定地址则必须置空。
//RS消息示例:
RFC4861规定源IP地址为源接口地址,更新后改为链路本地地址。
自动换行
Router Advertisement路由通告消息:
1@IP Fields:
源地址= = 发送报文的链路本地地址
目的地址= = 调用路由器请求的源地址或者all-nodes multicast address=ff02::1,
Hop Limit= = 255。
2@Type:134,
3@Code:0,
4@Checksum:校验ICMPv6和部分IPv6扩展头,
5@Cur Hop Limit:8字节的无符号整数,由传出该报文时IPv6头部的Hop Count字段填充。
//设备初始发送的IPv6单播报文的跳数限制或作为RA报文中的参数,帮助主机自动配置跳数限制。默认值是64。//ipv6 nd ra hop-limit用来配置RA报文的跳数限制。
6@5个bit位:
M-bit是管理地址配置标记位。置1时表示地址可通过DHCPv6获得,并且此时O-bit可忽略。
O-bit是其他配置标记位。置1时表示除地址外的其他信息可通过DHCPv6获得。
当M-bit和O-bit都可置0,表示不可从DHCPv6协议获取信息。
可在路由器上手动配置:
H-bit是本地代理标记位。主要与移动IPv6相关,移动IP可以实现将设备物理连接点从一个网络移动到另一个网络的无缝实现切换。关于移动IPv6的相关资料可参考2011年发布的RFC6275和CISCO提供的资料IP Mobility: Mobile IP Configuration Guide, Cisco IOS Release 15M&T。CISCO将Home agent本地代理描述为移动IPv6的3个核心组件之一。置1时,需要刷新本地代理列表。
Preference-bit是路由器优先级,共2bits。00为Medium,01为High,11为Low。
当主机所在的链路中存在多个交换模块时,主机需要根据报文的目的地址选择转发交换模块。在这种情况下,交换模块通过发布默认路由器优先级和特定路由信息给主机,提高主机根据不同的目的地址选择合适的转发交换模块的能力。
路由器发送RA报文的路由器优先级默认为medium:此时如果节点有多条路由,可优选High的Prefix产生的路由。
Proxy-bit是代理标记位。
7@Router Lifetime:路由器生存时间,16 位无符号整数。与默认路由器关联的生存期,以秒为单位。最大值65535s(RFC8391更改为此值)。置0时表示不可作为默认路由器,并且不可出现在默认路由器列表中。Router Lifetime 仅适用于作为默认路由器的路由器应用;对包括在其他消息字段或选项中的信息不适用。需要对它们的信息规定时间限制的选项有它们自己的生存期字段。
//路由器生存时间默认1800s。最小MaxRtrAdvInterval(RA报文发送的最大时间),最大9000s。详情查看4.1章节相关介绍。
8@Reachable Time:32 位无符号整数。此时间以毫秒计。在收到可达性确认后节点假定该邻居是可到达的。它由 Neighbor Unreachability Detection 算法使用。
9@Retrans Timer:32 位无符号整数。重发的 Neighbor Solicitation 消息间隔时间,以毫秒计。由地址解析和 Neighbor Unreachability Detection 算法使用。
需要注意RA的重传和NS的重传。一般来说RFC给出Neighbor Cache的Reachable_Time(节点常数,30000ms)和RETRANS_Timer(节点常数,1000ms)可等效为这两个值。
10@可能用到的Option字段:Source link-layer address、MTU和Prefix Information。
//RA消息示例:
3.2.2.NS和NA
Neighbor Solicitation邻居请求消息:
1@IP Fields:
源地址= = 发送报文的接口地址或(在DAD场景下,使用)未指定地址
目的地址= = 目标地址的请求节点组播地址或目标地址
Hop Limit= = 255。
2@Type:135
3@Code:0
4@Checksum:校验ICMPv6和部分IPv6扩展头
5@Reserved:4字节
6@Target Address:目标地址,不可为组播地址
7@可能用到的Option字段:Source link-layer address。
//NS消息示例:
自动换行
Neighbor Advertisement邻居通告消息:
1@IP Fields:
源地址= = 发送报文的接口地址
目的地址= = NS报文的源地址;如果NS源地址为空或者NA不是对NS的回应报文则使用all-nodes multicast address=ff02::1
Hop Limit= = 255。
2@Type:135
3@Code:0
4@Checksum:校验ICMPv6和部分IPv6扩展头
5@Flags:1字节的标志位
R-bits
路由器标识位。置1时标识发送NA报文的设备为路由器,可用于邻居不可达检测。
S-bits
请求标识位。置1时标识该NA报文是对NS报文的回应。在邻居不可达检测时置1表明邻居时可达的。在组播或未分配地址情况下,必须置0。
O-bits
重写标志位。置1时标识收到该NA报文的设备将重写现存的缓存条目并更新链路层地址MAC地址。置0时,不更新链路层MAC地址但更新缓存条目。对发往任播地址、不包含Target Link-Layer Address option的NA报文或者发送的是代理的请求应答类型的NA报文必须置0,其他场景必须置1。
6@Reserved:29-bits的保留位。
7@Target Address:对NS的请求回应类型的NA报文为NS对应地址,非请求回应/主动发送的NA报文为链路层地址。不可为组播地址。
8@可能用到的Option字段:Target link-layer address。
//NA消息示例:
3.2.3.Redirect和ND的Option
Redirect重定向消息:
1@IP Fields:
源地址= = 发送报文接口的链路本地地址
目的地址= = 触发重定向的数据包的源地址
Hop Limit= = 255。
2@Type:137
3@Code:0
4@Checksum:校验ICMPv6和部分IPv6扩展头
5@Reserved:保留位,4字节
6@Target Address:用于ICMP目标地址的更好的第一跳的IP地址。当目标是通信的实际端点,即目标是邻居时,目标地址字段必须包含与ICMP目标地址字段相同的值。否则,目标是更好的第一跳路由器,目标地址必须是路由器的链路本地地址,以便主机可以唯一地识别路由器。
7@Destination Address:被重定向到的地址
8@可能用到的Option字段:Target link-layer address、 Redirected Header
重定向生效的相应原则:其他内容不做过多介绍
自动换行
常见Options字段:Options字段必须是8字节的倍数
1/2@Source/Target Link-layer Address:
1@Type:1字节,1标识发送者的Source Link-layer Address、2标识目标的Target Link-layer Address。
2@Length:1字节,整个Option字段的长度。
3@Link-Layer Address:可变长的链路层地址
除了上文描述的每种ND消息所可以携带的该Option外,其他携带该Option字段的ND报文应当忽略其ND报文的该Option字段。其他Option也同理。(也即仅应识别和响应每种ND消息所要求的Option字段。)
自动换行
3@Prefix Information:
1@Type:1字节,必须为3。
2@Length:1字节,必须为4。
3@Prefix Length:1字节,无符号整数但取值0-128。
4@L-bit:1bit的标志位。置1时标识该前缀位于活动链路上(on-link)。
注意置0时,表示不传递关于链接上确定的信息,也即不生成相应的直连路由。并且不得解释为前缀所覆盖的地址是链接外(off-line)的。
只可通过L-bit置1且Lifetime置0撤销先前的活动链路状态(on-line)。
5@A-bit:1bit的标志位。置1时标识该前缀可用于无状态地址配置
6@Valid Lifetime:32-bits无符号整数。标识该前缀用于链路上(on-link)的时间,单位秒/s。0xffffffff标识无穷大。
7@Preferred Lifetime:32-bits无符号整数。标识该前缀用于无状态地址自动配置时地址的生存时间,单位秒/s。0xffffffff标识无穷大。
Preferred Lifetime不得大于Valid Lifetime。关于 Preferred Lifetime 和 Valid Lifetime 的详细表述可查看本文第6章节。
8@Prefix:IPv6前缀。不得是链路本地地址。
Prefix information:
最终生效://本Option通常用于SLAAC,用于为主机提供IPv6前缀以供自动生成IPv6地址。
自动换行
4@Redirected Header:
1@Type:1字节,必须为4。
2@Length:1字节,不定长。
3@IP header + data:重定向相关内容。
自动换行
5@MTU:
1@Type:1字节,必须为5。
2@Length:1字节,必须为1。
3@MTU:32位无符号整数。链路推荐MTU,确保链路上使用相同的MTU。可用于不同链路的最大MTU不同的异步传输场景下。
自动换行
6@Route Information:
Route Information:将特定的路由信息发布给本网段主机。主机可以使用这些路由来发送报文。//ipv6 nd ra route-information用来配置RA报文中的路由选项信息。主机收到包含路由选项信息的RA报文后,会更新自己的路由表。当主机向其他设备发送报文时,通过查询该列表的路由信息,选择合适的路由发送报文。
此处仅初步介绍了ND协议的报文字段,详细的报文交互和相应字段情况可阅读第4章节和第5章节。
4.ND协议的路由器和前缀发现-RS/RA报文
Neighbor Discovery协议主要通过Router Solicitation和Router Advertisement报文来完成路由器和前缀发现。
路由器发现用于实现前缀学习和无状态地址自动配置;前缀发现可用于确认自动所在的活动链路上可直达的IP地址范围。
主机任何情况下不发送RA报文,并丢弃收到的RS报文。但可以发送RS报文。
4.1.接口资源-ND通用
在介绍本部分内容前,首先介绍下每个路由器为IPv6接口分配的系统资源:主要参考RFC4861。
IsRouter:路由器标志位。该标志位用于表明该接口是否启用了路由功能,是否可用于从这个接口转发数据包或向该接口转发数据包。
Default: FALSE。
//此处可看到接口标识为路由器。
AdvSendAdvertisements:RA标志位。该标志位用于表明路由器是否周期发送RA报文并响应RS报文。
Default: FALSE。
RFC4861要求该系统IPv6标志位必须为FALSE,以便节点不会意外启动充当路由器,除非系统管理明确配置为发送 RA 路由器通告消息。目前厂家都遵循此规则。//ipv6 nd ra halt用于去使能系统发布RA报文功能。默认抑制RA的发送。
MaxRtrAdvInterval:接口发送非请求型组播RA报文的最大时间。
Default: 600s。取值:最小4s,最大1800s。
//ipv6 nd ra max-interval用来设置RA(Router Advertisement)报文的最大发布时间间隔。
MinRtrAdvInterval:接口发送非请求型组播RA报文的最小时间。
Default: 9s内等于MaxRtrAdvInterval,否则0.33*MaxRtrAdvInterval。取值:最小3s,最大0.75*MaxRtrAdvIntervals。
//ipv6 nd ra min-interval用来设置RA(Router Advertisement)报文的最小发布时间间隔。默认最小时间间隔是200秒。
AdvManagedFlag:RA报文的M-bit。用于是否DHCPv6。
Default: FALSE。
AdvOtherConfigFlag:RA报文的O-bit。用于是否支持DHCPv6的其他功能。
Default: FALSE。
AdvManagedFlag 和 AdvOtherConfigFlag 主要用于DHCPv6和SLAAC。关于IPv6地址的SLACC+DHCPv6具体交互原理和使用案例介绍,可参考博客–DHCPv6-原理浅谈+报文示例+简易配置(SLAAC+DHCPv6+PD前缀代理)–RFC8415。
AdvLinkMTU:路由器发送MTU Option中的MTU值。
Default: 0。
AdvReachableTime:路由器发送RA报文中Reachable Time字段的值。
Default: 0,表示路由器未分配。必须小于1h。
AdvRetransTimer:路由器发送RA报文中重传定时器的值。
Default: 0,表示路由器未分配。
AdvCurHopLimit:路由器发送RA报文中Cur Hop Limit字段值。
Default: Assigned Numbers。0表示路由器未分配,主机收到跳数限制为0的RA报文后,将自身的跳数限制设置为缺省值64。
//配置由设备初始发送的IPv6单播报文的跳数限制,或作为RA报文中的参数,帮助主机自动配置跳数限制。//ipv6 nd ra hop-limit用来配置RA报文的跳数限制。缺省情况下,RA报文的跳数限制是255。
AdvDefaultLifetime:路由器接口发送RA报文中Router Lifetime字段值。
Default: 3*MaxRtrAdvInterval。也即默认值为1800s。取值:最小MaxRtrAdvInterval,最大9000s。还可置为0时表示不可作为默认路由器。
此时表示填充于RA消息中Router Lifetime字段的值,设置RA报文的存活时间。//ipv6 nd ra router-lifetime用来配置RA报文的存活时间。
AdvPrefixList:路由器接口发送RA报文中Prefix Option中的前缀列表。
Default: 路由器通过路由协议应被通告的活动链路上的所有前缀,不包括链路本地地址前缀。
每个前缀都有独立的
AdvValidLifetime:Prefix Option中的Valid Lifetime。0xffffffff表示无穷大。Default: 2592000。
AdvOnLinkFlag:Prefix Option中的活动链路标志位L-bit。Default: TRUE。
自动换行
无状态地址配置还定义了如下信息:
AdvPreferredLifetime:Prefix Option中的Preferred Lifetime。0xffffffff表示无穷大。Default: 604800s,不能大于AdvValidLifetime。
AdvAutonomousFlag:Prefix Option中的Autonomous Flag。Default: TRUE。此时可在RA报文中看到Prefix Option:
自动换行
需要说明的是以上某些参数,在系统初始化时为了快速响应具有另外的资源值。
同样的,每个主机为IPv6接口分配的系统资源主要有:
CurHopLimit:发送IP包时的默认下一跳限制。
Default: 生效时的数值。
BaseReachableTime:计算随机ReachableTime的值。
Default: REACHABLE_TIME(节点常数,30,000ms)。
ReachableTime:邻居进行可达性确认的值。
无默认值,建议取MIN_RANDOM_FACTOR(节点常数,0.5)到MAX_RANDOM_FACTOR(节点常数,1.5)倍 BaseReachableTime 的值。
RetransTimer:邻居进行地址解析或在 Probe 状态时发送NS报文的间隔。
Default: RETRANS_TIMER(节点常数,1,000ms)。
//ipv6 nd ns retrans-timer命令用来设置系统发送NS报文的时间间隔。
该命令可用于:控制本路由设备进行邻居可达性探测的时间间隔,控制本路由设备进行重复地址检测的时间间隔,作为RA报文的参数,知会主机。主机将该值设置为自身发送邻居请求报文的时间间隔。
4.2.路由器RS/RA处理原则
点击此处查看ND报文字段介绍
路由器发送RS/RA:
1@:路由器以第4.1.章节介绍内容发送相应的RA报文。
在options中需要注意的是Source Link-Layer Address option在负载均衡的场景下又可能不携带。
如果接口的AdvLinkMTU为0,则也不携带MTU option。
Prefix option则依据接口AdvPrefixList内容进行携带。
2@:非请求型RA的发送并不严格按照周期进行发送。该随机数取值MinRtrAdvInterval到MaxRtrAdvInterval之间。
需要说明的是该参数,为RFC所要求。HW依照此要求执行,但其他厂家(例如,Cisco)有可能有独特规则。
3@:对于RS的响应RA,可以选择单播也可以选择组播回应。
通常情况下的RS/RA报文交互过程有如下原则:
1@:任何情况下,路由器将在收到RS报文后的一个随机数时间延迟后回应RA报文。
随机数取值0-MAX_RA_DELAY_TIME,该值为路由器常数=0.5s。也即系统随机启动一个0-0.5s的定时器,结束后对RS报文回应一个RA报文。
2@:发往所有节点组播地址ff02::1的RA报文速率,不得超过每MIN_DELAY_BETWEEN_RAS(该值为路由器常数,3s)时间间隔1个。
3@:(非请求型RA报文会周期发送,)如果系统计算的对RS回应RA的延时时间小于RA周期发送的剩余值,则以RA周期发送的剩余值为限发送RA。
也即当周期性/非请求型RA和请求型RA都临近发送时,以定时器小的RA进行发送。
4@:涉及第2点的速率限制时:如果在上一个3s内发送了RA报文,则在发送非请求型RA时相应的时间上进行增加。这样可满足第2点的速率限制。
允许路由器发送请求回应型RA,不受配置的MinRtrAdvInterval(非请求回应型RA最小发送间隔)限制以便频繁的相应RS报文。注意,但仍需要有第一条的随机延时时间。注意以上描述RA的限制,是请求回应型RA还是非请求型。
5@:源地址为未指定地址的RS不得更新路由器的Neighbor Cache;非未指定地址的RS在适当情况下更新Neighbor Cache,并将邻居状态置为STALE。
1@@:如果收到RS的邻居已经创建了相应的Neighbor Cache条目而且RS中Source Link-Layer Address option字段与邻居Neighbor Cache条目中不同,此时更新相应的条目,并将其Neighbor Cache条目置为STALE。
2@@:如果收到RS的邻居没有发送者的Neighbor Cache条目,路由器将创建一个,安装链接层地址,并将其可达性状态设置为STALE。
3@@:如果收到RS的邻居没有发送者的Neighbor Cache条目而且没有Source Link-Layer Address option字段,邻居既可以单播又可组播回应RA消息。
4@@:无论RS是否有Source Link-Layer Address option字段,都将该Neighbor Cache的IsRouter标识置为FALSE。
路由器/链路标识–link-local address:
link-local address通常很少改变。节点在收到ND消息后使用link-local address地址作为发送者的标识。如果节点收到来自同一台路由器发送的具有两个不同link-local address的RA报文,将认为它们可能来自不同节点。
因此,当节点的link-local address改变时,节点应当以旧link-local address发送几个生存时间为0的RA报文。同时以新link-local address发送几个RA报文。
4.3.主机RS/RA行为
主机行为:主机任何情况下不发送RA报文,并丢弃收到的RS报文。但可以发送RS报文。
尽管如此,主机还是需启动相应的内部程序对RA提供的参数做出相应调整。
在通过RA有效性检查后:
RA源地址
1@:如果该RA源地址在主机的Default Router List中不存在且通告的Router Lifetime为非0,则将在列表中创建一个新条目,并初始化其无效计时器值为Router Lifetime值。
2@:如果该RA源地址在主机的Default Router List中存在,则重置其无效计时器值为Router Lifetime值。
3@:如果该RA源地址在主机的Default Router List中存在且通告的Router Lifetime为0,则立刻老化该条目。
RA通用字段
4@:如果RA的Cur Hop Limit value非0,主机将CurHopLimit填充该值。
5@:如果RA的Reachable Time非0,主机将BaseReachableTime填充该值。如果收到最近的2次RA报文Reachable Time不同,则使用均一化算法进行调整。
Source Link-Layer Address Option
6@:如果RA包含Source Link-Layer Address Option,将该邻居的IsRouter设置为True。如果不包含该Option但有该Neighbor Cache,也将该邻居的IsRouter设置为True。
MTU Option
7@:如果RA的MTU Option非0,主机将LinkMTU填充该值。前提该值必须大于规定的最小MTU。
Prefix Option
8@:如果主机Prefix List中不存在前缀且RA的Prefix Option中Valid Lifetime为非0,则为前缀创建一个新条目,并将其invalidation timer初始化为该值。
9@:如果主机Prefix List中存在前缀,将其invalidation timer初始化为Valid Lifetime。
10@:如果主机Prefix List中存在前缀且RA的Prefix Option中Valid Lifetime为0,则立刻老化相应条目。
有一些需要说明的是:
RA报文中的未定义值并非表示让主机对相应的参数进行更改,而是保留上一个RA报文中对该参数的定义。具体的情况需要相应进行分析。
主机的Default Router List不一定全部存储所有路由器的地址,但至少需保存2个以便快速切换。
RS报文的发送:
1@:接口初始化。包括系统初始化,或路由器切换为主机的情况。
2@:主机第一次连接到链路上。
3@:主机在分离一段时间后重新连接到链路上。
例如主机在第一次启动时为了快速接收RA报文,将在0至MAX_RTR_SOLICITIONS(主机常数1s)之间产生随机数定时器,随后发送RS消息。每个消息至少间隔RTR_SOLICITION_INTERVAL秒(主机常数4s)。如果DAD检查已经经历过该时延,则可直接发送RS消息。
在某些情况下,例如移动IPv6的某些场景下,可以酌情省略该MAX_RTR_SOLICITIONS_DELAY延迟。
此外,如果主机发送MAX_RTR_SOLICITATIONS(主机常数,3次)的第3次后的MAX_RTR_SOLICITIONS_DELAY(主机常数,1s)内没有收到RA消息,则认为链路上不存在路由器。
4@:一旦主机发送RS消息,并接收到具有非0的Router Lifetime的有效RA,则主机必须停止在该接口上发送其他请求。
5.ND协议的地址解析和邻居不可达检测-NS/NA报文
与RS/RA报文相同,NS/NA报文也必须经过报文校验。通过校验的报文称为有效NS/NA报文。
5.1.地址解析
地址解析是节点仅给定IP地址就可确定邻居的链路层地址的过程。地址解析仅在被确定为活动链路(on-link)上且发送方不知道相应链路层地址的地址上执行。从不对多播地址上执行地址解析。
5.1.1.常用的NS/NA过程
地址解析的基本过程与IPv4的ARP请求过程非常类似,主要区别在于目标地址不再是广播MAC而是组播IP和组播MAC。
地址解析的基本过程如下:
1@-AR1发送NS:
链路层:SMAC=接口MAC,DMAC=组播MAC(组播IP转发而来。转化规则见1.1章节)
IP层:SIP=接口IP,DIP=请求节点组播IP(由被请求节点的单播IP转化而来。转化规则见1.1章节。这个单播IP也会填充在NS报文的Target address字段中)
ICMPv6:Target address为请求目标的IP,并携带Source Link-layer Address Option表明携带者的源地址。
2@-AR2回应NA:
链路层:SMAC=接口MAC,DMAC=目标接口MAC
IP层:SIP=接口IP,DIP=目标接口IP
ICMPv6:Target address为NS请求目标的IP(也就是自己节点IP),并携带Target Link-layer Address Option表明NS请求目标的地址(也就是自己节点MAC)。
此外还通过FLAG字段的R-bit、S-bit和O-bit表明自己是路由器,该NA报文是对NS的回应,并且需要刷新ND条目。
IPv4的一次ARP交互过程也类似:广播请求,单播回应//一次ARP交互过程。
自动换行
//reset ipv6 neighbor 可用于清空nd缓存条目,类似于reset arp命令 用于清空arp。
//display ipv6 neighbors 查看nd表项。
5.1.2.NS/NA交互的详细判定
由于IPv6新增了不同地址的分类,并通过TLV的方式对协议进行扩展。因此有必要对不同情况进行说明。
自动换行
1@NS报文的发送:
普通的NS/NA交互:当需要将单播包发送给邻居但不知道邻居链路层地址时,就会进行5.1.1.章节的地址解析。此时会为该地址创建并维护一个Neighbor Cache条目(详情可查看1.3.2章节有关介绍)。
交互详情不在说明,这里介绍下RFC有关说明:
1@:发往请求节点组播地址的NS报文,一般必须需要携带Source Link-layer Address Option
2@:发往单播地址的NS报文,可以不携带Source Link-layer Address Option。因为对端大概率已经保存了Neighbor Cache条目
3@:在地址解析时,程序需要为通信的数据包创建queue来存储数据包,在解析完成后传输
4@:NS报文将每Retrans_Timer(节点常数,1000ms)重复发送,如果在MAX_MULTICAST_SOLICIT(节点常数,3)次以内没有收到NA回应,认为地址解析失败。(注意:要是3次的Retrans_Timer(节点常数,1000ms)之后才开始判定,这之后收到仍算失败。)//NS的重传间隔设置,默认1000ms。
自动换行
2@NS报文的接收:
这里介绍下不同情况。
1@:NS目标地址为tentative实验地址,则进行SLAAC配置。(无状态地址自动分配)
2@:NS源地址不是非指定地址且携带Source Link-layer Address Option,则进行相应Neighbor Cache条目的创建/更新。
3@:通过这种方式创建的Neighbor Cache条目中的IsRouter应标记为FALSE。(如果不是第一次创建就不得更改为FALSE)。因为NS报文不携带路由器标识,并且该标识可被流量刷新或者被后续的NA报文刷新。自动换行
3@:NS源地址是非指定地址,则不得创建和更新Neighbor Cache条目。
自动换行
3@NA报文的发送:
1@:对于发往请求节点组播地址的NS报文,NA的回应一般必须需要携带Target Link-layer Address Option。且对于路由器,NA还需将R-bit置位。
2@:对于发往单播地址的NS报文,NA的回应可不携带Target Link-layer Address Option。与NS报文的发送原则类似。
3@:对于发往任播地址和代理单播的NS报文,NA的回应可不携带Target Link-layer Address Option。并且O-bit需不置位,否则需要置位。
4@:对于发往任播地址的NS报文,NA的回应应延迟一个随机数(0至节点常数MAX_ANYCAST_DELAY_TIME 1s)发送。
5@:对于源为未指定地址的NS报文,NA的回应必须将S-bit不置位,且将NA发往all-nodes address=ff02::1。否则S-bit置位并单播回应NA。
自动换行
4@NA报文的接收:
如果本地未缓存Target Address的Neighbor Cache条目应丢弃该NA报文。并且不创建相应的Neighbor Cache。这里讨论正常接收NA的情况。
本地Neighbor Cache状态为INCOMPLETE时有两种情况,
1@:链路层有地址并且不包含Target Link-Layer Address option时,丢弃该NA报文。
2@:否则,将链路层地址记录于Neighbor Cache中;如果S-bit置位将Neighbor Cache状态INCOMPLETE切换为REACHABLE,否则切换为STALE
3@:根据R-bit情况,将Neighbor Cache中IsRouter相应处理
4@:发送地址解析时队列中的数据包。
5@:忽略NA报文的O-bit
自动换行
本地Neighbor Cache状态高于INCOMPLETE时,
1@:O-bit被清除且链路层地址与Neighbor Cache不同时,如果条目为REACHABLE,将其转换为STALE并不更新条目。否则忽略NA报文不更新条目
2@:O-bit被置位或链路层地址与Neighbor Cache相同或无Target Link-Layer Address option必须更新Neighbor Cache条目。
此时
1@@:根据Target Link-Layer Address option更新链路层地址
2@@:S-bit置位时,Neighbor Cache条目必须更新为REACHABLE;S-bit未置位且链路层地址与本地不同时,条目必须更新为STALE。否则条目状态不改变。由于邻居不可达检测的存在,会对地址进行相应的检查。因此对于S-bit未置位时不更新条目
3@@:缓存条目中的IsRouter标志必须基于接收到的公告中的R-bit进行设置。如果IsRouter标志因该更新而从TRUE变为FALSE,则节点必须从默认路由器列表中删除该路由器。
自动换行
由于IPv6新增了不同地址的分类,并通过TLV的方式对协议进行扩展。因此有必要对其他NS/NA情况进行说明。
发送非请求型NA报文:
这种情况适用于链路层地址已经改变并且可能希望快速通知其邻居。
动作:此时进行MAX_NEIGHBOR_ADVERTISEMENT(节点常数,3次)的组播NA发送,每次发送间隔RetransTimer(节点常数,1000ms)。
报文:Target Address字段设置为自己接口的IP;S-bit必须不置位;R-bit根据情况置位;O-bit置位时提示邻居更新链路层地址,但无论置位与否邻居都会将该条目缓存状态更新为STALE。
其他:当节点是任播节点时,链路层地址的改变可以组播非请求型NA报文。当节点有多个地址时,发送每个地址的非请求型NA报文应当适当延迟以避免拥塞。
发送任播型NA报文:
通常情况下任播地址与单播地址完成相同,ND协议对任播型NA报文处理原则也与对单播型NA处理基本相同。
不同之处在于:
1@:属于请求型NA报文的发送应延迟一个随机数时间发送。随机数取值0-MAX_ANYCAST_DELAY_TIME(节点常数,1s)。
2@:NA的O-bit应不置位。
关于启用代理时的NS/NA报文交互,此处不做介绍。感兴趣者可查阅相关资料。
5.2.邻居不可达检测
邻居不可达检测(Neighbor Unreachability Detection,NUD)用于节点之间的路径可用性。当在运行了路由协议的路由节点等情况下,可不进行邻居不可达检测。
此外,仅对单播包的发送时进行邻居不可达检测而不检查组播包。
邻居可达的判断:
1@:上层协议通知。通常是指和邻居有报文交互。
2@:进行了NS/NA报文的交互。
NS/NA报文的交互必须是一一对应的。非请求型NA报文不适用可达确认。
NS/NA的交互是单方向的确认,邻居必须相互进行一次交互方可互相确认可达。因为邻居发送非请求型NA后,并不能确认该报文是否传递到了邻居
节点行为:
1@:邻居不可达性检测与向邻居发送数据包并行操作。如果没有向邻居发送流量,则不会发送探测。
2@:节点继续使用缓存的链路层地址向该邻居发送数据包。
3@:当收到邻居的最后一次可达性确认后已过了ReachableTime毫秒(节点常数,30000ms)时,Neighbor Cache条目的状态将从REACHABLE更改为STALE。
4@:向Neighbor Cache条目状态为STALE发送数据包时,发送方将状态更改为DELAY,并将计时器设置为在DELAY_first_PROBE_time秒(节点常数,5s)内过期。如果计时器到期时条目仍处于DELAY状态,则条目的状态变为PROBE。如果在这期间收到可达性确认,则条目的状态将更改为REACHABLE。
5@:PROBE状态下,节点使用缓存的链路层地址向邻居发送单播NA消息。每Retrans_Timer毫秒(节点常数1,000ms)重新发送NS,直到接收到可达性确认。如果在MAX_MULTICAST_SOLICIT次(节点常数,3次)的NS消息后没有收到NA报文,也即地址解析失败。此时将会删除Neighbor Cache。
点击此处回到目录
6.其他IPv6基础协议
首先需要介绍点关于地址的相关概念。
RFC4429和RFC4862这样介绍:
Tentative Address:分配给接口之前,正在验证链接上唯一性的地址。此时不讲该地址视为分配给接口,并丢弃发往该地址的数据包。但接收与ND的DAD相关数据包。
Preferred address:分配给接口使用的地址,并完全不受限制。Preferred_LifeTime时间内的地址,可被RA报文刷新。
Optimistic address:分配给接口使用的地址,但在链路上验证其唯一性时受到限制。可用但未进行完全的DAD检测。
Deprecated address:分配给接口地址,但不鼓励也不禁止使用。该地址不得创建新的交流关系,只能被动接收连接和保持原有连接。
Valid_LifeTime减去Preferred_LifeTime时间的地址获得该状态(RA的Prefix Option中携带)。
这个时间可用于地址前缀切换。超过Valid_LifeTime无法则启用该地址,也即invalid address。
//Optimistic address是一种特殊地址,RFC4429新引入。不能携带Soure Option的RS,发送NS源地址必须为未指定地址且NA回应必须将O-bit不置位避免影响Neighbor Cache,Optimistic address为源发送的NA也必须将O-bit不置位,不能进行地址解析但可以将数据转发给链路的默认路由器。
valid address:一个preferred或者deprecated address。
interface identifier:链路(至少)唯一的接口的链路相关标识符。用于和前缀一起完成地址自动生成。interface identifier介绍可参考RFC4291-IPv6 Addressing Architecture。如果这样产生的地址也无法保证唯一,有可能导致无法实现SLAAC。
//地址状态的相应关联。
6.1.Stateless Address Autoconfiguration
无状态地址自动配置(Stateless Address Autoconfiguration,可简称为SLLAC)主要用于在不使用DHCPv6的条件下自动进行IPv6地址获取。主要通过RS/RA报文携带Prefix Option实现无状态下的地址的下发。
关于IPv6的SLAAC和DHCPv6实现,可参考博客 – DHCPv6-原理浅谈+报文示例+简易配置(SLAAC+DHCPv6+PD前缀代理)–RFC8415。
SLAAC的原理:
1@:主机/呈现主机的路由器主动发起RS请求。
2@:其他节点收到RS请求后,忽视RA的周期“立即”发送主动进行一次RA的发送。
3@:节点根据RA消息中的Prefix Option选项,根据算法(Prefix+interface identifier)自动生成相应的子网。
4@:RA周期发送,此时可刷新地址的Valid_LifeTime和Preferred_LifeTime。
5@:考虑到denial-of-service攻击,RFC4862还对地址的Prefer_Timer和Valid_Timer做出建议。这里不做介绍,感兴趣者可查阅原文。
详细的处理机制可阅读第4章节。
SLAAC的配置示例:
此时:
//支持链路本地地址和全球单播地址的SLAAC。
注意:进行链路本地地址的SLAAC实际上不需要进行RS/RA交互,直接根据本地算法生成直接DAD检测即可。链路本地地址具有无穷大的preferred and valid lifetime,并且不会超时老化。
ipv6 address auto global default
//default的参数用于生成缺省路由。
相应的报文:
1@其他关于RA对SLAAC的参数设置,可点击此处查看ND报文字段。
2@通过SLAAC有时可以实现默认路由的双活网关或负载分担,这一功能相当于vrrp的效果。主要通过RA报文的 Preference-bit 字段实现相应原理,这里不再做相应介绍。
3@SLAAC一般适用于小型网络,满足即插即用的需求。并同时SLAAC和DHCPv6可以结合使用。实现的原理在于RA的Prefix Option的FLAG位。可点击此处查看ND报文字段。这里不做详细说明,有意者可查阅相关资料。
自动换行
6.2.Duplicate Address Detection
重复地址检测(Duplicate Address Detection,DAD)用于检测节点配置的IP是否被其他节点占用。
关于环路地址的DAD不做介绍,感兴趣者可查阅RFC或其他资料。
DAD检测的原则:
1@:所有单播地址(包括链路本地地址)都需要进行DAD检测。而对任播地址不进行DAD检测。
2@:在进行DAD检测的地址是tentative address,检测完成后方可过渡到Preferred address。此时可不受限制的转发数据包。
一般在接口启用IPv6地址时,自动进行一次DAD检测。//默认自动进行1次DAD检测。
3@:进行DAD检测的参数有:
DupAddrDetectTransmits–进行DAD检测的次数,默认为1;
RetransTimer:每次DAD检测的间隔时间,1000ms;
DAD检测的过程:发送NS报文
1@:
链路层:SMAC=接口SMAC;DMAC=组播MAC
IP层:SIP=未指定地址(也即:: );DIP=自己所进行检测IPv6单播地址的请求节点组播地址。
ICMPv6:发送NS类型ICMPv6,Target Address填充自己所进行检测IPv6单播地址并且不携带Source Link-layer Address Option
发送的NS报文示例://Type135=NS消息。
2@:如果未有相应的NA报文回包,则证明该链路上该地址未被使用。
3@:如果回应了相应的NA报文,则将该地址为重复地址。
链路层:SMAC=接口SMAC;DMAC=组播MAC
IP层:SIP=其他接口的该单播地址;DIP=所有节点组播地址ff02::1。
ICMPv6:发送NA类型ICMPv6,Target Address填充NS发送者所进行检测IPv6单播地址并且携带Target Link-layer Address Option
发送的NA报文以标识重复地址示例:
//已使用该地址的设备进行NA回应,用于表明该地址已被使用。
//收到NA报文的设备,将该地址状态置位DUPLICATE以表明指定地址已被占用。此时也就完成了地址重复检测。
这一行为在IPv4中的实现主要通过ARP:当接口启用一个IPv4地址时,进行通告一个免费ARP,如果未收到ARP的reply则认为该地址未在链路上被使用。
//如果有其他的接口进行该ARP的回应,将持续进行免费ARP的广播直到有一方更改地址。