基于Cisco技术的MPLS ××× 实现[一]
MPLS的出现是因为现有的路由选择以及转发技术无法应对越来越大的internet路由表. ATM技术相对于IP技术的优势在于ATM信元转发的快速性, IP技术相对于ATM技术的优势在于IP技术的实现容易性和灵活性. 虽然IP是可以承载在ATM之上的, 但是由于大容量的ATM交互矩阵的高成本以及每个53字节的ATM信元都会有8字节的ATM头带来的转发低效率, 标签转发技术适时的出现了.
下图是MPLS(多协议标签转发)技术的一个应用图表.
 
基于Cisco技术的MPLS原理以及应用实现[一]_第1张图片
 
 
在这个连载中, 我会依次讲解这些基于标签转发技术的应用细节和CISCO实现.
MPLS是一个2.5层技术, 可以参考下面的基于帧模式的一个协议字段图. MPLS的lable是加在帧头和IP头之间的. 也可以插入多标签针对不同的MPLS应用(比如MPLS-×××应用, 流量工程, 基于MPLS-×××的流量工程等).
 
基于Cisco技术的MPLS原理以及应用实现[一]_第2张图片
 
多标签情况如下图.
基于Cisco技术的MPLS原理以及应用实现[一]_第3张图片
 
由于标签的引入带来的MTU扩大问题. 标签的长度是4字节, 根据CISCO建议, 系统MTU设置为1524如果是以太网封装的话, 多的24字节可以承载6个标签的插入, 一般情况下6个标签适应于几乎所有的应用了.
下面6台路由器组成的一个拓扑环境就是这一部分的实验图.
基于Cisco技术的MPLS原理以及应用实现[一]_第4张图片
 
R1(IPS1)和R2(Border1)之间是EBGP邻居, R2(Border1)和R5(Border2)之间是IBGP邻居, R5(Border2)和R6(IPS2)之间是EBGP邻居. R2(Border1), R3(Core1), R4(Core2), R5(Border2)之间跑IGP协议, 图中是RIP, 后面的详细配置是OSPF. R2(Border1), R3(Core1), R4(Core2), R5(Border2)的相邻接口都启用MPLS并建立MPLS邻居.
R1(IPS1)宣告(network)一条R1的32环回路由给R2(Border1). R6(IPS2)宣告(network)一条R6的32环回路由给R5(Border2). Core1和Core2并没有跑BGP协议. 根据BGP原理, R2会从R1学习到一条EBGP路由,并且传递给IBGP邻居R5. R5会将这条IBGP路由传递给EBGP邻居R6. 反之亦然.
根据BGP原理, Core1和Core2并没有跑BGP,也没有将BGP重分发到IGP中, 因此如果从R1 ping 学习到的R6的环回口地址(BGP 路由), 是不会通的, 因为BGP路由黑洞. Core1会丢弃去往R6的包因为路由不可达. 
但是, 我们却可以在R1上(通过以宣告的环回口做源地址)traceroute或者ping学习到的EBGP路由(及是R6的环回口地址), 发现是可以通的.  这个就是MPLS转发起的作用了.
首先我们看一下LDP/TDP协议也就是标签分发协议. TDP是CISCO的私有协议,但是原理基本一致.
LDP/TDP的工作主要分下面几个部分: (1) 邻居发现阶段, 这一阶段通过基于UDP的Hello包发往组播地址224.0.0.2来发现链路上的邻居, 如果丢失三个hello包宣告邻居失效. 也可以通过配置peer来发送单播hello来建立邻居, 由于ldp session是基于TCP的, 所以ldp可以跨越网络建立session, 并不需要直连.
(2) TCP连接的建立 (3) LDP Session的建立 (4) 标签的分发
同一台路由器上不同接口可以分别启用ldp或者tdp协议, 同一接口上也可以启用ldp和tdp双协议.
 
基于Cisco技术的MPLS原理以及应用实现[一]_第5张图片
 
下面, 用一个实际的实现例子来解析MPLS的原理. 拓扑使用上面IPS1,IPS2,Border1,Border2,Core1,Core2组成的实验图.
路由器连接如下:
Router1 E1/0 <----> Router2 E1/0
Router2 E1/1 <----> Router3 E1/1
Router3 E1/2 <----> Router4 E1/2
Router4 E1/3 <----> Router5 E1/3
Router5 E1/0 <----> Router6 E1/0
路由器配置如下:
r1#sh run
Building configuration...
Current configuration : 1061 bytes
!
version 12.3
service timestamps debug datetime msec
service timestamps log datetime msec
no service password-encryption
!
hostname r1
!
boot-start-marker
boot-end-marker
!
!
no aaa new-model
ip subnet-zero
!
!
no ip domain lookup
!
ip cef
!
!
interface Loopback0
 ip address 1.1.1.1 255.255.255.255
!
interface FastEthernet0/0
 no ip address
 shutdown
 duplex half
!        
interface Ethernet1/0
 ip address 172.16.1.1 255.255.0.0
 duplex half
!
interface Ethernet1/1
 no ip address
 shutdown
 duplex half
!
interface Ethernet1/2
 no ip address
 shutdown
 duplex half
!
interface Ethernet1/3
 no ip address
 duplex half
 tag-switching ip
!
router bgp 200
 no synchronization
 bgp router-id 10.10.10.10
 bgp log-neighbor-changes
 network 1.1.1.1 mask 255.255.255.255
 neighbor 172.16.2.2 remote-as 100
 no auto-summary
!
ip classless
no ip http server
no ip http secure-server
!
gatekeeper
 shutdown
!
!
line con 0
 exec-timeout 0 0
 logging synchronous
 stopbits 1
line aux 0
 stopbits 1
line vty 0 4
 login
!
!
end
r1#
r1#
 
r2#sh run
Building configuration...
Current configuration : 1374 bytes
!
version 12.3
service timestamps debug datetime msec
service timestamps log datetime msec
no service password-encryption
!
hostname r2
!
boot-start-marker
boot-end-marker
!
!
no aaa new-model
ip subnet-zero
!
!
no ip domain lookup
!
ip cef
mpls label range 200 299
mpls label protocol ldp
tag-switching tdp router-id Loopback0

!
!
interface Loopback0
 ip address 2.2.2.2 255.255.255.255
!
interface FastEthernet0/0
 no ip address
 shutdown
 duplex half
!
interface Ethernet1/0
 ip address 172.16.2.2 255.255.0.0
 duplex half
!
interface Ethernet1/1
 ip address 10.2.2.2 255.255.255.0
 duplex half
 mpls label protocol ldp
 tag-switching ip

!
interface Ethernet1/2
 no ip address
 shutdown
 duplex half
!
interface Ethernet1/3
 no ip address
 shutdown
 duplex half
!        
router ospf 2
 log-adjacency-changes
 network 2.2.2.2 0.0.0.0 area 0
 network 10.2.2.0 0.0.0.255 area 0
 network 172.16.0.0 0.0.255.255 area 0
!
router bgp 100
 no synchronization
 bgp router-id 20.20.20.20
 bgp log-neighbor-changes
 neighbor 5.5.5.5 remote-as 100
 neighbor 5.5.5.5 update-source Loopback0
 neighbor 172.16.1.1 remote-as 200
 no auto-summary
!
ip classless
no ip http server
no ip http secure-server
!
!
gatekeeper
 shutdown
!
!
line con 0
 exec-timeout 0 0
 logging synchronous
 stopbits 1
line aux 0
 stopbits 1
line vty 0 4
 login
!
!
end
r2#
 
r3#sh run 
Building configuration...
Current configuration : 1147 bytes
!
version 12.3
service timestamps debug datetime msec
service timestamps log datetime msec
no service password-encryption
!
hostname r3
!
boot-start-marker
boot-end-marker
!
!
no aaa new-model
ip subnet-zero
!
!
no ip domain lookup
!
ip cef
mpls label range 300 399
mpls label protocol ldp
tag-switching tdp router-id Loopback0

!        
!
interface Loopback0
 ip address 3.3.3.3 255.255.255.255
!
interface FastEthernet0/0
 no ip address
 shutdown
 duplex half
!        
interface Ethernet1/0
 no ip address
 shutdown
 duplex half
!
interface Ethernet1/1
 ip address 10.2.2.3 255.255.255.0
 duplex half
 tag-switching ip
!
interface Ethernet1/2
 ip address 10.3.3.3 255.255.255.0
 duplex half
 tag-switching ip
!
interface Ethernet1/3
 no ip address
 shutdown
 duplex half
!
router ospf 3
 log-adjacency-changes
 network 3.3.3.3 0.0.0.0 area 0
 network 10.2.2.0 0.0.0.255 area 0
 network 10.3.3.0 0.0.0.255 area 0
!
ip classless
no ip http server
no ip http secure-server
!
!
gatekeeper
 shutdown
!
!
line con 0
 exec-timeout 0 0
 logging synchronous
 stopbits 1
line aux 0
 stopbits 1
line vty 0 4
 login
!
!
end
r3#
 
r4#sh run
Building configuration...
Current configuration : 1173 bytes
!
version 12.3
service timestamps debug datetime msec
service timestamps log datetime msec
no service password-encryption
!
hostname r4
!
boot-start-marker
boot-end-marker
!
!
no aaa new-model
ip subnet-zero
!
!
no ip domain lookup
!
ip cef
mpls label range 400 499
tag-switching tdp router-id Loopback0

!
!
interface Loopback0
 ip address 4.4.4.4 255.255.255.255
!
interface FastEthernet0/0
 no ip address
 shutdown
 duplex half
!
interface Ethernet1/0
 no ip address
 shutdown
 duplex half
!
interface Ethernet1/1
 no ip address
 shutdown
 duplex half
!
interface Ethernet1/2
 ip address 10.3.3.4 255.255.255.0
 duplex half
  mpls label protocol ldp
 tag-switching ip

!
interface Ethernet1/3
 ip address 10.4.4.4 255.255.255.0
 duplex half
  mpls label protocol tdp
 tag-switching ip

!
router ospf 4
 log-adjacency-changes
 network 4.4.4.4 0.0.0.0 area 0
 network 10.3.3.0 0.0.0.255 area 0
 network 10.4.4.0 0.0.0.255 area 0
!
ip classless
no ip http server
no ip http secure-server
!
!
gatekeeper
 shutdown
!
!        
line con 0
 exec-timeout 0 0
 logging synchronous
 stopbits 1
line aux 0
 stopbits 1
line vty 0 4
 login
!
!
end
r4#
 
r5#sh run
Building configuration...
Current configuration : 1353 bytes
!
version 12.3
service timestamps debug datetime msec
service timestamps log datetime msec
no service password-encryption
!
hostname r5
!
boot-start-marker
boot-end-marker
!
!
no aaa new-model
ip subnet-zero
!
!
no ip domain lookup
!
ip cef
mpls label range 500 599
tag-switching tdp router-id Loopback0

!
!
interface Loopback0
 ip address 5.5.5.5 255.255.255.255
!
interface FastEthernet0/0
 no ip address
 shutdown
 duplex half
!
interface Ethernet1/0
 ip address 192.168.5.5 255.255.0.0
 duplex half
!
interface Ethernet1/1
 no ip address
 shutdown
 duplex half
!
interface Ethernet1/2
 no ip address
 shutdown
 duplex half
!
interface Ethernet1/3
 ip address 10.4.4.5 255.255.255.0
 duplex half
 mpls label protocol tdp
 tag-switching ip
!
router ospf 5
 log-adjacency-changes
 network 5.5.5.5 0.0.0.0 area 0
 network 10.4.4.0 0.0.0.255 area 0
 network 192.168.0.0 0.0.255.255 area 0
!
router bgp 100
 no synchronization
 bgp router-id 50.50.50.50
 bgp log-neighbor-changes
 neighbor 2.2.2.2 remote-as 100
 neighbor 2.2.2.2 update-source Loopback0
 neighbor 192.168.6.6 remote-as 300
 no auto-summary
!
ip classless
no ip http server
no ip http secure-server
!
!
gatekeeper
 shutdown
!
!
line con 0
 exec-timeout 0 0
 logging synchronous
 stopbits 1
line aux 0
 stopbits 1
line vty 0 4
 login
!
!
end
r5#
 
r6#sh run
Building configuration...
Current configuration : 1055 bytes
!
version 12.3
service timestamps debug datetime msec
service timestamps log datetime msec
no service password-encryption
!
hostname r6
!
boot-start-marker
boot-end-marker
!
!
no aaa new-model
ip subnet-zero
!
!
no ip domain lookup
!
ip cef
!
!
interface Loopback0
 ip address 6.6.6.6 255.255.255.255
!
interface FastEthernet0/0
 no ip address
 shutdown
 duplex half
!        
interface Ethernet1/0
 ip address 192.168.6.6 255.255.0.0
 duplex half
!
interface Ethernet1/1
 no ip address
 shutdown
 duplex half
!
interface Ethernet1/2
 no ip address
 shutdown
 duplex half
!
interface Ethernet1/3
 no ip address
 shutdown
 duplex half
!
router bgp 300
 no synchronization
 bgp router-id 60.60.60.60
 bgp log-neighbor-changes
 network 6.6.6.6 mask 255.255.255.255
 neighbor 192.168.5.5 remote-as 100
 no auto-summary
!
ip classless
no ip http server
no ip http secure-server
!
!
gatekeeper
 shutdown
!
!
line con 0
 exec-timeout 0 0
 logging synchronous
 stopbits 1
line aux 0
 stopbits 1
line vty 0 4
 login
!
!
end
r6#
 
MPLS技术领域中需要熟记于心的控制层面,转发层面结构图如下所示.
基于Cisco技术的MPLS原理以及应用实现[一]_第6张图片
 
上图描述的还不是很全面. 控制层面中的routing protocol指的是IP层面的路由控制交互协议,比如RIP,OSPF等等. LDP指的是标签分发协议LDP或者TDP. IP Forwarding Table及是Cisco IOS中的cef table(FIB) 有ip routing table 和LIB 共同作用生成. 所有存在Label Forwarding Table(LFIB) 向IP Forwarding Table做的一个标签回灌动作. 同时, LFIB需要LIB和FIB信息产生, 所以通常可以认为LFIB = LIB + FIB
进入MPLS路由器的报文是查询FIB表还是LFIB表是根据报文是否带有标签决定的. 带有标签的报文,以太帧头中的类型字段是不一样的.
同理, 出MPLS路由器的报文既有可能是IP包(pop或者untag动作后)也有可能是标签包.
[常用命令]
(1) show mpls ldp bindings (查看LIB标签表)
(2) show mpls forwarding-table detail (查看LFIB的标签转发表)
(3) show  ip cef detail (查看FIB IP转发表)
[注!!!]
(1) CISCO的MPLS实现, ip cef 必须启用
(2) mpls ldp route-id 必须ip层面可达
(3) 次末跳弹出原则, ldp协议给本路由器直连网段分配空标签, 下一跳为空标签的情况下, 执行标签pop动作
(4) ldp协议不为BGP路由分配标签(在MPLS ×××的应用中为顶层标签), 该标签取自BGP路由下一跳地址所分配的标签
(5) 以上的实现中, R2与IPS1的网段和R5与IPS2的网段宣告进了OSPF. 如果这两个网段不宣告进OSPF, R2和R5互为IBGP邻居的配置中, 配置neighbour xx.xx.xx.xx next-hop-self, 从R1以lo0为源访问R6的lo0仍然是通的. !!!但是如果R2和R5的BGP router id 不取环回口lo0, 而取与Core1和Core2的直连接口做router id, 这样会有路由黑洞产生. (因为次末跳弹出原则, 从R1到R6的包, 在Core2处就会pop标签而查询FIB表,这个时候Core2并没有BGP路由,导致黑洞.) 所以在设计好的MPLS网络时候, 要仔细考虑协议.