我在上一篇文章《使用 BGP Auto-Steering 对内网流量进行路径调度》中已经写了 Cisco 平台上使用 SRTE 调度流量的方法,这一次我们在 Juniper 平台上部署 SRTE 并使用它做内网流量的调度。
该实验做完总共使用了 4 天时间。由于实验过程中坑实在是太多,多得差点让我吐血了,所以本篇文章将从头到尾完整写一遍,包括可能遇到的坑以及避免的方法。
实验拓扑如下:

所有链路的 Metric 值(TE/IGP) 以及链路的亲和属性已经标在了图中,我们按照图中参数进行配置。
// 所有路由器的公共配置
root@R1# show chassis
network-services enhanced-ip; // 将路由器模式设置为 enhanced-ip 模式,否则不能配置 segment routing,真机也是一样
root@R1# show protocols isis
interface ge-0/0/1.0 {
level 2 {
te-metric 5; // 按照图中所示配置 TE Metric 值
ipv4-adjacency-segment {
unprotected label 15001; // 手动从 SRLB 分配一个静态标签作为 Adj-SID
}
metric 20; // 按照图中所示配置 IGP Metric 值
}
point-to-point; // 优化,不要让它出现 IS-IS DIS,只要是两个路由器互联中间没其他设备,建议配上
}
interface ge-0/0/4.0 {
level 2 {
te-metric 2;
ipv4-adjacency-segment {
unprotected label 15004;
}
}
point-to-point;
}
interface lo0.0;
source-packet-routing {
srgb start-label 16000 index-range 8000; // 配置 SRGB,等同于 Cisco 中的 segment-routing global-block 16000 23999
node-segment ipv4-index 1; // 宣告索引号,之前文章已经讲过了
}
level 1 disable; // 默认关闭 Level 1,一般都不用
level 2 wide-metrics-only; // 开启 Level 2,而且 Metric 模式为 Wide,否则 SR 信息无法传递
traffic-engineering l3-unicast-topology; // 将链路状态信息下载到 TEDB (流量工程数据库),只需要在头端路由器配置
root@R1# show protocols mpls
traffic-engineering; // 启动 MPLS family TE 能力
admin-groups {
blue 0; // 定义 bit-position,让 IS-IS 在 sub-TLVs 里面传递链路的亲和属性,用于 SRTE
orange 1;
}
icmp-tunneling; // 开启 icmp 隧道功能,防止 L3VPN 数据传递中间跳不知道怎么回来然后看不见跳数,所有路由器都要配置
label-range {
static-label-range 15000 15999; // 配置 SRLB 范围,本地意义
}
interface ge-0/0/1.0 {
admin-group [ blue orange ]; // 给链路染色,并激活接口的 MPLS 功能
}
interface ge-0/0/4.0; // 仅激活接口的 MPLS 功能
配置完毕后,我们来检查一下 IS-IS LSP 以及标签功能:
root@R1> show isis database
IS-IS level 1 link-state database:
0 LSPs
IS-IS level 2 link-state database:
LSP ID Sequence Checksum Lifetime Attributes
R1.00-00 0x46 0xd946 1165 L1 L2
R2.00-00 0x48 0xef4 917 L1 L2
R3.00-00 0x49 0x5176 527 L1 L2
R4.00-00 0x48 0x5c9a 942 L1 L2
R5.00-00 0x47 0xaee8 589 L1 L2
R6.00-00 0x49 0xb94e 492 L1 L2
R7.00-00 0x49 0x5afd 928 L1 L2
R8.00-00 0x49 0xd9c5 938 L1 L2
8 LSPs
root@R1> show route table inet.3
inet.3: 7 destinations, 7 routes (7 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
10.0.0.2/32 *[L-ISIS/14] 04:33:26, metric 20
> to 10.10.12.2 via ge-0/0/1.0
10.0.0.3/32 *[L-ISIS/14] 04:33:26, metric 40
to 10.10.12.2 via ge-0/0/1.0, Push 16003
> to 10.10.15.5 via ge-0/0/4.0, Push 16003
10.0.0.4/32 *[L-ISIS/14] 04:33:26, metric 60
> to 10.10.15.5 via ge-0/0/4.0, Push 16004
10.0.0.5/32 *[L-ISIS/14] 04:33:26, metric 10
> to 10.10.15.5 via ge-0/0/4.0
10.0.0.6/32 *[L-ISIS/14] 04:33:26, metric 20
> to 10.10.15.5 via ge-0/0/4.0, Push 16006
10.0.0.7/32 *[L-ISIS/14] 04:33:26, metric 30
> to 10.10.15.5 via ge-0/0/4.0, Push 16007
10.0.0.8/32 *[L-ISIS/14] 04:33:26, metric 40
> to 10.10.15.5 via ge-0/0/4.0, Push 16008
邻居已经正常建立,而且 inet.3 已经有了所有人的 loopback 接口地址的标签了。
10.0.0.3/32 负载均衡是因为图中 Metrics 分配所以出现了负载均衡,10.0.0.{2,5}/32 两个没有标签是因为下一跳直连所以会直接 pop 掉,实际已经收到标签为 16002/16005 的标签了。
接下来,我们开始配置 SRTE 动态计算的 Policy.
1. 配置 Juniper 设备的 SRTE Policy
首先我们来配置一个 Policy 名字为 blue 的策略:
root@R1# show
compute-profile dynamic_blue { // 创建 compute profile,用于指定约束条件
admin-group include-any blue; // 约束条件1:必须包含链路亲和属性为 blue 的链路,任意包含即可
metric-type {
te; // 约束条件2:使用 TE Metric 来做路径的计算
}
}
source-routing-path blue { // 创建 SRTE Cpath,用于生成 SRTE LSP
to 10.0.0.8; // 目的地址:10.0.0.8
color 10; // 指定颜色 (SRTE Header) 10
binding-sid 15555; // 手工从 SRLB 分配 BSID
primary { // 指定首选路径(可多个,本实验只写一个)
blue { // 名字为 blue
compute { // 调用计算模块
dynamic_blue; // 使用 compute-profile 为 blue 预定义约束条件来做计算
}
}
}
}
在做完后,我们来看一下 SRTE LSP:
root@R1> show spring-traffic-engineering lsp detail
Name: blue
Tunnel-source: Static configuration
To: 10.0.0.8-10<c>
State: Down
Path: blue
Outgoing interface: NA
Auto-translate status: Disabled Auto-translate result: N/A
Compute Status:Enabled , Compute Result:failure , Compute-Profile Name:dynamic_blue
Total number of computed paths: 0
嗯?好像有点不太对劲,为什么起不来?是配错了什么吗?
在经过排查后,我发现是因为路由器的 TEDB 根本没包含链路 affinity,这就是导致没法计算出路径的元凶!如果只是使用 TE Metric 来计算,不使用约束条件,那么 LSP 就可以变为 UP 状态。
去 IS-IS database 查看后,验证了我的想法:
root@R1> show isis database R1.00-00 extensive
{..snip..}
TLVs:
{..snip..}
IS extended neighbor: R2.00, Metric: default 20 SubTLV len: 34
IP address: 10.10.12.1
Neighbor's IP address: 10.10.12.2
Local interface index: 336, Remote interface index: 334
Traffic engineering metric: 5
P2P IPV4 Adj-SID - Flags:0x34(F:0,B:0,V:1,L:1,S:0,P:1), Weight:0, Label: 15001
P2P IPv4 Adj-SID: 15001, Weight: 0, Flags: --VL-P
{..snip..}
IP extended prefix: 10.0.0.1/32 metric 0 up
8 bytes of subtlvs
Node SID, Flags: 0x40(R:0,N:1,P:0,E:0,V:0,L:0), Algo: SPF(0), Value: 1
IP extended prefix: 10.10.12.0/24 metric 20 up
IP extended prefix: 10.10.15.0/24 metric 10 up
Router Capability: Router ID 10.0.0.1, Flags: 0x00
{..snip..}
只看到了与 SR Capability 有关的 TLV,没有看到链路亲和属性的 TLVs,难怪 SRTE 会计算不出来正确路径!
可是我已经在 protocol mpls 里面已经定义了啊,怎么可能会没有?而且 Cisco 下只要是定义了就可以在 TLV 里面看到啊?关于这个问题我查了一天也没有头绪,Juniper 官方没有写关于链路 affinity 怎么注入到 IS-IS 进程的提示。
最后躺床上的时候灵光一闪,会不会 Juniper 还在使用远古的 affinity 发送方式,就是用 RSVP 来将链路 affinity 注入进 IS-IS 进程后再让 IS-IS 发送?话不多说,直接所有路由器接口上面激活 RSVP 协议:
root@R1# show protocols rsvp interface all; // 生产环境看情况进行配置,无法设置 Passive interface,我已经试过了
再来查看 IS-IS database:
root@R1> show isis database R1.00-00 extensive
{..snip..}
IS extended neighbor: R2.00, Metric: default 20 SubTLV len: 86
IP address: 10.10.12.1
Neighbor's IP address: 10.10.12.2
Local interface index: 336, Remote interface index: 334
{..snip..}
Administrative groups: 0x3 orange blue
P2P IPV4 Adj-SID - Flags:0x34(F:0,B:0,V:1,L:1,S:0,P:1), Weight:0, Label: 15001
P2P IPv4 Adj-SID: 15001, Weight: 0, Flags: --VL-P
{..snip..}
IP extended prefix: 10.0.0.1/32 metric 0 up
8 bytes of subtlvs
Node SID, Flags: 0x40(R:0,N:1,P:0,E:0,V:0,L:0), Algo: SPF(0), Value: 1
IP extended prefix: 10.10.12.0/24 metric 20 up
IP extended prefix: 10.10.15.0/24 metric 10 up
Router Capability: Router ID 10.0.0.1, Flags: 0x00
{..snip..}
我的想法果然是正确的,Juniper 使用 RSVP 将链路亲和属性注入到 IS-IS 中让 IS-IS 协议来发送,开启 RSVP 后可以看到 TLV 里面被染色的链路已经出现了亲和属性 ( Juniper 的链路 affinity 显示模式就是 Administrative groups)。
接下来,我们再来看看 SRTE LSP:
root@R1> show spring-traffic-engineering lsp detail
Name: blue
Tunnel-source: Static configuration
To: 10.0.0.8-10<c>
State: Up
Path: blue
Outgoing interface: NA
Auto-translate status: Disabled Auto-translate result: N/A
Compute Status:Enabled , Compute Result:success , Compute-Profile Name:dynamic_blue
Total number of computed paths: 1
Computed-path-index: 1
BFD status: N/A BFD name: N/A
TE metric: 23, IGP metric: 110; Metric optimized by type: TE
computed segments count: 4
computed segment : 1 (computed-node-segment):
node segment label: 16002
router-id: 10.0.0.2
computed segment : 2 (computed-node-segment):
node segment label: 16003
router-id: 10.0.0.3
computed segment : 3 (computed-adjacency-segment):
label: 15003
source router-id: 10.0.0.3, destination router-id: 10.0.0.4
source interface-address: 10.10.34.3, destination interface-address: 10.10.34.4
computed segment : 4 (computed-node-segment):
node segment label: 16008
router-id: 10.0.0.8
路径已经计算出来了,而且路径和我期望中一样( R1 -> R2 -> R3 -> R4 -> R8 ),这样子使用链路亲和属性作为计算约束条件的 SRTE LSP 就计算成功了。计算的过程以及原理,详见我的上一篇 SRTE 的文章《使用 BGP Auto-Steering 对内网流量进行路径调度》。
然后我们来创建另外两条 LSP,分别使用 ORANGE affinity,TE Metric(不含 affinity) 作为约束条件计算。配置完毕后,我们来查看路径:
root@R1> show spring-traffic-engineering lsp detail
Name: blue
Tunnel-source: Static configuration
To: 10.0.0.8-10<c>
State: Up
Path: blue
{..snip..}
computed segments count: 4
computed segment : 1 (computed-node-segment):
node segment label: 16002
router-id: 10.0.0.2
computed segment : 2 (computed-node-segment):
node segment label: 16003
router-id: 10.0.0.3
computed segment : 3 (computed-adjacency-segment):
label: 15003
source router-id: 10.0.0.3, destination router-id: 10.0.0.4
source interface-address: 10.10.34.3, destination interface-address: 10.10.34.4
computed segment : 4 (computed-node-segment):
node segment label: 16008
router-id: 10.0.0.8
Name: orange
Tunnel-source: Static configuration
To: 10.0.0.8-20<c>
State: Up
Path: orange
{..snip..}
computed segments count: 3
computed segment : 1 (computed-node-segment):
node segment label: 16002
router-id: 10.0.0.2
computed segment : 2 (computed-node-segment):
node segment label: 16003
router-id: 10.0.0.3
computed segment : 3 (computed-adjacency-segment):
label: 15000
source router-id: 10.0.0.3, destination router-id: 10.0.0.8
source interface-address: 10.10.38.3, destination interface-address: 10.10.38.8
Name: te
Tunnel-source: Static configuration
To: 10.0.0.8-30<c>
State: Up
Path: te
{..snip..}
computed segments count: 3
computed segment : 1 (computed-node-segment):
node segment label: 16007
router-id: 10.0.0.7
computed segment : 2 (computed-node-segment):
node segment label: 16003
router-id: 10.0.0.3
computed segment : 3 (computed-adjacency-segment):
label: 15000
source router-id: 10.0.0.3, destination router-id: 10.0.0.8
source interface-address: 10.10.38.3, destination interface-address: 10.10.38.8
他们的路径分别是这样的:
- blue – R1 -> R2 -> R3 -> R4 -> R8
- orange – R1 -> R2 -> R3 -> R8
- TE Metrics – R1 -> R5 -> R6 -> R7 -> R3 -> R8
配置完毕,我们来查看 inetcolor.0 路由表(染色后的 SRTE LSP 会被放在该路由表内,Juniper 系统机制)
root@R1> show route table inetcolor.0
inetcolor.0: 10 destinations, 10 routes (9 active, 0 holddown, 1 hidden)
+ = Active Route, - = Last Active, * = Both
10.0.0.8-20<c>/64
*[SPRING-TE/8] 00:00:08, metric 1, metric2 40
> to 10.10.12.2 via ge-0/0/1.0, Push 15000, Push 16003(top)
嗯?我的 LSP 呢?我那么大两个 LSP 跑哪去了?我们来看看 SRTE LSP 状况:
root@R1> show spring-traffic-engineering lsp
To State LSPname
10.0.0.8-10<c> Up blue
10.0.0.8-20<c> Up orange
10.0.0.8-30<c> Up te
root@R1> show spring-traffic-engineering route detail label 15555 // 查看对应 LSP 的 binding-SID
To : 15555
Tunnel-source : Static configuration
Route Nexthop Type: Unusable
Route Metric2 : 0
LSP Name: blue
{..snip..}
What?为啥 next-hop type 为 Unusable?明明下一跳是直连啊,标签还在 mpls.0 表里面呢?
这个问题我写了很多个 Cpath 来验证我的猜想,包括不限于改变 color 值,约束条件,甚至于改 policy 名字来试试系统是不是 bug 了导致的。实验做了一整天,一点头绪都没有。
不过到第三天的时候,事情出现了转机。最后我发现每次算出来路径的标签数小于等于 3 就没问题,一旦大于 3 后,就立马出现问题,下一跳直接 unusable. 我印象中貌似 Juniper 对接口的标签堆栈数量有严格限制的,而且以前也看到过类似的接口下面有 Max label 的值。我决定试试是不是因为标签数量限制导致下一跳 unusable.
root@R1> show interfaces ge-0/0/1.0
Logical interface ge-0/0/1.0 (Index 336) (SNMP ifIndex 547)
{..snip..}
Protocol mpls, MTU: 1974, Maximum labels: 3
{..snip..}
果然有限制,那我们把数量放开来会怎样呢?
root@R1# show groups
if-group {
interfaces {
<ge-*> {
unit <*> {
family mpls {
maximum-labels 16;
}
}
}
}
}
apply-groups if-group;
现在已经放开来了,inetcolor.0 的路由会好了吗?我们来查看一下:
root@R1> show interfaces ge-0/0/1.0
Logical interface ge-0/0/1.0 (Index 336) (SNMP ifIndex 547)
{..snip..}
Protocol mpls, MTU: 1974, Maximum labels: 16
{..snip..}
root@R1> show route table inetcolor.0
inetcolor.0: 10 destinations, 10 routes (10 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
10.0.0.8-10<c>/64
*[SPRING-TE/8] 00:00:52, metric 1, metric2 40
> to 10.10.12.2 via ge-0/0/1.0, Push 16008, Push 15003, Push 16003(top) // 实际发的时候是堆了 4 层标签,第一个是 16002,标签被 pop 掉后发给 R2
10.0.0.8-20<c>/64
*[SPRING-TE/8] 00:00:52, metric 1, metric2 40
> to 10.10.12.2 via ge-0/0/1.0, Push 15000, Push 16003(top) // 同理
10.0.0.8-30<c>/64
*[SPRING-TE/8] 00:00:52, metric 1, metric2 40
> to 10.10.15.5 via ge-0/0/4.0, Push 15000, Push 16003, Push 16007(top) // 这个是 IGP 直接到 16007 然后再进行下一步转发,出去时候并没有 pop 任何标签
果然生效了,将标签堆栈数量放开后,SRTE LSP 下一跳立刻就生效了,三条 LSP 都被安装进了 inetcolor.0 表内,非常棒。
2. 开始调度流量
接下来,我们开始对 L3VPN 的流量进行调度,和之前一样,我们使用 color community 的方式来把流量自动调度到隧道中。L3VPN 的配置和对路由进行染色的配置我们就略过了,我之前的文章有教过配置。染色和普通 community 的配置过程是一样的,不管是在路由发出方向还是路由接受方向均可。
Juniper 的解析机制稍微有点麻烦,需要写 resolution-map 将符合的 Next-hop + color 值的路由从使用 inet.3 路由表解析改成使用 inetcolor.0 路由表进行下一跳解析。关于 Juniper 设备的路由表之间的关系,详情可见 《inet.3 路由表到底是做什么的?》这篇文章。
路由的预定义路径规则如下:
- 100.64.1.0/24 – 使用 Blue LSP 作为转发路径
- 100.64.2.0/24 – 使用 Orange LSP 作为转发路径
- 100.64.3.0/24 – 使用 TE LSP 作为转发路径
我们来配置 resolution-map 以及导入规则:
root@R1# show policy-options
{..snip..}
policy-statement l3vpn-import {
term accept-all {
from community l3vpn;
then {
accept;
resolution-map odn; // 调度 resolution-map,让该 VRF 内的符合条件的路由改用 inetcolor.0 路由表来解析下一跳
// 这里指的是下一跳 + 路由携带的 color community 匹配上了 LSP 的 [ destination + color ] 值
}
}
}
resolution-map odn {
mode ip-color; // 定义 resolution-map,模式为匹配下一跳 + color 值(标准做法)
}
配置完成,我们来检查一下路由表:
root@R1> show route table l3vpn.inet.0
l3vpn.inet.0: 5 destinations, 5 routes (5 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
100.64.0.0/24 *[Direct/0] 15:14:41
> via ge-0/0/8.0
100.64.0.1/32 *[Local/0] 15:14:41
Local via ge-0/0/8.0
100.64.1.0/24 *[BGP/170] 00:41:52, localpref 100, from 10.0.0.8
AS path: I, validation-state: unverified
> to 10.10.12.2 via ge-0/0/1.0, Push 16, Push 16008, Push 15003, Push 16003(top)
100.64.2.0/24 *[BGP/170] 15:13:32, localpref 100, from 10.0.0.8
AS path: I, validation-state: unverified
> to 10.10.12.2 via ge-0/0/1.0, Push 16, Push 15000, Push 16003(top)
100.64.3.0/24 *[BGP/170] 00:26:40, localpref 100, from 10.0.0.8
AS path: I, validation-state: unverified
> to 10.10.15.5 via ge-0/0/4.0, Push 16, Push 15000, Push 16003, Push 16007(top)
不错,路由已经解析到对应的 inetcolor.0 表里面存放的下一跳了。但是,你以为这样就完了?且慢,我们来做个实验。
首先,我们把 SRTE Cpath 直接给关闭,模拟路径失效后的状况:
root@R1# deactivate protocols source-packet-routing
root@R1> show route table inetcolor.0
root@R1>
root@R1> show route table l3vpn.inet.0 hidden
l3vpn.inet.0: 5 destinations, 5 routes (2 active, 0 holddown, 3 hidden)
+ = Active Route, - = Last Active, * = Both
100.64.1.0/24 [BGP/170] 00:00:15, localpref 100, from 10.0.0.8
AS path: I, validation-state: unverified
Unusable
100.64.2.0/24 [BGP/170] 00:00:15, localpref 100, from 10.0.0.8
AS path: I, validation-state: unverified
Unusable
100.64.3.0/24 [BGP/170] 00:00:15, localpref 100, from 10.0.0.8
AS path: I, validation-state: unverified
Unusable
咦?LSP Down 后为啥 VRF 内路由全部消失了?因为 TE LSP 挂了后,inetcolor.0 里面路由表存放的 LSP 就消失了。但是 VRF 里面的符合条件的路由还是会去 inetcolor.0 查询下一跳,可表里面已经没条目了,还能解析出下一跳吗?不能!
所以我们需要给它配置 fallback 机制,来保证 LSP 消失后也能解析出下一跳。
root@R1# show | compare
[edit protocols isis]
+ rib-group inet3 inetcolor-fallback; // 调用该 rib-group,将路由 copy 到 inetcolor.0
[edit routing-options rib-groups]
+ inetcolor-fallback {
+ import-rib [ inet.3 inetcolor.0 ]; // 配置 rib-group,将 inet.3 的路由(这是 BGP 解析下一跳默认的表)copy 到 inetcolor.0
+ }
为什么用 IS-IS 协议来拷贝?因为 inet3 表里面的表项是由 IS-IS 进程生成的,所以需要在 IS-IS 里面操作。同样的,如果标签是 LDP 生成的,则需要在 LDP 进程里面操作。
操作完毕后,我们再来看一下 inetcolor.0 表:
root@R1> show route table inetcolor.0
inetcolor.0: 10 destinations, 10 routes (10 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
10.0.0.2-0<c>/32
*[L-ISIS/14] 00:00:06, metric 20
> to 10.10.12.2 via ge-0/0/1.0
10.0.0.3-0<c>/32
*[L-ISIS/14] 00:00:06, metric 40
to 10.10.12.2 via ge-0/0/1.0, Push 16003
> to 10.10.15.5 via ge-0/0/4.0, Push 16003
10.0.0.4-0<c>/32
*[L-ISIS/14] 00:00:06, metric 60
> to 10.10.15.5 via ge-0/0/4.0, Push 16004
10.0.0.5-0<c>/32
*[L-ISIS/14] 00:00:06, metric 10
> to 10.10.15.5 via ge-0/0/4.0
10.0.0.6-0<c>/32
*[L-ISIS/14] 00:00:06, metric 20
> to 10.10.15.5 via ge-0/0/4.0, Push 16006
10.0.0.7-0<c>/32
*[L-ISIS/14] 00:00:06, metric 30
> to 10.10.15.5 via ge-0/0/4.0, Push 16007
10.0.0.8-0<c>/32
*[L-ISIS/14] 00:00:06, metric 40
> to 10.10.15.5 via ge-0/0/4.0, Push 16008
10.0.0.8-10<c>/64
*[SPRING-TE/8] 00:00:06, metric 1, metric2 40
> to 10.10.12.2 via ge-0/0/1.0, Push 16008, Push 15003, Push 16003(top)
10.0.0.8-20<c>/64
*[SPRING-TE/8] 00:00:06, metric 1, metric2 40
> to 10.10.12.2 via ge-0/0/1.0, Push 15000, Push 16003(top)
10.0.0.8-30<c>/64
*[SPRING-TE/8] 00:00:06, metric 1, metric2 40
> to 10.10.15.5 via ge-0/0/4.0, Push 15000, Push 16003, Push 16007(top)
很好,inet.3 里面的表项已经转化成 inetcolor.0 格式并拷贝到该表里面了。默认情况下,在 LSP up 的时候,数据会选择 LSP 进行转发,因为 LSP 表项掩码更长。而当 LSP down 的时候,就会 fallback 到 inet.3 拷贝过来的表项进行转发。
我们再次掐掉 SRTE Cpath 来看看情况:
root@R1# run show route table l3vpn.inet.0
l3vpn.inet.0: 5 destinations, 5 routes (5 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
100.64.1.0/24 *[BGP/170] 00:07:38, localpref 100, from 10.0.0.8
AS path: I, validation-state: unverified
> to 10.10.15.5 via ge-0/0/4.0, Push 16, Push 16008(top)
100.64.2.0/24 *[BGP/170] 00:07:38, localpref 100, from 10.0.0.8
AS path: I, validation-state: unverified
> to 10.10.15.5 via ge-0/0/4.0, Push 16, Push 16008(top)
100.64.3.0/24 *[BGP/170] 00:07:38, localpref 100, from 10.0.0.8
AS path: I, validation-state: unverified
> to 10.10.15.5 via ge-0/0/4.0, Push 16, Push 16008(top)
非常好,所有 colored route 全部 fallback 到 inet.3 拷贝过来的表项上做解析了,数据也是可通的。这样,配置就算是完成了。
但是,我觉得这样太麻烦,如果我来配置模板让路由器自己算路径自己引流会怎样呢?我们来使用 Juniper SR-TE DTM 来让路由器来自动化这个配置过程吧!
3. 使用 Juniper SR-TE DTM 来实现按需生成 SR-Policy
我准备让 BLUE LSP 使用 DTM 功能来自动生成,这样只要匹配到预配置的条件,路由器就会自动生成 SR-TE Policy,这样就非常的方便,在需要创建大量 LSP Policy 的时候尤其节省时间以及减少维护成本,所以我非常喜欢这个功能。
话不多说,现在就开始做:
root@R1# show routing-options dynamic-tunnels
ODN-blue { // 创建 DTM Profile,名字叫 ODN-blue
spring-te { // 激活为 segment routing TE 动态创建 Policy 的功能
source-routing-path-template {
auto_blue color 10; // 调用刚刚配置好的模板,当遇到 color 10 的时候使用该模板创建 Policy
}
destination-networks {
10.0.0.0/24; // 下一跳为这个范围地址内的时候,动态创建 Policy,与上面调用的 template 互相作用,缺一不可
}
}
}
root@R1# show protocols source-packet-routing
compute-profile dynamic_blue { // 这是上面已经配置过的约束条件
admin-group include-any blue;
metric-type {
te;
}
}
source-routing-path-template auto_blue { // 配置 ODN 模板 auto_blue
primary {
blue {
compute {
dynamic_blue; // 指定路径,名字为 blue (其实什么都行),调用 compute-profile dynamic_blue 作为计算时的约束条件
}
}
}
}
配置完 ODN 功能后,我们来看看有没有自动创建隧道,以及 BGP 路由有没有被引入 LSP:
root@R1> show spring-traffic-engineering route
To Source SR Override Pref/Pref LSP Name Segment Lists
10.0.0.8-10<c> Dynamic Tunnel Module(DTM) 100 / 100 10.0.0.8:a:dt-srte-ODN-blue blue
10.0.0.8-20<c> Static configuration 100 / 100 orange orange
10.0.0.8-30<c> Static configuration 100 / 100 te te
15666 Static configuration 100 / 100 orange orange
15777 Static configuration 100 / 100 te te
root@R1> show route table l3vpn.inet.0 100.64.1.0/24
l3vpn.inet.0: 5 destinations, 5 routes (5 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
100.64.1.0/24 *[BGP/170] 00:23:35, localpref 100, from 10.0.0.8
AS path: I, validation-state: unverified
> to 10.10.12.2 via ge-0/0/1.0, Push 16, Push 16008, Push 15003, Push 16003(top)
可见 Color 10 隧道已经由 Juniper SR-TE DTM 动态创建,由于约束条件和我上面手动创建的 Policy 约束条件一样,所以路径也是一样的,可以由下面 VRF 内路由表项得出结论。
到最后,我们来测试下路由的走向:
root@L3VPN-Client-A:~# mtr 100.64.1.2 -n --report Start: 2021-06-18T14:29:10+0000 HOST: L3VPN-Client-A Loss% Snt Last Avg Best Wrst StDev 1.|-- 100.64.0.1 0.0% 10 2.6 25.4 1.6 230.9 72.2 2.|-- 10.10.12.2 0.0% 10 7.7 23.0 7.5 74.8 26.0 3.|-- 10.10.23.3 0.0% 10 10.5 15.5 7.2 65.6 17.8 4.|-- 10.10.34.4 0.0% 10 17.9 21.5 7.6 73.2 22.1 5.|-- 100.64.1.1 0.0% 10 7.1 70.1 6.5 481.6 151.9 6.|-- 100.64.1.2 0.0% 10 8.1 9.3 7.6 13.4 2.1 // 由 Blue LSP 引流,路径 R1 -> R2 -> R3 -> R4 -> R8,符合题意 root@L3VPN-Client-A:~# mtr 100.64.2.2 -n --report Start: 2021-06-18T14:29:28+0000 HOST: L3VPN-Client-A Loss% Snt Last Avg Best Wrst StDev 1.|-- 100.64.0.1 0.0% 10 1.6 45.3 1.6 387.3 121.1 2.|-- 10.10.12.2 0.0% 10 81.1 18.8 7.5 81.1 22.8 3.|-- 10.10.23.3 0.0% 10 10.6 59.9 5.5 515.3 160.0 4.|-- 100.64.1.1 0.0% 10 20.9 31.7 5.6 213.4 64.4 5.|-- 100.64.2.2 0.0% 10 8.3 8.1 6.5 12.7 1.9 // 由 Orange LSP 引流,路径 R1 -> R2 -> R3 -> R8,符合题意 root@L3VPN-Client-A:~# mtr 100.64.3.2 -n --report Start: 2021-06-18T14:29:45+0000 HOST: L3VPN-Client-A Loss% Snt Last Avg Best Wrst StDev 1.|-- 100.64.0.1 0.0% 10 2.1 15.4 1.9 132.6 41.2 2.|-- 10.10.15.5 0.0% 10 71.4 55.8 8.8 334.2 100.7 3.|-- 10.10.56.6 0.0% 10 9.3 39.9 7.4 210.6 68.2 4.|-- 10.10.67.7 0.0% 10 8.2 41.2 7.3 289.3 88.0 5.|-- 10.10.37.3 0.0% 10 8.0 16.4 7.7 56.0 14.3 6.|-- 100.64.1.1 0.0% 10 10.3 11.1 6.7 37.7 9.4 7.|-- 100.64.3.2 0.0% 10 7.4 9.1 6.4 13.6 2.2 // 由 TE LSP 引流(通过 TE Metric 计算出来的路径,不含亲和属性作为约束条件),路径 R1 -> R5 -> R6 -> R7 -> R3 -> R8,符合题意
到这里,我们就完成了 Juniper 设备的 SRTE 配置,真的是坑死人不偿命啊。
总结:
- 要是使用链路亲和属性作为计算条件,你需要打开 RSVP,否则亲和属性不会注入到 IS-IS TLV 里面,应该是设计问题。
- 亲和属性 include-any 如果路上出现了不包含指定的 affinity 的链路,则计算会失败,应该也是设计问题。Cisco 没有这个毛病。
- 配置 SRTE 前,请将接口的 Max label 调大,否则堆栈标签数超过接口限制会导致下一跳 unusable
- 配置 SRTE Policy 时,一定要记得把 inet.3 copy 到 inetcolor.0 (为了 LSP 挂了后能 fallback)
参考资料:
《[ SR-TE ] 在 Juniper 设备中使用 SR-TE DTM 调度流量》有3个想法
太感謝了,我也是從cisco的SRTE跳到juniper的,這篇對我的幫助極大,感謝分享!!
感谢支持。
请问大佬,您这个网络中color怎么定义的?,能不能提供一个模板?