1. 从一个真实运维场景说起:为什么还要聊MPLS
前阵子帮一个做企业组网的朋友排查问题,他们总部和三个分支之间跑着一条跨运营商的专线,业务侧反馈视频会议偶尔卡顿、ERP系统跨站点访问延迟忽高忽低。抓包一看,中间路径跳数多、转发路径不固定,部分流量甚至绕了一圈才到目的地。这种场景下,传统逐跳路由转发的短板就暴露出来了:每一跳都要查路由表、做最长匹配,路径完全跟着IGP的度量走,想人为规划一条稳定路径非常费劲。
这时候MPLS就派上用场了。MPLS全称Multi-Protocol Label Switching,多协议标签交换,核心思路是把"逐跳查路由"变成"按标签转发"。它在二层和三层之间加了一层"2.5层",入口路由器给数据包打上标签,中间设备只看标签转发,不再关心IP头里的目的地址。这样做的好处很直接:转发效率高、路径可控、天然支持流量工程和虚拟专用网络。
很多人觉得MPLS是"老技术",现在都讲SRv6、SD-WAN了,学它还有用吗?我的看法是:运营商骨干网、金融专线、大型企业广域网里,MPLS依然是主力承载技术,而且MPLS的标签转发思想是理解SR、Segment Routing、甚至部分SD-WAN底层封装的基础。你把MPLS搞明白了,再看这些新技术会发现很多概念是一脉相承的。这篇内容我打算从原理讲到单域实验,把标签分发、LSP建立、标签转发表这些容易含糊的地方掰开揉碎讲清楚,最后给一套可以照着敲的单域MPLS实验配置。适合有一定路由交换基础、想系统搞懂MPLS转发机制的网络工程师和备考人员。
2. MPLS核心原理拆解:标签到底是怎么转发的
2.1 标签的结构与转发逻辑
要理解MPLS,先得搞清楚标签长什么样。MPLS标签是32位,夹在二层帧头和三层IP头之间,结构如下:
| 字段 | 长度 | 作用 |
|---|---|---|
| Label | 20 bit | 标签值,决定转发行为 |
| EXP | 3 bit | 原用于QoS优先级,现多称TC |
| S | 1 bit | 栈底标志,1表示最后一层标签 |
| TTL | 8 bit | 生存时间,防止环路 |
标签可以多层嵌套,形成标签栈。外层标签用于骨干网转发,内层标签用于区分不同业务或虚拟专用网络。转发时设备只看栈顶标签,这叫"标签交换"。
我常用一个类比解释:传统IP转发像快递员每到一个中转站都要拆开包裹看详细地址;MPLS像给包裹贴了一个"中转站编号",中转站只看编号就知道往哪个方向发,不用拆包。入口贴标签(Push),中间换标签(Swap),出口撕标签(Pop),这三个动作就是MPLS转发的全部核心。
2.2 转发等价类FEC与标签绑定
MPLS不会给每个目的IP都分配一个标签,那样标签空间会爆炸。它把具有相同转发处理方式的报文归为一类,叫FEC(Forwarding Equivalence Class,转发等价类)。同一个FEC的报文,在同一个节点上被赋予相同的标签,走相同的路径。
FEC的划分粒度很灵活:可以按目的网段划分,可以按业务类型划分,也可以按虚拟专用网络实例划分。比如一条去往10.1.1.0/24的流量,在入口被划为一个FEC,分配标签1001;去往10.2.2.0/24的划为另一个FEC,分配标签1002。中间设备收到标签1001的包,就知道该往哪个下一跳送。
这里有个容易混淆的点:标签是"本地有效"的,不是全局唯一的。同一台设备上标签1001代表去往A,另一台设备上标签1001可能代表去往B,这完全没问题,因为标签只在相邻设备之间有意义。理解这一点,后面看标签转发表就不会晕。
2.3 LSP与标签分发协议
标签交换路径LSP(Label Switched Path)就是报文在MPLS域内经过的一系列标签交换节点组成的路径。LSP是单向的,从入节点Ingress到出节点Egress,中间经过若干Transit节点。
LSP的建立依赖标签分发协议。常见的有三种:
- LDP(Label Distribution Protocol):最基础,跟着IGP路由走,为每条IGP路由分配标签,适合单域场景。
- RSVP-TE:支持流量工程,可以显式指定路径、预留带宽,配置复杂但控制力强。
- BGP扩展:用于跨域虚拟专用网络场景,通过BGP传递标签。
单域实验里我们用LDP就够了,它配置简单、和IGP联动自然。LDP的工作过程可以概括为:邻居发现(Hello)→ 会话建立(TCP)→ 标签映射通告(Label Mapping)→ 标签转发表生成。两台设备成为LDP邻居后,各自把自己本地路由对应的标签告诉对方,对方据此生成转发表项。
2.4 标签转发表的生成过程
这是很多人学MPLS时最卡的地方,我用一个具体例子讲。假设有四台设备R1-R2-R3-R4串联,R1背后有网段192.168.1.0/24。
R4上配置了该网段的路由,它通过LDP给R3发一个标签映射:去往192.168.1.0/24,我用标签4001。R3收到后,生成入标签4001、出标签4001、下一跳R4的转发表项,同时给R2发标签映射:去往192.168.1.0/24,我用标签3001。R2收到后生成入标签3001、出标签3001、下一跳R3的表项,再给R1发标签映射:我用标签2001。R1收到后生成入标签2001、出标签2001、下一跳R2的表项。
当R1收到去往192.168.1.0/24的IP包时,查FIB发现要走LSP,于是压入标签2001发给R2。R2收到标签2001的包,查LFIB(标签转发信息库),把标签换成3001发给R3。R3换成4001发给R4。R4是出节点,弹出标签,按IP转发到192.168.1.0/24。
注意:入节点做Push,中间节点做Swap,出节点做Pop。出节点弹出标签后,如果下一跳还是MPLS域内设备,可能做"次末跳弹出"(PHP),提前把标签弹掉,减轻出节点负担。
3. 单域MPLS实验环境与规划
3.1 实验拓扑设计思路
单域实验的目的是把LDP标签分发、LSP建立、标签转发这条链路完整跑通。拓扑不宜太复杂,四到五台设备足够体现Ingress、Transit、Egress三种角色。我设计的拓扑如下:
- R1(Ingress)—— R2(Transit)—— R3(Transit)—— R4(Egress)
- R1背后挂业务网段192.168.1.0/24
- R4背后挂业务网段192.168.2.0/24
- 设备之间用10.0.0.0/30互联,R1-R2用10.0.0.0/30,R2-R3用10.0.0.4/30,R3-R4用10.0.0.8/30
- 全网运行OSPF作为IGP,R1和R4把业务网段引入OSPF
- 全网开启LDP,接口使能LDP
这个拓扑的好处是:路径清晰,每台设备的角色明确,抓包时能清楚看到标签的Push、Swap、Pop过程。如果你用模拟器,四台路由器资源占用也不高。
3.2 地址与标签规划
地址规划要留足余量,避免后期扩展时重编。我习惯这样规划:
| 设备 | 接口 | 地址 | 说明 |
|---|---|---|---|
| R1 | G0/0 | 10.0.0.1/30 | 连R2 |
| R1 | Lo0 | 1.1.1.1/32 | 环回,LDP会话用 |
| R2 | G0/0 | 10.0.0.2/30 | 连R1 |
| R2 | G0/1 | 10.0.0.5/30 | 连R3 |
| R2 | Lo0 | 2.2.2.2/32 | 环回 |
| R3 | G0/0 | 10.0.0.6/30 | 连R2 |
| R3 | G0/1 | 10.0.0.9/30 | 连R4 |
| R3 | Lo0 | 3.3.3.3/32 | 环回 |
| R4 | G0/0 | 10.0.0.10/30 | 连R3 |
| R4 | Lo0 | 4.4.4.4/32 | 环回 |
标签方面,LDP默认从本地标签池动态分配,不用手工指定。但如果你想观察方便,可以配置标签范围,比如mpls label range 1000 1999,这样抓包时看到的标签都在1000-1999之间,容易识别。
提示:环回接口一定要配,LDP会话通常用环回地址建立,这样链路抖动时会话不容易断。环回地址要宣告进IGP,保证互通。
3.3 模拟器与版本选择
实验环境我用的是常见的网络模拟器,路由器镜像选支持MPLS的版本。这里不点名具体产品,只说选型原则:镜像要支持MPLS转发、LDP、OSPF,命令行风格要和你实际工作环境接近。如果你用物理设备,注意接口是否支持MPLS,部分低端设备需要特定许可才能开启MPLS功能。
资源分配上,四台路由器每台给512MB内存、1个CPU核心就够跑基础实验。如果模拟器支持,把抓包功能打开,在R2和R3之间的链路上抓包,能直观看到标签的变化。
4. 单域MPLS实验完整配置与验证
4.1 基础IGP配置:先把路由跑通
MPLS依赖IGP提供到达各节点的路由,所以第一步是把OSPF配好。以R1为例:
R1(config)# router ospf 1 R1(config-router)# router-id 1.1.1.1 R1(config-router)# network 10.0.0.0 0.0.0.3 area 0 R1(config-router)# network 1.1.1.1 0.0.0.0 area 0 R1(config-router)# network 192.168.1.0 0.0.0.255 area 0R2、R3、R4类似配置,注意router-id用各自的环回地址,互联网段和环回都宣告进area 0。R4要把192.168.2.0/24也宣告进去。
配完后在R1上show ip route,应该能看到去往2.2.2.2、3.3.3.3、4.4.4.4、192.168.2.0/24的路由,下一跳逐跳指向R2。这一步不通,后面LDP肯定起不来,所以务必先确认IGP收敛。
实操心得:OSPF的network命令用反掩码,0.0.0.3对应/30,0.0.0.0对应/32,0.0.0.255对应/24。写错反掩码是新手最常见的翻车点,配完一定用
show ip ospf interface brief核对。
4.2 开启MPLS与LDP
IGP通了之后,全局开启MPLS转发,接口使能MPLS,再开启LDP。以R1为例:
R1(config)# mpls ip R1(config)# mpls label range 1000 1999 R1(config)# mpls ldp router-id Loopback0 force R1(config)# interface GigabitEthernet0/0 R1(config-if)# mpls ip R1(config-if)# mpls ldp discovery transport-address interfaceR2、R3、R4做同样操作,注意每台设备的标签范围可以错开,比如R1用1000-1999,R2用2000-2999,这样抓包时一眼就能看出是哪个节点分配的标签。mpls ldp router-id Loopback0 force这条命令很关键,强制LDP用环回地址作为router-id,保证会话稳定。
接口下的mpls ldp discovery transport-address interface让LDP用接口地址建立会话,适合直连场景。如果是非直连的LDP会话,需要用环回地址。
4.3 验证LDP邻居与标签映射
配置完成后,先看LDP邻居:
R1# show mpls ldp neighbor正常应该看到R2的邻居状态是Oper,TCP连接已建立。如果卡在Initialized或者没有邻居,检查IGP是否互通、接口是否使能LDP、ACL是否挡了646端口(LDP用UDP 646发现、TCP 646建会话)。
再看标签映射:
R1# show mpls ldp bindings这里会列出本地为各网段分配的标签,以及从邻居学到的标签。重点看去往192.168.2.0/24的条目,应该能看到本地标签和远程标签。
最后看标签转发表:
R1# show mpls forwarding-table这张表是MPLS转发的核心。每一行包含:本地标签(In Label)、出标签(Out Label)、前缀(Prefix)、下一跳(Next Hop)。R1上去往192.168.2.0/24的条目,本地标签应该是1000-1999之间的某个值,出标签是R2分配的,下一跳是10.0.0.2。
注意:如果Out Label显示为"Untagged"或"Pop Label",说明下一跳是出节点或者做了PHP,这是正常现象,不是配置错误。
4.4 抓包验证标签转发全过程
光看表还不够直观,抓包最能说明问题。在R2和R3之间的链路抓包,然后从R1 ping R4背后的192.168.2.1。
第一个包:R1发出,标签是R1本地分配的入标签对应的出标签(R2分配的),EXP和TTL正常。 第二个包:R2收到后Swap标签,发给R3的包标签变成R3分配的。 第三个包:R3收到后Swap,发给R4的包标签变成R4分配的,或者因为PHP直接是IP包。
抓包时重点看MPLS头部:Label值、S位(栈底)、TTL。TTL每跳减1,和IP转发一样。如果看到标签值在1000-1999之间,说明是R1分配的;2000-2999是R2分配的,以此类推。
我实测下来,最容易出问题的是PHP。R4作为出节点,R3在转发前会把标签弹掉,直接发IP包给R4。这时候在R3-R4链路上抓包,看到的是纯IP包,没有MPLS头。如果你不知道PHP,会以为标签转发没生效,其实是正常的优化行为。
4.5 连通性测试与路径追踪
基础验证做完,做端到端测试:
R1# ping 192.168.2.1 source 192.168.1.1 R1# traceroute 192.168.2.1 source 192.168.1.1Ping通说明LSP建立成功。Traceroute可以看到路径,MPLS域内可能显示为标签交换的跳数。如果想看LSP的详细信息,可以用show mpls ldp lsp或者show mpls forwarding-table 192.168.2.0。
这里有个细节:ping的时候指定source,否则可能用出接口地址作为源,回程路径可能不一致,导致误判。指定source能保证来回路径都走预期的LSP。
5. 常见问题与排查技巧实录
5.1 LDP邻居起不来的排查顺序
LDP邻居起不来是最常见的问题,我整理了一个排查顺序,按这个走基本能定位:
| 排查项 | 检查命令 | 常见原因 |
|---|---|---|
| IGP互通 | show ip route | 路由没通,LDP无法建TCP |
| 接口LDP | show mpls ldp discovery | 接口没使能mpls ip |
| Router-ID | show mpls ldp neighbor | 环回没配或没宣告 |
| 传输地址 | show mpls ldp discovery detail | transport-address配错 |
| ACL/防火墙 | show access-lists | 挡了UDP/TCP 646 |
我踩过的一个坑:两台设备都能ping通对方环回,但LDP邻居就是不起来。查了半天发现是其中一台设备的环回地址没有宣告进OSPF,IGP里有这条路由但下一跳不对。所以show ip route看到路由存在不代表可用,要看下一跳是否可达。
5.2 标签转发表为空或不全
有时候LDP邻居起来了,但show mpls forwarding-table里没有预期条目。原因通常是:
- 该前缀没有被LDP分配标签。LDP默认只为IGP学到的路由分配标签,如果你用静态路由,需要额外配置。
- 标签分配被过滤。检查是否配了
mpls ldp label的过滤策略。 - 会话虽然Oper但标签映射没交换完。等几秒再看,或者
clear mpls ldp neighbor *重置会话。
还有一种情况:转发表里有条目,但Out Label是"Untagged"。这通常发生在出节点,或者下一跳不支持MPLS。如果是出节点,正常;如果是中间节点,检查下一跳接口是否使能了mpls ip。
5.3 PHP导致的"标签消失"误判
前面提过PHP,这里再强调一次。次末跳弹出是MPLS的标准行为,出节点的上一跳会把标签弹掉,直接发IP包给出节点。抓包时看到纯IP包,不要慌,这是正常的。
如果你想禁用PHP观察完整标签路径,可以在出节点上配置mpls ldp explicit-null,这样出节点会通告显式空标签(标签值0),次末跳不弹标签,而是换成0发给出节点。出节点收到标签0,知道要弹标签做IP转发。这个配置在实验里很有用,能让你看到完整的标签栈。
实操心得:生产环境一般不禁用PHP,因为PHP能减轻出节点负担。但排查问题时,临时开explicit-null能帮你确认标签路径是否完整。
5.4 MTU问题导致的转发异常
MPLS标签会增加报文长度,每层标签4字节。如果链路MTU是1500,加上标签后可能超过MTU,导致大包被丢弃。表现是ping小包通、大包不通,或者TCP建连成功但传输大文件失败。
解决办法是调整接口MTU,或者配置mpls mtu。一般把物理接口MTU调到1504或更高,给标签留出空间。这个坑在跨运营商场景特别常见,因为中间链路MTU可能不一致。
5.5 路由震荡引发LSP反复重建
IGP不稳定时,LDP会跟着震荡,LSP反复重建,业务表现为间歇性中断。排查时先看IGP是否稳定,show ip ospf neighbor看邻居是否频繁Up/Down。如果是链路质量问题,先解决物理层;如果是配置问题,检查OSPF的hello/dead计时器是否一致。
LDP本身也有稳定性机制,比如mpls ldp session protection,可以在直连链路故障时通过环回保持会话。单域实验里可以不配,但生产环境建议开启。
6. 从单域到跨域:MPLS的扩展方向
单域实验跑通后,你算是摸到了MPLS的门。但真实网络里,MPLS往往要跨多个域、承载多种业务。这里简单说说扩展方向,给你后续学习指个路。
跨域MPLS主要有三种方式:Option A是域间背靠背,两个域的出节点用虚拟专用网络实例对接;Option B是域间标签交换,通过BGP传递标签;Option C是多跳EBGP,域间直接交换标签。三种方式复杂度递增,Option A最好理解但扩展性差,Option C扩展性最好但配置最复杂。
另一个方向是MPLS流量工程,用RSVP-TE建立显式路径,可以指定带宽、优先级、亲和属性。这在需要保障关键业务质量的场景很有用,比如金融交易专线。配置上比LDP复杂不少,需要理解RSVP的路径消息、预留消息、错误消息。
再往后就是Segment Routing,它把标签换成"段标识"SID,去掉了LDP和RSVP这些协议,靠IGP或BGP直接分发SID。思想上和MPLS一脉相承,但控制面简化了很多。你把MPLS的标签转发搞懂了,学SR会顺很多。
我个人在实际操作中的体会是:MPLS这东西,看十遍书不如敲一遍实验。标签转发表、LDP绑定、PHP这些概念,光看文字容易似懂非懂,抓一次包、看一次表,立刻就通透了。单域实验是最好的起点,拓扑简单、现象清晰,把这一套跑熟,后面跨域和流量工程都是在这个基础上加东西。最后分享一个小技巧:实验时把每台设备的标签范围错开,抓包时看标签值就能判断是哪个节点分配的,排查问题时能省不少时间。