在IPv4中,路由器使用ICMP向源节点报告向目的地传输IP报文过程中的错误和信息。它为诊断、信息通知和管理目的定义了一些消息,如目的不可达、报文超长、超时、回显请求和回显应答等。在IPv6中,ICMPv6除了提供ICMPv4常用的功能之外,还作为其他一些功能的基础,如邻居发现、无状态地址配置(包括重复地址检测)、PMTU发现等。

ICMPv6的协议类型号(即IPv6报文中的Next Header字段的值)为58。ICMPv6报文的格式:

值得学习的ICMPv6 协议_ICMPv6

报文中部分各字段的含义如下:

  • Type:表明消息的类型,0~127表示错误报文类型,128~255表示消息报文类型。
  • Code:表示此消息类型细分的类型。
  • Checksum:表示ICMPv6报文的校验和。

ICMPv6错误报文用于报告在转发IPv6报文过程中出现的错误。ICMPv6目的不可达错误报文可以分为以下5种:

  • 0:没有能到达目标的路由(路由表中,没有与目标相匹配的路由)
  • 1:与目标的通信被管理策略禁止(与目标的通信被管理策略禁止,通常是被防火墙丢弃)
  • 2:超出源站的地址范围(目标节点地址不在源站点地址的范围内。当数据包被一个不在源地址范围内的网络接口转发时,由路由器发送该类型报文)
  • 3:地址不可到达(目的地址不可到达。在无法解析目标的链路层地址时,发送该类型报文)
  • 4:端口不可到达(通常是由于包含UDP报文的IPV6数据包到达了目标,但是在目标中却没有应用程序侦听UDP端口)

ICMPv6信息报文提供诊断功能和附加的主机功能,比如组播侦听发现和邻居发现。常见的ICMPv6信息报文主要包括Echo Request(回显请求)报文Echo Reply(回显应答)报文,这两种报文也就是通常使用的Ping报文。

  • 回显请求报文:将回显请求报文发送到目标节点,以使目标节点立即发回一个回显应答报文。回显请求报文的Type字段值为128,Code字段的值为0。
  • 回显应答报文:当收到一个回显请求报文时,ICMPv6会用回显应答报文响应。回显应答报文的Type字段的值为129,Code字段的值为0。

在IPv4中,报文如果过大,必须要分片进行发送,所以在每个节点发送报文之前,设备都会根据发送接口的MTU来对报文进行分片。但是在IPv6中,为了减少中间转发设备的处理压力,中间转发设备不对IPv6报文进行分片,报文将由发送者进行分片。当中间转发设备的接口收到一个报文后,如果发现报文长度比转发接口的MTU值大,则会将其丢弃;同时将转发接口的MTU值通过ICMPv6的报文过大错误报文发给源端主机,源端主机以该值重新发送IPv6报文,这样带来了额外流量开销。PMTU发现协议可以动态地收集整条传输路径上各链路的MTU值,减少由重传带来的额外流量开销

PMTU协议是通过ICMPv6的报文过大错误报文来完成的。首先源节点假设PMTU就是其出接口的MTU,发出一个试探性的报文,当转发路径上存在一个小于当前假设的PMTU时,转发设备就会向源节点发送报文过大错误报文,并且携带自己的MTU值,此后源节点将PMTU的假设值更改为新收到的MTU值,然后继续发送报文。如此反复,直到报文到达目的地之后,源节点就能获得到达目的地的PMTU了。

PMTU的工作过程如图下图所示:

值得学习的ICMPv6 协议_ICMPv6_02

该示例中,整条传输路径包含了4条链路,每条链路的MTU分别是1500 Byte、1400 Byte和1300 Byte,当源节点发送一个分片报文的时候,首先按照PMTU为1500 Byte进行分片并发送分片报文,当到达MTU为1400 Byte的出接口时,设备返回报文过大错误报文,同时携带MTU值为1400 Byte的信息。源节点接收到之后会将报文重新按照PMTU为1400 Byte进行分片,并再次发送一个分片报文,当分片报文到达MTU值为1300 Byte的出接口时,同样返回报文过大错误报文,携带MTU值为1300 Byte的信息。之后源节点重新按照PMTU为1300 Byte进行分片并发送分片报文,最终到达目的地,这样就找到了该路径的PMTU。

由于IPv6要求链路层所支持的最小MTU为1280 Byte,所以PMTU的值必须大于等于1280 Byte。建议将1500 Byte作为链路的PMTU值