跳到主要内容

3. 分片和路径 MTU 发现

正如可能接收一个过大而无法在其输出链路上传输的不带标签 IP 数据报一样, 也可能接收一个过大而无法在其输出链路上传输的带标签数据包。

还有可能, 一个接收到的数据包(带标签或不带标签)原本足够小, 可以在该链路上传输, 但因为在其标签栈上压入了一个或多个额外的标签而变得过大。在标签交换中, 如果一个数据包被压入了额外的标签, 它就可能在尺寸上变大。因此, 如果接收一个标签栈上带有 1500 字节帧载荷的带标签数据包, 并压入一个额外的标签, 就需要将其作为一个带有 1504 字节载荷的帧进行转发。

本节规定了处理"过大"的带标签数据包的规则。特别地, 它提供的规则确保: 实现了路径 MTU 发现(Path MTU Discovery)[4] 的主机, 以及使用 IPv6 [7,8] 的主机, 能够生成不需要分片的 IP 数据报, 即使这些数数据报在网络中传输时被加上了标签。

一般而言, 没有实现路径 MTU 发现 [4] 的 IPv4 主机会发送不超过 576 字节的 IP 数据报。由于当今大多数数据链路上使用的 MTU 都是 1500 字节或更大, 这类数据报即使被加上标签, 需要被分片的概率也极小。

一些没有实现路径 MTU 发现 [4] 的主机, 只要 IP 源地址和目的地址在同一子网内, 就会生成包含 1500 字节的 IP 数据报。这些数据报不会经过路由器, 因此不会被分片。

遗憾的是, 一些主机会生成包含 1500 字节的 IP 数据报, 只要 IP 源地址和目的地址具有相同的分类网络号。这是当这类数据报被加上标签时, 存在任何分片风险的唯一情形。(即便如此, 除非该数据包在首次被加标签和取消标签之间的时间里必须穿越某种以太网, 否则不太可能发生分片。)

本文档规定了一些规程, 使网络可以被配置成: 来自未实现路径 MTU 发现的主机的大型数据报, 在首次被加标签时仅被分片一次。这些规程使得(在适当的配置下)可以避免对任何已经被加上标签的数据包进行分片的需要。

3.1. 术语

对于特定的数据链路, 我们可以使用以下术语:

  • 帧载荷(Frame Payload):

    数据链路帧的内容, 不包括任何数据链路层头部或尾部(例如, MAC 头部、LLC 头部、802.1Q 头部、PPP 头部、帧校验序列等)。

    当一帧承载一个不带标签的 IP 数据报时, 帧载荷就是 IP 数据报本身。当一帧承载一个带标签的 IP 数据报时, 帧载荷由标签栈项和 IP 数据报组成。

  • 常规最大帧载荷大小(Conventional Maximum Frame Payload Size):

    数据链路标准所允许的最大帧载荷大小。例如, 以太网的常规最大帧载荷大小为 1500 字节。

  • 真实最大帧载荷大小(True Maximum Frame Payload Size):

    连接在数据链路上的接口硬件能够正确发送和接收的最大帧载荷大小。

    在 ethernet 和 802.3 网络上, 据信真实最大帧载荷大小比常规最大帧载荷大小大 4-8 个字节(只要既不存在 802.1Q 头部也不存在 802.1p 头部, 并且在数据包到达下一跳的过程中, 交换机或网桥不会加入这两者中的任何一个)。例如, 据信大多数以太网设备能够正确发送和接收承载 1504 字节、甚至可能是 1508 字节载荷的数据包, 至少, 只要以太网头部没有 802.1Q 或 802.1p 字段即可。

    在 PPP 链路上, 真实最大帧载荷大小可能实际上没有上限。

  • 带标签数据包的有效最大帧载荷大小(Effective Maximum Frame Payload Size for Labeled Packets):

    根据数据链路上设备的能力以及所使用的数据链路头部的大小, 它可能是常规最大帧载荷大小, 也可能是真实最大帧载荷大小。

  • 初始被标签的 IP 数据报(Initially Labeled IP Datagram):

    假设在一个特定的 LSR 处接收到一个不带标签的 IP 数据报, 并且该 LSR 在转发该数据报之前压入了一个标签。这样的数据报在该 LSR 处被称为"初始被标签的 IP 数据报"。

  • 先前被标签的 IP 数据报(Previously Labeled IP Datagram):

    在一个特定的 LSR 接收到它之前, 已经被加上标签的 IP 数据报。

3.2. 初始被标签的 IP 数据报的最大大小

每一个能够

  • a) 接收一个不带标签的 IP 数据报,

  • b) 为该数据报添加一个标签栈, 并且

  • c) 转发所得的带标签数据包

的 LSR, SHOULD 支持一个名为"初始被标签的 IP 数据报的最大大小"(Maximum Initially Labeled IP Datagram Size)的配置参数, 该参数可以被设置为一个非负值。

如果将该配置参数设置为零, 则它没有任何效果。

如果将其设置为一个正值, 则按以下方式使用。如果:

  • a) 接收到一个不带标签的 IP 数据报, 并且

  • b) 该数据报的 IP 头部中没有设置 DF 位, 并且

  • c) 该数据报在转发之前需要被加上标签, 并且

  • d) 该数据报的大小(加标签之前)超过了该参数的值,

那么

  • a) 该数据报必须被分片, 每一片的大小都不大于该参数的值, 并且

  • b) 每一片必须被加上标签, 然后被转发。

例如, 如果该配置参数被设置为 1488, 那么任何包含超过 1488 字节的不带标签 IP 数据报, 都会在加标签之前被分片。每一片都能够承载在 1500 字节的数据链路上, 而无需进一步分片, 即使其标签栈上被压入了多达三个标签。

换句话说, 将该参数设置为非零值, 可以消除对"先前被标签的 IP 数据报"的所有分片, 但它可能导致对"初始被标签的 IP 数据报"进行一些不必要的分片。

请注意, 该参数的设置不影响那些设置了 DF 位的 IP 数据报的处理; 因此路径 MTU 发现的结果不受该参数设置的影响。

3.3. 带标签的 IP 数据报何时"过大"?

一个带标签的 IP 数据报, 如果其大小超过了它将被转发其上的数据链路的常规最大帧载荷大小, MAY 被视为"过大"。

一个带标签的 IP 数据报, 如果其大小超过了它将被转发其上的数据链路的真实最大帧载荷大小, MUST 被视为"过大"。

一个并非"过大"的带标签 IP 数据报 MUST 在不分片的情况下进行传输。

3.4. 处理过大的带标签 IPv4 数据报

如果一个带标签的 IPv4 数据报"过大", 并且其 IP 头部中没有设置 DF 位, 那么 LSR MAY 静默地丢弃该数据报。

请注意, 只有在网络中每一个能够向不带标签的 IP 数据报添加标签栈的 LSR 都将"初始被标签的 IP 数据报的最大大小"设置为非零值时, 丢弃这类数据报才是一种合理的规程。

如果 LSR 选择不丢弃一个过大的带标签 IPv4 数据报, 或者该数据报中设置了 DF 位, 那么它 MUST 执行以下算法:

  1. 剥除标签栈项, 以获得 IP 数据报。

  2. 令 N 为标签栈中的字节数(即, 标签栈项个数的 4 倍)。

  3. 如果 IP 数据报的 IP 头部中没有设置"不分片"(Don't Fragment)位:

    a. 将其转换为分片, 每个分片 MUST 至少比有效最大帧载荷大小小 N 个字节。

    b. 为每个分片加上相同的标签头部——如果分片不是必需的话, 该标签头部本应出现在原始数据报上。

    c. 转发这些分片。

  4. 如果 IP 数据报的 IP 头部中设置了"不分片"位:

    a. 该数据报 MUST NOT 被转发。

    b. 创建一个 ICMP 目的不可达消息(Destination Unreachable Message):

    i. 将其 Code 字段 [3] 设置为"需要分片且设置了 DF"(Fragmentation Required and DF Set),

    ii. 将其 Next-Hop MTU 字段 [4] 设置为有效最大帧载荷大小与 N 值之差。

    c. 如果可能, 将该 ICMP 目的不可达消息发送给被丢弃数据报的源地址。

3.5. 处理过大的带标签 IPv6 数据报

要处理一个过大的带标签 IPv6 数据报, LSR MUST 执行以下算法:

  1. 剥除标签栈项, 以获得 IP 数据报。

  2. 令 N 为标签栈中的字节数(即, 标签栈项个数的 4 倍)。

  3. 如果 IP 数据报包含超过 1280 字节(不计入标签栈项), 或者它不包含分片头部(fragment header), 那么:

    a. 创建一个 ICMP Packet Too Big 消息, 并将其 Next-Hop MTU 字段设置为有效最大帧载荷大小与 N 值之差。

    b. 如果可能, 将该 ICMP Packet Too Big 消息发送给该数据报的源地址。

    c. 丢弃该带标签的 IPv6 数据报。

  4. 如果 IP 数据报不大于 1280 个八位组, 并且它包含分片头部, 那么

    a. 将其转换为分片, 每个分片 MUST 至少比有效最大帧载荷大小小 N 个字节。

    b. 为每个分片加上相同的标签头部——如果分片不是必需的话, 该标签头部本应出现在原始数据报上。

    c. 转发这些分片。

    这些分片将在目的主机处进行重组。

3.6. 关于路径 MTU 发现的含义

上面所述的用于处理设置了 DF 位但"过大"的数据报的规程, 对 RFC 1191 [4] 的路径 MTU 发现规程有影响。实现了这些规程的主机会发现一个足够小的 MTU, 使得可以在数据报上压入 n 个标签而无需分片, 其中 n 是沿当前所用路径实际被压入的标签个数。

换句话说, 来自使用路径 MTU 发现的主机的数据报, 永远不会因为需要加上标签头部、或向已有标签头部添加新标签而需要被分片。(此外, 来自使用路径 MTU 发现的主机的数据报通常设置了 DF 位, 因此无论如何都不会被分片。)

请注意, 只有在带标签 IP 数据报需要进行分片的位置, 能够将 ICMP 目的不可达消息路由回该数据包的源地址时, 路径 MTU 发现才能正常工作。参见 2.3 节。

如果无法将 ICMP 消息从 MPLS"隧道"内路由回数据包的源地址, 但网络配置使得位于隧道发送端的 LSR 能够接收到必须通过该隧道、却过大而无法不分片地通过隧道的数据包, 那么:

  • 位于隧道发送端的 LSR MUST 能够确定整个隧道的 MTU。它 MAY 通过将数据包通过该隧道发送到隧道的接收端点, 并对这些数据包执行路径 MTU 发现来做到这一点。

  • 每当隧道的发送端点需要向隧道中发送一个数据包, 且该数据包设置了 DF 位, 并超过了隧道 MTU 时, 隧道的发送端点 MUST 向源地址发送 ICMP 目的不可达消息, 其 Code 为"需要分片且设置了 DF", 并且 Next-Hop MTU 字段按上述方式设置。