IPv6协议规范(中文版)

 Internet 协议第六版 (IPv6) 规范

1。绪论

IP 第 6 版 (IPv6) 是继 IP 第 4 版 (IPv4) [RFC-791] 以后,Internet 协议的一个新版本。由 IPv4 到IPv6的改变主要集中在以下几个方面:

    • 地址容量的扩展
      IPv6把 IP 地址的大小从 32 位增至 128 位,可以支持更多的地址层次,更大数量的节点,以及更简单的地址自动配置。组播路由的可缩放性改进为给组播地址增加一个"范围"字段。又定义了一个叫做"anycast"的新的地址类型,用于把包发送给一组节点中的任意一个。
    • 首部格式的简化
      一些 IPv4 首部字段被删除或者成为可选字段,减少了一般情况下包的处理开销以及IPv6首部占用的带宽。
    • 支持扩展和选项的改进
      IP 首部选项编码方式的修改导致更加高效的传输,在选项长度方面更少的限制,以及将来引入新的选项时更强的适应性。
    • 数据流标签的能力
      加入一个新的能力,使得那些发送者要求特殊处理的属于特别的传输"流"的包能够贴上"标签",比如非缺省质量的服务或者"实时"服务。
    • 认证和保密的能力

为支持认证,数据完整性以及(可选的)数据保密的扩展都在IPv6中说明。本文描述IPv6基本首部以及最初定义的IPv6 扩展首部和选项。还将讨论包的大小问题,数据流标签和传输类别的语法,以及IPv6对上层协议的影响。IPv6 地址的格式和语法在其它文章中单独说明。IPv6版的 ICMP 是所有IPv6应用都需要包含的。

2。术语

节点 - 应用IPv6的一个设备。
路由器 - 传送不是发给自己的IPv6包的节点. [参见下面的说明]
主机 - 任何非路由器节点. [参见下面的说明]
上层 - 直接在IPv6上层的协议层。典型的例子是传输协议如 TCP UDP,控制协议如 ICMP,路由协议如 OSPF,以及网络层或在IPv6里被开凿了通道 (也就是封装在IPv6) 的低层协议,比如 IPXAppleTalkIPv6自身。
链路 - 一个通讯设备或者媒体。通过它节点可以与链路层,也就是直接在IPv6下面的那一层进行通讯。典型的例子是以太网(简单的或者网桥的)PPP 连接,X.25,帧中继,或者ATM网络以及网络层(或更高层)"通道"。比如说通过 IPv4 或者IPv6本身的通道。
邻居 - 连在同一个链路上的节点。
接口 - 节点与链路的连接。
地址 -IPv6层中一个接口或者一组接口的标识符。
-IPv6首部加上有效数据。
链路 MTU - 最大传输单元。也就是以八位组为单位的能在链路中传输的包的最大大小。
路径 MTU - 源节点到目的节点之间的路径中所有链路的最小链路 MTU

注意: 尽管不常见,但这是可能的: 就是一个设备具有多个接口,用来传输从它的某些(不是全部)接口传来的,不以自身为目的节点的包,并且抛弃那些从其他接口传来的,不以自身为目的节点的包。当这样的设备通过前一种接口接收包或者与其邻居联系时,它必须遵循协议中有关路由器的要求。当它通过后一种接口接收包或者与其邻居联系时,它必须遵循协议中有关宿主机的要求。

3.IPv6首部格式

版本

4 位Internet协议版本号=6。

传输类别

8 位传输类别字段。

数据流标签

20位数据流标签。

有效数据长度

16 位无符号整数,IPv6有效数据长度。也就是以八位组为单位,在这个包中IPv6首部后面的其余部分的长度。(注意,扩展首部将被认为是有效数据的一部分,计算在长度里)

下一个首部

8 位选择器。标识紧接在IPv6首部后面的下一个首部的类型。使用与 IPv4 协议字段相同的数值。

跳数限制

8 位无符号整数。在每个传输此包的节点处递减1。如

果跳数限制减为零,就抛弃此包。

源地址

128 位包的制作者的地址。

目的地址

128 位包的预期接收者的地址 (如果存在路由首部的话,可能不是最终的接收者)。

 

4.IPv6扩展首部

在IPv6里,可选的网络层信息在一个独立的首部编码,放在包中IPv6首部与上层协议首部之间。有这样几个为数不多的扩展首部,每个首部由不同的"下一个首部"的值来标识。一个IPv6首部可以携带零个,一个或者更多的扩展首部,每个扩展首部由前一个首部中的"下一个首部"字段标识。如下例所示:

 

除了一个特例,扩展首部不在包的传送路径中的任何节点检测和处理,直到这个包到达目的地址字段标识的那个节点(或者在组播的情况下,一组节点中的每一个)。在这里,对IPv6 首部的"下一个首部"字段的常规处理将是调用处理模块来处理第一个扩展首部,或者,如果不存在扩展首部,就处理上层首部。每个扩展首部的内容和语义决定是否处理下一个首部。因此,扩展首部必须严格按照它们在包中出现的次序来处理;这样,接收者就不能搜索整个包来寻找某个特定类型的首部,并且在处理所有前面的首部之前处理它。

上文所述的特例是指 Hop-by-Hop 选项首部。它携带了包的传送路径中的每个节点都必须检测和处理的信息,包括源节点和目的节点。Hop-by-Hop 选项首部如果存在,就必须紧跟在IPv6首部后面. IPv6首部中"下一个首部"字段的值为零表示存在这个首部。如果一个首部的处理结果要求节点处理下一个首部,但是节点无法识别这个首部的"下一个首部"字段值,那么节点就应该抛弃这个包,并且给包的源节点发送一个ICMP "参数存在问题"的报文,ICMP 编码值为 1 ("遇到无法识别的'下一个首部'类型")。ICMP 指针字段包含那个无法识别的值在原包中的偏移量。如果节点遇到IPv6首部以外的其他首部中的"下一个首部"字段的值为零的情况,应做相同的处理。

为了后面的首部保持8个八位组对齐,每个扩展首部都是8个八位组的整数倍长。每个扩展首部的多八位组字段都以它们的自然边界对齐。也就是说,宽度为 n 个八位组的字段放在距首部开始位置处 n 个八位组的整数倍的位置上,其中 n = 1,2, 4,或者 8。一个完整的IPv6实现应包含以下扩展首部的处理程序:

  • Hop-by-Hop 选项首部
  • 路由首部 (类型 0)
  • 分片首部
  • 目的地址首部
  • 认证首部
  • 封装安全有效数据首部 (ESP 首部)

4.1 扩展首部的顺序

当在同一个包中使用多于一个扩展首部时,建议以如下顺序排列这些首部:

IPv6首部

Hop-by-Hop 选项首部

目的地址选项首部 (注 1)

路由首部

分片首部

认证首部 (注 2)

封装安全有效数据首部 (注 2)

目的地址选项首部 (注 3)

上层协议首部

注 1: 由IPv6目的地址字段及路由首部列出的后续地址中第一个出现的目的地址处理的选项。
注 2: 关于认证首部和封装安全有效数据首部的相关顺序的附加建议参见其它文献。
注 3: 只由包的最终目的地址处理的选项。

除了目的地址选项首部最多出现两次 (一次在路由首部前,一次在上层协议首部前)以外,每个扩展首部应当只出现一次。如果上层协议首部是另一个IPv6首部 (在使用通道技术或封装在IPv6中的情况下),它后面可以有自己的扩展首部. 这些扩展首部以同样的建议顺序独立排列。如果定义了其他的扩展首部,与上面列出的扩展首部相关的次序限制必须加以说明。除了 Hop-by-Hop 选项首部必须紧跟在IPv6首部后面以外,IPv6节点必须接受并且尽量处理任意顺序的,以及在同一个包内出现任意多次的扩展首部。尽管如此,建议IPv6包的源节点遵守上面的建议顺序,除非后续的协议规范修改这一顺序。

4.2 选项

当前已定义的扩展首部中的两个:Hop-by-Hop 选项首部和目的地址选项首部,携带不定数量的,以类型-长度-值(TLV)格式进行编码的选项,其格式如下:

选项类型

8 位标识符,标识选项的类型。

选项数据长度

8 位无符号整数。以八位组为单位的选项数据字段的长度。

选项数据

可变长度字段。依选项类型而不同的数据。

首部中的选项必须严格按照它们在首部中出现的次序来处理;这样,接收方就不能搜索整个首部来寻找某个特定类型的选项,并且在处理所有前面的选项之前处理它。选项类型标识符以如下规则编码: 其最高两位指定了当IPv6节点无法识别这一选项类型时所必须的反应:

00

跳过这一选项,继续处理首部。

01

抛弃这个包

10

抛弃这个包,并且不管包的目的地址是不是组播地址,都给包的源地址发送一个 ICMP "参数存在问题",编码 2 的报文,指针指向无法识别的选项类型。

11

抛弃这个包,并且只有当包的目的地址不是组播地址时,才给包的源地址发送一个 ICMP "参数存在问题",编码 2 的报文,指针指向无法识别的选项类型。

选项类型标识符的第三位指明了选项数据是否可以改变到最终目的地址的选路。若存在认证首部,在包计算或校验认证值时,可改变选路的选项的整个数据字段都必须当作全零的八位组来处理。

0 - 选项数据不会改变选路
1 - 选项数据可能改变选路

上述的前三位应作为选项类型的一部分,而不能独立于选项类型之外。这就是说,某一特定的选项是由全部 8 位的选项类型标识符标识的,而并不只是选项类型中的后面 5 位。Hop-by-Hop 选项首部和目的地址选项首部使用相同的选项类型编码空间。尽管如此,某一特定类型的选项的规范可以限制其只用于两者之一。有些选项可能具有明确的对齐要求,以保证选项数据字段中的多八位组值能够落在其自然边界上。选项的对齐要求用符号 xn+y 来说明,表示选项类型必须出现在从首部开始位置处 x 个八位组的整数倍加上 y 个八位组的位置上。例如: 2n表示从首部开始处 2 个八位组的整数倍的偏移量。8n+2 表示从首部开始处 8 个八位组的整数倍加上 2 个八位组的偏移量。有两种填充选项,用来在需要时对齐后续的选项,以及把整个首部填充成 8 个八位组的整数倍长。所有的IPv6实现都必须能够识别这些填充选项。

填充1 选项 (对齐要求: 无)

填充1 选项是一种特殊情况 -- 它没有长度字段和数值字段。填充1 选项用于在首部的选项区填充一个八位组。如果需要填充多于一个的八位组,那么就应该使用下面要介绍的填充N 选项,而不是多个填充1 选项。

填充N 选项 (对齐要求: 无)

填充N 选项用于在首部的选项区填充两个或两个以上的八位组。对于 N 个八位组的填充,选项数据长度字段应包含值 N-2,选项数据由 N-2 个零值八位组组成。

4.3 Hop-by-Hop 选项首部

Hop-by-Hop 选项首部用于传送必须由包的传送路径中的每个节点检测的可选信息。Hop-by-Hop 选项首部由IPv6首部中"下一个首部"字段值为 0 来标识,并且具有如下的格式:

下一个首部

8 位选择器。标识紧跟在Hop-by-Hop 选项首部后面的首部的类型。使用与 IPv4 协议字段 相同的数值。

首部扩展长度

8 位无符号整数。以 8 个八位组为单位的 Hop-by-Hop选项首部的长度,不包括开始的 8 个八位组。

选项

可变长度字段,其长度须使整个 Hop-by-Hop 选项首部的长度为 8 个八位组的整数倍。包含一个或多个 TLV 编码的选项,如第 4.2 章中所述。

在本文中定义的仅有的 Hop-by-Hop 选项是填充1 及填充N 选项。

4.4 路由首部

路由首部用于IPv6源节点列出到包的目的节点的路径中所应"访问"的一个或多个中间节点。这一功能十分类似于 IPv4 的松散源地址和路由记录选项。前面的首部中"下一个首部"字段中的值为 43 表示下一个首部为路由首部。路由首部具有如下的格式:

下一个首部

8 位选择器。标识紧跟在路由首部后面的首部的类型。使用与 IPv4 协议字段相同的数值。

首部扩展长度

8 位无符号整数。以 8 个八位组为单位的路由首部的长度,不包括开始的 8 个八位组。

路由类型

8 位的某种特定路由首部变量的标识符。

分段剩余

8 位无符号整数。剩余的路由分段的数量。也就是在到达最终的目的节点之前仍然应当访问的,明确列出的中间节点的数量。

特定类型的数据

可变长度字段。其格式由路由类型决定,其长度须使整个路由首部的长度为 8 个八位组的整数倍。

如果节点在处理收到的包的过程中遇到了含有无法识别的路由类型值的路由首部,节点应根据分段剩余字段中的值进行处理,如下所述:如果分段剩余值是零,节点必须忽略路由首部,继续处理包中的下一个首部,其类型由路由首部中的"下一个首部"字段中的值来标识。如果分段剩余值非零,节点必须抛弃这个包,并且给包的源地址发送一个 ICMP"参数存在问题",编码 0 的报文,指针指向无法识别的路由类型。如果中间节点在处理路由首部之后,确定应将包传送到一个链路 MTU 小于此包的大小的链路中去,那么中间节点必须抛弃此包,并且给包的源地址发送一个 ICMP"包太大"的报文。

类型 0 的路由首部具有如下格式:

下一个首部

8 位选择器。标识紧跟在路由首部后面的首部的类型。使用与 IPv4 协议字段相同的数值。

首部扩展长度

8 位无符号整数。以 8 个八位组为单位的路由首部的长度,不包括开始的 8 个八位组。对于类型 0 的路由首部,首部扩展长度等于首部中地址数量的两倍。

路由类型

0

分段剩余

8 位无符号整数。剩余的路由分段的数量。也就是在到达最终的目的节点之前仍然应当访问的,明确列出的中间节点的数量。

保留

32 位保留字段。传输时初始化为零;接收时忽略。

地址[1..n]

128 位地址向量,从 1 到 n 编号。

不允许组播地址出现在类型 0 的路由首部中,也不允许出现在携带类型 0 路由首部的包中的IPv6目的地址字段中。直到包到达IPv6首部中的目的地址字段所标识的那个节点才对路由首部进行检测和处理。在这个节点调用路由首部处理模块,并且对于路由类型 0,执行下面的算法:

 

          if 分段剩余 = 0 {
             继续处理包中的下一个首部,其类型由路由首部中"下一个首部"字段所标识
          }
          else if 首部扩展长度为奇数 {
                给源地址发送一个 ICMP "参数存在问题",编码 0 的报文,指针指向首部扩展长度字段,并且抛弃此包
          }
          else {
             计算出n,也就是路由首部中的地址数量。方法是首部扩展长度除以 2
             if 分段剩余比 n 大 {
                给源地址发送一个 ICMP "参数存在问题",编码 0 的报文,指针指向分段剩余字段,并且抛弃此包
             }
             else {
                分段剩余减一;
                计算 i,也就是地址向量(地址列表)中要"访问"的下一个地址,方法是 n 减分段剩余
                if 地址[i] 或者IPv6目的地址是组播地址 {
                   抛弃此包
                }
                else {
                   交换IPv6目的地址和地址[i]
                   ifIPv6跳数限制小于等于 1 {
                      给源地址发送一个 ICMP "超时 - 传输超过跳数限制" 的报文,并且抛弃此包
                   }
                   else {
                   跳数限制减一;
                   向IPv6模块重新提交此包,传给新的目的节点
                   }
                }
             }
          }

作为上述算法的一个例子,考虑这样一种情况: 源节点 S 给目的节点 D 发送一个包,用路由首部来使这个包经过中间节点 I1,I2 和 I3。在传送路径的每段中, IPv6首部中的相关字段值以及路由首部字段值应为如下所述:

当包从 S 传到 I1:

源地址 = S

目的地址 = I1

首部扩展长度 = 6

分段剩余 = 3

地址[1] = I2

地址[2] = I3

地址[3] = D

当包从 I1 传到 I2:

源地址 = S

目的地址 = I2

首部扩展长度 = 6

分段剩余 = 2

地址[1] = I1

地址[2] = I3

地址[3] = D

当包从 I2 传到 I3:

源地址 = S

目的地址 = I3

首部扩展长度 = 6

分段剩余 = 1

地址[1] = I1

地址[2] = I2

地址[3] = D

当包从 I3 传到 D:

源地址 = S

目的地址 = D

首部扩展长度 = 6

分段剩余 = 0

地址[1] = I1

地址[2] = I2

地址[3] = I3

4.5 分片首部

IPv6源节点使用分片首部来发送大于去往目的节点的路径 MTU 的包。(注意: 不同于 IPv4 的是,在IPv6里,只有包的源节点才能进行分片,传输路径中的路由器不能进行分片 ?参见第 5 章) 前面的首部中"下一个首部"字段中的值为 44 表示下一个首部为分片首部。分片首部具有如下格式:

下一个首部

8 位选择器。标识原包(后面有定义)中可分片部分的初始首部的类型。使用与 IPv4 协议字段相同的数值。

保留

8 位保留字段。传输时初始化为零;接收时忽略。

分片偏移量

13 位无符号整数。以 8 个八位组为单位的,首部后面的数据相对于原包中可分片部分的开始位置处的偏移量。

Res (保留)

2 位保留字段。传输时初始化为零;接收时忽略。

M 标志位

1 = 还有分片;0 = 最后一个分片。

标识

32 位。参见下面的说明。

要发送大于去往目的节点的路径 MTU 的包,源节点可以将包分成若干分片,每个分片单独发送,并且在接收者处进行重组。源节点应为每个要分片的包规定一个标识值。这个标识值必须不同于近期之内,同一对源节点和目的节点之间其他的分片包的标识值。如果存在路由首部,那么目的节点是指最终目的节点。"近期之内" 是指包可能的最大生存期。其中包括从源节点到目的节点的传输时间,以及等待与同一包的其他分片重组所花费的时间。尽管如此,源节点并没有必要知道包的最大生存期。它只需将标识字段值作为一个简单的32 位循环计数器,每次将包分片时计数器增加一个增量即可。具体的实现可以自己选择是维护一个计数器还是多个计数器,还可以选择是为每个节点可能的源地址维护一个计数器,还是为每个活动的 (源地址,目的地址) 对维护一个计数器。最初的,未分片的大数据包称为"原包"。原包可以看作是由两部分组成的,如下所示:

原包:

不可分片部分包括IPv6首部,以及那些必须由路由中的节点处理的扩展首部。也就是以下三种情况: 所有路由首部以前(含路由首部)的首部(如果存在的话),或者是 Hop-by-Hop 选项首部(如果存在的话),或者没有扩展首部。包中其余的部分为可分片部分,也就是只需由包的最终目的节点处理的扩展首部,以及上层协议首部和数据。原包中可分片部分被划分成若干分片,除去最后("最右")一个分片,每个分片都为8 个八位组的整数倍长。这些分片由相互独立的"分片包"来传送,如下例所示:

原包:

分片包:

每个分片包由下述几部分构成:

(1) 原包中的不可分片部分。其中原来IPv6首部中有效数据长度值只应包含本分片包的长度 (不包含IPv6首部自身的长度)。不可分片部分中最后一个首部的"下一个首部"字段值改为 44。

(2) 分片首部。其中包括:其"下一个首部"值标识原包中可分片部分的第一个首部。其分片偏移量字段 包含以 8 个八位组为单位的,本分片相对于原包中可分片部分开始位置处的偏移量。第一个("最左")分片的分片偏移量为 0。其 M 标志位为 0 表示这是最后("最右")一个分片,否则 M 标志位为 1。其标识值依原包产生。

(3) 分片自身

分片的长度应使分片包的大小适于去往目的节点的路径 MTU。在目的节点,分片包重组为原来未分片的形式,如下例所示:

重组的原包:

重组应遵循如下原则:

原包只能由具有相同源地址,目的地址和分片标识的分片包重组。重组后的包中的不可分片部分由第一个分片包(也就是分片偏移量为 0 的那个包)中分片首部前面所有的首部(不含分片首部)组成,并作如下两处修改:从第一个分片的分片首部中的"下一个首部"字段得到不可分片部分最后一个首部中的"下一个首部"字段值。由不可分片部分的长度及最后一个分片的长度和偏移量计算出重组包的有效数据长度。计算重组包的有效数据长度的公式为:

PL.orig = PL.first - FL.first - 8 + (8 * FO.last) + FL.last

PL.orig = 重组包的有效数据长度字段。
PL.first = 第一个分片包的有效数据长度字段。
FL.first = 第一个分片包中分片首部后面的分片长度。
FO.last = 最后一个分片包中分片首部的分片偏移量字段。
FL.last = 最后一个分片包中分片首部后面的分片长度。

重组包的可分片部分由各分片包中分片首部后面的分片组成。各分片的长度可由分片包的有效数据长度减去此包中IPv6首部与分片之间所有首部的长度计算得到。各分片在可分片部分中的相对位置由其分片偏移量值计算得到。最终重组后的包不含分片首部。包的重组过程可能出现下列错误情形:

  • 如果收到包的第一个(到达的)分片之后 60 秒内没有收到全部分片以完成重组,那么必须终止这次重组,抛弃所有已收到的包。如果收到了第一个分片 (也就是分片偏移量为零的那个分片),应给分片的源节点发送一个 ICMP "超时 -- 分片重组超时"报文。
  • 如果由分片包的有效数据长度字段得到的分片长度不是 8 个八位组的整数倍,而且分片的 M 标志位被置为 1,那么必须抛弃这个分片,并且给分片的源节点发送一个 ICMP "参数存在问题",编码 0 的报文,指针指向分片包的有效数据长度字段。
  • 如果分片的长度和偏移量使得重组后的包的有效数据长度超过了 65,535 个八位组,那么必须抛弃这个分片,并且向分片的源节点发送一个 ICMP "参数存在问题",编码 0 的报文,指针指向分片包的分片偏移量字段。

不希望出现下述情形,但不将它们视为错误:

  • 同一个原包的不同分片中,分片首部前面的首部在数量和内容上都可能不同。
  • 当每个分片包到达时,无论分片首部前面的首部是什么,都应在进入分片重组队列之前进行处理。只有分片偏移量为零的那个包中的首部才保留在重组后的包中。
  • 同一个原包的不同分片中,分片首部中"下一个首部"值可能不同。只有分片偏移量为零的那个包中的值才可用于重组。

4.6 目的地址选项首部

目的地址选项首部用于携带只需由包的目的节点检测的可选信息。前面的首部中"下一个首部"字段中的值为 60 表示下一个首部为目的地址选项首部。目的地址选项首部具有如下格式:

下一个首部

8 位选择器。标识紧跟在目的地址选项首部后面的首部的类型。使用与 IPv4 协议字段相同的数值。

首部扩展长度

8 位无符号整数。以 8 个八位组为单位的目的地址选项首部的长度,不包括开始的 8 个八位组。

选项

可变长度字段,其长度须使整个目的地址选项首部的长度为 8 个八位组的整数倍。包含一个或多个 TLV 编码的选项,如第 4.2 章中所述。

在本文中定义的仅有的目的地址选项是填充1 及填充N 选项,如第 4.2 章中所述。需要注意的是,有两种途径来编码目的地址的可选信息: 或者作为目的地址选项首部中的一个选项,或者作为一个独立的扩展首部。分片首部和认证首部就是后者的典型例子。使用哪种方法取决于目的节点无法识别这一可选信息时,希望采取的措施:

o 如果希望节点抛弃这个包,并且当包的目的地址不是组播地址时,给包的源地址发送一个 ICMP "类型无法识别"报文,可以将这一信息编码成独立的扩展首部或者目的地址选项首部中的一个选项,其选项类型的最高两位为 11。最终的选择可以根据其他的因素而定,比如哪一个可以使用更少的八位组,哪一个能生成更好的对齐或者具有更高的处理效率。

o 如果希望采取其他的措施,那么这一信息必须作为目的地址选项首部的一个选项进行编码。其选项类型的最高两位为 00,01 或 10,指定所需采取的措施。

4.7 "无下一个首部"

IPv6首部或者扩展首部中"下一个首部"的值为 59 表示这个首部后面没有其他的首部了。如果IPv6首部中的有效数据字段表明最后一个首部 ("下一个首部"字段为 59 的那个首部) 后面还有其他的八位组,那么这些八位组将被忽略,并且在传输过程中保持不变。

5. 包的大小问题

IPv6要求互联网上的每条链路具有 1280 或更多个八位组的 MTU。无法在一片之内传送 1280 个八位组的链路必须根据链路的情况在IPv6下层的协议中提供分片和重组机制。具有可配置 MTU 的链路 (比如 PPP 链路 [RFC-1661]) 必须配置为具有至少 1280个八位组的 MTU;建议配置成具有 1500 或更多个八位组的 MTU,这样可以容纳可能的封装 (也就是"通道") 而不至于在IPv6协议层分片。与链路直接连接的节点必须能够接收链路 MTU 大小的包。建议IPv6节点使用 "路径 MTU 发现" 技术 [RFC-1981],以发现比 1280 个八位组更大的路径 MTU,并发挥其优点。但是,一个最小的IPv6实现 (比如,在启动 ROM 里) 可以简单的限制自己只发送小于 1280 个八位组的包,从而忽略 "路径 MTU 发现" 技术。要发送大于路径 MTU 的包,节点可以使用IPv6分片首部,在源节点将包分片,并在目的节点将包重组。但是,如果应用程序能够调整包的大小来适合标准的路径MTU,那么最好不要使用分片。节点必须能够接收重组后大小为 1500 个八位组的分片包。同时,允许节点接收重组后大于 1500 个八位组的分片包。基于IPv6分片来发送大于路径 MTU 的包的上层协议或应用程序不应发送大于 1500 个八位组的包,除非它确信目的节点能够重组这样大的包。

作为发往 IPv4 目的节点的IPv6包 (也就是从IPv6转换成 IPv4 的包) 的响应, IPv6的初始节点可能收到 ICMP "包太大"报文,报告下一跳 MTU 小于 1280。在这种情况下,IPv6节点不必将后续的包的大小减小到 1280 以下,但必须在这些包中包含一个分片首部,使得负责从IPv6到 IPv4 之间转换的路由器能够得到一个适当的标识值,用来生成 IPv4 分片。需要注意的是,这就意味着有效数据将减小到 1232 个八位组 ( 1280 减去IPv6首部的 40 和分片首部的 8),如果还有其他的扩展首部,有效数据将变得更小。

6。数据流标签

IPv6首部中 20 位的数据流标签字段用于源节点标识那些需要IPv6路由器特殊处理的包的序列,比如非缺省质量的服务或者"实时"服务。本文产生之时,IPv6在这方面尚处于实验阶段,并且随着因特网上支持数据流的要求变得越来越清楚,它还可能有所改变。不支持数据流标签字段功能的主机和路由器应在初始化数据包的时候将此字段设为零,传输包的时候保持不变,接收包的时候忽略。

7。传输类别

IPv6首部中 8 位的传输类别字段可用于初始节点和/或转寄路由器标识和区分不同IPv6包的类别或优先级。撰写本规范的时候,已经总结了在使用 IPv4 服务类型和/或优先级位 (用来为 IP 包提供不同形式的"区别服务",不同于显式的建立数据流) 的过程中的若干经验. IPv6首部中的传输类别字段在IPv6中提供了相似的功能。希望这些经验能够使得人们在哪种传输分类对 IP 包最为有用的问题上达成一致意见。对IPv6传输类别中全部或部分数据位的结构和语义的详细定义,或者是实验性的,或者是最终的标准,都将在另外的文章中提供。

下面是传输类别字段所应满足的总的要求:

o 节点中IPv6服务的服务接口必须为上层协议规定一种给初始包提供传输类别数据位的值的方法。

o 支持部分或全部传输类别数据位的某一特定 (实验性的或最终标准) 用法的节点可以根据其用法修改它们所生成的,传输的或者收到的包中的这些位的值。如果节点不支持这一用法,应忽略这些位,并保持其值不变。

o 上层协议不应假定所收到的包中传输类别数据位的值与源节点发送此包时的值相同。

8. 上层协议的问题

8.1 上层协议校验和

在计算校验和时包含 IP 首部中地址的传输层或其他上层协议必须为通过IPv6进

行传输加以相应的改进,将 32 位的 IPv4 地址改为 128 位的IPv6地址。特别

地,下面的例子展示了 TCP 和 UDP 的IPv6"伪首部":

o 如果IPv6包包含路由首部,伪首部使用的目的地址就是最终的目的地址。在初始节点,这一地址就是路由首部的最后一个元素;在接收者一方,这一地址在IPv6首部的目的地址字段。

o 伪首部中"下一个首部"字段值标识了上层协议的类型 (比如 6 为 TCP,17为 UDP)。如果IPv6首部和上层协议首部之间还存在扩展首部,那么伪首部中"下一个首部"字段的值可能与IPv6首部中的值有所不同。

o 伪首部中上层协议包的长度是指上层协议的首部和数据 (比如,TCP 首部加上 TCP 数据)。一些上层协议携带了自己的长度信息 (比如,UDP 首部中的长度字段);对于这样的协议,这些信息就是伪首部使用的长度信息。其他协议 (比如 TCP) 不携带自己的长度信息,在这种情况下,伪首部使用的长度就是IPv6首部中的有效数据长度字段值减去IPv6首部与上层协议首部之间扩展首部的长度。

o 与 IPv4 不同的是,当IPv6节点生成 UDP 包时,UDP 校验和不是可选的。也就是说,只要生成 UDP 包,IPv6节点必须计算数据包和伪首部的 UDP 校验和。而且,如果计算结果为 0,必须将其改为十六进制的 FFFF,放入 UDP首部. IPv6接收节点必须抛弃包含零校验和的 UDP 包,并记录这一错误。

IPv6版本的 ICMP在计算校验和时包含上述的伪首部;这是一个与 IPv4的版本不同的地方 -- IPv4 的版本在校验和中不包含伪首部。改变的原因是防止ICMP 发生不正确的传送,以及IPv6首部中的这些字段发生讹误 -- 它们没有受到网络层校验和的保护。ICMP 的伪首部中"下一个首部"字段的值为 58,标识IPv6版本的 ICMP。

8.2 包的最大生存期

与 IPv4 不同的是,IPv6节点不必强制规定一个包的最大生存期。这就是 IPv4 中的"生存期"字段在IPv6中改名为"跳数限制"的原因。在实际中,IPv4 实现很少强制要求限制包的生存期,所以这一点实际上并没有改变。任何依赖网络层协议 (IPv4 或 IPv6) 来限制包的生存期的上层协议必须进行升级,自己提供检测和抛弃过期的数据包的机制。

8.3 上层协议的最大有效数据大小

当计算可提供给上层协议数据的最大有效数据大小的时候,上层协议必须考虑到IPv6首部比 IPv4 首部大。例如,在 IPv4 里,TCP 的 MSS 选项是包的最大尺寸 (缺省值或者由路径 MTU 发现技术提供的值) 减去 40 个八位组 (IPv4 首部的最小长度 20 和 TCP 首部的最小长度 20)。当通过IPv6使用 TCP 时,MSS 必须改为包的最大大小减去 60 个八位组,这是因为IPv6首部的最小长度 (也就是没有任何扩展首部的IPv6首部) 比 IPv4 首部的最小长度长 20 个八位组。

8.4 对携带路由首部的包的响应

当上层协议发送一个或多个包,作为包含路由首部的包的响应时,响应包中不能包含由所收到的路由首部"反向"而自动得到的路由首部。除非收到的源地址和路由首部的完整性和可靠性已得到验证 (比如通过使用收到的包中的认证首部)。换句话说,只有下面几类包可以响应由路由首部定向的包:

o 不携带路由首部的响应包。

o 携带路由首部的响应包,但其携带的路由首部不是由所收到的包中的路由首部反向得到的 (例如,由本地配置信息提供的路由首部)

o 携带路由首部的响应包,其路由首部是由所收到的包中的路由首部反向而得到的。但所收到的包中的源地址和路由首部的完整性和可靠性必须经过响应者验证。

附录 A. 数据流标签字段的语义和用法

数据流是指从某特定的源节点向某特定的 (单播或组播) 目的节点发送的数据包的序列。当源节点希望中间的路由器对数据包进行一些特殊处理时,可以使用数据流。这一特殊处理的种类可以由某一控制协议,如资源预约协议,或者由数据流中的包自身中的信息,如在 hop-by-hop 选项首部里的选项,传达给路由器。关于这样的控制协议或者选项的详细资料已经超出了本文的范围。从源节点到目的节点之间可能有数条活动的数据流,还可能有同任何数据流都无关的业务量。一个数据流由一个源地址和一个非零的数据流标签唯一地标识。不属于任何一个数据流的包具有零值的数据流标签。由数据流的源节点为数据流分配数据流标签。新的数据流标签必须从 1 到 FFFF(十六进制) 之间伪随机地选出来。随机分配数据流标签的目的是使得路由器能够使用数据流标签字段中的任意一组位作为哈希关键字,用来查询与数据流相关的状态。属于同一数据流的包必须具有相同的源地址,目的地址和数据流标签。如果其中的一些包包含 Hop-by-Hop 选项首部,那么它们都必须具有相同内容的 Hop-by-Hop选项首部 (除了 Hop-by-Hop 选项首部中的"下一个首部"字段)。如果其中的一些包包含路由首部,那么它们在路由首部之前 (含路由首部) 的所有扩展首部的内容都必须相同 (除了路由首部中的"下一个首部"字段)。允许但不要求路由器或目的节点检验上述条件是否满足。如果检测到违反上述条件,应向源节点发送 ICMP"参数存在问题",编码 0 的报文,指针指向数据流标签字段的高位 (也就是,在IPv6包中偏移量为 1)。在数据流的路径中建立的数据流处理状态的最大生存期必须作为描述状态建立机制的一部分加以规范。比如资源预约协议,或者"数据流建立" hop-by-hop 选项。使用一个数据流标签以后,不允许源节点在这个已建立的数据流处理状态的最大生存期内重新使用这个数据流标签。当节点停机和重新启动(比如系统崩溃)时,它必须小心,不要使用先前用过的可能尚未过期的数据流的数据流标签。有多种解决方法: 可以在稳定可靠的存储器中记录数据流标签的使用情况,这样节点就能在系统崩溃前后记住它。或者在所有先前建立的数据流过期以前,避免使用任何数据流。如果知道系统重新启动的最短时间,这一时间可从开始分配数据流标签之前的等待时间中扣除。不要求全部的包,甚或大多数的包处于数据流中 (也就是,携带非零的数据流标签)。这一观察报告放在这里,提醒协议的设计者和实现者不要对此做出任何假定。例如,设计一个这样的路由器是不明智的,其性能只有在大多数包处于数据流中的时候才差强人意。再如,设计一个只用于数据流中的包的首部压缩方案也是欠考虑的。

附录 B. 选项字段格式的指导方针

本附录对设计用于 Hop-by-Hop 选项首部和目的地址选项首部 (见第 4.2 章) 的新选项时如何安排字段提出了一些建议。这些原则以如下假设为基础:

o 选项的数据区中任意多八位组字段应放在其自然边界上. 也就是说,长度为n 个八位组的字段应放在距 Hop-by-Hop 选项首部和目的地址选项首部的开始位置处 n 个八位组的整数倍的位置上,其中 n = 1,2,4,或 8。

o Hop-by-Hop 选项首部和目的地址选项首部应使用尽量少的空间。但必须满足,整个首部的长度应为 8 个八位组的整数倍。

o 不妨假定携带选项的首部即使存在,也只携带非常少的选项,通常只有一个。

由这些假设可以设计出如下安排选项中字段的方法: 以由小到大的顺序排列字段,其间没有内部填充,然后由最大字段的对齐要求得到整个选项的对齐要求 (最大到8 个八位组的对齐)。下面的例子说明了这一方法:

例1:如果选项 X 需要两个数据字段,一个为 8 个八位组,一个为 4 个八位组,这些字段应如下排列:

这一选项的对齐要求为 8n+2,保证 8 八位组字段从距所在的首部开始位置处 8 个八位组的整数倍处开始。包含此选项的完整的 Hop-by-Hop 选项首部或目的地址选项首部看上去应是下面的样子:

例2:如果选项 Y 需要三个数据字段,一个为 4 个八位组,一个为 2 个八位组,一个为 1 个八位组,这些字段应如下排列:

这一选项的对齐要求为 4n+3,保证 4 八位组字段从距所在的首部开始位置处 4 个八位组的整数倍处开始。包含此选项的完

你可能感兴趣的:(IPv6协议规范(中文版))