RFC 8200:Internet Protocol, Version 6 (IPv6) Specification在上个月(七月份)刚刚发布,趁热打铁来学习一下IPv6。你可能会问IPv6不是早就有了吗?没错,IPv6最早在1995年的时候发布于RFC 1883。但标准就是这样,旧的RFC不符合实践的地方不断被更新,于是有新的RFC出来替换旧的RFC,这是一个取其精华去其糟粕的过程。

IPv4

先来看看IPv4的协议头(在RFC 791中定义):

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |Version|  IHL  |Type of Service|          Total Length         |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |         Identification        |Flags|      Fragment Offset    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  Time to Live |    Protocol   |         Header Checksum       |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                       Source Address                          |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Destination Address                        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Options                    |    Padding    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

我们可以根据功能对协议头部字段进行分类,下面的几类跟跟IP报文自身相关:

版本和校验相关

  • Version:IP版本,为固定值4
  • Header Checksum:用于校验IP报文的完整性

长度相关

  • Total Length:报文长度,因为链路层可能会有填充,所以IP报文需要知道自己的长度
  • IHL:Internet Header Length,为协议头+扩展项(Options)的长度,单位为32bit

分片相关

  • Identification:用于标识报文分片
  • Flags:跟报文分片相关的控制位
  • Fragment Offset:分片在报文的位置偏移

生命周期相关

  • Time to Live:报文的最大生存时间,按秒计数;经过每个路由器都要至少减去一秒

下面的字段则跟上层服务相关:

上层服务相关

  • Protocol:指示次IP报文承载的上层协议类型,已TCP为例,该值是7
  • Source Address:源地址
  • Destination Address:目的地址
  • Type of Service:这个字段简称TOS,需要特别注意;一开始它的含义被RFC 795所定义,后来被RFC 2417重新定义,被当成Differentiated Services也就是DS字段使用,后来RFC 3168又增加了和Explicit Congestion Notification相关的定义。

IPv6

IPv6最早由RFC 2460定义,后来又被许许多多的RFC更新。RFC 8200相当于是对IPv6的一次总结性修订。

IPv6对IPv4做了多方面的修改,最明显的改动是把IP地址从32位增加到128位,其他修改有:

  • 简化协议头格式
  • 更弹性的扩展方式
  • 增加一些新功能

先看看IPv6的头:

   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |Version| Traffic Class |           Flow Label                  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |         Payload Length        |  Next Header  |   Hop Limit   |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   +                                                               +
   |                                                               |
   +                         Source Address                        +
   |                                                               |
   +                                                               +
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   +                                                               +
   |                                                               |
   +                      Destination Address                      +
   |                                                               |
   +                                                               +
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

除了两个大大的128位的Source Address和Destination Address,其他部分看起来是不是简化多了?

其他从IPv4升级而来的字段:

  • Version,现在这个值为6。
  • Traffic Class,和IPv4的Type of Service一样,不过换了一个名字。
  • Hop Limit:其实就是IPv4的Time to Live字段,因为没有网络真正去计算报文的生存时间,所以这个字段就改成Hop Limit了,意思是路由器的转发跳数限制。

和IPv4不尽相同的字段:

  • Flow Label:新增的字段,用于标记一系列的报文,以至于网络能对这些报文做相似的处理。
  • Payload Length:负载长度,相当于IPv4的 Total Length减去(IHL*4)
  • Next Header:扩展头部,下面着重介绍

IPv6的扩展机制

IPv4虽然支持使用Options来扩展,但是Options的个数和长度是有限制的。因为IHL能表示的最大值为60字节,再减去固定的20字节,只有40个字节能用来做扩展。

IPv6的固定头部虽然有40个字节,但是它可以通过Next Header以类似链表的形式来扩展,显得更有灵活性,下面是个例子:

   +---------------+------------------------
   |  IPv6 header  | TCP header + data
   |               |
   | Next Header = |
   |      TCP      |
   +---------------+------------------------

   +---------------+-----------------+-----------------
   |  IPv6 header  | Fragment header | fragment of TCP
   |               |                 |  header + data
   | Next Header = |  Next Header =  |
   |    Routing    |       TCP       |
   +---------------+-----------------+-----------------

跟IPv4相比,IPv6有两个地方需要特别指出:

  • 报文的分片现在放在扩展中做了,而且必须由主机来分片,中间的路由器不能分片,相当于简化了路由器
  • 原先的Checksum现在取消了,规定由TCP或者UDP这种传输层协议来计算,路由器这种三层的设备就不需要计算Checksum,省去了工作量。

另外还通过扩展头的形式增加了一些新功能,比如通过其扩展头来支持IPSec所需要的协议字段。

IPv6明确定义了哪些扩展头由主机负责,哪些扩展头中间的路由器可以更改,责任更明确了。

报文大小相关的

最后要说的一点是和网络所能报文大小相关的:

  • IPv4要求网络最小能够支持68字节的报文,而进行分片
  • IPv4要求主机能够处理最小576字节的报文
  • IPv6要求网络和主机能够处理的最小报文是1280字节

这些数字怎么来的不得而知,更多详细信息可以参考WikiPedia的Maximum Transmission Unit

(完)