4. IPv6 扩展头部 (IPv6 Extension Headers)
- IPv6 Extension Headers
在 IPv6 中, 可选的互联网层信息被编码在独立头部中, 这些头部可以放在数据包的 IPv6 头部与上层头部之间. 这种扩展头部数量较少, 每一种都由不同的 Next Header 值标识.
扩展头部编号来自 IANA IP Protocol Numbers [IANA-PN], 与 IPv4 和 IPv6 使用的值相同. 在处理数据包中的 Next Header 值序列时, 第一个不是扩展头部 [IANA-EH] 的值表示数据包中的下一项是对应的上层头部. 如果没有上层头部, 则使用特殊的 "No Next Header" 值.
如以下示例所示, 一个 IPv6 数据包可以携带零个, 一个或多个扩展头部, 每个扩展头部都由前一个头部的 Next Header 字段标识:
+---------------+------------------------ | IPv6 header | TCP header + data | | | Next Header = | | TCP | +---------------+------------------------
+---------------+----------------+------------------------ | IPv6 header | Routing header | TCP header + data | | | | Next Header = | Next Header = | | Routing | TCP | +---------------+----------------+------------------------
+---------------+----------------+-----------------+----------------- | IPv6 header | Routing header | Fragment header | fragment of TCP | | | | header + data | Next Header = | Next Header = | Next Header = | | Routing | Fragment | TCP | +---------------+----------------+-----------------+-----------------
扩展头部 (Hop-by-Hop Options header 除外) 不会由数据包传递路径上的任何节点处理, 插入或删除, 直到数据包到达 IPv6 头部的 Destination Address 字段所标识的节点 (或在组播情况下到达所标识的一组节点中的每个节点).
Hop-by-Hop Options header 不会被插入或删除, 但数据包传递路径上的任何节点都可以检查或处理它, 直到数据包到达 IPv6 头部的 Destination Address 字段所标识的节点 (或在组播情况下到达所标识的一组节点中的每个节点). 当存在 Hop-by-Hop Options header 时, 它必须紧跟在 IPv6 头部之后. 其存在由 IPv6 头部中 Next Header 字段的零值表示.
注: 虽然 [RFC2460] 要求所有节点都必须检查并处理 Hop-by-Hop Options header, 现在的预期是, 数据包传递路径上的节点只有在被显式配置为这样做时, 才检查并处理 Hop-by-Hop Options header.
在目的节点, 基于 IPv6 头部 Next Header 字段的常规解复用会调用模块处理第一个扩展头部, 或在不存在扩展头部时处理上层头部. 每个扩展头部的内容和语义决定是否继续处理下一个头部. 因此, 扩展头部必须严格按照它们在数据包中出现的顺序处理; 接收方不得例如扫描数据包以寻找某一特定类型的扩展头部, 并在处理所有先前头部之前处理该头部.
如果由于处理某个头部, 目的节点需要继续处理下一个头部, 但当前头部中的 Next Header 值不被该节点识别, 则它应该丢弃该数据包, 并向数据包源发送 ICMP Parameter Problem 消息, 其中 ICMP Code 值为 1 ("unrecognized Next Header type encountered"), ICMP Pointer 字段包含原始数据包中该未识别值的偏移. 如果节点在 IPv6 头部以外的任何头部中遇到 Next Header 值为零, 也应该采取同样的操作.
每个扩展头部的长度都是 8 个八位字节的整数倍, 以便后续头部保持 8-octet 对齐. 每个扩展头部内的多八位字节字段按其自然边界对齐, 即宽度为 n 个八位字节的字段放置在从头部起始处算起 n 个八位字节的整数倍位置, 其中 n = 1, 2, 4 或 8.
IPv6 的完整实现包括以下扩展头部的实现:
Hop-by-Hop Options
Fragment
Destination Options
Routing
Authentication
Encapsulating Security Payload
前四个在本文档中规定; 后两个分别在 [RFC4302] 和 [RFC4303] 中规定. 当前 IPv6 扩展头部列表可见 [IANA-EH].
4.1. 扩展头部顺序 (Extension Header Order)
当同一数据包中使用多个扩展头部时, 建议这些头部按以下顺序出现:
IPv6 header
Hop-by-Hop Options header
Destination Options header (note 1)
Routing header
Fragment header
Authentication header (note 2)
Encapsulating Security Payload header (note 2)
Destination Options header (note 3)
Upper-Layer header
note 1: 用于需要由 IPv6 Destination Address 字段中出现的第一个目的地以及 Routing header 中列出的后续目的地处理的选项.
note 2: 关于 Authentication 和 Encapsulating Security Payload 头部相对顺序的其他建议见 [RFC4303].
note 3: 用于只需要由数据包最终目的地处理的选项.
每个扩展头部最多应该出现一次, Destination Options header 除外, 它最多应该出现两次 (一次在 Routing header 之前, 一次在上层头部之前).
如果上层头部是另一个 IPv6 头部 (即 IPv6 在 IPv6 上隧道化或封装的情况), 它后面可以跟随自己的扩展头部, 这些扩展头部单独适用同样的顺序建议.
如果以及当定义其他扩展头部时, 必须规定它们相对于上面所列头部的顺序约束.
IPv6 节点必须接受并尝试处理同一数据包中以任意顺序出现且出现任意次数的扩展头部, 但 Hop-by-Hop Options header 除外, 它被限制为只能紧跟在 IPv6 头部之后出现. 尽管如此, 强烈建议 IPv6 数据包源遵循上述建议顺序, 直到以及除非后续规范修订该建议.
4.2. 选项 (Options)
本文档规定的当前已定义扩展头部中有两个, 即 Hop-by-Hop Options header 和 Destination Options header, 会携带数量可变的 "options", 这些选项采用 type-length-value (TLV) 编码, 格式如下:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - -
| Option Type | Opt Data Len | Option Data
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - -
Option Type 8-bit 标识符, 表示选项的类型.
Opt Data Len 8-bit 无符号整数. 此选项的 Option Data 字段长度, 单位为八位字节.
Option Data 可变长度字段. Option-Type-specific 数据.
一个头部内的选项序列必须严格按照它们在头部中出现的顺序处理; 接收方不得例如扫描头部以寻找某一特定类型的选项, 并在处理所有先前选项之前处理该选项.
Option Type 标识符内部编码为: 其最高 2 位指定当处理该选项的 IPv6 节点不识别 Option Type 时必须采取的操作:
00 - 跳过此选项并继续处理该头部.
01 - 丢弃数据包.
10 - 丢弃数据包, 并且无论数据包的 Destination Address 是否为组播地址, 都向数据包的 Source Address 发送 ICMP Parameter Problem, Code 2 消息, 指向未识别的 Option Type.
11 - 丢弃数据包, 并且仅当数据包的 Destination Address 不是组播地址时, 向数据包的 Source Address 发送 ICMP Parameter Problem, Code 2 消息, 指向未识别的 Option Type.
Option Type 的第三高位指定该选项的 Option Data 在前往数据包最终目的地的途中是否可以改变. 当数据包中存在 Authentication header 时, 对于任何数据在途中可能改变的选项, 在计算或验证数据包的认证值时, 其整个 Option Data 字段必须被视为零值八位字节.
0 - Option Data 在途中不改变
1 - Option Data 在途中可以改变
上述三个高位应被视为 Option Type 的一部分, 而不是独立于 Option Type. 也就是说, 一个特定选项由完整的 8-bit Option Type 标识, 而不只是由 Option Type 的低 5 位标识.
Hop-by-Hop Options header 和 Destination Options header 使用同一个 Option Type 编号空间. 但是, 特定选项的规范可以将其使用限制为仅用于这两个头部之一.
单个选项可以有特定的对齐要求, 以确保 Option Data 字段内的多八位字节值落在自然边界上. 一个选项的对齐要求使用 xn+y 表示法规定, 意味着 Option Type 必须出现在从头部起始处算起 x 个八位字节的整数倍位置再加 y 个八位字节处. 例如:
2n 表示从头部起始处算起任意 2-octet 偏移.
8n+2 表示从头部起始处算起任意 8-octet 偏移, 再加
2 个八位字节.
有两个填充选项, 在需要对齐后续选项并将所在头部填充到长度为 8 个八位字节的整数倍时使用. 所有 IPv6 实现都必须识别这些填充选项:
Pad1 option (alignment requirement: none)
+-+-+-+-+-+-+-+-+
| 0 |
+-+-+-+-+-+-+-+-+
注! Pad1 option 的格式是一个特殊情况 -- 它没有长度和值字段.
Pad1 option 用于向头部的 Options 区域插入 1 个八位字节的填充. 如果需要多于 1 个八位字节的填充, 应该使用下面描述的 PadN option, 而不是多个 Pad1 option.
PadN option (alignment requirement: none)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - -
| 1 | Opt Data Len | Option Data
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - -
PadN option 用于向头部的 Options 区域插入两个或更多八位字节的填充. 对于 N 个八位字节的填充, Opt Data Len 字段包含值 N-2, Option Data 由 N-2 个零值八位字节组成.
Appendix A 包含设计新选项的格式化准则.
4.3. Hop-by-Hop Options Header
Hop-by-Hop Options header 用于携带可由数据包传递路径上每个节点检查和处理的可选信息. Hop-by-Hop Options header 由 IPv6 头部中值为 0 的 Next Header 标识, 其格式如下:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Next Header | Hdr Ext Len | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
| |
. .
. Options .
. .
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Next Header 8-bit 选择器. 标识紧跟在 Hop-by-Hop Options
header 之后的头部类型. 使用与 IPv4
Protocol 字段相同的值 [IANA-PN].
Hdr Ext Len 8-bit 无符号整数. Hop-by-Hop Options header
的长度, 单位为 8-octet, 不包括最初的
8 个八位字节.
Options 可变长度字段, 其长度使完整的 Hop-by-Hop
Options header 长度为 8 个八位字节的整数倍.
包含一个或多个 TLV 编码选项, 如 Section 4.2
所述.
本文档定义的唯一逐跳选项是 Section 4.2 中规定的 Pad1 和 PadN 选项.
4.4. Routing Header
Routing header 由 IPv6 源用于列出一个或多个中间节点, 这些节点将在数据包前往目的地途中被 "访问". 此功能与 IPv4 的 Loose Source and Record Route 选项非常相似. Routing header 由紧邻前一个头部中值为 43 的 Next Header 标识, 其格式如下:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Next Header | Hdr Ext Len | Routing Type | Segments Left |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
. .
. type-specific data .
. .
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Next Header 8-bit 选择器. 标识紧跟在 Routing header
之后的头部类型. 使用与 IPv4 Protocol 字段
相同的值 [IANA-PN].
Hdr Ext Len 8-bit 无符号整数. Routing header 的长度,
单位为 8-octet, 不包括最初的 8 个八位字节.
Routing Type 8-bit 标识符, 表示特定 Routing header 变体.
Segments Left 8-bit 无符号整数. 剩余路由段数量, 即在到达
最终目的地前仍需访问的显式列出中间节点数量.
type-specific data 可变长度字段, 其格式由 Routing Type 决定,
其长度使完整的 Routing header 长度为 8 个
八位字节的整数倍.
如果在处理收到的数据包时, 节点遇到带有未识别 Routing Type 值的 Routing header, 该节点所需行为取决于 Segments Left 字段的值, 如下:
如果 Segments Left 为零, 节点必须忽略 Routing header, 并继续处理数据包中的下一个头部, 该头部类型由 Routing header 中的 Next Header 字段标识.
如果 Segments Left 非零, 节点必须丢弃该数据包, 并向数据包的 Source Address 发送 ICMP Parameter Problem, Code 0 消息, 指向未识别的 Routing Type.
如果在处理收到数据包的 Routing header 后, 中间节点确定该数据包将被转发到某条链路, 而该链路的 MTU 小于数据包大小, 则该节点必须丢弃该数据包, 并向数据包的 Source Address 发送 ICMP Packet Too Big 消息.
当前定义的 IPv6 Routing Headers 及其状态可见 [IANA-RH]. IPv6 Routing Headers 的分配准则可见 [RFC5871].
4.5. Fragment Header
Fragment header 由 IPv6 源用于向目的地发送大于路径 MTU 可容纳大小的数据包. (注: 与 IPv4 不同, IPv6 中的分片只由源节点执行, 不由数据包传递路径上的路由器执行 -- 见 Section 5.) Fragment header 由紧邻前一个头部中值为 44 的 Next Header 标识, 其格式如下:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Next Header | Reserved | Fragment Offset |Res|M| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Identification | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Next Header 8-bit 选择器. 标识原始数据包 Fragmentable Part
的初始头部类型 (定义见下文). 使用与 IPv4
Protocol 字段相同的值 [IANA-PN].
Reserved 8-bit 保留字段. 发送时初始化为零; 接收时忽略.
Fragment Offset 13-bit 无符号整数. 此头部之后的数据相对于
原始数据包 Fragmentable Part 起始处的偏移,
单位为 8-octet.
Res 2-bit 保留字段. 发送时初始化为零; 接收时忽略.
M flag 1 = 还有更多片段; 0 = 最后一个片段.
Identification 32 bits. 见下文说明.
为了发送一个过大而无法适合通向其目的地路径 MTU 的数据包, 源节点可以将该数据包分成多个片段, 并将每个片段作为单独的数据包发送, 由接收方重组.
对于每个将被分片的数据包, 源节点生成一个 Identification 值. 对于最近* 使用相同 Source Address 和 Destination Address 发送的任何其他分片数据包, Identification 必须不同. 如果存在 Routing header, 这里关注的 Destination Address 是最终目的地的地址.
* "recently" 表示在数据包最大可能生命周期内, 包括从源到目的地的传输时间以及等待与同一数据包的其他片段重组所花费的时间. 但是, 并不要求源节点知道最大数据包生命周期. 相反, 假定可以通过实现一种使标识重用频率较低的算法来满足该要求. [RFC7739] 描述了能够满足此要求的算法示例.
初始的大型未分片数据包称为 "original packet", 并被认为由三部分组成, 如下图所示:
original packet:
+------------------+-------------------------+---//----------------+ | Per-Fragment | Extension & Upper-Layer | Fragmentable | | Headers | Headers | Part | +------------------+-------------------------+---//----------------+
Per-Fragment headers 必须由 IPv6 头部加上任何必须由前往目的地途中节点处理的扩展头部组成, 即如果存在 Routing header, 则包括直到并包含 Routing header 的所有头部; 否则如果存在 Hop-by-Hop Options header, 则包括它; 否则不包括扩展头部.
Extension headers 是所有未包含在数据包 Per-Fragment headers 部分中的其他扩展头部. 为此目的, Encapsulating Security Payload (ESP) 不被视为扩展头部. Upper-Layer header 是第一个不是 IPv6 扩展头部的上层头部. 上层头部的示例包括 TCP, UDP, IPv4, IPv6, ICMPv6, 以及如前所述的 ESP.
Fragmentable Part 由上层头部之后的数据包剩余部分组成, 或由包含 No Next Header 的 Next Header 值的任何头部 (即初始 IPv6 头部或扩展头部) 之后的数据包剩余部分组成.
原始数据包的 Fragmentable Part 被划分为片段. 必须选择片段长度, 使得到的片段数据包适合通向数据包目的地的路径 MTU. 除最后一个 ("rightmost") 片段可能例外, 每个完整片段的长度都是 8 个八位字节的整数倍.
片段作为独立的 "fragment packets" 传输, 如下图所示:
original packet:
+-----------------+-----------------+--------+--------+-//-+--------+ | Per-Fragment |Ext & Upper-Layer| first | second | | last | | Headers | Headers |fragment|fragment|....|fragment| +-----------------+-----------------+--------+--------+-//-+--------+
fragment packets:
+------------------+---------+-------------------+----------+ | Per-Fragment |Fragment | Ext & Upper-Layer | first | | Headers | Header | Headers | fragment | +------------------+---------+-------------------+----------+
+------------------+--------+-------------------------------+ | Per-Fragment |Fragment| second | | Headers | Header | fragment | +------------------+--------+-------------------------------+ o o o +------------------+--------+----------+ | Per-Fragment |Fragment| last | | Headers | Header | fragment | +------------------+--------+----------+
第一个片段数据包由以下内容组成:
(1) 原始数据包的 Per-Fragment headers, 其中原始 IPv6 头部的 Payload Length 被改为只包含此片段数据包的长度 (不包括 IPv6 头部本身的长度), 并且 Per-Fragment headers 最后一个头部的 Next Header 字段被改为 44.
(2) 一个 Fragment header, 其中包含:
标识原始数据包 Per-Fragment headers 之后第一个头部的 Next Header 值.
一个 Fragment Offset, 其中包含该片段相对于原始数据包 Fragmentable Part 起始处的偏移, 单位为 8-octet. 第一个 ("leftmost") 片段的 Fragment Offset 为 0.
M flag 值为 1, 因为这是第一个片段.
为原始数据包生成的 Identification 值.
(3) 扩展头部 (如果有) 以及 Upper-Layer header. 这些头部必须位于第一个片段中. 注: 这将直到 Upper-Layer header 的头部大小限制为通向数据包目的地路径的 MTU.
(4) 第一个片段.
后续片段数据包由以下内容组成:
(1) 原始数据包的 Per-Fragment headers, 其中原始 IPv6 头部的 Payload Length 被改为只包含此片段数据包的长度 (不包括 IPv6 头部本身的长度), 并且 Per-Fragment headers 最后一个头部的 Next Header 字段被改为 44.
(2) 一个 Fragment header, 其中包含:
标识原始数据包 Per-Fragment headers 之后第一个头部的 Next Header 值.
一个 Fragment Offset, 其中包含该片段相对于原始数据包 Fragmentable Part 起始处的偏移, 单位为 8-octet.
如果该片段是最后一个 ("rightmost") 片段, 则 M flag 值为 0; 否则 M flag 值为 1.
为原始数据包生成的 Identification 值.
(3) 片段本身.
不得创建与从原始数据包创建的任何其他片段重叠的片段.
在目的地, 片段数据包会重组为原始的未分片形式, 如下所示:
重组后的原始数据包:
+---------------+-----------------+---------+--------+-//--+--------+ | Per-Fragment |Ext & Upper-Layer| first | second | | last | | Headers | Headers |frag data|fragment|.....|fragment| +---------------+-----------------+---------+--------+-//--+--------+
以下规则管理重组:
原始数据包只能由具有相同 Source Address, Destination Address 和 Fragment Identification 的片段数据包重组.
重组后数据包的 Per-Fragment headers 由第一个片段数据包 (即 Fragment Offset 为零的数据包) 中直到但不包括 Fragment header 的所有头部组成, 并进行以下两项更改:
Per-Fragment headers 中最后一个头部的 Next Header 字段从第一个片段的 Fragment header 的 Next Header 字段获得.
重组后数据包的 Payload Length 根据 Per-Fragment headers 的长度以及最后一个片段的长度和偏移计算. 例如, 计算重组后原始数据包 Payload Length 的公式为:
PL.orig = PL.first - FL.first - 8 + (8 * FO.last) + FL.last
其中
PL.orig = 重组后数据包的 Payload Length 字段.
PL.first = 第一个片段数据包的 Payload Length 字段.
FL.first = 第一个片段数据包中跟随 Fragment header 的片段长度.
FO.last = 最后一个片段数据包中 Fragment header 的 Fragment Offset 字段.
FL.last = 最后一个片段数据包中跟随 Fragment header 的片段长度.
重组后数据包的 Fragmentable Part 由每个片段数据包中跟随 Fragment header 的片段构造. 每个片段的长度通过从数据包的 Payload Length 中减去 IPv6 头部与片段本身之间的头部长度来计算; 其在 Fragmentable Part 中的相对位置根据其 Fragment Offset 值计算.
最终重组后的数据包中不存在 Fragment header.
如果片段是完整数据报 (即 Fragment Offset 字段和 M 标志均为零), 则它不需要任何进一步重组, 应作为完全重组后的数据包处理 (即更新 Next Header, 调整 Payload Length, 删除 Fragment header 等). 与该数据包匹配的任何其他片段 (即相同 IPv6 Source Address, IPv6 Destination Address 和 Fragment Identification) 应独立处理.
重组分片数据包时可能出现以下错误条件:
o 如果在收到某数据包第一个到达片段后的 60 秒内, 收到的片段不足以完成该数据包重组, 则必须放弃该数据包的重组, 并丢弃已为该数据包收到的所有片段. 如果已收到第一个片段 (即 Fragment Offset 为零的片段), 则应向该片段的源发送 ICMP Time Exceeded -- Fragment Reassembly Time Exceeded 消息.
o 如果根据片段数据包 Payload Length 字段导出的片段长度不是 8 个八位字节的倍数, 且该片段的 M 标志为 1, 则必须丢弃该片段, 并应向片段源发送 ICMP Parameter Problem, Code 0 消息, 指向片段数据包的 Payload Length 字段.
o 如果片段的长度和偏移会使从该片段重组的数据包 Payload Length 超过 65,535 个八位字节, 则必须丢弃该片段, 并应向片段源发送 ICMP Parameter Problem, Code 0 消息, 指向片段数据包的 Fragment Offset 字段.
o 如果第一个片段未包含直到 Upper-Layer header 为止的所有头部, 则应丢弃该片段, 并应向片段源发送 ICMP Parameter Problem, Code 3 消息, 且 Pointer 字段设置为零.
o 如果正在重组的任何片段与同一数据包正在重组的任何其他片段重叠, 则必须放弃该数据包的重组, 并丢弃已为该数据包收到的所有片段, 且不应发送 ICMP 错误消息.
需要注意, 片段可能在网络中重复. 实现可以选择检测这种情况并丢弃完全重复片段, 同时保留属于同一数据包的其他片段, 而不是将这些完全重复片段视为重叠片段.
以下条件预计不会经常发生, 但如果发生也不视为错误:
同一原始数据包的不同片段中, 位于 Fragment header 之前的头部数量和内容可能不同. 每个片段数据包中位于 Fragment header 之前的任何头部, 都会在数据包到达时处理, 先于将片段排队等待重组. 只有 Offset 为零的片段数据包中的那些头部会保留在重组后的数据包中.
同一原始数据包不同片段的 Fragment header 中的 Next Header 值可能不同. 只有来自 Offset 为零的片段数据包的值用于重组.
IPv6 头部中的其他字段也可能在正在重组的各片段之间变化. 如果使用来自 Offset 为零片段的值这一基本机制不足够, 使用这些字段的规范可以提供额外指令. 例如, [RFC3168] Section 5.3 描述了如何组合不同片段的 Explicit Congestion Notification (ECN) 位, 以推导重组后数据包的 ECN 位.
4.6. Destination Options Header
Destination Options header 用于携带只需要由数据包目的节点检查的可选信息. Destination Options header 由紧邻前一个头部中值为 60 的 Next Header 标识, 其格式如下:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Next Header | Hdr Ext Len | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
| |
. .
. Options .
. .
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Next Header 8-bit 选择器. 标识紧跟在 Destination Options
header 之后的头部类型. 使用与 IPv4
Protocol 字段相同的值 [IANA-PN].
Hdr Ext Len 8-bit 无符号整数. Destination Options header
的长度, 单位为 8-octet, 不包括最初的
8 个八位字节.
Options 可变长度字段, 其长度使完整的 Destination
Options header 长度为 8 个八位字节的整数倍.
包含一个或多个 TLV 编码选项, 如 Section 4.2
所述.
本文档定义的唯一目的地选项是 Section 4.2 中规定的 Pad1 和 PadN 选项.
注意, 在 IPv6 数据包中编码可选目的地信息有两种可能方式: 作为 Destination Options header 中的一个选项, 或作为单独的扩展头部. Fragment header 和 Authentication header 是后一种方式的示例. 可以使用哪种方式, 取决于当目的节点不理解该可选信息时所期望的操作:
o 如果期望的操作是让目的节点丢弃数据包, 并且仅当数据包的 Destination Address 不是组播地址时, 向数据包的 Source Address 发送 ICMP Unrecognized Type 消息, 则该信息既可以编码为单独的头部, 也可以编码为 Destination Options header 中的一个选项, 其中该选项 Option Type 最高 2 位的值为 11. 选择哪一种方式可能取决于哪一种占用更少八位字节, 或哪一种能得到更好的对齐或更高效的解析.
o 如果期望任何其他操作, 则该信息必须编码为 Destination Options header 中的一个选项, 其中该选项 Option Type 最高 2 位的值为 00, 01 或 10, 用于指定期望操作 (见 Section 4.2).
4.7. No Next Header
IPv6 头部或任何扩展头部的 Next Header 字段中的值 59 表示该头部之后没有任何内容. 如果 IPv6 头部的 Payload Length 字段表明, 在 Next Header 字段包含 59 的头部末尾之后仍存在八位字节, 则这些八位字节必须被忽略; 如果数据包被转发, 则必须原样传递这些八位字节.
4.8. 定义新的扩展头部和选项 (Defining New Extension Headers and Options)
不建议定义新的 IPv6 扩展头部, 除非不存在可通过为某个现有 IPv6 扩展头部指定新选项来使用的现有 IPv6 扩展头部. 指定新 IPv6 扩展头部的提案必须包含详细技术说明, 解释为什么现有 IPv6 扩展头部不能用于期望的新功能. 更多背景信息见 [RFC6564].
注: 不得定义需要逐跳行为的新扩展头部, 因为如本文档 Section 4 所规定, 唯一具有逐跳行为的扩展头部是 Hop-by-Hop Options header.
不建议定义新的逐跳选项, 因为节点可能被配置为忽略 Hop-by-Hop Options header, 丢弃包含 Hop-by-Hop Options header 的数据包, 或将包含 Hop-by-Hop Options header 的数据包分配到慢速处理路径. 考虑定义新逐跳选项的设计者需要意识到这种可能行为. 在任何新逐跳选项被标准化之前, 必须有非常明确的理由说明为什么需要它.
建议使用 Destination Options header 携带只需要由数据包目的节点检查的可选信息, 而不是定义新的扩展头部, 因为它们提供更好的处理和向后兼容性.
如果定义新的扩展头部, 它们需要使用以下格式:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Next Header | Hdr Ext Len | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
| |
. .
. Header-Specific Data .
. .
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Next Header 8-bit 选择器. 标识紧跟在扩展头部之后的
头部类型. 使用与 IPv4 Protocol 字段相同
的值 [IANA-PN].
Hdr Ext Len 8-bit 无符号整数. Destination Options
header 的长度, 单位为 8-octet, 不包括
最初的 8 个八位字节.
Header Specific Data 可变长度字段. 特定于该扩展头部的字段.