目录
1. 绪论..........................................................2
2. 术语..........................................................3
3. IPv6 首部格式.................................................4
4. IPv6 扩展首部.................................................6
4.1 扩展首部的顺序...........................................7
4.2 选项.....................................................9
4.3 Hop-by-Hop 选项首部.....................................11
4.4 路由首部................................................12
4.5 分片首部................................................18
4.6 目的地址选项首部........................................23
4.7 "无下一个首部"..........................................24
5. 包的尺寸问题.................................................24
6. 数据流标签. .................................................25
7. 传输类别.....................................................25
8. 上层协议问题.................................................27
8.1 上层协议校验和..........................................27
8.2 包的最大生存期..........................................28
8.3 上层协议的最大有效载荷尺寸..............................28
8.4 对携带路由首部的包的响应................................29
附录 A. 数据流标签字段的语义和用法..............................30
附录 B. 选项字段格式的几点指导方针..............................32
安全性的考虑................................................... 35
致谢............................................................35
作者的地址......................................................35
参考文献........................................................35
自 RFC-1883 以来的变化..........................................36
完整的版权声明..................................................39
1. 绪论
IP 第 6 版 (IPv6) 是继 IP 第 4 版 (IPv4) [RFC-791] 以后, Internet 协议的
一个新版本. 由 IPv4 到 IPv6 的改变主要集中在以下几个方面:
o 地址容量的扩展
IPv6 把 IP 地址的大小从 32 位增至 128 位, 可以支持更多的地址层次, 更
大数量的节点, 以及更简单的地址自动配置. 组播路由的可缩放性改进为
给组播地址增加一个"范围"字段. 又定义了一个叫做"anycast"的新的地址
类型, 用于把包发送给一组节点中的任意一个.
o 首部格式的简化
一些 IPv4 首部字段被删除或者成为可选字段, 减少了一般情况下包的处理
开销以及 IPv6 首部占用的带宽.
o 支持扩展和选项的改进
IP 首部选项编码方式的修改导致更加高效的传输, 在选项长度方面更少的
限制, 以及将来引入新的选项时更强的适应性.
o 数据流标签的能力
加入一个新的能力, 使得那些发送者要求特殊处理的属于特别的传输"流"的
包能够贴上"标签", 比如非缺省质量的服务或者"实时"服务.
o 认证和保密的能力
为支持认证, 数据完整性以及(可选的)数据保密的扩展都在 IPv6 中说明.
本文描述 IPv6 基本首部以及最初定义的 IPv6 扩展首部和选项. 还将讨论包的
尺寸问题, 数据流标签和传输类别的语法, 以及 IPv6 对上层协议的影响. IPv6 地
址的格式和语法在 [ADDRARCH] 中单独说明. IPv6 版的 ICMP 是所有 IPv6 应用
都需要包含的, 它在 [ICMPv6] 中说明.
2. 术语
节点 - 应用 IPv6 的一个设备.
路由器 - 传送不是发给自己的 IPv6 包的节点. [参见下面的说明]
主机 - 任何非路由器节点. [参见下面的说明]
上层 - 直接在 IPv6 上层的协议层. 典型的例子是传输协议如 TCP 和
UDP,
控制协议如 ICMP, 路由协议如 OSPF, 以及网络层或在 IPv6 里被
开凿了隧道 (也就是封装在 IPv6 里) 的低层协议, 比如 IPX,
AppleTalk, 或者 IPv6 自身.
链路 - 一个通讯设备或者媒体. 通过它节点可以与链路层, 也就是直接
在 IPv6 下面的那一层进行通讯. 典型的例子是以太网 (简单的
或者网桥的); PPP 连接; X.25帧中继, 或者 ATM 网络; 以及网络
层(或更高层)的"隧道". 比如说通过 IPv4 或者 IPv6 本身的隧
道.
邻居 - 连在同一个链路上的节点.
接口 - 节点与链路的连接.
地址 - IPv6 层中一个接口或者一组接口的标识符.
包 - IPv6 首部加上有效载荷.
链路 MTU - 最大传输单元. 也就是以八位组为单位的能在链路中传输的包的
最大尺寸.
路径 MTU - 源节点到目的节点之间的路径中所有链路的最小链路 MTU.
注意: 尽管不常见, 但这是可能的: 就是一个设备具有多个接口, 用来传输从它的
某些(不是全部)接口传来的, 不以自身为目的节点的包, 并且抛弃那些从其他接口
传来的, 不以自身为目的节点的包. 当这样的设备通过前一种接口接收包或者与
其邻居联系时, 它必须遵循协议中有关路由器的要求. 当它通过后一种接口接收
包或者与其邻居联系时, 它必须遵循协议中有关宿主机的要求.
3. IPv6 首部格式
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 版本 | 传输类别 | 数据流标签 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 有效载荷长度 | 下一个首部 | 跳数限制 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ +
| |
+ 源 地 址 +
| |
+ +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ +
| |
+ 目 的 地 址 +
| |
+ +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
版本 4 比特 Internet 协议版本号 = 6.
传输类别 8 比特传输类别字段. 参见第 7 章.
数据流标签 20 比特数据流标签. 参见第 6 章.
有效载荷长度 16 比特无符号整数. IPv6 有效载荷长度. 也就是以八
位组为单位, 在这个包中 IPv6 首部后面的其余部分的长
度. (注意, 扩展首部 [第 4 章] 将被认为是有效载荷的
一部分, 计算在长度里.)
下一个首部 8 比特选择器. 标识紧接在 IPv6 首部后面的下一个首部
的类型. 使用与 IPv4 协议字段 [RFC-1700 及后续协议]
相同的数值.
跳数限制 8 比特无符号整数. 在每个传输此包的节点处递减1. 如
果跳数限制减为零, 就抛弃此包.
源地址 128 比特包的制作者的地址. 参见 [ADDRARCH]
目的地址 128 比特包的预期接收者的地址 (如果存在路由首部的话,
可能不是最终的接收者). 参见 [ADDRARCH] 和第 4.4 章.
4. IPv6 扩展首部
在 IPv6 里, 可选的网络层信息在一个独立的首部编码, 放在包中 IPv6 首部与上
层协议首部之间. 有这样几个为数不多的扩展首部, 每个首部由不同的"下一个首
部"的值来标识. 一个 IPv6 首部可以携带零个, 一个或者更多的扩展首部, 每个
扩展首部由前一个首部中的"下一个首部"字段标识. 如下例所示:
+---------------+------------------------
| IPv6 首部 | TCP 首部 + 数据
| |
| 下一个首部 = |
| TCP |
+---------------+------------------------
| IPv6 首部 | 路由首部 | TCP 首部 + 数据
| | |
| 下一个首部 = | 下一个首部 = |
| 路由首部 | TCP |
+---------------+----------------+------------------------
+---------------+----------------+-----------------+-----------------
| IPv6 首部 | 路由首部 | 分片首部 | TCP 首部 + 数据
| | | | 的分片
| 下一个首部 = | 下一个首部 = | 下一个首部 = |
| 路由首部 | 分片首部 | TCP |
+---------------+----------------+-----------------+-----------------
除了一个特例, 扩展首部不在包的传送路径中的任何节点检测和处理, 直到这个包
到达目的地址字段标识的那个节点 (或者在组播的情况下, 一组节点中的每一个).
在这里, 对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)
分片首部
RFC 2460 IPv6 Specification December 1998
上文所述的特例是指 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 首部)
前四个将在本文中加以说明, 后两个在 [RFC-2402] 和 [RFC-2406] 中分别进行说
明.
4.1 扩展首部的顺序
当在同一个包中使用多于一个扩展首部时, 建议以如下顺序排列这些首部:
IPv6 首部
Hop-by-Hop 选项首部
目的地址选项首部 (注 1)
路由首部
分片首部
认证首部 (注 2)
封装安全有效载荷首部 (注 2)
目的地址选项首部 (注 3)
上层协议首部
注 1: 由 IPv6 目的地址字段及路由首部列出的后续地址中第一个出现
的目的地址处理的选项.
注 2: 关于认证首部和封装安全有效载荷首部的相关顺序的附加建议参
见 [RFC-2406].
注 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 选项 (对齐要求: 无)
+-+-+-+-+-+-+-+-+
| 0 |
+-+-+-+-+-+-+-+-+
注意! 填充1 选项是一种特殊情况 -- 它没有长度字段和数值字段.
填充1 选项用于在首部的选项区填充一个八位组. 如果需要填充多于一个的八
位组, 那么就应该使用下面要介绍的填充N 选项, 而不是多个填充1 选项.
填充N 选项 (对齐要求: 无)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - -
| 1 | 选项数据长度 | 选项数据
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - -
填充N 选项用于在首部的选项区填充两个或两个以上的八位组. 对于 N 个八
位组的填充, 选项数据长度字段应包含值 N-2, 选项数据由 N-2 个零值八位组
组成.
附录 B 包含了设计新的选项格式的指导方针.
4.3 Hop-by-Hop 选项首部
Hop-by-Hop 选项首部用于传送必须由包的传送路径中的每个节点检测的可选信息.
Hop-by-Hop 选项首部由 IPv6 首部中"下一个首部"字段值为 0 来标识, 并且具有
如下的格式:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 下一个首部 | 首部扩展长度 | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
| |
. .
. 选 项 .
. .
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
下一个首部 8 比特选择器. 标识紧跟在 Hop-by-Hop 选项首部后面的
首部的类型. 使用与 IPv4 协议字段 [RFC-1700 及后续
协议] 相同的数值.
首部扩展长度 8 比特无符号整数. 以 8 个八位组为单位的 Hop-by-Hop
选项首部的长度, 不包括开始的 8 个八位组.
选项 可变长度字段, 其长度须使整个 Hop-by-Hop 选项首部的
长度为 8 个八位组的整数倍. 包含一个或多个 TLV 编码
的选项, 如第 4.2 章中所述.
在本文中定义的仅有的 Hop-by-Hop 选项是填充1 及填充N 选项, 如第 4.2 章中
所述.
4.4 路由首部
路由首部用于 IPv6 源节点列出到包的目的节点的路径中所应"访问"的一个或多个
中间节点. 这一功能十分类似于 IPv4 的松散源地址和路由记录选项. 前面的首
部中"下一个首部"字段中的值为 43 表示下一个首部为路由首部. 路由首部具有
如下的格式:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 下一个首部 | 首部扩展长度 | 路由类型 | 分段剩余 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
. .
. 特定类型的数据 .
. .
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
下一个首部 8 比特选择器. 标识紧跟在路由首部后面的首部的类型.
使用与 IPv4 协议字段 [RFC-1700 及后续协议] 相同的数
值.
首部扩展长度 8 比特无符号整数. 以 8 个宋蛔槲ノ坏穆酚墒撞康? 长度, 不包括开始的 8 个八位组.
路由类型 8 比特的某种特定路由首部变量的标识符.
分段剩余 8 比特无符号整数. 剩余的路由分段的数量. 也就是在
到达最终的目的节点之前仍然应当访问的, 明确列出的中
间节点的数量.
特定类型的数据 可变长度字段. 其格式由路由类型决定, 其长度须使整个
路由首部的长度为 8 个八位组的整数倍.
如果节点在处理收到的包的过程中遇到了含有无法识别的路由类型值的路由首部,
节点应根据分段剩余字段中的值进行处理, 如下所述:
如果分段剩余值是零, 节点必须忽略路由首部, 继续处理包中的下一个首部, 其
类型由路由首部中的"下一个首部"字段中的值来标识.
如果分段剩余值非零, 节点必须抛弃这个包, 并且给包的源地址发送一个 ICMP
"参数存在问题", 编码 0 的报文, 指针指向无法识别的路由类型.
如果中间节点在处理路由首部之后, 确定应将包传送到一个链路 MTU 小于此包的
尺寸的链路中去, 那么中间节点必须抛弃此包, 并且给包的源地址发送一个 ICMP
"包太大"的报文.
类型 0 的路由首部具有如下格式:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 下一个首部 | 首部扩展长度 | 路由类型 = 0 | 分段剩余 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 保 留 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ +
| |
+ 地 址 [1] +
| |
+ +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ +
| |
+ 地 址 [2] +
| |
+ +
| |
+ +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
. . .
. . .
. . .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ +
| |
+ 地 址 [n] +
| |
+ +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
下一个首部 8 比特选择器. 标识紧跟在路由首部后面的首部的类型.
使用与 IPv4 协议字段 [RFC-1700 及后续协议] 相同的数
值.
首部扩展长度 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]
if IPv6 跳数限制小于等于 1 {
给源地址发送一个 ICMP "超时 – 传输超过跳数限制" 的报文, 并且
抛弃此包
}
else {
跳数限制减一;
向 IPv6 模块重新提交此包, 传给新的目的节点
}
}
}
}
作为上述算法的一个例子, 考虑这样一种情况: 源节点 S 给目的节点 D 发送一个
包, 用路由首部来使这个包经过中间节点 I1, I2 和 I3. 在传送路径的每段中,
IPv6 首部中的相关字段值以及路由首部字段值应为如下所述:
当包从 S 传到 I1:
源地址 = S 首部扩展长度 = 6
目的地址 = I1 分段剩余 = 3
地址[1] = I2
地址[2] = I3
地址[3] = D
当包从 I1 传到 I2:
源地址 = S 首部扩展长度 = 6
目的地址 = I2 分段剩余 = 2
地址[1] = I1
地址[2] = I3
地址[3] = D
当包从 I2 传到 I3:
源地址 = S 首部扩展长度 = 6
目的地址 = I3 分段剩余 = 1
地址[1] = I1
地址[2] = I2
地址[3] = D
当包从 I3 传到 D:
源地址 = S 首部扩展长度 = 6
目的地址 = D 分段剩余 = 0
地址[1] = I1
地址[2] = I2
地址[3] = I3
4.5 分片首部
IPv6 源节点使用分片首部来发送大于去往目的节点的路径 MTU 的包. (注意: 不
同于 IPv4 的是, 在 IPv6 里, 只有包的源节点才能进行分片, 传输路径中的路由
器不能进行分片 – 参见第 5 章) 前面的首部中"下一个首部"字段中的值为 44 表
示下一个首部为分片首部. 分片首部具有如下格式:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 下一个首部 | 保 留 | 分片偏移量 |Res|M|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 标 识 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
下一个首部 8 比特选择器. 标识原包(后面有定义)中可分片部分的初
始首部的类型. 使用与 IPv4 协议字段 [RFC-1700 及后
续协议] 相同的数值.
保留 8 比特保留字段. 传输时初始化为零; 接收时忽略.
分片偏移量 13 比特无符号整数. 以 8 个八位组为单位的, 首部后面
的数据相对于原包中可分片部分的开始位置处的偏移量.
Res (保留) 2 比特保留字段. 传输时初始化为零; 接收时忽略.
M 标志位 1 = 还有分片; 0 = 最后一个分片.
标识 32 比特. 参见下面的详细说明.
要发送大于去往目的节点的路径 MTU 的包, 源节点可以将包分成若干分片, 每个
分片单独发送, 并且在接收者处进行重组.
源节点应为每个要分片的包规定一个标识值. 这个标识值必须不同于近期之内*同
一对源节点和目的节点之间其他的分片包的标识值. 如果存在路由首部, 那么目
的节点是指最终目的节点.
* "近期之内" 是指包可能的最大生存期. 其中包括从源节点到目的节点的传
输时间, 以及等待与同一包的其他分片重组所花费的时间. 尽管如此, 源节
点并没有必要知道包的最大生存期. 它只需将标识字段值作为一个简单的
32 比特循环计数器, 每次将包分片时计数器增加一个增量即可. 具体的实
现可以自己选择是维护一个计数器还是多个计数器, 还可以选择是为每个节
点可能的源地址维护一个计数器, 还是为每个活动的 (源地址, 目的地址) 对
维护一个计数器.
最初的, 未分片的大数据包称为"原包". 原包可以看作是由两部分组成的, 如下
所示:
原包:
+------------------+----------------------//-----------------------+
| 不可分片 | 可分片 |
| 部分 | 部分 |
+------------------+----------------------//-----------------------+
不可分片部分包括 IPv6 首部, 以及那些必须由路由中的节点处理的扩展首部.
也就是以下三种情况: 所有路由首部以前(含路由首部)的首部(如果存在的话),
或者是 Hop-by-Hop 选项首部(如果存在的话), 或者没有扩展首部.
包中其余的部分为可分片部分, 也就是只需由包的最终目的节点处理的扩展首
部, 以及上层协议首部和数据.
原包中可分片部分被划分成若干分片, 除去最后("最右")一个分片, 每个分片都为
8 个八位组的整数倍长. 这些分片由相互独立的"分片包"来传送, 如下例所示:
原包:
+------------------+--------------+--------------+--//--+----------+
| 不可分片 | 第一个 | 第二个 | | 最后一个 |
| 部分 | 分片 | 分片 | .... | 分片 |
+------------------+--------------+--------------+--//--+----------+
分片包:
+------------------+--------+--------------+
| 不可分片 | 分片 | 第一个 |
| 部分 | 首部 | 分片 |
+------------------+--------+--------------+
+------------------+--------+--------------+
| 不可分片 | 分片 | 第二个 |
| 部分 | 首部 | 分片 |
+------------------+--------+--------------+
o
o
o
+------------------+--------+--------------+
| 不可分片 | 分片 | 最后一个 |
| 部分 | 首部 | 分片 |
+------------------+--------+--------------+
每个分片包由下述几部分构成:
(1) 原包中的不可分片部分. 其中原来 IPv6 首部中有效载荷长度值只应包含
本分片包的长度 (不包含 IPv6 首部自身的长度). 不可分片部分中最后
一个首部的"下一个首部"字段值改为 44.
(2) 分片首部. 其中包括:
1. 绪论..........................................................2
2. 术语..........................................................3
3. IPv6 首部格式.................................................4
4. IPv6 扩展首部.................................................6
4.1 扩展首部的顺序...........................................7
4.2 选项.....................................................9
4.3 Hop-by-Hop 选项首部.....................................11
4.4 路由首部................................................12
4.5 分片首部................................................18
4.6 目的地址选项首部........................................23
4.7 "无下一个首部"..........................................24
5. 包的尺寸问题.................................................24
6. 数据流标签. .................................................25
7. 传输类别.....................................................25
8. 上层协议问题.................................................27
8.1 上层协议校验和..........................................27
8.2 包的最大生存期..........................................28
8.3 上层协议的最大有效载荷尺寸..............................28
8.4 对携带路由首部的包的响应................................29
附录 A. 数据流标签字段的语义和用法..............................30
附录 B. 选项字段格式的几点指导方针..............................32
安全性的考虑................................................... 35
致谢............................................................35
作者的地址......................................................35
参考文献........................................................35
自 RFC-1883 以来的变化..........................................36
完整的版权声明..................................................39
1. 绪论
IP 第 6 版 (IPv6) 是继 IP 第 4 版 (IPv4) [RFC-791] 以后, Internet 协议的
一个新版本. 由 IPv4 到 IPv6 的改变主要集中在以下几个方面:
o 地址容量的扩展
IPv6 把 IP 地址的大小从 32 位增至 128 位, 可以支持更多的地址层次, 更
大数量的节点, 以及更简单的地址自动配置. 组播路由的可缩放性改进为
给组播地址增加一个"范围"字段. 又定义了一个叫做"anycast"的新的地址
类型, 用于把包发送给一组节点中的任意一个.
o 首部格式的简化
一些 IPv4 首部字段被删除或者成为可选字段, 减少了一般情况下包的处理
开销以及 IPv6 首部占用的带宽.
o 支持扩展和选项的改进
IP 首部选项编码方式的修改导致更加高效的传输, 在选项长度方面更少的
限制, 以及将来引入新的选项时更强的适应性.
o 数据流标签的能力
加入一个新的能力, 使得那些发送者要求特殊处理的属于特别的传输"流"的
包能够贴上"标签", 比如非缺省质量的服务或者"实时"服务.
o 认证和保密的能力
为支持认证, 数据完整性以及(可选的)数据保密的扩展都在 IPv6 中说明.
本文描述 IPv6 基本首部以及最初定义的 IPv6 扩展首部和选项. 还将讨论包的
尺寸问题, 数据流标签和传输类别的语法, 以及 IPv6 对上层协议的影响. IPv6 地
址的格式和语法在 [ADDRARCH] 中单独说明. IPv6 版的 ICMP 是所有 IPv6 应用
都需要包含的, 它在 [ICMPv6] 中说明.
2. 术语
节点 - 应用 IPv6 的一个设备.
路由器 - 传送不是发给自己的 IPv6 包的节点. [参见下面的说明]
主机 - 任何非路由器节点. [参见下面的说明]
上层 - 直接在 IPv6 上层的协议层. 典型的例子是传输协议如 TCP 和
UDP,
控制协议如 ICMP, 路由协议如 OSPF, 以及网络层或在 IPv6 里被
开凿了隧道 (也就是封装在 IPv6 里) 的低层协议, 比如 IPX,
AppleTalk, 或者 IPv6 自身.
链路 - 一个通讯设备或者媒体. 通过它节点可以与链路层, 也就是直接
在 IPv6 下面的那一层进行通讯. 典型的例子是以太网 (简单的
或者网桥的); PPP 连接; X.25帧中继, 或者 ATM 网络; 以及网络
层(或更高层)的"隧道". 比如说通过 IPv4 或者 IPv6 本身的隧
道.
邻居 - 连在同一个链路上的节点.
接口 - 节点与链路的连接.
地址 - IPv6 层中一个接口或者一组接口的标识符.
包 - IPv6 首部加上有效载荷.
链路 MTU - 最大传输单元. 也就是以八位组为单位的能在链路中传输的包的
最大尺寸.
路径 MTU - 源节点到目的节点之间的路径中所有链路的最小链路 MTU.
注意: 尽管不常见, 但这是可能的: 就是一个设备具有多个接口, 用来传输从它的
某些(不是全部)接口传来的, 不以自身为目的节点的包, 并且抛弃那些从其他接口
传来的, 不以自身为目的节点的包. 当这样的设备通过前一种接口接收包或者与
其邻居联系时, 它必须遵循协议中有关路由器的要求. 当它通过后一种接口接收
包或者与其邻居联系时, 它必须遵循协议中有关宿主机的要求.
3. IPv6 首部格式
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 版本 | 传输类别 | 数据流标签 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 有效载荷长度 | 下一个首部 | 跳数限制 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ +
| |
+ 源 地 址 +
| |
+ +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ +
| |
+ 目 的 地 址 +
| |
+ +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
版本 4 比特 Internet 协议版本号 = 6.
传输类别 8 比特传输类别字段. 参见第 7 章.
数据流标签 20 比特数据流标签. 参见第 6 章.
有效载荷长度 16 比特无符号整数. IPv6 有效载荷长度. 也就是以八
位组为单位, 在这个包中 IPv6 首部后面的其余部分的长
度. (注意, 扩展首部 [第 4 章] 将被认为是有效载荷的
一部分, 计算在长度里.)
下一个首部 8 比特选择器. 标识紧接在 IPv6 首部后面的下一个首部
的类型. 使用与 IPv4 协议字段 [RFC-1700 及后续协议]
相同的数值.
跳数限制 8 比特无符号整数. 在每个传输此包的节点处递减1. 如
果跳数限制减为零, 就抛弃此包.
源地址 128 比特包的制作者的地址. 参见 [ADDRARCH]
目的地址 128 比特包的预期接收者的地址 (如果存在路由首部的话,
可能不是最终的接收者). 参见 [ADDRARCH] 和第 4.4 章.
4. IPv6 扩展首部
在 IPv6 里, 可选的网络层信息在一个独立的首部编码, 放在包中 IPv6 首部与上
层协议首部之间. 有这样几个为数不多的扩展首部, 每个首部由不同的"下一个首
部"的值来标识. 一个 IPv6 首部可以携带零个, 一个或者更多的扩展首部, 每个
扩展首部由前一个首部中的"下一个首部"字段标识. 如下例所示:
+---------------+------------------------
| IPv6 首部 | TCP 首部 + 数据
| |
| 下一个首部 = |
| TCP |
+---------------+------------------------
| IPv6 首部 | 路由首部 | TCP 首部 + 数据
| | |
| 下一个首部 = | 下一个首部 = |
| 路由首部 | TCP |
+---------------+----------------+------------------------
+---------------+----------------+-----------------+-----------------
| IPv6 首部 | 路由首部 | 分片首部 | TCP 首部 + 数据
| | | | 的分片
| 下一个首部 = | 下一个首部 = | 下一个首部 = |
| 路由首部 | 分片首部 | TCP |
+---------------+----------------+-----------------+-----------------
除了一个特例, 扩展首部不在包的传送路径中的任何节点检测和处理, 直到这个包
到达目的地址字段标识的那个节点 (或者在组播的情况下, 一组节点中的每一个).
在这里, 对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)
分片首部
RFC 2460 IPv6 Specification December 1998
上文所述的特例是指 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 首部)
前四个将在本文中加以说明, 后两个在 [RFC-2402] 和 [RFC-2406] 中分别进行说
明.
4.1 扩展首部的顺序
当在同一个包中使用多于一个扩展首部时, 建议以如下顺序排列这些首部:
IPv6 首部
Hop-by-Hop 选项首部
目的地址选项首部 (注 1)
路由首部
分片首部
认证首部 (注 2)
封装安全有效载荷首部 (注 2)
目的地址选项首部 (注 3)
上层协议首部
注 1: 由 IPv6 目的地址字段及路由首部列出的后续地址中第一个出现
的目的地址处理的选项.
注 2: 关于认证首部和封装安全有效载荷首部的相关顺序的附加建议参
见 [RFC-2406].
注 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 选项 (对齐要求: 无)
+-+-+-+-+-+-+-+-+
| 0 |
+-+-+-+-+-+-+-+-+
注意! 填充1 选项是一种特殊情况 -- 它没有长度字段和数值字段.
填充1 选项用于在首部的选项区填充一个八位组. 如果需要填充多于一个的八
位组, 那么就应该使用下面要介绍的填充N 选项, 而不是多个填充1 选项.
填充N 选项 (对齐要求: 无)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - -
| 1 | 选项数据长度 | 选项数据
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - -
填充N 选项用于在首部的选项区填充两个或两个以上的八位组. 对于 N 个八
位组的填充, 选项数据长度字段应包含值 N-2, 选项数据由 N-2 个零值八位组
组成.
附录 B 包含了设计新的选项格式的指导方针.
4.3 Hop-by-Hop 选项首部
Hop-by-Hop 选项首部用于传送必须由包的传送路径中的每个节点检测的可选信息.
Hop-by-Hop 选项首部由 IPv6 首部中"下一个首部"字段值为 0 来标识, 并且具有
如下的格式:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 下一个首部 | 首部扩展长度 | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
| |
. .
. 选 项 .
. .
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
下一个首部 8 比特选择器. 标识紧跟在 Hop-by-Hop 选项首部后面的
首部的类型. 使用与 IPv4 协议字段 [RFC-1700 及后续
协议] 相同的数值.
首部扩展长度 8 比特无符号整数. 以 8 个八位组为单位的 Hop-by-Hop
选项首部的长度, 不包括开始的 8 个八位组.
选项 可变长度字段, 其长度须使整个 Hop-by-Hop 选项首部的
长度为 8 个八位组的整数倍. 包含一个或多个 TLV 编码
的选项, 如第 4.2 章中所述.
在本文中定义的仅有的 Hop-by-Hop 选项是填充1 及填充N 选项, 如第 4.2 章中
所述.
4.4 路由首部
路由首部用于 IPv6 源节点列出到包的目的节点的路径中所应"访问"的一个或多个
中间节点. 这一功能十分类似于 IPv4 的松散源地址和路由记录选项. 前面的首
部中"下一个首部"字段中的值为 43 表示下一个首部为路由首部. 路由首部具有
如下的格式:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 下一个首部 | 首部扩展长度 | 路由类型 | 分段剩余 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
. .
. 特定类型的数据 .
. .
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
下一个首部 8 比特选择器. 标识紧跟在路由首部后面的首部的类型.
使用与 IPv4 协议字段 [RFC-1700 及后续协议] 相同的数
值.
首部扩展长度 8 比特无符号整数. 以 8 个宋蛔槲ノ坏穆酚墒撞康? 长度, 不包括开始的 8 个八位组.
路由类型 8 比特的某种特定路由首部变量的标识符.
分段剩余 8 比特无符号整数. 剩余的路由分段的数量. 也就是在
到达最终的目的节点之前仍然应当访问的, 明确列出的中
间节点的数量.
特定类型的数据 可变长度字段. 其格式由路由类型决定, 其长度须使整个
路由首部的长度为 8 个八位组的整数倍.
如果节点在处理收到的包的过程中遇到了含有无法识别的路由类型值的路由首部,
节点应根据分段剩余字段中的值进行处理, 如下所述:
如果分段剩余值是零, 节点必须忽略路由首部, 继续处理包中的下一个首部, 其
类型由路由首部中的"下一个首部"字段中的值来标识.
如果分段剩余值非零, 节点必须抛弃这个包, 并且给包的源地址发送一个 ICMP
"参数存在问题", 编码 0 的报文, 指针指向无法识别的路由类型.
如果中间节点在处理路由首部之后, 确定应将包传送到一个链路 MTU 小于此包的
尺寸的链路中去, 那么中间节点必须抛弃此包, 并且给包的源地址发送一个 ICMP
"包太大"的报文.
类型 0 的路由首部具有如下格式:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 下一个首部 | 首部扩展长度 | 路由类型 = 0 | 分段剩余 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 保 留 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ +
| |
+ 地 址 [1] +
| |
+ +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ +
| |
+ 地 址 [2] +
| |
+ +
| |
+ +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
. . .
. . .
. . .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ +
| |
+ 地 址 [n] +
| |
+ +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
下一个首部 8 比特选择器. 标识紧跟在路由首部后面的首部的类型.
使用与 IPv4 协议字段 [RFC-1700 及后续协议] 相同的数
值.
首部扩展长度 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]
if IPv6 跳数限制小于等于 1 {
给源地址发送一个 ICMP "超时 – 传输超过跳数限制" 的报文, 并且
抛弃此包
}
else {
跳数限制减一;
向 IPv6 模块重新提交此包, 传给新的目的节点
}
}
}
}
作为上述算法的一个例子, 考虑这样一种情况: 源节点 S 给目的节点 D 发送一个
包, 用路由首部来使这个包经过中间节点 I1, I2 和 I3. 在传送路径的每段中,
IPv6 首部中的相关字段值以及路由首部字段值应为如下所述:
当包从 S 传到 I1:
源地址 = S 首部扩展长度 = 6
目的地址 = I1 分段剩余 = 3
地址[1] = I2
地址[2] = I3
地址[3] = D
当包从 I1 传到 I2:
源地址 = S 首部扩展长度 = 6
目的地址 = I2 分段剩余 = 2
地址[1] = I1
地址[2] = I3
地址[3] = D
当包从 I2 传到 I3:
源地址 = S 首部扩展长度 = 6
目的地址 = I3 分段剩余 = 1
地址[1] = I1
地址[2] = I2
地址[3] = D
当包从 I3 传到 D:
源地址 = S 首部扩展长度 = 6
目的地址 = D 分段剩余 = 0
地址[1] = I1
地址[2] = I2
地址[3] = I3
4.5 分片首部
IPv6 源节点使用分片首部来发送大于去往目的节点的路径 MTU 的包. (注意: 不
同于 IPv4 的是, 在 IPv6 里, 只有包的源节点才能进行分片, 传输路径中的路由
器不能进行分片 – 参见第 5 章) 前面的首部中"下一个首部"字段中的值为 44 表
示下一个首部为分片首部. 分片首部具有如下格式:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 下一个首部 | 保 留 | 分片偏移量 |Res|M|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 标 识 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
下一个首部 8 比特选择器. 标识原包(后面有定义)中可分片部分的初
始首部的类型. 使用与 IPv4 协议字段 [RFC-1700 及后
续协议] 相同的数值.
保留 8 比特保留字段. 传输时初始化为零; 接收时忽略.
分片偏移量 13 比特无符号整数. 以 8 个八位组为单位的, 首部后面
的数据相对于原包中可分片部分的开始位置处的偏移量.
Res (保留) 2 比特保留字段. 传输时初始化为零; 接收时忽略.
M 标志位 1 = 还有分片; 0 = 最后一个分片.
标识 32 比特. 参见下面的详细说明.
要发送大于去往目的节点的路径 MTU 的包, 源节点可以将包分成若干分片, 每个
分片单独发送, 并且在接收者处进行重组.
源节点应为每个要分片的包规定一个标识值. 这个标识值必须不同于近期之内*同
一对源节点和目的节点之间其他的分片包的标识值. 如果存在路由首部, 那么目
的节点是指最终目的节点.
* "近期之内" 是指包可能的最大生存期. 其中包括从源节点到目的节点的传
输时间, 以及等待与同一包的其他分片重组所花费的时间. 尽管如此, 源节
点并没有必要知道包的最大生存期. 它只需将标识字段值作为一个简单的
32 比特循环计数器, 每次将包分片时计数器增加一个增量即可. 具体的实
现可以自己选择是维护一个计数器还是多个计数器, 还可以选择是为每个节
点可能的源地址维护一个计数器, 还是为每个活动的 (源地址, 目的地址) 对
维护一个计数器.
最初的, 未分片的大数据包称为"原包". 原包可以看作是由两部分组成的, 如下
所示:
原包:
+------------------+----------------------//-----------------------+
| 不可分片 | 可分片 |
| 部分 | 部分 |
+------------------+----------------------//-----------------------+
不可分片部分包括 IPv6 首部, 以及那些必须由路由中的节点处理的扩展首部.
也就是以下三种情况: 所有路由首部以前(含路由首部)的首部(如果存在的话),
或者是 Hop-by-Hop 选项首部(如果存在的话), 或者没有扩展首部.
包中其余的部分为可分片部分, 也就是只需由包的最终目的节点处理的扩展首
部, 以及上层协议首部和数据.
原包中可分片部分被划分成若干分片, 除去最后("最右")一个分片, 每个分片都为
8 个八位组的整数倍长. 这些分片由相互独立的"分片包"来传送, 如下例所示:
原包:
+------------------+--------------+--------------+--//--+----------+
| 不可分片 | 第一个 | 第二个 | | 最后一个 |
| 部分 | 分片 | 分片 | .... | 分片 |
+------------------+--------------+--------------+--//--+----------+
分片包:
+------------------+--------+--------------+
| 不可分片 | 分片 | 第一个 |
| 部分 | 首部 | 分片 |
+------------------+--------+--------------+
+------------------+--------+--------------+
| 不可分片 | 分片 | 第二个 |
| 部分 | 首部 | 分片 |
+------------------+--------+--------------+
o
o
o
+------------------+--------+--------------+
| 不可分片 | 分片 | 最后一个 |
| 部分 | 首部 | 分片 |
+------------------+--------+--------------+
每个分片包由下述几部分构成:
(1) 原包中的不可分片部分. 其中原来 IPv6 首部中有效载荷长度值只应包含
本分片包的长度 (不包含 IPv6 首部自身的长度). 不可分片部分中最后
一个首部的"下一个首部"字段值改为 44.
(2) 分片首部. 其中包括: