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