Segment Routing(后续简称 SR)是一种源路由协议,由源节点来为应用报文指定路径,并将路径转换成一个有序的 Segment 列表封装到报文头中,路径的中间节点只需要根据报文头中指定的路径进行转发。Segment 是指导设备处理报文的任何指令,如:根据最短路径转发报文到目的地、通过指定接口转发报文、将报文转发到指定的应用/业务实例等。
Segment Routing 能够使网络更加简化,并具有良好的可扩展能力。它不像 RSVP-TE 一样给路由器带来的复杂的状态拓扑,且只需要 IGP 路由协议来维护路由器标签的分发,并解决了 LDP 与 IGP 同步问题,在协议维护和流量工程两方面大大简化了维护的工作量。
由于 SR 使用的是 MPLS / IPv6 作为转发平面,所以现有的网络也更易平滑迁移至 SR. 本篇文章则记录从 LDP 迁移至 SR 的全过程。
实验拓扑如下(迁移前):
根据拓扑,我们需要将骨干网络从 LDP 迁移到 SR 模式。该拓扑已经配置好了 LDP + IS-IS + BGP 协议,R3 为路由反射器,R4,5,8 分别和 R3 建立了 iBGP session 关系,且 Client 之间互相 ping 也是可达的。
在本拓扑中,边缘网络 LDP Area A/B 不支持 SR,所以我们需要在骨干网络边界进行 LDP 与 SR 的互操作,以保证两种区域内都可以进行通信。
我们现在到 R1/2/3/4 上配置 SR. 在该图中,我们为每台路由器的接口配置上静态的 adjacency-sid,adjacency-sid 的分配规则为 1500[x],其中 x 代表接口号,如 g0/0/0/1 接口的 adjacency-sid 即为 15001.
请注意,要配置 SR,需要将 IS-IS 的 metric-type 改成 wide 模式,否则将无法通告 SR 信息。
RP/0/RP0/CPU0:R1(config)#show configuration Fri Jun 11 13:11:21.347 UTC Building configuration... !! IOS XR Configuration 7.3.1 router isis 1 address-family ipv4 unicast segment-routing mpls // 激活 SR-MPLS 功能 ! interface Loopback0 address-family ipv4 unicast prefix-sid index 1 // 配置公告的时候需要发布的 SRGB 索引值,必须全网唯一 ! ! interface GigabitEthernet0/0/0/0 address-family ipv4 unicast adjacency-sid absolute 15000 // 配置 Adj-SID, 用于 SRTE 计算 Cpath 用,本文不做阐述 ! ! interface GigabitEthernet0/0/0/1 address-family ipv4 unicast adjacency-sid absolute 15001 ! ! ! segment-routing global-block 16000 23999 local-block 15000 15999 ! end
RP/0/RP0/CPU0:R2(config)#show confi Fri Jun 11 13:13:26.059 UTC Building configuration... !! IOS XR Configuration 7.3.1 router isis 1 address-family ipv4 unicast segment-routing mpls ! interface Loopback0 address-family ipv4 unicast prefix-sid index 2 ! ! interface GigabitEthernet0/0/0/0 address-family ipv4 unicast adjacency-sid absolute 15000 ! ! interface GigabitEthernet0/0/0/1 address-family ipv4 unicast adjacency-sid absolute 15001 ! ! ! segment-routing global-block 16000 23999 local-block 15000 15999 ! end
RP/0/RP0/CPU0:R3(config)#show confi Fri Jun 11 13:15:49.639 UTC Building configuration... !! IOS XR Configuration 7.3.1 router isis 1 address-family ipv4 unicast segment-routing mpls ! interface Loopback0 address-family ipv4 unicast prefix-sid index 3 ! ! interface GigabitEthernet0/0/0/0 address-family ipv4 unicast adjacency-sid absolute 15000 ! ! interface GigabitEthernet0/0/0/1 address-family ipv4 unicast adjacency-sid absolute 15001 ! ! ! segment-routing global-block 16000 23999 local-block 15000 15999 ! end
RP/0/RP0/CPU0:R4(config)#show confi Fri Jun 11 13:18:05.689 UTC Building configuration... !! IOS XR Configuration 7.3.1 router isis 1 address-family ipv4 unicast segment-routing mpls ! interface Loopback0 address-family ipv4 unicast prefix-sid index 4 ! ! interface GigabitEthernet0/0/0/0 address-family ipv4 unicast adjacency-sid absolute 15000 ! ! interface GigabitEthernet0/0/0/1 address-family ipv4 unicast adjacency-sid absolute 15001 ! ! ! segment-routing global-block 16000 23999 local-block 15000 15999 ! end
SRGB 用于 SR 在全网内的范围号,用于通告 Prefix-SID 索引(index),最佳的实践是使用同一个 SRGB,易于管理。每台路由器的 SRGB 索引必须为全网唯一索引值!
SRLB 用于手工给接口分配 adj-SID,仅仅只有本地意义。在 SRTE 中会用到,个人建议在使用前规定好使用规则,以免带来管理上的不便。
配置完成后,我们来检查路由器的标签值。首先随便抓取一台路由器查看 IS-IS TLVs:
RP/0/RP0/CPU0:R1#show isis database R3.00-00 verbose IS-IS 1 (Level-2) Link State Database LSPID LSP Seq Num LSP Checksum LSP Holdtime/Rcvd ATT/P/OL R3.00-00 0x00000019 0xe9b8 1019 /1200 0/0/0 {..snip..} Metric: 0 IP-Extended 10.0.0.3/32 Prefix-SID Index: 3, Algorithm:0, R:0 N:1 P:0 E:0 V:0 L:0 // 可以看到 SR 通告的为 SID index, 而不是具体标签值。N=1 代表这个是一个 Node-SID Prefix Attribute Flags: X:0 R:0 N:1 E:0 A:0 Source Router ID: 10.0.0.3 {..snip..} Local Interface ID: 7, Remote Interface ID: 7 Interface IP Address: 10.10.13.3 Neighbor IP Address: 10.10.13.1 ADJ-SID: F:0 B:0 V:1 L:1 S:0 P:0 weight:0 Adjacency-sid:24015 // 自动分配的 Adj-SID ADJ-SID: F:0 B:0 V:1 L:1 S:0 P:1 weight:0 Adjacency-sid:15001 // 手动从 SRLB 分配的 Adj-SID Metric: 10 IS-Extended R4.00 Local Interface ID: 6, Remote Interface ID: 6 Interface IP Address: 10.10.34.3 Neighbor IP Address: 10.10.34.4 ADJ-SID: F:0 B:0 V:1 L:1 S:0 P:0 weight:0 Adjacency-sid:24017 ADJ-SID: F:0 B:0 V:1 L:1 S:0 P:1 weight:0 Adjacency-sid:15000 Router Cap: 10.0.0.3 D:0 S:0 Segment Routing: I:1 V:0, SRGB Base: 16000 Range: 8000 SR Local Block: Base: 15000 Range: 1000 Node Maximum SID Depth: Label Imposition: 10 // 通告的 MSD 值,用于公告自己能压入多少层标签 SR Algorithm: // flex-algo 有关,本文不做阐述 Algorithm: 0 Algorithm: 1
再查看以下路由器的标签:
RP/0/RP0/CPU0:R1#show isis segment-routing label table Fri Jun 11 13:24:13.893 UTC IS-IS 1 IS Label Table Label Prefix Interface ---------- ---------------- --------- 16001 10.0.0.1/32 Loopback0 16002 10.0.0.2/32 16003 10.0.0.3/32 16004 10.0.0.4/32
可以得知我们 SR 基本配置已经配好了。但这时候我们还没有完成所有配置,默认状态下,Cisco IOS-XR 并不会优先使用 SR Label 来对数据进行转发,所以我们在 traceroute 的时候,还是会压入 LDP 标签:
RP/0/RP0/CPU0:R4#traceroute 10.0.0.1 source lo0 Fri Jun 11 13:47:57.344 UTC Type escape sequence to abort. Tracing the route to 10.0.0.1 1 10.10.34.3 [MPLS: Label 24000 Exp 0] 5 msec 3 msec 3 msec 2 10.10.13.1 6 msec * 10.10.12.1 7 msec
要解决这个问题,我们需要在 IS-IS 进程下激活 SR 优先选项(该选项只需要在头端路由器配置):
RP/0/RP0/CPU0:R4(config-isis-af)#segment-routing mpls sr-prefer RP/0/RP0/CPU0:R4(config-isis-af)#commit RP/0/RP0/CPU0:R4#traceroute 10.0.0.1 source lo0 Fri Jun 11 13:45:36.906 UTC Type escape sequence to abort. Tracing the route to 10.0.0.1 1 10.10.24.2 [MPLS: Label 16001 Exp 0] 24 msec 10.10.34.3 7 msec 10.10.24.2 3 msec 2 10.10.13.1 10 msec * 6 msec
我们可以发现,路由器跟踪网内的设备已经走 SR Label 了。如果是全网都部署好 SR 的话,我们就可以撤掉 SR 网内的 LDP 了。但是由于边界还存在 LDP 设备,所以要做一些互操作配置。但是在本实验内,我们先撤掉 LDP,观察会发生什么现象。
我们撤掉 LDP 后,从 Area-A 的客户端 trace 到 Area-B,看看发生了什么:
My traceroute [v0.92] localhost (100.64.0.2) 2021-06-11T14:03:04+0000 Keys: Help Display mode Restart statistics Order of fields quit Packets Pings Host Loss% Snt Last Avg Best Wrst StDev 1. 100.64.0.1 0.0% 1 1.7 1.7 1.7 1.7 0.0 2. ???
数据包居然在第二跳丢掉了!这是为什么?我们来查看 R6 的 MPLS 转发表:
R6#show mpls forwarding-table Local Outgoing Prefix Bytes Label Outgoing Next Hop Label Label or Tunnel Id Switched interface {..snip..} 29 24013 10.0.0.8/32 3608 Gi2 10.10.16.1
转发表项是存在的啊?为什么会出现这种情况?要知道这个问题,我们还得看 R1 的转发表项:
RP/0/RP0/CPU0:R1#show mpls forwarding Fri Jun 11 14:06:56.465 UTC Local Outgoing Prefix Outgoing Next Hop Bytes Label Label or ID Interface Switched ------ ----------- ------------------ ------------ --------------- ------------ {..snip..} 24013 Unlabelled 10.0.0.8/32 Gi0/0/0/0 10.10.12.2 12154 {..snip..}
由于没有 LDP 的通告,导致缺少了到 10.0.0.8 的标签,所以导致数据包标签在 R1 上被弹掉,又因为 R1 不知道 100.64.2.0/24 是谁(无此路由),所以丢弃了该数据包!
LDP 进入 SR 域内没有问题,因为会迭代到 SR 的标签。问题出在了 SR 到 LDP 这一段,缺少了目的地的标签信息导致数据包被丢弃!
针对这种情况,我们需要在 SR 域内配置 SRMS ( Segment Routing Mapping Server )来给 LDP 域分配 Prefix-SID,确保到 LDP 域内有可达性。SRMS 的最佳配置实现就是多 SRMS 做主备,防止一个 SRMS 下线后导致 SR -> LDP 缺少标签再次不通。
(本文只配置一个 SRMS 用于现象演示)
RP/0/RP0/CPU0:R3#show configuration commit changes last 1 Fri Jun 11 14:17:36.798 UTC Building configuration... !! IOS XR Configuration 7.3.1 router isis 1 address-family ipv4 unicast segment-routing prefix-sid-map advertise-local // 激活 IS-IS 的 SRMS 通告功能 ! ! segment-routing mapping-server prefix-sid-map address-family ipv4 10.0.0.5/32 5 range 4 // 配置 Prefix-SID-Map,从 10.0.0.5 开始,index 号为5,连续分配 4 个 // 如果 loopback 接口不是连续的 IP, 则需要每行写一个,总之都是可以分配的。 ! ! ! ! end
SRMS 配置完了,我们来检查下 MPLS 转发表:
RP/0/RP0/CPU0:R3#show mpls forwarding Fri Jun 11 14:17:56.865 UTC Local Outgoing Prefix Outgoing Next Hop Bytes Label Label or ID Interface Switched ------ ----------- ------------------ ------------ --------------- ------------ {..snip..} 16001 Pop SR Pfx (idx 1) Gi0/0/0/1 10.10.13.1 0 16002 16002 SR Pfx (idx 2) Gi0/0/0/0 10.10.34.4 0 16002 SR Pfx (idx 2) Gi0/0/0/1 10.10.13.1 0 16004 Pop SR Pfx (idx 4) Gi0/0/0/0 10.10.34.4 1243 16005 26 SR Pfx (idx 5) Gi0/0/0/3 10.10.36.6 0 16006 Pop SR Pfx (idx 6) Gi0/0/0/3 10.10.36.6 0 16007 16007 SR Pfx (idx 7) Gi0/0/0/0 10.10.34.4 0 16008 16008 SR Pfx (idx 8) Gi0/0/0/0 10.10.34.4 0 {..snip..}
已经有了 Prefix-SID 表项了!我们再来看一下 SRMS 发过来的 IS-IS 的 TLVs:
RP/0/RP0/CPU0:R1#show isis database R3.00-00 verbose Fri Jun 11 14:23:02.372 UTC IS-IS 1 (Level-2) Link State Database LSPID LSP Seq Num LSP Checksum LSP Holdtime/Rcvd ATT/P/OL R3.00-00 0x0000001e 0xe2d2 844 /1200 0/0/0 {..snip..} Metric: 0 IP-Extended 10.0.0.3/32 Prefix-SID Index: 3, Algorithm:0, R:0 N:1 P:0 E:0 V:0 L:0 Prefix Attribute Flags: X:0 R:0 N:1 E:0 A:0 Source Router ID: 10.0.0.3 {..snip..} Router Cap: 10.0.0.3 D:0 S:0 Segment Routing: I:1 V:0, SRGB Base: 16000 Range: 8000 SR Local Block: Base: 15000 Range: 1000 Node Maximum SID Depth: Label Imposition: 10 SR Algorithm: Algorithm: 0 Algorithm: 1 SID Binding: 10.0.0.5/32 F:0 M:0 S:0 D:0 A:0 Weight:0 Range:4 // SRMS sub-TLV SID: Start:5, Algorithm:0, R:0 N:0 P:0 E:0 V:0 L:0 RP/0/RP0/CPU0:R1#show isis segment-routing prefix-sid-map active-policy Fri Jun 11 14:26:11.074 UTC IS-IS 1 active policy Prefix SID Index Range Flags 10.0.0.5/32 5 4 Number of mapping entries: 1
可以看到多了一个 SRMS 的 SID Binding 信息,且查看 IGP SRMS Policy 也是有表项的。
再从 LDP Area-A 区域跟踪到 LDP Area-B 区域:
root@localhost:~# mtr 100.64.2.2 --report -n Start: 2021-06-11T14:27:47+0000 HOST: localhost Loss% Snt Last Avg Best Wrst StDev 1.|-- 100.64.0.1 0.0% 10 0.9 1.9 0.5 3.9 1.2 2.|-- 10.10.56.6 0.0% 10 12.7 9.9 5.2 16.3 3.1 3.|-- 10.10.16.1 0.0% 10 7.1 8.3 5.1 12.3 2.0 4.|-- 10.10.12.2 0.0% 10 13.3 9.7 4.5 18.6 4.8 5.|-- ??? 100.0 10 0.0 0.0 0.0 0.0 0.0 6.|-- 10.10.78.8 0.0% 10 11.1 7.3 3.2 11.1 2.2 7.|-- 100.64.2.2 0.0% 10 6.3 9.3 3.7 14.7 3.5
没问题,我们再从 R5 跟踪到 R8,看看经过并压入的标签是什么:
R5#traceroute 10.0.0.8 source lo0 Type escape sequence to abort. Tracing the route to 10.0.0.8 VRF info: (vrf in name/id, vrf out name/id) 1 10.10.56.6 [MPLS: Label 29 Exp 0] 15 msec 14 msec 5 msec // LDP 2 10.10.16.1 [MPLS: Label 24013 Exp 0] 6 msec 6 msec 9 msec // LDP 进入 SR 网络 3 10.10.12.2 [MPLS: Label 16008 Exp 0] 23 msec 13 msec 7 msec // 迭代到 SR Label 进行转发 4 10.10.27.7 [MPLS: Label 29 Exp 0] 9 msec 7 msec 7 msec // 出 SR 网络,迭代到 LDP Label 进行转发 5 10.10.78.8 9 msec * 30 msec // 倒数第二跳弹出
数据包的路径为 R5 -> R6 -> R1 -> R2 -> R7 -> R8, 没有问题。
经过测试,骨干区域已完成从 LDP 到 SR 的迁移,且保留了对边缘 LDP 网络的兼容性,配置成功。