3. SR-MPLS 数据平面深入

在 MX 系列平台上,SR-MPLS 的数据平面行为最终都落在 MPLS 标签栈的三种基本动作上:压入(Push)、交换(Swap)和弹出(Pop)。理解这三类动作在 MX 转发路径中的触发条件与标签变化,是排查 SR 转发异常、验证 SID 分配正确性的基础。本节从标签栈操作出发,结合前缀 SID、邻接 SID 与全局标签空间,说明 MX 上 SR-MPLS 报文实际如何被转发。

一、标签栈的三种基本动作

MPLS 转发本质上是“入标签 → 出标签 + 下一跳”的映射。在 SR-MPLS 中,这个映射由 SID 决定。MX 的 PFE(Packet Forwarding Engine)在收到带标签报文后,会查 MPLS 转发表(mpls.0),执行以下动作之一:

  • Push(压入):在已有标签栈顶部再压入一个或多个标签。典型场景是入口 PE 将 IP 报文封装为 SR-MPLS 报文,压入由前缀 SID 组成的标签栈。
  • Swap(交换):替换栈顶标签,标签栈深度不变。典型场景是中间 P 路由器根据栈顶 SID 查表,将入标签替换为出标签并转发到下一跳。
  • Pop(弹出):移除栈顶标签。典型场景是倒数第二跳(Penultimate Hop Popping,PHP)或目的节点弹出标签,将报文还原为 IP 或交给上层。

需要注意,SR-MPLS 中还存在“Pop 后继续查表”的隐式操作,例如 PHP 弹出后由最后一跳按 IP 转发;以及“Swap 到隐式空标签”的情况,即出标签为 3(Implicit Null),表示下一跳将直接弹出该标签。

二、前缀 SID 与邻接 SID 的标签行为差异

前缀 SID(Prefix SID)是全局标签空间中的标签,由 IGP(IS-IS 或 OSPF)泛洪,通常对应某个 Loopback 地址。它的标签值在整张 SR 域内唯一,转发时表现为“逐跳 Swap,最终 Pop”。例如某节点 Loopback 为 10.0.0.1/32,分配前缀 SID 16001,则整条路径上各节点都会安装 16001 对应的转发表项,中间节点执行 Swap,倒数第二跳执行 PHP。

邻接 SID(Adjacency SID)是本地标签空间中的标签,只在本地节点有效,用于标识某条特定链路或邻接关系。它不参与全局泛洪,通常用于显式路径、流量工程或 TI-LFA 备份路径。邻接 SID 的转发行为通常是“Pop 后从指定接口发出”,即弹出该标签并将报文送到对应邻接。

两者在 MX 上的关键区别可以归纳为:前缀 SID 是“目的导向”,标签值全局唯一,转发路径由 IGP 最短路径决定;邻接 SID 是“链路导向”,标签值本地有效,转发路径由显式栈指定。实际部署中,前缀 SID 负责基础可达性,邻接 SID 负责路径约束与保护。

三、全局标签空间与本地标签空间的分配机制

MX 上 SR-MPLS 的标签分配涉及两个空间:

  • 全局标签空间(Global Label Space):由 SRGB(Segment Routing Global Block)定义,默认范围通常为 16000–23999。前缀 SID 从该空间分配,标签值 = SRGB 起始值 + SID 索引。例如 SRGB 起始 16000,索引 1 对应标签 16001。
  • 本地标签空间(Local Label Space):由 SRLB(Segment Routing Local Block)定义,默认范围通常为 30000–39999。邻接 SID 从该空间分配,仅本地有效。

在 MX 上查看 SRGB 与 SRLB 配置:

show configuration protocols isis source-packet-routing
    srgb start-label 16000 index-range 8000;
    srlb start-label 30000 index-range 1000;

查看前缀 SID 与邻接 SID 分配结果:

show isis database detail | match "SID"
show isis adjacency detail | match "Adjacency SID"
show route table mpls.0 label 16001

典型输出中,前缀 SID 会显示为“Prefix-SID 16001”,邻接 SID 会显示为“Adj-SID 30001”等。MX 的 PFE 会将它们分别安装到 mpls.0 表中,前缀 SID 对应 Swap 或 Pop 动作,邻接 SID 对应 Pop 并指定出接口。

四、MX 上标签栈操作的转发路径示例

假设拓扑为 PE1 — P1 — P2 — PE2,PE2 的 Loopback 为 10.0.0.2/32,前缀 SID 为 16002。PE1 向 PE2 发送 IP 报文时,入口 PE1 执行 Push,压入标签 16002。P1 收到后查 mpls.0,执行 Swap,将 16002 替换为出标签 16002(若下一跳为 P2,且 P2 也分配了相同前缀 SID,则标签值不变,但出接口改变)。P2 作为倒数第二跳,执行 PHP,弹出标签 16002,将 IP 报文转发给 PE2。PE2 收到无标签 IP 报文,正常路由。

若使用邻接 SID 构建显式路径,例如 PE1 压入栈 [16002, 30001, 30002],则 P1 弹出 30001 并从指定接口发出,P2 弹出 30002 并从指定接口发出,最终到达 PE2。此时栈顶标签逐个被弹出,体现邻接 SID 的“链路导向”特性。

MX 上 SR-MPLS 标签栈操作:Push / Swap / Pop PE1 入口 · Push P1 中间 · Swap P2 倒数第二跳 · PHP PE2 目的 · Pop 标签栈变化 16002 Push 前缀 SID 16002 Swap 出标签 16002 16002 PHP 弹出 IP 无标签转发 全局标签空间 SRGB 范围:16000 – 23999(示例) 前缀 SID = SRGB 起始 + 索引 本地标签空间 SRLB 范围:30000 – 39999(示例) 邻接 SID 仅本地有效 关键判断:栈顶标签决定动作,出标签决定下一跳 前缀 SID → 全局唯一,逐跳 Swap,最终 Pop;邻接 SID → 本地有效,Pop 后指定出接口

五、实际观察与判断依据

在 MX 上验证标签栈行为,最直接的方式是查看 mpls.0 转发表。例如执行 show route table mpls.0 label 16002,若输出中显示“to 10.0.0.2 via ge-0/0/0.0, swap 16002”,说明该节点执行 Swap;若显示“to 10.0.0.2 via ge-0/0/0.0, pop”,说明执行 Pop。对于邻接 SID,通常会看到“to 10.0.0.2 via ge-0/0/0.0, pop”并带有出接口信息。

另一个重要观察点是隐式空标签(Implicit Null,标签值 3)。当 MX 作为倒数第二跳时,若下一跳是目的节点,出标签可能显示为“swap 3”或“pop”,表示 PHP 行为。此时最后一跳收到的是无标签 IP 报文,直接按 IP 路由转发。

在 SR-MPLS 中,前缀 SID 的标签值在整个 SR 域内必须唯一,否则会导致转发环路或黑洞。部署时应确保各节点的 SRGB 起始值一致,且索引分配不冲突。邻接 SID 虽然本地有效,但在显式路径中需要确保各节点对邻接 SID 的理解一致,避免因标签空间重叠导致误转发。

六、常见异常与排查思路

若 SR-MPLS 转发异常,可按以下顺序排查:

  1. 确认 IGP 是否泛洪了前缀 SID,执行 show isis database detail 查看 SID 子 TLV。
  2. 确认 mpls.0 表中是否存在对应标签项,执行 show route table mpls.0 检查。
  3. 确认出标签与下一跳是否正确,若出标签为 3 或 pop,检查是否触发 PHP。
  4. 确认邻接 SID 是否安装,执行 show isis adjacency detail 查看 Adj-SID 分配。
  5. 若使用显式路径,检查标签栈是否按预期压入和弹出,可通过 show route table mpls.0 逐跳核对。

理解 MX 上 SR-MPLS 的标签栈操作,核心是抓住“栈顶标签决定动作、出标签决定下一跳”这一原则。前缀 SID 与邻接 SID 分别对应全局与本地标签空间,前者负责基础可达性,后者负责路径约束。掌握 Push、Swap、Pop 在 MX 转发路径中的具体表现,就能在实际网络中快速定位 SR 转发问题,并验证 SID 分配是否符合设计预期。