☰
MPLS工作原理:从IP逐跳路由到标签交换
2026/10/20 13:23:24 网站建设 项目流程

MPLS 是很多广域网工程师又爱又恨的话题。爱它,是因为数据中心互联、专线接入、骨干网调度,几乎都绕不开它;恨它,是因为教材里满屏的 LSR、LER、FEC、LDP、PHP,每个词都认识,连起来就是看不懂。这篇文章我想换一种讲法:不按“概述、原理、应用”的教科书顺序展开,而是从一个问题出发——为什么已经有了 IP 路由,还要再搞一套标签转发机制?搞清楚这个动机,再把标签、转发路径和一次完整的报文穿越过程拆开讲,你就能真正理解 MPLS 的工作原理。如果你正在学网络基础、备考网络相关认证,或者被运营商和客户侧的 MPLS 配置搞昏头,这篇内容能帮你在脑子里搭起一张清晰的地图。

1. 从逐跳查表到标签交换:MPLS 到底在解决什么问题

1.1 传统 IP 转发:每台设备都在重复做同一件事

在传统 IP 网络里,一个报文从路由器 A 经过 B、C 到达 D,每一台路由器收到这个报文,都要先剥离二层封装,取出 IP 报文,用目的 IP 去查自己的 FIB(转发信息库)。FIB 是路由表经过优化后用于硬件转发的表,形式上还是“目的前缀 + 下一跳 + 出接口”。查到结果后重新封装二层帧,发给下一跳。这个过程在每一台路由器上会完整重复一遍。

问题就出在这里。第一,查表次数和跳数成正比,虽然硬件转发芯片很快,但路由表规模一旦大了,表项维护、收敛、内存占用都会成为压力。第二,路径只能被动跟随路由协议算法,OSPF 或 IS-IS 用 SPF 算法算出“最短路径”,流量就会都挤到那条路上,而管理员想让某条低利用率链路承担业务,传统 IP 转发很难做到“路径可控”。第三,每一台核心设备都必须认得目的地 IP,这意味着骨干网设备要装载大量全网路由,在某些需要隐藏内部网络结构的组网场景里,这本身就是一种暴露和负担。

我经常用一个快递分拣的类比来解释:传统 IP 转发就像一个包裹每到一个中转站,工作人员都要重新读一遍完整收件地址,查一遍地图册,然后决定下一站去哪。如果包裹数量巨大,每个中转站都背着一张全国地图,代价可想而知。

1.2 MPLS 标签交换:把分布式查表变成短标签匹配

MPLS 改变的是分工方式。它提出:从 A 到 D 的路径上,只有入口路由器需要认真看一次 IP 头,决定这个报文属于哪个转发类别;中间的 B 和 C 不看 IP,只看入口设备塞进来的一个短标签,根据一张“标签转发表”决定从哪个接口出去、换成什么新标签。

这样一来,核心节点不需要知道目的 IP 的细节,只需要维护一张小得多的标签表。路径也可以由管理策略预先构建成一条条“交换路径”,而不是只能被动听从路由协议的计算结果。还是拿快递打比方:上门取件的快递员看一眼完整地址,打出一张运单号,后续每个中转中心只看运单号,不再读详细地址。运单号就是标签,中转中心的分拣规则就是标签转发表。

MPLS 的工作机制里有一个非常重要的区分:控制平面和转发平面。控制平面负责建立“标签与转发路径”的映射关系,转发平面只按标签动作。这种分离,让网络设备可以像一个“管道节点”一样工作,也正是后面承载多租户隔离、流量工程这些能力的基础。

2. 基础概念一次理清:标签、FEC、LSR/LER

2.1 三类路由器角色与标签的报文结构

在一个 MPLS 域里,路由器按位置和作用分为三类:

  • 入站 LER(边缘标签路由器):位于 MPLS 网络边缘,负责把普通 IP 报文压入标签,通常也叫入站 PE。
  • 核心 LSR(标签交换路由器):位于网络中间,不看 IP 头,只做标签替换和转发,也叫 P 路由器。
  • 出站 LER:负责弹出标签,把 MPLS 报文还原成普通 IP 报文,从出接口送到目的地侧。

需要说明的是,一台设备可以同时承担多个角色。比如两台核心设备互联时,这台设备相对于某个方向是入站 LER,相对于另一个方向又可能只是核心 LSR,角色是由流量方向和组网位置决定的,不是固定标签。

标签本身是什么?它不是一个“报头”那么简单的概念,而是在二层头和 IP 头之间插入的一个 4 字节 shim header。结构分成四部分:

  • Label:20 位,真正的标签值,范围是 0 到 1048575。
  • TC:3 位,早期叫 EXP 字段,用于 QoS 分类,可以标记报文的优先级。
  • S:1 位,栈底标识。S 等于 1 表示这是标签栈里最内层的一个,后面紧跟着 IP 头;S 等于 0 表示后面还有外层标签。
  • TTL:8 位,作用和 IP TTL 一样,防止环路。

支持标签栈是 MPLS 特别重要的特性。一个报文可以带多层标签,转发时永远先处理最外层标签。理解这一点,后面看“两层标签如何实现业务隔离”时就会非常顺畅。

2.2 FEC 与 LSP:MPLS 世界的“门牌号”和“管道”

FEC 是 Forwarding Equivalence Class,转发等价类。入站 LER 会把目的地址、服务质量等因素相同的一批报文归为一个 FEC。例如,所有去往 10.2.0.0/24 的报文,在入站设备看来都走同一个出接口、同一个下一跳,那它们就是同一个 FEC。

为什么一定要引入 FEC 这个概念?因为如果为每一个 IP 地址都建立一条标签路径,表项数量完全不可控。FEC 的粒度让 MPLS 可以用少量路径状态覆盖大量真实流量,像是物流公司按城市分拣,而不是精确到每个门牌号。这种粗粒度划分是 MPLS 能在大规模网络里落地的核心原因之一。

LSP 是 Label Switched Path,标签交换路径。它由同一个 FEC 从入站 LER 到出站 LER 之间所有 LSR 共同构成。每个节点为这条 FEC 分配一个本地标签,整条路径就是一条“从入站开始依次替换标签”的接力链。这里有个新手常忽略的点:LSP 是单向的。用户从上海到北京的业务流量走一条 LSP,从北京回上海的流量是另一条完全独立的 LSP,两条路径可以不同。

3. 控制平面怎么学来一张标签转发表

3.1 LDP 的邻居发现与会话建立

MPLS 本身只是一个框架,它规定了标签怎么封装、怎么转发,但没规定标签怎么分发。控制平面可以有很多实现方式:静态配置、LDP、RSVP-TE,甚至可以通过 BGP 分发标签。正是这种开放性,让 MPLS 能承载各种上层业务。

最常见的动态标签分发协议是 LDP(标签分发协议)。LDP 的工作分两步:发现邻居和建立会话。

LDP 通过 UDP 发送 Hello 消息,在链路上发现邻居。这个 Hello 报文会携带一个 LDP 标识,告诉对端“我在这条链路上,标识是 XXX”。对端收到后,会尝试和源端建立 TCP 连接,会话端口也是 LDP 的知名端口。TCP 会话建立后,双方才会开始交换标签映射信息。

为什么要先建 TCP 会话再传标签?因为标签通告必须可靠、有序,TCP 恰好满足这两个要求。而 Hello 用 UDP,是为了让设备能快速发现新邻居、快速感知邻居消失,开销更小。这个设计细节在很多认证考试里都是考点,实际排障时也能用上:如果 LDP 会话起不来,先看 UDP 646 端口的 Hello 是否互通,再看 TCP 646 是否被过滤。

3.2 标签的分配、通告与 LFIB 的诞生

LDP 最常见的工作机制可以概括为:每台 LSR 为自己路由表中每条“可能成为 FEC”的 IPv4 前缀分配一个本地标签,然后通过 LDP 通告给邻居。邻居收到后,在自己的标签转发表里记一笔:当收到这个标签时,应该换成什么标签、从哪个接口发出去。

这个过程中有一个非常关键的方向问题:标签映射是“从出站端向入站端”反向通告的,而数据转发方向与通告方向相反。

我举个例子。出站 LER X 为 FEC A 分配了本地标签 100,通过 LDP 通告给上游的 P。P 收到后,知道“如果我收到标签 100,下一跳就是 X”,于是 P 也为 FEC A 分配一个本地标签 200,再通告给更上游的入站 LER Y。Y 收到后,在自己的 LFIB 里记录:入标签 200,出标签 100,出接口到 P。

当真正的业务报文从 Y 流向 X 时,链路是这样走的:Y 给报文打上标签 200,P 收到后把标签换成 100,再从出接口发给 X,X 收到 100 后弹出标签,恢复成普通 IP 报文继续转发。

每个节点的 LFIB 表项,一般会包含入标签、出标签、出接口或下一跳、执行动作(替换、弹出等)。这张表就是 MPLS 转发平面的“业务底稿”。初学时很容易死记硬背“入标签、出标签”的对应关系,我的经验是画一条链路,把每个节点的表项自己填一遍,填过一次就真正理解了。

4. 一条报文穿越 MPLS 网络的完整旅程

4.1 从入站 LER 到出站 LER:一次完整的标签替换

前面讲了很多概念,这里我把一条真实报文从用户侧设备 CE-A 发往远端 CE-B 的过程,按步骤拆开。

假设 CE-A 连接着入站 PE-A,CE-B 连接着出站 PE-B,中间有两台核心路由器 P1 和 P2。CE-A 发出的普通 IP 报文,目的地址是 10.2.0.0/24 网段里的某个 IP。

第一步,PE-A 收到这台路由器转发来的 IP 报文。它执行一次常规 IP 路由查询,发现目的地址属于某个 FEC,并且这个 FEC 对应一条已经建好的 LSP。在 FIB 的标签信息里,PE-A 查到应该压入外层标签 200(这个标签是 P1 通告给它的),下一跳是 P1。PE-A 把标签压入报文,然后从连接 P1 的接口发出去。

第二步,P1 收到一个二层帧,剥开二层头后发现这是一个 MPLS 报文,栈顶标签是 200。P1 不查 IP 路由表,直接用标签 200 去查 LFIB,匹配到一项:入标签 200,动作是“替换为 300”,出接口是连接 P2 的接口。P1 将标签改成 300,重新封装,发给 P2。

第三步,P2 收到标签 300,同样用标签去查 LFIB。这里有一个常见细节:如果 P2 的 LFIB 里记录的动作是“弹出(pop)”,说明 P2 是这条 LSP 的倒数第二跳,它会直接移除标签,把原来的 IP 报文原样转发给 PE-B。

第四步,PE-B 收到一个不带标签的普通 IP 报文,按常规 IP 路由表把它转发给 CE-B,完成一次通信。

整个过程中,P1 和 P2 从头到尾没看过目的 IP 是什么。它们只做了两件事:根据入标签找下一跳,替换标签并转发。这就是“标签交换”的本质。

4.2 藏在细节里的 TTL 与标签栈

虽然核心转发逻辑看起来很简单,但细节里藏着几个影响排障的关键点。

第一点是 TTL。入站 LER 在压入标签时,会把 IP 报文里的 TTL 值复制到 MPLS 标签的 TTL 字段。此后在 MPLS 域内,每经过一跳,标签 TTL 就减一。到达出站 LER 时,设备会把 MPLS TTL 再拷回 IP 报文头。如果标签 TTL 在中间减到 0,报文会被丢弃,并且可能产生 ICMP TTL 超时消息。

第二点是标签栈。如果一个 MPLS 报文带了两层标签,倒数第二跳弹出时只弹最外层,内层标签会一直保留到出站 LER。这一点在承载“多租户隔离”场景时尤其重要。很多刚学的朋友以为“PHP 弹出”就是把所有标签都弹掉,这是一个很常见的误解。实际情况是,最外层标签用于在核心网络里找到出站 LER,内层标签用于告诉出站 LER“这个报文属于哪个租户、哪个虚拟路由表”,所以内层必须完整保留。

4.3 倒数第二跳弹出:PHP 为什么是标准动作

PHP 是 Penultimate Hop Pop,倒数第二跳弹出。它几乎是现在所有 MPLS 实现的标配。为什么不让出站 LER 自己来弹出最外层标签?

如果出站 LER 收到一个完整的外层标签,它必须先查一次 LFIB,弹出标签,然后再查一次 IP 路由表,才能继续转发。这两次查找虽然可以合并优化,但总归多一步处理。更关键的是,如果让倒数第二跳把外层标签弹掉,出站 LER 收到的就是一个干净的普通 IP 报文,直接走常规 IP 转发路径,效率更高。

实现上,出站 LER 会通过 LDP 向直接上游通告一个特殊标签值,叫“隐式空标签”。这个通告的意思是:你不要把最后一个标签发给我,你直接把它弹掉就行。于是,倒数第二跳设备收到这个通告后,就会为这条路径安装一条“pop”表项。

我还是用快递来类比:PHP 相当于最后一个中转站把外包装拆掉,让快递员直接拿着内件包裹给收件人,收件人不需要再费一次手拆包装。这个“把额外工作尽量前移”的思想,在大型网络里能省下非常可观的处理资源。

5. MPLS 的真正价值:隔离、可控路径与快速切换

5.1 两层标签如何实现多租户隔离和物理网复用

MPLS 最常见的商业用途,是为不同租户在三层虚拟专用网络场景里提供隔离。没有 MPLS 的时候,服务商要在同一套物理设备上承载多个客户的私网业务,非常麻烦。要么做物理隔离,成本极高;要么靠传统的接口划分,但扩展性很差。

MPLS 的解法很优雅:每个租户在 PE 上拥有一个独立的虚拟路由转发表,维护自己私网路由。当租户的报文进入网络时,入站 PE 会压入两层标签:

  • 外层标签:用于在服务商骨干网中从入站 PE 传到目的 PE,核心路由器只认这层。
  • 内层标签:用于标识这个报文属于哪个租户、应该进哪个虚拟路由表。

中间的核心 P 路由器只看外层标签,完全不感知内层标签,也不需要知道客户的私网路由。目的 PE 收到后,先弹掉外层,再看内层标签,才知道“这是某租户的报文,应该送到它的虚拟路由表里去查询”。

这个设计相当于一份包裹上贴着两张面单:外层单写着“从分拣中心 A 送到分拣中心 B”,内层单写着“到了 B 之后再去客户的几号仓库”。中间运输只看外层单,到了终点才拆开看内层。正是这种两层标签栈的能力,让同一张物理网络能同时承载成百上千个租户的业务,彼此隔离、互不干扰。

5.2 流量工程与快速重路由:可控路径的价值

MPLS 的另一个重要价值是路径可控。传统 IP 网络里,OSPF 或 IS-IS 算出来的最短路径是全网一致的,流量往往会拥挤在同一批链路上,而另一些链路却很空闲。管理员即使知道问题在哪,也很难通过调整 metric 实现精确控制,因为调整一个 metric 会影响全网所有流量的计算。

MPLS 可以通过 RSVP-TE 建立显式 LSP,也就是人为指定一条路径:从 A 出发,明确经过哪些节点,绕过哪些拥塞链路,甚至可以为这条路径预留带宽。这种基于约束的路径计算和资源预留能力,是单纯 IP 路由协议做不到的。

在此基础上,MPLS 快速重路由(FRR)提前在主 LSP 沿途为关键路径建立备份路径。当主路径上的某条链路或某个节点故障时,故障点本地设备可以在几十毫秒内把流量切到备份路径,完全不需要等待全网的 IGP 收敛。

我遇到过一些对链路稳定性要求非常高的客户,他们对网络的第一要求不是“快”,而是“故障不要断”。MPLS 在骨干网的统治地位,靠的其实不是“少查一次表”,而是这种“业务可隔离、路径可控制、故障可快速恢复”的综合能力。

6. 实战排障:标签学不会与 MTU 陷阱

6.1 标签一直学不到:先分清控制面还是转发面

做 MPLS 排障时,我见过最多的现象是:LDP 邻居状态是 Established,但查看 LSP 表时发现,某个目的网段对应的标签路径就是不出来。

遇到这种情况,先别急着抓包,按顺序查四个点。

第一,接口有没有使能 MPLS 和 LDP。很多设备有全局使能和接口使能两级开关,经常有人只配了全局,忘了在物理接口或子接口下开启 MPLS 能力。

第二,IGP 路由有没有收敛。LDP 是依赖 IGP 路由表工作的,如果 OSPF 或 IS-IS 的路由都没出现在本设备的路由表里,LDP 就不可能为这条前缀生成标签映射。这是最容易被忽略的根因。

第三,LDP 会话状态是否正常。可以检查会话是否又是 Established。如果发现会话卡在非正常状态,重点排查 UDP 646 端口的 Hello 报文是否被 ACL 或安全策略过滤,TCP 646 是否被防火墙拦截。

第四,路由过滤策略。某些情况下,对端设备对发布的路由做了过滤,导致本端认为某些前缀不可达,自然不会产生对应的 FEC。

我的排查口诀是:先看 IGP,再看 LDP 会话,最后看 LFIB。按这个顺序来,绝大多数“标签学不到”的问题都能在几分钟内定位。

6.2 MPLS MTU 失配带来的隐蔽丢包

MPLS 报文标签栈会额外增加 4 字节长度。如果链路 MTU 是标准的 1500 字节,一个原本 1500 字节的 IP 报文压入标签后变成 1504 字节,已经超过接口 MTU。

问题在于,很多 MPLS 网络设计上不允许分片,或者报文设置了 DF 位(不可分片)。结果就是小包能通,大包被静默丢弃,业务表现非常诡异:管理地址能 ping 通,但文件传输总是断断续续,视频会议偶尔卡顿。

我帮一个客户排查过类似问题。客户反馈语音偶尔断续,但网络基础监控显示一切正常。后来抓包才发现,核心链路出现了大量超过 MTU 的 MPLS 帧被丢弃。调整了链路 MTU 和相关 MPLS MTU 配置后,问题立刻消失。

排查时建议关注三件事:一是链路接口的 MTU 是否一致,二是设备上的 MPLS MTU 是否单独配置,三是如果启用了 RSVP-TE,还要确认 RSVP 的 MTU 信号协商是否正常。简单说,MPLS 表项越多,标签栈越深,MTU 越容易成为藏雷点。

6.3 几条常用的验证命令与排查顺序

不同厂商的命令风格略有差异,但下面的命令形态是通用的,换到主流设备上基本都能找到对应版。以常见命令行风格为例:

display mpls lsp # 查看所有标签交换路径,能直接看到入标签、出标签、出接口,确认 LSP 是否建立 display mpls ldp session # 查看 LDP 会话状态,Established 才是正常 display mpls ldp peer # 查看 LDP 邻居及其能力参数,确认双方协商是否正常

如果设备支持 MPLS ping,还可以直接用类似ping mpls ipv4 10.2.0.0/24的方式,从本地发起验证,看整条 LSP 是否贯通。注意这是验证 MPLS 转发表的连通性,和普通的 ICMP ping 不是一个层级。

我自己的总结是:接口状态和 IGP 路由先行,LDP 会话次之,LSP 表项再往后,最后才是标签栈和 MTU 细节。每当有同事说“MPLS 好难排”,我发现绝大多数情况是他们把排查顺序搞反了,在转发面上花了太多时间,却没有先确认控制面的“标签到底学没学到”。

最后说一个我自己的习惯。MPSL 学到头你会发现,真正的难点不在“标签怎么加、怎么换”,而在于脑子里要同时维护控制平面和转发平面两张地图。控制面决定这条 LSP 是怎么建立起来的,转发面决定一个具体报文到了每一跳会发生什么操作。动手排障时,永远先问自己两个问题:这个标签是哪个邻居通过什么协议告诉我的?这个报文到达当前节点时,栈最外层是什么?把这两个问题想清楚,你已经比很多只背概念的人强太多了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询