
一、MPLS基本原理
1. 标签交换路径
LSP(Label Switched Path,标签交换路径),标签报文穿越MPLS网络到达目的地址所经过的路径。MPLS网络通过标签分发协议自行进行标签的分配和学习,为流量建立一条标签转发的通道,LSP是单向的。实际上,LSP是报文在穿越MPLS网络或部分MPLS网络时的路径。为了满足通信节点之间的双向通信,我们往往需要建立双向的LSP。

LSP分为静态LSP和动态LSP两种,静态LSP由管理员手工配置,动态LSP则利用路由协议和标签分发协议动态建立,具体可以查看下列这篇文章。
2. FEC转发等价类
FEC(Forwarding Equivalence Class,转发等价类)是在转发过程中,具有相同处理方式和处理待遇的数据流,可以通过地址、隧道、CoS等方式来标识。通常在一台设备上,对于一个FEC分配相同的标签。属于一个FEC的流量具有相同的转发方式、转发路径和转发待遇。
但是并不是所有拥有相同标签的报文都属于一个FEC,因为这些报文的EXP值可能不相同,执行方式可能不同,因此它们可能属于不同的FEC。决定报文属于哪一个FEC的路由器是入站LSR,因为是它对报文进行分类和压入标签。
一条FEC可以包含多个流,但不是一个流一个FEC。例如,一台主机在观看微信的视频号,这是一个流;同时又在回复信息,这又是一个流。这两个流在微信发送给远程主机时,经过的路径大概是相同的,所以一个FEC有多个流,但是每个流可能没有单独的FEC。FEC的划分范例如下:
目的IP地址
源IP地址
QoS标识
二层标识
3. LDP概述
标签报文在MPLS网络沿着标签交换路径转发的过程中,中间LSR都只是查看数据标签值,并且针对该标签进行查询、置换等操作。我们需要一个协议,这个协议能够帮助我们为特定的流量建立LSP,能够为FEC分配标签,并且将标签映射传递给其它的标签交换路由器。
LDP(Label Distribution Protocol,标签分发协议)独立于其它路由协议,且能够结合路由协议一起使用。LDP能够为特定的FEC绑定标签,并且将标签分发给其它LSR。每一台运行LDP的LSR都会为自己路由表中的路由前缀捆绑标签,然后再将分配的标签发送给所有LSR邻居。
LDP邻居将这些接收到的标签视为出站标签Outgoing label(或者远端标签),之后邻居将该出站标签和其自己本地的标签存储于一张特殊的表中。通常一台LDP路由器会有多个LDP邻居,那么这些邻居都会给路由分配标签然后将这些标签传给自己。

4. LSP连通性检测
在MPLS网络中,当LSP发生数据转发故障时,负责建立LSP的控制面感知不到错误,导致网络维护复杂度较高。为了降低网络维护成本,提高MPLS网络的可用性,引入了MPLS Ping和MPLS Traceroute两个LSP连通性检测工具。
LSP连通性检测与传统的Ping和Traceroute类似,都是基于Echo Request和Echo Reply模式。区别在于MPLS Ping和MPLS Traceroute是基于UDP协议实现,而不是ICMP协议。其中Echo Request使用的UDP端口为3503,只有开启MPLS功能的设备才能识别该端口号。
4.1 MPLS Ping
MPLS Ping主要用于检测LSP的连通性,入口LER为MPLS Echo Request报文加上待检测LSP对应的标签,沿着LSP将报文发送给出口LER。出口LER回应MPLS Echo Reply报文。如果入口LER收到的MPLS Echo Reply报文正常,则说明LSP可以用来转发数据。如果入口LER收到MPLS Echo Reply报文带有错误码,则说明LSP存在故障。
4.2 MPLS Traceroute
MPLS Traceroute主要用于逐跳跟踪入口LER到出口LER经过的LSR。除了能够检测LSP的连通性,还能用于定位网络故障发生的具体位置。入口LER沿着LSP路径连续发送MPLS Echo Request报文,LSP经过的每一跳LSR收到请求报文后,会回应MPLS Echo Reply报文,因此入口LER可以收集到每一跳LSR的信息,定位出发生故障的位置。除此之外,通过MPLS Traceroute还能够收集到LSR分配的标签等重要信息。
二、LSP连通性检测案例
1. LDP基础配置
案例拓扑

案例需求
R1、R2、R3、R4运行OSPF路由协议,进程号为1,归属区域为0,通告直连接口及Loopback0接口
所有路由器激活MPLS,基于Loopback接口建立LDP邻居
[Step1] R1上的OSPF路由配置。
R1(config)#router ospf 1
R1(config-router)#router-id 1.1.1.1
Change router-id and update OSPF process! [yes/no]:yes
R1(config-router)#network 1.1.1.1 0.0.0.0 area 0
R1(config-router)#network 12.1.1.0 0.0.0.255 area 0
R1(config-router)#exit[Step2] R2上的OSPF路由配置。
R2(config)#router ospf 1
R2(config-router)#router-id 2.2.2.2
Change router-id and update OSPF process! [yes/no]:yes
R2(config-router)#network 2.2.2.2 0.0.0.0 area 0
R2(config-router)#network 12.1.1.0 0.0.0.255 area 0
R2(config-router)#network 23.1.1.0 0.0.0.255 area 0
R2(config-router)#exit[Step3] R3上的OSPF路由配置。
R3(config)#router ospf 1
R3(config-router)#router-id 3.3.3.3
Change router-id and update OSPF process! [yes/no]:yes
R3(config-router)#network 3.3.3.3 0.0.0.0 area 0
R3(config-router)#network 23.1.1.0 0.0.0.255 area 0
R3(config-router)#network 34.1.1.0 0.0.0.255 area 0
R3(config-router)#exit[Step4] R4上的OSPF路由配置。
R4(config)#router ospf 1
R4(config-router)#router-id 4.4.4.4
Change router-id and update OSPF process! [yes/no]:yes
R4(config-router)#network 4.4.4.4 0.0.0.0 area 0
R4(config-router)#network 34.1.1.0 0.0.0.255 area 0
R4(config-router)#exit[Step5] R1上全局开启MPLS转发功能和LDP标签分发协议,开启互联接口的标签交换能力和LDP协议。
// 全局开启MPLS转发功能
R1(config)#mpls ip
// 全局开启LDP标签分发协议
R1(config)#mpls router ldp
// 指定LDP的Router-ID,使用force强制属性使其立即生效
R1(config-mpls-router)#ldp router-id interface loopback 0 force
R1(config-mpls-router)#exit
R1(config)#interface g0/0
// 接口下开启LDP协议
R1(config-if-GigabitEthernet 0/0)#mpls ip
// 缺省情况下,三层接口只能识别IP数据包,需要开启接口的标签交换功能
R1(config-if-GigabitEthernet 0/0)#label-switching
R1(config-if-GigabitEthernet 0/0)#exit[Step6] R2上全局开启MPLS转发功能和LDP标签分发协议,开启互联接口的标签交换能力和LDP协议。
R2(config)#mpls ip
R2(config)#mpls router ldp
R2(config-mpls-router)#ldp router-id interface loopback 0 force
R2(config-mpls-router)#exit
R2(config)#interface range g0/0-1
R2(config-if-range)#mpls ip
R2(config-if-range)#label-switching
R2(config-if-range)#exit[Step7] R3上全局开启MPLS转发功能和LDP标签分发协议,开启互联接口的标签交换能力和LDP协议。
R3(config)#mpls ip
R3(config)#mpls router ldp
R3(config-mpls-router)#ldp router-id interface loopback 0 force
R3(config-mpls-router)#exit
R3(config)#interface range g0/0-1
R3(config-if-range)#mpls ip
R3(config-if-range)#label-switching
R3(config-if-range)#exit[Step8] R4上全局开启MPLS转发功能和LDP标签分发协议,开启互联接口的标签交换能力和LDP协议。
R4(config)#mpls ip
R4(config)#mpls router ldp
R4(config-mpls-router)#ldp router-id interface loopback 0 force
R4(config-mpls-router)#exit
R4(config)#interface g0/0
R4(config-if-GigabitEthernet 0/0)#mpls ip
R4(config-if-GigabitEthernet 0/0)#label-switching
R4(config-if-GigabitEthernet 0/0)#exit[Step9] 验证:查看R2上的LDP邻居,能够看到与R1和R3成功建立邻居。
R2#show mpls ldp neighbor 
[Step10] 验证:查看R3上的LDP邻居,能够看到与R2和R4成功建立邻居。
R3#show mpls ldp neighbor 
2. MPLS Ping连通性测试
2.1 正常联通的情况
[Step1] 在R1上使用Loopback地址为源,对去往4.4.4.4/32的MPLS IPv4 LSP执行连通性检测,此时能够正常连通。
R1#ping mpls ipv4 4.4.4.4/32 source 1.1.1.1
[Step2] R1构造MPLS Echo Request报文,IP头中的目的地址为127.0.0.1/8,同时将4.4.4.4填入Echo Request报文中的Target FEC Stack,然后查找标签转发表,压入标签栈,最后将报文发送给R2。使用Wireshark在R1的出接口G0/0上抓取MPLS Echo Request报文能够看到相关信息。

[Step3] 中间节点R2和R3对MPLS Echo Request报文采取和Target FEC一样的转发策略,进行普通的MPLS转发。

[Step4] 如果转发路径无故障,则MPLS Echo Request报文到达LSP的出节点R4。R4检查目的FEC中包含目的地址4.4.4.4是自身Loopback接口地址,返回正确的MPLS Echo Reply报文。使用Wireshark在R1的出接口G0/0上抓取MPLS Echo Reply报文能够看到相关信息。

2.2 LSP不存在的情况
[Step1] 在R1上将G0/0接口下关闭LDP协议和标签交换功能。
R1(config)#interface gigabitEthernet 0/0
R1(config-if-GigabitEthernet 0/0)#no label-switching
R1(config-if-GigabitEthernet 0/0)#no mpls ip
R1(config-if-GigabitEthernet 0/0)#exit[Step2] 在R2上将G0/0接口下关闭LDP协议和标签交换功能。
R2(config)#interface gigabitEthernet 0/0
R2(config-if-GigabitEthernet 0/0)#no mpls ip
R2(config-if-GigabitEthernet 0/0)#no label-switching
R2(config-if-GigabitEthernet 0/0)#exit [Step3] 在R2上查看LDP邻居关系,能够看到R2与R1邻居关系已经断开。
R2#show mpls ldp neighbor
[Step4] 在R1上使用Loopback地址为源,对去往4.4.4.4/32的MPLS IPv4 LSP执行连通性检测。从结果可见,5个探测报文全部发送失败,返回码为“QQQQQ”。出现该现象的原因是,LSP Ping的第一步就是验证目标LSR是否存在,如果不存在则返回错误信息并停止Ping。我们在上述步骤中断开了R1前往R4的有效LSP,因此显示发送失败。
R1#ping mpls ipv4 4.4.4.4/32 source 1.1.1.1
2.3 中间节点MPLS转发失败的情况
[Step1] 在R2上将G0/1接口下关闭LDP协议和标签交换功能。
R2(config)#interface g0/1
R2(config-if-GigabitEthernet 0/1)#mpls ip
R2(config-if-GigabitEthernet 0/1)#no label-switching
R2(config-if-GigabitEthernet 0/1)#no mpls ip
R2(config-if-GigabitEthernet 0/1)#exit[Step2] 在R1上使用Loopback地址为源,对去往4.4.4.4/32的MPLS IPv4 LSP执行连通性检测。从结果可见,5个探测报文全部发送失败,返回码为“BBBBB”。出现该现象的原因是,如果中间节点转发失败,则中间节点返回带有错误码的MPLS Echo Reply报文。
R1#ping mpls ipv4 4.4.4.4/32 source 1.1.1.1
[Step3] 使用Wireshark在R1的出接口G0/0上抓取MPLS Echo Reply报文能够看到相关信息。

3. MPLS Traceroute路径追踪
[Step1] 在R1上使用Loopback地址为源,对去往4.4.4.4/32的MPLS IPv4 LSP执行连通性检测,此时能够正常连通且显示经过的LSP路径。
R1#traceroute mpls ipv4 4.4.4.4/32 source 1.1.1.1
[Step2] 初始节点R1发送Echo Request消息将沿着LSP一直发送到出节点,与MPLS LSP Ping不同的是,Echo Request报文中将携带Downstream Mapping TLV,接收方会检查比对相应字段(下一跳地址、出标签)是否正确。使用Wireshark在R1的出接口G0/0上抓取MPLS Echo Request报文能够看到相关信息。

[Step3] 中间节点R2和R3对MPLS Echo Request报文与MPLS LSP Ping一样,进行普通的MPLS转发。

[Step4] 如果转发路径无故障,MPLS Echo Request报文将沿着LSP完整的转发至出节点R4。R4校验报文中的目标FEC与自身环回地址一致后,向入节点返回Echo Reply响应报文。使用Wireshark在R1的出接口G0/0上抓取MPLS Echo Reply报文能够看到相关信息。

[Step5] 特性:首个Echo Request报文中的MPLS TTL值为1,后续的Echo Request报文中的MPLS TTL值会依次加1,直至发现出节点位置。使用Wireshark在R1的出接口G0/0上抓取MPLS Echo Request报文能够看到MPLS TTL值的变化,这里我们一共经过了三跳便到达R4,因此TTL值累计为3。



