什么是ipv6网络协议
ICMPv6概述
ICMPv6是IPv6的基础协议之一,协议类型号(即IPv6 Next Header)为58,用于向源节点传递报文转发的信息或者错误。
在IPv6中,ICMPv6除了提供ICMPv4的对应功能之外,还有其它一些功能的基础,如邻居发现、无状态地址配置、重复地址检测、PMTU发现等。
报文解释:
- Type:表明消息的类型,0至127表示差错报文类型,128至255表示消息报文类型。
- Code:表示此消息类型细分的类型。
- Checksum:表示ICMPv6报文的校验和。
ICMPv6 message Type(两大类)
- 错误类消息(error messages),也称为差错报文,8bits类型字段中的最高bit为0,也就是ICMPv6 Type=[0,127]
- 信息类消息(information messages) ,也称为信息报文, 8bits类型字段中的最高bit为1,也就是ICMPv6 Type=[128,255]
消息类型 | TYPE | 名称 | CODE |
差错消息 | 1 | 目的不可达 | 0 无路由 |
1 因管理原因禁止访问 | |||
2 未指定 | |||
3 地址不可达 | |||
4 端口不可达 | |||
2 | 数据包过长 | 0 | |
3 | 超时 | 0 跳数到0 | |
1 分片重组超时 | |||
4 | 参数错误 | 0 错误的包头字段 | |
1 无法识别的下一包头类型 | |||
2 无法识别的ipv6选项 | |||
信息消息 | 128 | Echo request | 0 |
129 | Echo reply | 0 |
IPv6邻居发现协议 - NDP
NDP(Neighbor Discovery Protocol,邻居发现协议)在RFC2462及RFC4861中定义。NDP实现了IPv6中诸多重要机制,如下图所示:
NDP使用ICMPv6的相关报文如下图所示:
- RS(Router Solicitation):路由器请求报文
- RA(Router Advertisement):路由器通告报文
- NS(Neighbor Solicitation):邻居请求报文
- NA(Neighbor Advertisement):邻居通告报文
地址解析
地址解析过程中使用了两种ICMPv6报文:邻居请求(Neighbor Solicitation)和邻居通告(Neighbor Advertisement)。
邻居请求 (Neighbor Solicitation,NS)格式如下图所示:
- Type=135,Code=0。
- Target Address是需要解析的IPv6地址。
邻居通告 (Neighbor Advertisement,NA)格式如下图所示:
- Type=136,Code=0
- R标志(Router flag)表示发送者是否为路由器,如果1则表示是;
- S标志(Solicited flag)表示发送邻居通告是否是响应某个邻居请求,如果1则表示是;
- O标志(Overide flag)表示邻居通告中的消息是否覆盖已有的条目信息,如果1则表示是;
- Target Address表示所携带的链路层地址对应的IPv6地址。
- 被请求的链路层地址被放在Options字段中,其格式仍然采用TLV格式
PC1现要请求2001::2的地址,解析过程如下:
1、PC1发送邻居请求报文,发送者的源链路层地址会被放在NS的Options字段中。NS的Target address是需要解析的IPv6地址2001::2。
2、 PC2收到这个数据帧后,进行如下处理
- 由于本地网卡接收目的MAC地址为3333-FF00-0002的数据帧,因此在对数据帧做校验之后从帧头的类型字段得知里头是个IPv6报文,于是将帧头拆掉,把IPv6报文上送IPv6协议栈处理。
- IPv6协议栈从报文的IPv6头部中的目的IPv6地址得知这个数据包是发往一个被请求节点组播地址FF02::1:FF00:2,而本地网卡加入了这个组播组。继续处理该报文
- 接着,从IPv6包头的NextHeader字段得知IPv6包头后面封装着一个ICMPv6的报文,因此将IPv6包头拆除,将ICMPv6报文交给ICMPv6协议去处理。
- 最后ICMPv6发现这是个NS报文,要请求自己2001::2对应的MAC地址,于是回送一个NA报文给PC1,在该报文中就包含着PC2的MAC地址。
重复地址检测DAD
接口在启用任何一个单播IPv6地址前都需要先进行DAD,确认是否有其它的节点使用了该地址。
一个IPv6单播地址在分配给一个接口之后且通过重复地址检测之前称为试验地址(Tentative Address)。此时该接口不能使用这个试验地址进行单播通信,但是仍然会加入两个组播组:ALL-NODES组播组和实验地址所对应的Solicited-Node组播组。
IPv6重复地址检测技术和IPv4中的免费ARP类似:节点向一个自己将使用的试验地址所在的Solicited-Node组播组发送一个以该实验地址为请求的目标地址的NS报文,如果收到某个其他站点回应的NA报文,就证明该地址已被网络上使用,节点将不能使用该实验地址通讯。
DAD检测过程如下:
- PC1的IPv6地址2001::FFFF为新配置地址,即2001::FFFF为PC1的试验地址。
- PC1向2001::FFFF的Solicited-Node组播组发送一个以2001::FFFF为请求的目标地址的NS报文进行重复地址检测,由于2001::FFFF并未正式指定,所以NS报文的源地址为未指定地址。
- 当PC2收到该NS报文后,有两种处理方法:
- 如果PC2发现2001::FFFF是自身的一个实验地址,则PC2放弃使用这个地址作为接口地址,并且不会发送NA报文。
- 如果PC2发现2001::FFFF是一个已经正常使用的地址,那么PC2会向该地址的ALL-NODES组播组发送一个NA报文,该消息中会包含2001::FFFF。这样,PC1收到这个消息后就会发现自身的实验地址是重复的,从而弃用该地址。
邻居状态
在实际的IPV6通讯过程中不仅仅是地址解析这么简单,而是需要维护一张邻居表,每个邻居都有相应的状态,状态之间可以迁移。邻居状态有5种:
- INCOMPLETE:未完成,邻居请求已经发送到目标节点的请求组播地址,但没有收到邻居的通告;
- REACHABLE:可达,收到确认,不需再发包确认;
- STALE:陈旧,从收到上一次可达性确认后过了超过30s;
- DELAY:延迟,在stale状态后发送过一个报文,并且5s内没有可达性确认;
- PROBE:探查,每隔1s重传邻居请求来主动请求可达性确认,直到收到确认。
下面以A、B两个节点之间相互通讯过程的A节点的邻居状态变化,假设A、B两个节点之前没有任何通讯:
- A先发送NS,并生成邻居缓存条目,状态为Incomplete;
- 若B回复NA,则Incomplete->Reachable,否则10s后Incomplete->Empty,即删除条目;
- 经过ReachableTime(默认30s),条目状态Reachable->Stale;或者在Reachable状态,收到B的非请求NA,且链路层地址不同,则马上->Stale;
- 在Stale状态若A需要向B发送数据,则Stale->Delay,同时发送NS请求;
- 在Delay_First_Probe_Time(默认5秒)后,Delay->Probe,其间若有NA应答,则Delay->Reachable;
- 在Probe状态,每隔RetransTimer(默认1秒)发送单播NS,发送MAX_UNICAST_SOLICIT个后再等RestransTimer,有应答则->Reachable,否则进入Empty,即删除表项。
查看IPv6邻居路由表
IPv6不像IPv4那样使用ARP表来缓存IP与MAC地址的映射,而是维护一个IPv6邻居表。在华为数通设备上则使用display ipv6 neighbors命令来查看IPv6邻居表。
说明:
在windows操作系统里,可以使用netsh interface ipv6 show neighbors命令查看邻居缓存的内容。
路由器发现
路由器发现功能用来发现与本地链路相连的设备,并获取与地址自动配置相关的前缀和其他配置参数。路由器发现功能主要通过以下两种报文实现:
- RA(Router Advertisement,路由器通告)报文:每台设备为了让二层网络上的主机和设备知道自己的存在,可以定时以组播方式发送RA报文,RA报文中会带有网络前缀信息,及其他一些标志位信息。RA报文的Type字段值为134。
- RS(Router Solicitation,路由器请求)报文:很多情况下主机接入网络后希望尽快获取网络前缀进行通信,此时主机可以立刻发送RS报文给路由器。网络上的路由器收到该RS报文后会立即向相应的主机单播回应RA报文,告知主机该网段的默认路由器和相关配置参数。RS报文的Type字段值为133。
RA
链路上的路由器会定期的发送RA(Router Advertisement)消息。
- 收到RA的主机将加入默认路由器列表中。
- 收到RA的路由器将检查RA内容的一致性。
RS
主机接口初始化时发RS(Router Solicitation)消息,路由器回应RA。
IPv6无状态地址自动配置
IPv6支持无状态地址自动配置,无需使用诸如DHCP之类的辅助协议,主机即可获取IPv6前缀并自动生成接口ID。路由器发现功能是IPv6地址自动配置功能的基础,主要通过以下两步骤获取:
- 网络节点向相连的路由器发送RS,请求地址前缀信息。
- 路由器通过发送路由器通告RA,回复地址前缀信息。
如上图所示,IPv6无状态地址自动配置的工作过程如下:
- 主机根据本地接口ID自动产生网卡的链路本地地址。
- 主机对链路本地地址进行DAD检测, 如果该地址不存在冲突则可以启用。
- 主机发送RS报文尝试在链路上发现IPv6路由器,该报文的源地址为主机的链路本地地址。
- 路由器回复RA报文(携带IPv6前缀信息,路由器在未收到RS时也能够配置主动发出RA报文)。
- 主机根据路由器回应的RA报文,获得IPv6地址前缀信息,使用该地址前缀,加上本地产生的接口ID,形成单播IPv6地址。
- 主机对生成的IPv6地址进行DAD检测,如果没有检测到冲突,那么该地址才能够启用。
重定向报文
当网关路由器知道更好的转发路径时,会以重定向报文的方式告知主机,让报文发送者选择另一个网关路由器。
重定向报文的结构如下:
- 报文格式中Type为137,Code为0;
- Target Address是更好的路径下一跳地址;
- Destination Address是需要重定向转发的报文的目的地址。
如下图所示,假设主机A想与主机B通讯,主机A的默认网关路由器是RTA,那么当A发送报文给B时报文会被送到RTA。RTA接收到A发送的报文以后会发现实际上主机A直接发送给路由器RTB更好,它将发送一个ICMPv6重定向报文给主机A,其中Target Address为RTB,Destination Address为主机B。
主机A接收到了重定向报文之后,会在默认路由表中添加一个主机路由,以后发往主机B的报文就直接给RTB。
这就是重定向的一个简单过程,其中会有个问题:RTA如何知道去往主机B的路径通过RTB更好呢?
其实这个很简单,因为RTA会发现报文进入的接口就是报文路由得出接口,也就是说发往主机B的路由实际上只是在RTA上转了一圈出来了,然后转发到RTB,据此,RTA能判断出直接给RTB是更好的路径。
Path MTU
在IPv6中,为了减少中间转发设备的处理压力,中间转发设备不对IPv6报文进行分片,报文的分片将在源节点进行。
PMTU协议是通过ICMPv6的Packet Too Big报文来完成的。首先源节点假设PMTU就是其出接口的MTU,发出一个试探性的报文,当转发路径上存在一个小于当前假设的PMTU时,转发设备就会向源节点发送Packet Too Big报文,并且携带自己的MTU值,此后源节点将PMTU的假设值更改为新收到的MTU值继续发送报文。如此反复,直到报文到达目的地之后,源节点就能知道到达目的地的PMTU了。
如下图所示整条传输路径需要通过4条链路,每条链路的MTU分别是1500、1500、1400、1300,当源节点发送一个分片报文的时候,Path MTU工作过程如下:
- 首先按照PMTU为1500进行分片并发送分片报文,当到达MTU为1400的出接口时,路由器返回Packet Too Big错误,同时携带MTU值为1400的信息。
- 源节点接收到之后会将报文重新按照PMTU为1400进行分片并再次发送一个分片报文,当分片报文到达MTU值为1300的出接口时,同样返回Packet Too Big错误,携带MTU值为1300的信息。
- 之后源节点重新按照PMTU为1300进行分片并发送分片报文,最终到达目的地,这样就找到了该路径的PMTU。