RFC2473:Generic Packet Tunneling in IPv6 Specification,December 1998
本备忘录的状态
本文档为 Internet 社区指定了 Internet 标准跟踪协议,并请求讨论和改进建议。本协议的标准化状态和现状请参考当前版本的《互联网官方协议标准》(STD 1)。本备忘录的分发不受限制。
版权声明
版权所有 (C) 互联网协会 (1998)。版权所有。
梗概
本文档定义了 Internet 数据包(例如 IPv6 和 IPv4)的 IPv6 封装模型和通用机制。该模型和机制也可以应用于其他协议数据包,例如 AppleTalk、IPX、CLNP 或其他。
1、 简介
本文档规定了一种方法和通用机制,通过该方法和通用机制将数据包封装并作为 IPv6 数据包中的有效负载进行传输,生成的数据包称为 IPv6 隧道数据包,隧道数据包的源和目的之间的转发路径称为 IPv6 隧道,该技术称为 IPv6 隧道。
IPv6 隧道的典型场景是中间节点通过为选定的数据包指定特定的转发路径来施加显式路由控制的情况。这种控制是通过将 IPv6 报文头添加到每个选定的原始数据包来实现的。这些前置报文头标识转发路径。
除了作为本文档重点的通用 IPv6 隧道机制的描述外,本文还描述了用于隧道化 IPv6 和 IPv4 数据包的特定机制。
关键字 MUST、MUST NOT、MAY、OPTIONAL、REQUIRED、RECOMMENDED、SHALL、SHALL NOT、SHOULD、SHOULD NOT 将按照 RFC 2119 中的定义进行解释。
2、 术语
original packet:原始数据包,一个经过封装的数据包。
original header:原始报文头,原始数据包的报文头。
tunnel:隧道,两个节点之间的转发路径,数据包的有效载荷是原始数据包。
tunnel end-node:隧道端节点,隧道开始或结束的节点。
tunnel header:隧道头,封装期间附加到原始数据包的报文头。它将隧道端点指定为源和目标。
tunnel packet:隧道包,封装原始数据包的数据包。
tunnel entry-point:隧道入口点,封装原始数据包的隧道端节点。
tunnel exit-point:隧道出口点,隧道包被解封装的隧道端节点。
IPv6 tunnel:IPv6隧道,隧道配置为两个 IPv6 节点之间的虚拟链路,其封装协议为 IPv6。
tunnel MTU:隧道MTU,不需要分片的隧道数据包有效负载的最大大小,即隧道入口点和隧道出口点节点之间的路径 MTU 减去隧道头的大小。
tunnel hop limit:隧道跳数限制,隧道数据包从隧道入口点到隧道出口点的最大跳数。
inner tunnel:内隧道,一条隧道,它是另一条隧道的一跳(虚拟链路)。
outer tunnel:外隧道,包含一个或多个内部隧道的隧道。
nested tunnel packet:嵌套隧道包,具有作为有效载荷的隧道数据包的隧道数据包。
nested tunnel header:嵌套隧道头,嵌套隧道数据包的隧道头。
nested encapsulation:嵌套封装,封装数据包的封装。
recursive encapsulation:递归封装,在退出隧道之前重新进入隧道的数据包的封装。
tunnel encapsulation limit:隧道封装限制,一个数据包的最大嵌套封装数。
3、 IPv6 隧道
IPv6 隧道是一种在两个 IPv6 节点之间建立“虚拟链路”的技术,用于传输作为 IPv6 数据包有效载荷的数据包(见图 1)。从两个节点的角度来看,这条称为 IPv6 隧道的“虚拟链路”表现为一条点对点链路,IPv6 在其上充当链路层协议。这两个 IPv6 节点扮演着特定的角色。一个节点封装从其他节点或从自身接收到的原始数据包,并通过隧道转发生成的隧道数据包。另一个节点解封装接收到的隧道数据包,并将生成的原始数据包转发到它们的目的地,可能是它自己。封装节点称为隧道入口节点,是隧道数据包的来源。解封装节点称为隧道出口点,它是隧道数据包的目的地。
笔记:
本文档特别涉及由单播地址标识的两个节点之间的隧道——这种隧道看起来像“虚拟点对点链路”。这里描述的机制也适用于其中出口点节点由其他类型的地址标识的隧道,例如任播或组播。这些隧道可能看起来像“虚拟点对多点链路”。在撰写本文档时,IPv6 任播地址是正在进行的规范和实验工作的主题。
图1、隧道
IPv6 隧道是一种单向机制——隧道数据包流发生在 IPv6 隧道入口点和出口点节点之间的一个方向上(见图 1)。
图2、双向隧道机制
双向隧道是通过合并两种单向机制来实现的,即配置两条隧道,每条隧道的方向相反——一条隧道的入口节点是另一条隧道的出口节点(见图2 )。
3.1、 IPv6 封装
IPv6 封装包括在原始数据包之前添加 IPv6 报文头和可选的一组 IPv6 扩展报文头(参见图 3),它们统称为隧道 IPv6 报文头。封装发生在 IPv6 隧道入口点节点中,因为原始数据包被转发到由隧道表示的虚拟链路上。原始数据包在转发过程中根据该数据包协议的转发规则进行处理。例如,如果原始数据包是:
(a) IPv6 数据包,IPv6 原始报文头跳数限制减一。
(b) IPv4 数据包,IPv4 原始报文头生存时间 (time to live,TTL) 字段减 1。
在封装时,隧道 IPv6 报文头的源字段用隧道入口点节点的 IPv6 地址填充,目的字段用隧道出口点的 IPv6 地址填充。随后,封装产生的隧道包被发送到隧道出口点节点。
图 3、封装数据包
隧道扩展头应该按照定义扩展头的规范推荐的顺序出现,例如[IPv6-Spec]。
原始数据包的来源和封装这些数据包的隧道入口点可以是同一节点。
3.2、 隧道中的数据包处理
隧道中的中间节点根据 IPv6 协议处理 IPv6 隧道数据包。例如,一个隧道 Hop by Hop Options 扩展头由隧道中的每个接收节点处理;隧道路由扩展头标识中间处理节点,更细粒度地控制隧道报文通过隧道的转发路径;在隧道出口点节点处处理隧道目的地选项扩展报文头。
3.3、 IPv6 解封装
解封装如图 4 所示:
图 4、解封装数据包
在接收到目的地为隧道出口点节点的IPv6地址的IPv6数据包后,其IPv6协议层将处理隧道头。对扩展头应用严格的从左到右处理规则。处理完成后,控制权交给下一个协议引擎,该引擎由上一个处理的报文头中的下一个报文头字段值标识。如果将其设置为隧道协议值,隧道协议引擎将丢弃隧道头,并将生成的原始数据包传递给由该值标识的互联网或较低层协议,以供进一步处理。
例如,如果 Next Header 字段具有 IPv6 Tunnel Protocol 值,则生成的原始数据包将传递到 IPv6 协议层。
解封装隧道数据包的隧道出口点节点和接收结果原始数据包的目的节点可以是同一节点。
3.4、 IPv6隧道协议引擎
通过节点上的 IPv6 隧道协议引擎的数据包流(路径 #1-7)如图 5 所示:
图 5、节点上 IPv6 隧道协议引擎中的数据包流
笔记:
在图 5 中,Upper-Layer Protocols 框表示 TCP/UDP 等传输协议、ICMP 等控制协议、OSPF 等路由协议以及在 IPv6 上“隧道”的 Internet 或下层协议,例如 IPv4, IPX 等。Link-Layer Protocols 框代表以太网、令牌环、FDDI、PPP、X.25、帧中继、ATM 等,以及互联网层“隧道”,例如 IPv4 隧道。
IPv6 隧道协议引擎既充当“上层”又充当“链路层”,每个都有特定的输入和输出,如下所示:
(u.i) “隧道上层输入” - 由将被解封装的隧道 IPv6 数据包组成。隧道数据包通过 IPv6 层从以下位置传入:
(u.i.1) 链路层 - (path #1, Fig.5)
这些是发往该节点的隧道数据包,将进行解封装。
(u.i.2) 隧道链路层 - (path #7, Fig.5)
这些是在该节点上进行了一次或多次解封装的隧道数据包,即数据包具有一个或多个嵌套隧道报文头,而一个嵌套隧道报文头刚刚被丢弃。该节点是外部隧道及其一个或多个内部隧道的出口点。
对于上述两种情况,生成的原始数据包作为“隧道链路层”输出传回 IPv6 层,以供进一步处理(参见 b.2)。
(u.o) “隧道上层输出” - 由隧道 IPv6 数据包组成,这些数据包通过 IPv6 层向下传递到:
(u.o.1) 链路层 - (路径 #2, 图 5)
这些数据包经过封装并被发送到隧道出口点
(u.o.2) 隧道链路层 - (路径 #8,图 5)
这些隧道数据包经过嵌套封装。该节点是外隧道及其一个或多个内隧道的入口点节点。
实施说明:
隧道上层输入和输出可以类似于其他上层协议的输入和输出来实现。
隧道链路层输入输出如下:
(l.i)“隧道链路层输入”——由将要封装的原始 IPv6 数据包组成。
原始数据包通过 IPv6 层从以下位置传入:
(l.i.1) 上层 - (path #4, Fig.5)
这些是源自该节点并经过封装的原始数据包。原始数据包源和隧道入口点是同一个节点。
(l.i.2) 链路层 - (路径 #6,图 5)
这些是从不同节点传入的原始数据包,在此隧道入口点节点上进行封装。
(l.i.3) 隧道上层 - (路径#8,图 5)
这些数据包是经过嵌套封装的隧道数据包。该节点是外部隧道及其一个或多个内部隧道的入口点节点。
生成的隧道数据包作为隧道上层输出数据包通过 IPv6 层(参见 u.o)传递到:
(l.o)“隧道链路层输出”——由解封装产生的原始 IPv6 数据包组成。这些数据包通过 IPv6 层传递到:
(l.o.1) 上层 - (path #3, Fig.5)
这些原始数据包的目的地是这个节点。
(l.o.2) 链路层 - (路径 #5, Fig.5)
这些原始数据包的目的地是另一个节点;它们通过通往目的地的链接传输。
(l.o.3) 隧道上层 - (path #7, Fig.5)
这些数据包经过另一个解封装;它们是嵌套的隧道数据包。该节点既是外隧道的出口节点,也是一个或多个内隧道的出口节点。
实施说明:
隧道链路层输入和输出的实现类似于其他链路层协议的输入和输出,例如,将接口或伪接口与 IPv6 隧道相关联。
选择“IPv6 隧道链路”而不是其他链路是根据节点路由表的内容做出的数据包转发决定的结果。
4、 嵌套封装
嵌套 IPv6 封装是对隧道数据包的封装。它发生在 IPv6 隧道的一跳是隧道时。包含隧道的隧道称为外隧道。包含在外部隧道中的隧道称为内部隧道 - 参见图 6。内隧道及其外隧道是嵌套隧道。
图 6、嵌套封装
“内部IPv6隧道”的入口点节点接收由“外部IPv6隧道”入口点节点封装的隧道IPv6数据包。“内部隧道入口节点”将接收到的隧道数据包视为原始数据包并进行封装。生成的数据包是“内部 IPv6 隧道”的“隧道数据包”和“外部 IPv6 隧道”的“嵌套隧道数据包”。
4.1、 限制嵌套封装
隧道 IPv6 数据包被限制为最大 IPv6 数据包大小 [IPv6-Spec]。每次封装都会使封装数据包的大小增加隧道 IPv6 报文头的大小。因此,隧道报文头的数量以及嵌套封装的数量受到最大数据包大小的限制。然而,这个限制是如此之大(对于一个最小大小的原始数据包来说,超过 1600 个封装)以至于在大多数情况下它不是一个有效的限制。
由于嵌套封装导致隧道 IPv6 数据包大小的增加可能需要在隧道入口点进行分片 [IPv6-Spec] - 请参阅第 7 节。此外,由于嵌套封装,已经分片的隧道数据包的每个分片都会导致分片数量翻倍。此外,一旦这种分片开始,每个新的嵌套封装很可能会导致额外的分片。因此建议限制嵌套封装。
用于限制过度嵌套封装的建议机制是“隧道封装限制”选项,它在伴随封装 IPv6 报文头的 IPv6 目的地选项扩展报文头中携带。
4.1.1、 隧道封装限制选项
隧道入口点节点可以配置为包括隧道封装限制选项,作为附加到在该节点进入隧道的所有数据包的信息的一部分。Tunnel Encapsulaton Limit 选项承载在 Destination Options 扩展报文头 [IPv6-Spec] 中,位于封装 IPv6 报文头和原始数据包的 IPv6 报文头之间。(其他 IPv6 扩展头也可能出现在目标选项扩展头之前或之后,这取决于隧道入口点节点的配置信息。)
隧道封装限制选项指定允许在数据包前面添加多少额外的封装级别,或者换句话说,允许对数据包进行多少进一步的嵌套级别,而不包括包含选项本身的封装。例如,包含限制值为零的隧道封装限制选项意味着携带该选项的数据包在退出当前隧道之前可能不会进入另一个隧道。
隧道封装限制选项具有以下格式:
选项类型,值为十进制4
- 最高两位 - 设置为 00 - 表示“如果无法识别该选项,则跳过该选项”。
- 第三高位 - 设置为 0 - 表示此选项中的选项数据在到达数据包目的地 [IPv6-Spec] 的途中不会改变。
Opt Data Len 值为1 - 选项的数据部分是一个八位字节长。
Opt Data Value,Tunnel Encapsulation Limit value - 8 位无符号整数,指定允许多少进一步封装级别。
隧道封装限制选项仅对隧道入口点有用。隧道入口点节点需要为每个进入该节点的隧道的数据包执行以下过程:
(a) 检查数据包,查看其IPv6标头后是否存在隧道封装限制选项。必须严格按照“从左到右”的顺序检查IPv6报头之后的报头,一旦遇到以下任何一个报头,检查就会停止:(i)包含隧道封装限制的目标选项扩展报头,(ii)另一个IPv6报头,(iii)非扩展报头,如TCP、UDP或ICMP,或(iv)由于已加密或其类型未知而无法解析的标头。(请注意,此要求是IPv6一般规则的一个例外,即目的地选项扩展头只需由数据包的目的地节点检查。另一种选择是“更干净”这种方法本来可以使用逐跳扩展头来实现这一目的,但这会在隧道路径上的每个IPv6节点上造成不希望的额外处理负担,并可能导致额外延迟。)
(b) 如果在进入隧道的数据包中发现 Tunnel Encapsulation Limit 选项并且其限制值为零,则丢弃该数据包并向数据包的源发送 ICMP 参数问题消息 [ICMP-Spec],即前一个隧道入口点节点。Parameter Problem 消息的 Code 字段设置为零(“遇到错误的头字段”),Pointer 字段设置为指向 Tunnel Encapsulation Limit 选项的第三个八位字节(即包含零限值的八位字节) .
(c) 如果在进入隧道的数据包中发现 Tunnel Encapsulation Limit 选项并且其限制值非零,则必须包括一个附加的 Tunnel Encapsulation Limit 选项作为在此入口点添加的封装头的一部分。封装选项中的限制值设置为比在被封装的数据包中找到的限制值小一。
(d) 如果在进入隧道的数据包中没有找到 Tunnel Encapsulation Limit 选项,并且已经为该隧道配置了封装限制,则必须将 Tunnel Encapsulation Limit 选项作为封装报文头的一部分添加到该入口点,选项中的限制值设置为配置的限制。
(e) 如果在进入隧道的数据包中没有找到 Tunnel Encapsulation Limit 选项,并且如果没有为该隧道配置封装限制,则在此入口点添加的封装报文头中不包含 Tunnel Encapsulation Limit 选项。
在隧道入口点节点添加的隧道封装限制选项作为该隧道出口点节点的解封装过程的一部分被删除。
下面描述了两种应该避免的封装情况:
4.1.2、 环路封装
必须避免的一种特殊的封装情况是环路封装。环路封装发生在隧道 IPv6 入口点节点封装源自其自身并发往其自身的隧道 IPv6 数据包时。这可以在入口点节点中生成无限处理环路。
为避免这种情况,建议实现具有检查和拒绝隧道配置的机制,其中入口点和出口点节点地址都属于同一节点。还建议封装引擎检查并拒绝对隧道入口点和出口点地址对与原始数据包源地址和最终目标地址对相同的数据包进行封装。
4.1.3、 路由环路嵌套封装
在具有多层嵌套隧道的转发路径的情况下,当来自内部隧道的数据包重新进入它们尚未退出的外部隧道时,从内部隧道到外部隧道的路由环路特别危险。在这种情况下,嵌套封装成为递归封装,具有 4.1 中描述的负面影响。由于每个嵌套封装都增加了一个带有新跳数限制值的隧道头,因此IPv6跳数限制机制无法控制数据包到达外层隧道入口节点的次数,从而无法控制递归封装的次数。
当数据包从源到最终目的地的路径包括隧道时,数据包可以遍历的最大跳数应由两种机制共同控制,以避免路由环路中递归封装的负面影响:
(a) 原始数据包跳数限制。
它在对原始数据包执行的每个转发操作时递减。这包括原始数据包的每个封装。它不包括原始数据包的嵌套封装
(b) 隧道 IPv6 数据包封装限制。
它在数据包的每个嵌套封装时递减。
有关嵌套封装中过度封装风险因素的讨论,请参见附录 A。
5、 隧道 IPv6 报文头
隧道入口点节点填写隧道 IPv6 主报文头 [IPv6-Spec] 如下:
版本:值 6
流量等级:根据入口点节点隧道配置,流量类别可以设置为原始数据包或预配置值 - 请参阅第 6.4 节。
流量标签:根据入口点节点隧道配置,流标签可以设置为预先配置的值。典型值为零 - 请参阅第 6.5 节。
有效载荷长度:原始数据包长度加上封装(前置)IPv6 扩展报文头的长度(如果有)。
下一个报文头:下一个报文头值根据来自 Assigned Numbers RFC [RFC-1700 或其后继者] 的 [IPv6-Spec]。
例如,如果原始数据包是 IPv6 数据包,则设置为:
- 十进制值 41(为 IPv6 分配的下一个报文头编号)- 如果没有隧道扩展报文头。
- 值 0(为 IPv6 逐跳选项扩展报文头分配的下一个报文头编号) - 如果逐跳选项扩展报文头紧跟隧道 IPv6 报文头。
- 十进制值 60(为 IPv6 目标选项扩展报文头分配的下一个报文头编号)- 如果目标选项扩展报文头紧跟在隧道 IPv6 报文头之后。
跳数限制:隧道 IPv6 报文头跳数限制设置为预配置值 - 请参阅第 6.3 节。
主机的默认值是邻居发现通告的跳数限制 [ND-Spec]。路由器的默认值是来自 Assigned Numbers RFC 的默认 IPv6 Hop Limit 值(在撰写本文档时为 64)。
源地址:隧道入口点节点的出接口的 IPv6 地址。此地址配置为隧道入口点节点地址 - 参见第 6.1 节。
目的地地址:隧道出口点节点的 IPv6 地址。此地址配置为隧道出口点节点地址 - 参见第 6.2 节。
5.1、 隧道 IPv6 扩展头
根据 IPv6 节点配置参数,隧道入口点节点可能会在隧道 IPv6 主报文头中附加一个或多个 IPv6 扩展报文头,例如逐跳选项报文头、路由报文头等。
为了限制数据包的嵌套封装的数量,如果它被配置为这样做 - 参见第 6.6 节 - 隧道入口点包括一个包含隧道封装限制选项的目标选项扩展头。如果该选项是 Destination Options 报文头中存在的唯一选项,则报文头具有以下格式:
下一个报文头:标识原始数据包头的类型。例如,如果原始数据包是 IPv6 数据包,则下一个报文头协议值设置为十进制值 41(为 IPv6 分配的有效负载类型编号)。
Hdr Ext Len:Destination Options 扩展报文头的长度,以 8 个八位字节为单位,不包括前 8 个八位字节。如果此目标选项报文头中不存在其他选项,则设置为值 0。
选项类型:值 4 - 参见第 4.1.1 节。
选项数据长度:值 1 - 见第 4.1.1 节。
Tun Encap Lim:8 位无符号整数 - 参见第 4.1.1 节。
选项类型:值为1 - PadN 选项,用于在此报文头之后对齐报文头。
选项数据长度:值为1 - 一个八位字节的期权数据。
选项数据:值为0 - 一个零值八位字节。
6、 IPv6 隧道状态变量
IPv6 隧道状态变量(其中一些是或可能在隧道入口点节点上配置)是:
6.1、 IPv6隧道入口节点地址
隧道入口点节点地址是入口点节点的有效 IPv6 单播地址之一 - 建议在隧道配置时验证地址。
在数据包封装期间,隧道入口点节点地址被复制到隧道 IPv6 报文头中的源地址字段。
6.2、 IPv6隧道出口节点地址
隧道出口点节点地址用作隧道 IPv6 报文头的 IPv6 目标地址。隧道就像入口点节点和出口点节点之间的虚拟点对点链接。
在数据包封装期间,隧道出口点节点地址被复制到隧道 IPv6 报文头中的目标地址字段。
隧道入口点和出口点地址的配置不受 IPv6 自动配置或 IPv6 邻居发现的约束。
6.3、 IPv6 隧道跳数限制
IPv6 隧道被建模为“单跳虚拟链路”隧道,其中原始数据包通过隧道的传递就像原始数据包在单跳链路上的传递,而与 IPv6 中的跳数无关隧道。
“单跳”机制应该通过让隧道入口点节点设置独立于原始报文头的跳数限制的隧道 IPv6 报文头跳数限制来实现。
“单跳”机制从原始 IPv6 数据包中隐藏了隧道的 IPv6 跳数。
建议将隧道跳数限制配置为确保:
(a) 隧道 IPv6 数据包可以到达隧道出口点节点
(b) 如果在 IPv6 隧道内出现路由环路,则隧道包的快速到期。
主机的隧道跳数限制默认值是 IPv6 邻居发现通告的跳数限制 [ND-Spec]。路由器的隧道跃点限制默认值是来自 Assigned Numbers RFC 的默认 IPv6 跃点限制值(在撰写本文档时为 64)。
隧道跳数限制被复制到隧道入口点节点封装的每个数据包的隧道 IPv6 报文头的跳数限制字段中。
6.4、 IPv6 隧道包流量类
IPv6 Tunnel Packet Traffic Class表示隧道入口节点在隧道头的Traffic Class字段中设置的值。默认值为零。配置的 Packet Traffic Class 还可以指示隧道头中的 Traffic Class 字段的值是从原始头中复制而来,还是设置为预先配置的值。
6.5、 IPv6 隧道流标签
IPv6隧道流标签表示隧道入口节点在隧道头的流标签中设置的值。默认值为零。
6.6、 IPv6 隧道封装限制
隧道封装限制值可以指示入口点节点是否配置为限制源自该节点的隧道数据包的封装数量。IPv6 隧道封装限制是允许在该入口点节点进行封装的数据包的最大额外封装数。推荐的默认值为 4。配置为限制嵌套封装数量的入口点节点将包含隧道封装限制选项的目标选项扩展报文头附加到正在进行封装的原始数据包 - 请参阅第 4.1 节和第 4.1.1 节。
6.7、 IPv6 隧道 MTU
隧道 MTU 动态设置为隧道入口点和隧道出口点节点之间的路径 MTU,减去隧道报文头的大小:可以通过隧道发送而不分片的隧道数据包有效负载的最大大小 [ IPv6 规范]。隧道入口点节点在隧道入口点和出口点节点 [PMTU-Spec]、[ICMP-Spec] 之间的路径上执行路径 MTU 发现。嵌套隧道的隧道 MTU 是外部隧道的隧道 MTU 减去嵌套隧道头的大小。
7、 IPv6 隧道数据包大小问题
预先添加隧道报文头会增加数据包的大小,因此由封装 IPv6 原始数据包产生的隧道数据包可能需要分片。
由原始数据包封装产生的隧道 IPv6 数据包被认为是源自隧道入口点节点的 IPv6 数据包。因此,与任何 IPv6 数据包源一样,隧道入口点节点必须支持隧道 IPv6 数据包的分片。
将隧道数据包转发到隧道中的另一个节点的隧道中间节点遵循一般 IPv6 规则,即它不得对正在转发的数据包进行分片。
在隧道末端接收隧道数据包进行解封装的隧道出口点节点对扩展报文头应用严格的从左到右处理规则。在分片隧道数据包的情况下,在确定存在嵌入数据包之前,将这些片段重新组合成一个完整的隧道数据包。
笔记:
当分片隧道数据包的目的地是由任播地址标识的出口点节点时,会出现一个特殊问题。问题类似于原始分片 IPv6 数据包发往由任播地址标识的节点的问题,即数据包的所有分片必须到达同一目标节点,该节点才能成功执行重组,即发送到任播地址的数据包不一定满足的要求。
7.1、 IPv6隧道包分片
当一个 IPv6 原始数据包进入隧道时,如果原始数据包大小超过隧道 MTU(即隧道入口点和隧道出口点之间的路径 MTU 减去隧道头的大小),它处理如下:
(a) 如果原始 IPv6 数据包大小大于 IPv6 最小链路 MTU [IPv6-Spec],则入口点节点丢弃该数据包并向原始数据包的源地址发送 ICMPv6“Packet Too Big”消息推荐的MTU大小字段设置为隧道MTU或IPv6最小链路MTU,取较大者,即max(隧道MTU,IPv6最小链路MTU)。另见第 6.7 和 8.2 节。
(b) 如果原始 IPv6 数据包等于或小于 IPv6 最小链路 MTU,则隧道入口点节点封装原始数据包,随后将生成的 IPv6 隧道数据包分成不超过到路径 MTU 的 IPv6 片段。隧道出口点。
7.2、 IPv4隧道包分片
当一个 IPv4 原始数据包进入隧道时,如果原始数据包大小超过隧道 MTU(即隧道入口点和隧道出口点之间的路径 MTU 减去隧道头的大小),它处理如下:
(a) 如果原始 IPv4 数据包头中的 Don't Fragment - DF - 位标志为 SET,则入口点节点丢弃该数据包并返回 ICMP 消息。ICMP 消息的类型 =“无法到达”,代码 =“数据包太大”,建议的 MTU 大小字段设置为隧道 MTU 的大小 - 参见第 6.7 和 8.3 节。
(b) 如果在原始数据包头中 Don't Fragment - DF - 位标志为 CLEAR,则隧道入口点节点封装原始数据包,随后将生成的 IPv6 隧道数据包分成不超过路径的 IPv6 片段MTU 到隧道出口点。
8、 IPv6 隧道错误处理和报告
IPv6 隧道遵循一般规则,即在处理 IPv6 数据包期间检测到的错误通过 ICMP 消息报告给数据包的源。
在包含 IPv6 隧道的转发路径上,将不属于任何隧道的节点检测到的错误直接报告给原始 IPv6 数据包的源。
隧道内节点检测到的错误会报告给隧道报文的源,即隧道入口节点。发送到隧道入口点节点的 ICMP 消息将隧道 IPv6 数据包作为 ICMP 有效负载,该隧道 IPv6 数据包将原始数据包作为其有效负载。
在隧道内遇到数据包错误的原因可能是以下问题:
(a) 隧道报文头,或
(b) 隧道包。
隧道报文头和隧道数据包问题都报告给隧道入口点节点。
如果隧道数据包问题是原始数据包(即隧道数据包的有效负载)问题的结果,那么该问题也会报告给原始数据包的源。
要将隧道内检测到的问题报告给原始数据包的源,隧道入口点节点必须将从隧道内部接收到的 ICMP 消息中继到原始 IPv6 数据包的源。
图 7 和图 8 说明了节点错误报告机制中可能发生的处理示例:
图 7、节点中的错误报告流程(IPv6 隧道协议引擎)
图 7 路径 #0 和图 8 (a) - IPv6 隧道入口点从隧道内部接收 ICMP 数据包,在图 7 中标记为隧道 ICMPv6 消息。隧道入口点节点 IPv6 层将收到的 ICMP 消息传递给 ICMPv6 输入。ICMPv6 输入基于 ICMP 类型和代码 [ICMP-Spec] 生成内部“错误代码”。
图 7 路径 #1 - 内部错误代码,与“ICMPv6 消息有效负载”一起传递给上层协议 - 在这种情况下是 IPv6 隧道上层错误输入。
图 7 路径 #2 和图 8 (b) - IPv6 隧道错误输入解封装隧道 IPv6 数据包,即 ICMPv6 消息有效负载,获得原始数据包,从而
获得原始报文头并调度“内部错误代码” ,从原始数据包头的源地址和原始数据包,一直到由 ICMP 消息有效负载中原始数据包之前的隧道头中的 Next Header 字段标识的协议的错误报告块。
从这里开始,处理取决于原始数据包的协议:
(a) - 对于 IPv6 原始数据包
图7路径#3和图8(c.1)-对于IPv6原始数据包,ICMPv6错误报告根据“内部错误代码”构建类型和代码的ICMP消息,其中包含作为ICMP有效负载的“原始数据包”。
图7路径#4和图8(d.1)-ICMP消息将隧道入口点节点地址作为源地址,原始数据包源节点地址作为目的地址。隧道入口点节点将ICMP消息发送到原始数据包的源节点。
(b) - 对于 IPv4 原始数据包
图 7 路径 #5 和图 8 (c.2) - 对于 IPv4 原始数据包,ICMPv4 错误报告构建一个类型和代码源自“内部错误代码”的 ICMP 消息,包含“原始数据包” " 作为 ICMP 有效负载。
图 7 路径 #6 和图 8 (d.2) - ICMP 消息以隧道入口点节点 IPv4 地址作为源地址,将原始数据包 IPv4 源节点地址作为目的地址。隧道入口点节点将 ICMP 消息发送到原始数据包的源节点。
正在发生的报文头处理的图形描述如下:
或对于 IPv4 原始数据包
图 8、ICMP 错误报告和处理
8.1、 隧道 ICMP 消息
报告给原始数据包源的隧道 ICMP 消息是:
hop limit exceeded,超出跳数限制
隧道的跳数限制配置错误,或包含路由环路,并且数据包无法到达隧道出口点节点。将此问题报告给隧道入口点节点,可以将隧道跳数限制重新配置为更高的值。如第 8.2 节或第 8.3 节所述,该问题会进一步报告给原始数据包的来源。
unreachable node,不可达节点
隧道中的节点之一不可达或不再可达。将此问题报告给隧道入口点节点,应重新配置隧道入口点和出口点之间的有效和活动路径。
如第 8.2 节或第 8.3 节所述,该问题会进一步报告给原始数据包的来源。
parameter problem,参数问题
参数问题 ICMP 消息指向有效的 Tunnel Encapsulation Limit Destination 报文头,其中 Tun Encap Lim 字段值设置为 1,这表明隧道数据包超过了允许的最大封装数。如第 8.2 节或第 8.3 节所述,该问题会进一步报告给原始数据包的来源。
隧道内部检测到的上述三个问题,即隧道配置问题和隧道拓扑问题,作为由“链路问题”引起的隧道通用“不可达”问题报告给原始 IPv6 数据包的源 - 参见第 8.2 节和 8.3。
packet too big,包太大
隧道数据包超过隧道路径 MTU。
此类ICMP报文携带的信息使用如下:
- 由接收隧道入口点节点设置或调整隧道MTU
- 由发送隧道入口点节点向原始数据包的源指示在向隧道入口点节点发送 IPv6 数据包时应该使用的 MTU 大小。
8.2、 IPv6 原始数据包的 ICMP 消息
隧道入口点节点构建发送到原始数据包源的 ICMP 消息的 ICMP 和 IPv6 报文头,如下所示:
IPv6 字段:
源地址:传出接口的有效单播 IPv6 地址。
目的地址:复制自原始 IPv6 报文头的源地址字段。
ICMP 字段:
对于以下任何隧道 ICMP 错误消息:
“超出跳数限制”
“无法访问的节点”
“参数问题” - 指向有效的 Tunnel Encapsulation Limit 目标报文头,其中 Tun Encap Lim 字段设置为零值:
类型, 1 - 不可达节点
代码, 3 - 地址不可达
对于隧道 ICMP 错误消息“数据包太大”:
类型, 2 - 数据包太大
代码, 0
MTU, 隧道 ICMP 消息中的 MTU 字段减去隧道头的长度。
根据 7.1 中描述的一般规则,只有当原始数据包大小大于 IPv6 [IPv6-Spec] 所需的最小链路 MTU 大小时,才会向原始数据包的源发送 ICMP“数据包太大”消息。
8.3、 IPv4 原始数据包的 ICMP 消息
隧道入口点节点构建发送到原始数据包源的 ICMP 消息的 ICMP 和 IPv4 报文头,如下所示:
IPv4 字段:
源地址:传出接口的有效单播 IPv4 地址。
目的地址:复制自原始 IPv4 报文头的源地址字段。
ICMP 字段:
对于以下任何隧道 ICMP 错误消息:
“超出跳数限制”
“无法访问的节点”
“参数问题” - 指向有效的 Tunnel Enacpsulation Limit 目标报文头,其中 Tun Encap Lim 字段设置为零值:
类型, 3 - 目的地不可达
代码, 1 - 主机不可达
对于隧道 ICMP 错误消息“数据包太大”:
类型, 3 - 目的地不可达
代码, 4 - 数据包太大
MTU ,隧道 ICMP 消息中的 MTU 字段减去隧道头的长度。
根据第 7.2 节中描述的一般规则,如果原始 IPv4 报文头具有 DF - 不要分片 - 位标志 SET,则将 ICMP“数据包太大”消息发送到原始 IPv4 数据包源节点。
8.4、 嵌套隧道包的 ICMP 消息
在嵌套隧道数据包发现错误的情况下,从内部隧道报告节点接收 ICMP 错误消息的内部隧道入口点按照第 8 节中描述的机制将 ICMP 消息中继到外部隧道入口点.,8.1、8.2 和 8.3。此外,外部隧道入口点将 ICMP 消息中继到原始数据包的源,遵循相同的机制。
9、 安全考虑
可以通过保护隧道入口点和出口点节点之间的 IPv6 路径来保护 IPv6 隧道。安全架构、机制和服务在 [RFC2401]、[RFC2402] 和 [RFC2406] 中进行了描述。一个安全的 IPv6 隧道可以充当网关到网关的安全路径,如 [RFC2401] 中所述。
对于安全的 IPv6 隧道,除了本文前面描述的机制外,隧道的入口点节点对数据包执行安全算法,并在隧道报文头中添加一个或多个符合 [IPv6-规范]、[RFC2401] 和 [RFC2402] 或 [RFC2406]。
安全 IPv6 隧道的出口点节点执行安全算法并处理隧道安全报文头[s],作为前面描述的隧道报文头处理的一部分,并符合 [RFC2401]、[RFC2402] 或 [RFC2406]。出口点节点在隧道报文头处理完成后丢弃隧道安全报文头和其余隧道报文头。
在安全 IPv6 隧道的入口点和出口点节点对隧道数据包执行的完整性、身份验证和机密性程度以及安全处理取决于安全报文头的类型 - 身份验证 (AH) 或加密 (ESP) - 以及在隧道的安全关联中配置的参数。应用于隧道数据包的安全级别和机制与应用于作为隧道数据包有效载荷的原始数据包的安全性之间不存在依赖或交互。在嵌套隧道的情况下,每个内部隧道可能有自己的一组安全服务,独立于外部隧道的安全服务,或原始数据包的源和目的地之间的安全服务。
10、 致谢
本文档部分来源于 IPng 工作组邮件列表中关于 IPv6 隧道的多次讨论,以及 IPng 工作组对 1995 年 7 月在斯德哥尔摩举行的第 33 届 IETF 上关于 IPv6 隧道的 IPv6 演示的反馈。
此外,以下关注隧道或封装的文档是有用的参考:RFC 1933 (R. Gilligan, E. Nordmark), RFC 1241 (R. Woodburn, D. Mills), RFC 1326 (P. Tsuchiya), RFC 1701, RFC 1702 (S. Hanks, D. Farinacci, P. Traina)、RFC 1853 (W.Simpson) 以及 RFC 2003 (C. Perkins)。
Brian Carpenter、Richard Draves、Bob Hinden、Thomas Narten、Erik Nordmark(按字母顺序)为改进本文档提供了宝贵的审阅意见和建议。Scott Bradner、Ross Callon、Dimitry Haskin、Paul Traina 和 James Watt(按字母顺序)分享了他们对本文档中关注问题的看法或经验。Judith Grossman 提供了她多年的编辑和写作经验以及大量探索性技术问题的样本。
11、 参考文献
[IPv6-Spec] Deering, S. and R. Hinden, "Internet Protocol Version 6 (IPv6) Specification", RFC 2460, December 1998. [ICMP-Spec] Conta, A. and S. Deering "Internet Control Message Protocol for the Internet Protocol Version 6 (IPv6)", RFC 2463, December 1998. [ND-Spec] Narten, T., Nordmark, E., and W. Simpson "Neighbor Discovery for IP Version 6 (IPv6)", RFC 2461, December 1998. [PMTU-Spec] McCann, J., Deering, S. and J. Mogul, "Path MTU Discovery for IP Version 6 (IPv6)", RFC 1981, August 1996. [RFC2401] Atkinson, R., "Security Architecture for the Internet Protocol", RFC 2401, November 1998. [RFC2402] Atkinson, R., "IP Authentication Header", RFC 2402, November 1998. [RFC2406] Atkinson, R., "IP Encapsulation Security Payload (ESP)", RFC 2406, November 1998. [RFC-1853] Simpson, W., "IP in IP Tunneling", RFC 1853, October 1995. [Assign-Nr] Reynolds, J. and J. Postel, "Assigned Numbers", STD 2, RFC 1700, October 1994. See also: http://www.iana.org/numbers.html [RFC2119] Bradner, S., "Key words for use in RFCs to indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
附录 A
A.1、 嵌套封装中的风险因素
如果数据包在退出之前重新进入外部隧道,则数据包的嵌套封装成为递归封装。递归封装的高风险情况是隧道入口节点无法确定经过封装的数据包在退出隧道之前是否重新进入隧道的情况。导致隧道数据包在退出隧道之前重新进入隧道的路由环路肯定是问题的主要原因。但由于路由环路存在并发生,理解和描述递归封装风险较高的情况很重要。
有两个重要因素决定了路由环路递归封装的风险因素:
(a) 隧道类型,
(b) 到隧道出口点的路由类型,它决定了数据包通过隧道转发,即通过隧道虚拟链路。
A.1.1、 嵌套封装中的风险因素 - 隧道类型。
被确定为路由环路中递归封装的高风险因素的隧道类型是:
“具有相同出口点的内部隧道”。
由于原始数据包的源和目的地是用于决定是否通过隧道转发数据包的主要信息,因此在单个隧道(非内部)的情况下可以通过检查数据包来避免递归封装要封装的不是起源于入口点节点。这种机制在 [RFC-1853] 中提出。
然而,这种类型的保护在具有不同入口点和相同出口点的内部隧道的情况下似乎效果不佳。
当封装在内部隧道中的数据包通过路由环路到达外部隧道的入口点节点时,具有不同入口点和相同出口点的内部隧道在决定是否封装数据包时会产生歧义。由于隧道数据包的源是内部隧道入口节点,与外部隧道的入口节点不同,源地址检查(如上所述)无法检测到无效封装,因此隧道数据包每次通过路由环路到达它时,都会在外部隧道中被封装。
A.1.2、 嵌套封装中的风险因素 - 路由类型。
到隧道出口点节点的路由类型也被确定为路由环路中递归封装的高风险因素。
到隧道出口点节点的一种类型的路由是到指定目的地节点的路由,即目的地是有效的指定IPv6地址(到节点的路由)。可以基于原始分组目的地地址与存储在该路由的隧道入口点节点路由表条目中的目的地地址的最长匹配来选择这样的路由。在这种路由上转发的数据包首先被封装,然后转发到隧道出口点节点。
到隧道出口点节点的另一种路由类型是到指定前缀网络的路由,即目的地是有效的指定 IPv6 前缀(到网络的路由)。可以基于原始分组目的地地址与存储在该路由的隧道入口点节点路由表条目中的前缀目的地的最长路径匹配来选择这样的路由。在这种路由上转发的数据包首先被封装,然后转发到隧道出口点节点。
最后,通往隧道出口点的另一种路线是默认路线,或通往未指定目的地的路线。当在路由表中没有找到原始数据包的目的地的其他匹配时,选择此路由。作为默认路由的第一跳的隧道是“默认隧道”。
如果到隧道出口点的路由是到节点的路由,则递归封装的风险因素是最小的。
如果通往隧道出口点的路线是通往网络的路线,则递归封装的风险系数为中等。有一系列目标地址将与路由关联的前缀匹配。如果一个或多个具有不同隧道入口点的内部隧道具有与外部隧道出口点的路由匹配的出口点节点地址,则如果隧道数据包从这样的内部隧道内部转移,则可能会发生递归封装到外部隧道的入口点,其出口点的路线与内部隧道的出口点相匹配。
如果到隧道出口点的路由是默认路由,则递归封装的风险系数最大。由于缺少更好的路由,数据包通过默认隧道转发。在许多情况下,通过默认隧道转发可能会发生在范围广泛的目标地址上,最大范围是整个 Internet 减去节点的链接。因此,很可能在路由环路的情况下,如果隧道数据包从内部隧道转移到隧道是默认隧道的外部隧道入口点,则该数据包将再次被封装,因为默认路由机制将无法根据目的地进行不同的辨别。
完整的版权声明
版权所有 (C) 互联网协会 (1998)。版权所有。
本文件及其翻译可以复制和提供给其他人,对其发表评论或以其他方式解释或协助其实施的衍生作品可以全部或部分准备、复制、出版和分发,不受任何形式的限制, 前提是上述版权声明和本段包含在所有此类副本和衍生作品中。但是,不得以任何方式修改本文档本身,例如删除版权声明或对 Internet 协会或其他 Internet 组织的引用,除非出于开发 Internet 标准的需要,在这种情况下,版权程序定义在必须遵循互联网标准流程,或根据需要将其翻译成英语以外的其他语言。
上述授予的有限权限是永久性的,不会被互联网协会或其继任者或受让人撤销。
本文档和此处包含的信息按“原样”提供,互联网协会和互联网工程工作组不提供任何明示或暗示的保证,包括但不限于使用此处信息不会做出的任何保证侵犯任何权利或任何对适销性或特定用途适用性的默示保证。