前面讲 VXLAN 的时候说过,它的思路是"用三层网络承载二层流量"。其实在 VXLAN 之前,MPLS 已经用类似的思路把"标签转发"这件事做了十几年——只是它承载的是三层 VPN。

理解 MPLS VPN 只需要抓住两件事:① 转发靠标签,不靠 IP 查表;② 隔离靠 VRF(RD + RT),不靠加密。剩下的都是这两件事的展开。

MPLS 解决什么问题

传统 IP 转发每跳都要做一次"最长匹配查表",在核心节点上这是很大的负担。而且 IP 转发只认目的地,没法表达"走哪条路"。

MPLS 的做法是:在进入 MPLS 域时给包打一个短标签,域内只看标签转发。标签是定长的、只在本地的标签表里查——查表快,还能天然支持流量工程和 VPN。

角色全称干什么
LERLabel Edge Router,标签边缘路由器MPLS 域的出入口。入口压标签(Push),出口弹标签(Pop)
LSRLabel Switching Router,标签交换路由器域内转发,只换标签(Swap)
LSPLabel Switched Path,标签交换路径一条标签走过的路径,相当于"隧道"
FECForwarding Equivalence Class,转发等价类被同一个标签标识的一组报文(通常是一个路由前缀)

标签长什么样

MPLS 标签是 4 字节(32 位),夹在二层帧头和 IP 头之间:

label · 4 bytes
┌──────────────────────┬──────┬───┬────────┐
│    Label(20 bit)    │ EXP  │ S │  TTL   │
│     标签值            │ 3bit │1bit│ 8 bit │
└──────────────────────┴──────┴───┴────────┘
   │                     │      │      └── 每跳减 1,到 0 丢弃
   │                     │      └───────── 栈底标志:1 = 最后一层
   │                     └──────────────── 优先级(类似 802.1p,QoS 用)
   └────────────────────────────────────── 标签值:0~15 是保留值

关键保留标签:
  0    IPv4 显式空标签(PHP 用,告诉上游"弹出标签再转发")
  3    Implicit Null(隐式空标签,直接不压标签)
  7    Router Alert(给路由器自己看的)
  14   OAM Alert

三种标签动作

动作在哪做干什么
PushIngress LER压入一层(或多层)标签
Swap中间 LSR把入标签换成出标签,标签值只在本地有意义
PopEgress LER弹出标签,恢复成普通 IP 包

PHP:次末跳弹出

正常情况下,出口 LER 要先把标签 Pop 掉,再去查 IP 路由表——多一次查表。MPLS 用 PHP(Penultimate Hop Popping,次末跳弹出)优化掉这一步:

标签是怎么分发的

标签不是手工配的(虽然可以),主流是协议分发:

协议特点场景
LDPLabel Distribution Protocol。跟着 IGP 的最优路径走,只能建"最短路径"的 LSP普通 MPLS VPN,最常用
RSVP-TE可以显式指定路径,支持带宽预留流量工程(MPLS TE)
SR(Segment Routing)用 IGP 扩展直接分发标签(SR-MPLS),不再需要 LDP/RSVP新一代骨干网
MP-BGP给 VPN 私网路由分发标签MPLS VPN 必用

LDP 的标签分发有两种模式,华为默认是 DU(Downstream Unsolicited,下游自主) + 有序方式(Ordered):

MPLS VPN:隔离靠什么

运营商要在一张物理网上跑几十个客户的 VPN,最大的麻烦是客户地址会重叠——A 客户和 B 客户都用 192.168.1.0/24,怎么办?

解法是三层隔离:

① VPN 实例(VRF):先把路由表分开

每个 PE 上为每个 VPN 建一个 VPN 实例(VRF),它有自己独立的路由表、FIB、接口。不同 VRF 的路由天然互不可见。

② RD:让相同前缀能共存

光有 VRF 还不够——BGP 在 PE 之间传递时,两条 192.168.1.0/24 会冲突。于是给每条路由前面加一个 RD(Route Distinguisher,路由标识符):

VPNv4 路由 = RD + IPv4 前缀
A 客户:192.168.1.0/24  →  RD 100:1 + 192.168.1.0/24  =  100:1:192.168.1.0/24
B 客户:192.168.1.0/24  →  RD 100:2 + 192.168.1.0/24  =  100:2:192.168.1.0/24

★ 两条路由现在【不一样了】,可以共存于 MP-BGP 表里
★ RD 是 8 字节,两种写法:
    ASN:nn    (如 100:1,AS 号 2 字节 + 编号 4 字节)
    IP:nn     (如 1.1.1.1:1,IP 4 字节 + 编号 2 字节)
★ RD 只负责【让前缀唯一】,不控制谁能收——那是 RT 的事

③ RT:控制谁能收到

RT(Route Target,路由目标)才是真正决定"这条路由发给谁"的属性。它是一个 BGP 扩展团体属性,分两个方向:

作用
Export RT从本 VRF 发出去的路由,打上这个 RT
Import RT收到的路由,如果带的 RT 匹配本 VRF 的 import 列表,就装进本 VRF
RT 怎么实现"选择性互通"
场景:A、B 两个客户各自独立,但都需要访问同一个"公共服务 VRF"

VPN_A   export RT 1:1     import RT 1:1
VPN_B   export RT 1:2     import RT 1:2
VPN_SRV export RT 1:100   import RT 1:1, 1:2

效果:
  · SRV 把路由打上 RT 1:100 发出去
  · A 和 B 的 import 列表里【都没有 1:100】,所以收不到 SRV 的路由
  · A 发的路由带 RT 1:1,SRV 的 import 里有 1:1 → SRV 能收到
  · 想反过来也通,就要在 A/B 的 import 里加上 1:100

★ Hub-Spoke 组网就是靠 RT 单向性实现的:
  Hub 的 import 包含所有 Spoke 的 RT,export 只有一个 RT;
  Spoke 的 import 只包含 Hub 的 RT → Spoke 之间不能直接互通,必须过 Hub

转发过程:双层标签栈

MPLS VPN 的报文上压两层标签,这是最核心的一张图:

MPLS VPN 双层标签栈与逐跳转发:外层公网标签、内层私网标签
▲ MPLS VPN 的双层标签栈与逐跳转发过程
逐跳拆解
CE-A ── PE-1 ── P1 ── P2 ── PE-2 ── CE-B

① CE-A 发普通 IP 包 → PE-1
② PE-1(Ingress LER):
   · 在 VRF-A 里查到目的地址,下一跳是 PE-2
   · 压【内层私网标签】(MP-BGP 分配的,标识这个 VRF)
   · 再压【外层公网标签】(LDP 分配的,指向 PE-2 的 LSP)
   → 变成「公网标签 | 私网标签 | IP 包」

③ P1、P2(LSR):
   · 只看【外层标签】,做 Swap
   · 完全不看私网标签,也不知道有 VPN 存在
   → 这就是 MPLS VPN 的"透明承载"

④ PE-2(Egress LER):
   · 弹出外层标签(PHP 可能让 P2 就弹了)
   · 看到私网标签 → 知道属于哪个 VRF
   · 弹掉私网标签,在对应 VRF 里查表 → 转发给 CE-B

★ 关键:P 设备不需要任何 VPN 配置,只跑 IGP + LDP 就行

跨域 MPLS VPN:三种 Option

一个客户的站点分布在两个 AS 里,怎么打通?三种方案,复杂度递增、扩展性也递增:

Option AOption BOption C
做法ASBR 之间背靠背 VRF,每个 VPN 建一个子接口 + EBGPASBR 之间跑 MP-EBGP 交换 VPNv4 路由,ASBR 不存 VPN 实例路由两端 PE 之间直接建多跳 MP-EBGP,ASBR 只传带标签的公网路由
ASBR 压力大(要存所有 VPN 的路由)中(存 VPNv4 路由,不存 VPN 实例)小(只存公网路由)
扩展性差(VPN 数量一多,子接口爆炸)中最好
配置复杂度简单中最复杂
用在哪小型跨域、VPN 数量少主流方案大型运营商骨干

Hub-Spoke 组网

Hub-Spoke 是最常见的 MPLS VPN 拓扑之一,用 RT 的导入导出不对称就能实现:

注意:Spoke 访问 Spoke 时流量会绕到 Hub 再回来,Hub 侧要留意带宽和转发性能。

配置:一个完整的 MPLS VPN

huawei · 公网侧(所有设备)
mpls lsr-id 1.1.1.1
mpls
 mpls ldp
#
interface GigabitEthernet0/0/1
 mpls
 mpls ldp

# 用 LDP 给 IGP 路由分配标签,形成 LSP
huawei · PE-1:VPN 实例
ip vpn-instance VPN_A
 ipv4-family
  route-distinguisher 100:1                              # RD
  vpn-target 1:1 export-extcommunity                      # Export RT
  vpn-target 1:1 import-extcommunity                      # Import RT

interface GigabitEthernet0/0/2
 ip binding vpn-instance VPN_A
 ip address 192.168.1.1 255.255.255.0
huawei · PE 之间的 MP-BGP
bgp 100
 peer 2.2.2.2 as-number 100
 peer 2.2.2.2 connect-interface LoopBack0

 ipv4-family vpnv4                                       # ★ 关键:VPNv4 地址族
  peer 2.2.2.2 enable
  peer 2.2.2.2 advertise-community                       # 要带 RT,必须开

 ipv4-family vpn-instance VPN_A
  import-route direct
  import-route static

★ 顺序不能错:先建 VPN 实例、再配 MP-BGP,
  否则 vpn-instance 地址族下会找不到实例

验证与排错

huawei
# 公网侧
display mpls lsp                      # ★ 所有 LSP
display mpls ldp session              # LDP 会话状态(Oper 才算正常)
display mpls ldp peer
display mpls lsp verbose              # 看某条 LSP 的入/出标签和下一跳

# VPN 侧
display ip vpn-instance               # VPN 实例列表
display ip vpn-instance VPN_A         # ★ RD、RT、绑定接口
display ip routing-table vpn-instance VPN_A   # ★ VRF 里的路由
display bgp vpnv4 all peer            # MP-BGP 邻居
display bgp vpnv4 vpn-instance VPN_A routing-table   # VRF 的 BGP 路由
display bgp vpnv4 all routing-table   # ★ 所有 VPNv4 路由(含 RD)

# 端到端
ping -vpn-instance VPN_A 192.168.2.2  # 在指定 VRF 里 ping

四个高频问题:

一句话总结:MPLS 用标签替代逐跳查表,MPLS VPN 用"VRF 隔离路由表 + RD 让前缀唯一 + RT 控制收发 + 双层标签转发"四件事,在运营商的一张物理网上跑出成千上万个互不可见的客户 VPN。P 设备对 VPN 完全无感——这是它最漂亮的地方。

📌 本篇整理自 2024–2025 的「数通」学习笔记(HCIE-Datacom 方向)

合并了原始笔记中「MPLS-VPN / MPLS-hty / mpls 跨域 / mpls-vpn--hub-spoke / VPN技术 / 隧道技术及GRE」几页。
原笔记里夹着大量 MPLS 实验截图(含 display mpls lsp 输出与标签栈抓包),本文把标签结构和转发过程重新画成了图。
配置命令保留华为 VRP 原样。