第157篇:PHP(次末跳弹出)机制

关键词

PHP、Penultimate Hop Popping、次末跳弹出、Implicit NULL、Explicit NULL、标签栈优化


一、为什么需要 PHP?

1.1 Egress LSR 的负担

回顾标准的 MPLS 转发过程:

 Ingress          Transit          Egress
LSR ──▶ Push R2 LSR ───────▶ Swap R3 LSR ──────▶ Pop R4 ──────────▶ IP 转发
└───────┘ L=200 └───────┘ L=100 └───────┘ L=100
│ 还要查 LFIB
IP 路由表

问题:Egress LSR 做了两件事: 1. 收到标签 → 查找 LFIB → Pop 2. 去掉标签后 → 查找 IP 路由表 → 转发给 CE

但如果 Egress LSR 的 CPU/转发引擎比较紧张,查两次表会降低转发性能。

1.2 PHP 的解决思路

PHP 的核心思想:在 LSP 的倒数第二跳(Penultimate Hop)就把标签弹出,这样 Egress LSR 收到的是普通的 IP 包,直接进行 IP 转发即可,不必再做标签查找。

             PHP 之后:
  Ingress          Transit(PHP)         Egress
LSR ───▶ Push R2 LSR ───────▶ Pop R3 LSR ──────────▶ 直接 IP 转发 R4 ──────────▶
└───────┘ L=200 └───────┘ 裸 IP 包 └───────┘ 只看 IP 路由

二、Implicit NULL(隐式空标签)

2.1 什么是 Implicit NULL

Implicit NULL(隐式空标签) 是一个特殊标签值 3

当 Egress LSR 为某个 FEC 分配标签时,它可以分配标签值 3(Implicit NULL),而不是一个普通标签。

含义:告诉上游 LSR——"你不需要给我发标签,直接把标签弹出,把裸 IP 包扔给我就行。"

2.2 分配过程

                LDP 标签分配
R2 ◀────── Label Map FEC= 10.0 Label =300 R3 ◀────── Label Map FEC= 10.0 Label =200 R4
R4 分配标签:Implicit NULL(3)
告诉 R3:不要送标签给我,Pop 掉

R3 收到 Implicit NULL 后: - 不再为这一 FEC 分配出标签 - 在 LFIB 中,操作设为 Pop(PHP)

2.3 转发表对比

没有 PHP 的情况:

R3 的 LFIB:
  In-Label   Out-Label   Out-IF   Operation
  ────────   ────────    ──────   ─────────
  200        100         GE0/0/1  Swap

R4 的 LFIB:
  In-Label   Out-Label   Out-IF   Operation
  ────────   ────────    ──────   ─────────
  100        -           -        Pop → IP lookup

开启 PHP(Implicit NULL)后:

R3 的 LFIB:
  In-Label   Out-Label   Out-IF   Operation
  ────────   ────────    ──────   ─────────
  200        -           GE0/0/1  Pop(PHP)

R4 的 LFIB:
  In-Label   Out-Label   Out-IF   Operation
  ────────   ────────    ──────   ─────────
  -          -           -        -(不需要入标签了)

三、Explicit NULL(显式空标签)

3.1 为什么需要 Explicit NULL

Implicit NULL 有一个副作用:标签弹出后,原本标签中的 EXP 位信息也丢失了

Exp(3 位)用于携带 QoS 信息。如果在次末跳就把标签弹掉了,Egress LSR 就无法根据 Exp 位做 QoS 处理。

Explicit NULL(显式空标签,标签值 0)解决了这个问题:

  • Egress LSR 分配标签 0(Explicit NULL)
  • 上游 LSR 收到后,照常 Push 标签 0 到 Egress
  • Egress LSR 收到标签 0 后,先读取 Exp 位(QoS 信息),再 Pop 标签
  • 标签 0 的头部长度仍然是 4 字节,Exp 位得以保留

3.2 Implicit NULL vs Explicit NULL

对比项 Implicit NULL(3) Explicit NULL(0)
PHP 行为 次末跳弹出,不送标签 次末跳照常送标签 0
Egress 收到 裸 IP 包 标签 0 + IP 包
Egress 操作 直接 IP 转发 读 Exp → Pop → IP 转发
Exp 保留 丢失 保留
适用场景 不需要 QoS 的纯转发 需要 QoS 保留的场景

3.3 Explicit NULL 的配置

# 华为设备强制使用 Explicit NULL
mpls ldp
 explicit-null                              # 全局配置 Explicit NULL
!
# 或针对特定 FEC
ip prefix-list FORCE_EXPLICIT_NULL permit 10.0.0.0/24
mpls ldp
 explicit-null for prefix-list FORCE_EXPLICIT_NULL

四、PHP 的完整转发对比

4.1 无 PHP

R1 发送 IP 包
  │
R2(Ingress):Push Label 200
  │   MPLS(200)
R3(Transit):Swap → Label 100
  │   MPLS(100)
R4(Egress):Pop → IP → IP 路由转发
  │   IP
CE

R4 的工作量:LFIB 查找(Pop)+ IP 路由表查找 = 两次查找

4.2 有 PHP(Implicit NULL)

R1 发送 IP 包
  │
R2(Ingress):Push Label 200
  │   MPLS(200)
R3(PHP):Pop → 裸 IP 包
  │   IP
R4(Egress):仅 IP 路由转发
  │   IP
CE

R4 的工作量:IP 路由表查找 = 一次查找

4.3 有 Explicit NULL

R1 发送 IP 包
  │
R2(Ingress):Push Label 200
  │   MPLS(200)
R3(Transit):Swap → Label 0(Explicit NULL)
  │   MPLS(0, Exp=5)
R4(Egress):读 Exp → Pop → IP 路由转发
  │   IP(标记优先级)
CE

五、华为设备上的 PHP 行为

5.1 默认行为

华为设备默认启用 PHP,即 Egress LSR 会分发 Implicit NULL 标签给上游邻居。

<HUAWEI> display mpls lsp

                 LSP Information: LDP LSP

FEC                In-Label  Out-Label  Interface        Out-Interface       LSID
10.0.0.0/24        -         200        -                GE0/0/0             3
                                                         ^^^^^^^^
操作类型为 3(Pop),即 PHP

5.2 验证 PHP

# 查看 LDP 标签绑定
<HUAWEI> display mpls ldp label

Label[Out]: 3          Label[In]: 200        FEC: 10.0.0.0/24
                    ↑
标签值为 3 表示 Implicit NULL

5.3 配置 Explicit NULL

mpls ldp
 explicit-null        # 全局启用 Explicit NULL

# 验证
<HUAWEI> display mpls ldp label

Label[Out]: 0          Label[In]: 200        FEC: 10.0.0.0/24
                    ↑
标签值为 0 表示 Explicit NULL

六、PHP 的适用场景

场景 推荐模式 原因
普通 LDP LSP Implicit NULL 减少 Egress 负担,默认即可
MPLS VPN Implicit NULL Egress PE 需要查 VPN 标签,不再需要外层标签
需要 QoS 保留 Explicit NULL Exp 位需要在 Egress 被读取
管道模型(Pipe Model) Explicit NULL QoS 必须在 Egress 被传递到 CE
短标签场景 Implicit NULL 标签资源紧张时优先使用

七、常见问题

7.1 PHP 后的 IP TTL

问:PHP 弹出标签后,IP TTL 是否受影响?

答:不影响。标签的 TTL 与 IP TTL 是独立维护的: - MPLS TTL 只在标签操作时递减 - IP TTL 保持原值 - PHP 只是去掉标签,不影响 IP 层

7.2 多层标签的 PHP

在 MPLS VPN(双层标签)场景中: - 外层标签(LDP 标签)在倒数第二跳被 PHP 弹出 - 内层标签(VPN 标签)保留到 Egress PE 查看

 PE1          P1          P2          PE2
Push LDP+ VPN ────▶ Swap LDP (外层) ───▶ PHP (Pop 外层) ───▶ 仅 VPN 标签 查 VRF ───▶ CE
双层标签 双层标签 只剩VPN 标签恢复
标签 IP

八、总结

知识点 核心要点
PHP 次末跳弹出,Egress 不再做标签查找
Implicit NULL(3) 次末跳直接 Pop,Egress 收到裸 IP 包
Explicit NULL(0) 次末跳照常送标签 0,保留 Exp 位
默认行为 华为/Cisco/Juniper 均默认启用 Implicit NULL
适用场景 普通转发用 Implicit NULL;需要 QoS 保留用 Explicit NULL

九、思考

  1. PHP 解决了什么问题?
  2. Implicit NULL 和 Explicit NULL 的核心区别是什么?
  3. 为什么有些场景需要使用 Explicit NULL?
  4. 在 MPLS VPN 中,PHP 只弹出哪一层标签?为什么?
  5. 如何验证设备当前使用的是 Implicit NULL 还是 Explicit NULL?

下篇预告:第158篇《MPLS 流量工程基础:RSVP-TE》——MPLS TE 如何显式控制流量路径,RSVP-TE 如何通过信令建立 TE 隧道。