取消
显示结果 
搜索替代 
您的意思是: 
cancel
11460
查看次数
73
有帮助
19
评论
one-time
Level 13
Level 13
作者简介:李嘉明 思科系统工程师、苏远超 思科首席工程师、钟庆 思科系统工程师
183506nswjha5qqwjtt7wy.png
摘要:本文基于Linux SRv6功能,结合Mininet、Quagga、Python等工具,验证SRv6的一系列功能,包括VPN、流量工程、服务链等。
本文第二篇详见:Linux SRv6实战(第二篇):服务链功能详解,主要介绍基于Linux SRv6功能,结合Vagrant,Snort等工具,对SRv6服务链功能进行详细解析和验证。实现SRv6服务链上同时支持SR-aware服务和Non SR-aware服务。
一、SRv6简介
Segment Routing(以下简称 SR )指由思科发明,并主要由 IETF SPRING(Source Packet Routing In Networking)工作组进行标准化的新一代网络传送技术。SR 基于源路由并且只在网络边缘维持状态,这使得 SR 非常适合于超大规模 SDN 部署,在极大简化网络的同时,SR 也为网络提供了高度的可编程能力以及端到端的流量工程能力。因此在出现仅短短五年后,SR 已经成为业界共识,是新一代网络尤其是 5G 网络的事实 SDN 架构标准。
183532pcmmfcdzxxu6acmm.jpg
SR 数据平面有两种实现方式,一种是 SR MPLS,重用了 MPLS 数据平面;另一种是 SRv6,使用 IPv6 数据平面。SR 架构可以运行在这两种数据平面上,这是自 SR 提出第一天起就确立的原则。
SRv6 采用 IPv6 标准中定义的路由扩展报头(Routing Extension Header)承载新定义的SRH(Segment Routing Header)扩展路由报头,SRH 类型号定义为 4。在 SRH 中包含了Segment 列表。SRv6 Segment 形式上是一个 128 位的 IPv6 的地址,但其实此 Segment 由 Locator (定位器)和 Function (指令)构成(还可以含有”参数”信息, 本文先略过),Locator 用于 IPv6 路由,Function 用于指定节点需要对数据包施加的各种 SRv6 操作,实现网络的可编程性。
和 SR MPLS 不一样,在数据包的转发过程中 SRv6 通常不会弹出 Segment,而是通过 SRH 中的 Segment Left (剩余 Segment,是个不小 0 的数值)字段作为指针,指向活动 Segment,类似于 SR MPLS 中的顶层标签。每经过一个 SRv6 端节点,Segment Left 减 1,更新 IPv6 报头的目的地址为 Segment 列表中当前 Segment Left 对应的 Segment,并遵循常规的 IPv6 路由把数据包转发出去。
需要强调的是, 如果网络中有节点只支持常规的 IPv6 而不支持 SRv6,当此节点收到 SRv6 数据包时, 按照 IPv6 RFC 的规定,由于数据包目的地址不是节点自身网段地址, 此节点不处理扩展报头,而只是单纯地根据数据包目的地址进行 IPv6 转发。这意味着,SRv6 可以与现有的IPv6 网络无缝互操作,换句话说,SRv6 可以在 IPv6 网络上实现增量部署,无须替换现网所有设备。
以下是本文用到的 SRv6 操作简介:
End : 该操作要求 Segment Left 不为 0(不是最后一跳),会将 Segment Left 减 1,并更新 IPv6 数据包的目的地址为下一个 Segment,这是最常见的 SRv6 操作。相当于 SR MPLS 中的 Prefix-SID。
End.X:该操作和 End 操作基本一致,区别是可以将处理过的数据包发送到指定的下一跳地址。相当于 SR MPLS 中的 Adj-SID。
End.DX4:该操作要求 Segment Left 为 0 且数据包内封装了 IPv4 数据包,会去掉外层的 IPv6 报头,并将内部的 IPv4 数据包转发给指定的下一跳地址。相当于 VPNv4 Per-CE 标签。
End.DX6:该操作要求 Segment Left 为 0 且数据包内封装了 IPv6 数据包,会去掉外层的 IPv6 报头,并将内部的 IPv6 数据包转发给指定的下一跳地址。相当于 VPNv6 Per-CE 标签。
End.B6:该操作会在已有的 SRH 的基础上,插入一个新的 SRH,并可以定义新的 Segment 列表,数据包将首先按照插入的新的 SRH 进行转发。相当于 Binding-SID。
End.B6.Encaps:该操作和 End.B6 基本一致,区别是该操作将在数据包外层新增一个新的 IPv6 报头和 SRH,而不是仅仅添加一个 SRH 的路由报头。
T.Encaps:该操作在中转节点(即数据包经过的支持 SRv6 的路由器,但节点本身不在 Segment 列表中)上执行,会在数据包外层新加一个 IPv6 报头以及 SRH 报头,并可以定义新的 Segment 列表,数据包将首先按照新 IPv6 报头中的 SRH 进行转发。
二、Why Linux SRv6 ?
1. 试验环境容易建立
Linux 内核从 4.10 版本 (2017 年 2 月) 开始就支持 SRv6,距今已经有差不多 2 年的时间,功能已经比较成熟。事实上本文的所有测试,都是在一台主机上借助 Mininet 完成。
另一方面,虽然思科在业界率先在网络设备上支持了 SRv6,但总体而言,目前业界网络设备对 SRv6 的支持程度还比较有限,特别是对于流量工程和服务链等高级功能的支持,因此当前用网络设备不能完全体现出 SRv6 “极简+编程”的革命性创新。但我们相信,随着 SRv6 成为业界共识,网络设备对 SRv6 的支持也会越来越好。
2. 支持丰富的SRv6操作
目前 Linux 对 SRv6 的支持情况如下表所示:
185218c2n1nrzruzd2ndsr.png
表1:Linux 支持 SRv6 情况
可以看到 Linux 已经支持大部分 SRv6 功能,但部分功能需要使用 srext 这个内核扩展模块来实现。本文中我们将只使用 Linux 内核中原生支持的功能进行验证。
可以看到Linux已经支持大部分SRv6功能,但部分功能需要使用srext这个内核扩展模块来实现。本文中我们将只使用Linux内核中原生支持的功能进行验证,srext支持的功能将在下一篇文章中进行讲述。
3. 适用于虚拟化/叠加网络环境
在数据中心/云端广泛采用Linux+NFV技术提供防火墙、入侵检测(IDS)、负载均衡等增值网络业务及服务链(Service Chaining)功能,Linux SRv6可以在其中大显身手。
另一方面,不少用户在数据中心/云端采用主机叠加网络(Host Overlay)来为租户服务,但如何在Host Overlay与Underlay间实现无缝耦合、保证SLA一直是个难题。Linux SRv6可以完美整合Overlay和Underlay,因为无论是Overlay还是Underlay,本质上都是对应着不同的SRv6 Segment(操作)而已;如果需要提高Linux SRv6性能,可以优化DPDK或者使用FD.IO(VPP),其中FD.IO已经内置了完善的SRv6支持,在使用上会更为方便。
三、准备工作
验证环境基于Ubuntu以及Mininet,也可以使用Vagrant+Virtualbox实现。

  • Linux,要求内核版本高于 4.15
  • 最新版Mininet
  • Quagga(在Mininet虚拟拓扑下,提供路由器的静态路由/OSPF/BGP等路由协议支持)
  • Python (通过脚本建立测试拓扑及初始配置)

四、安装教程
下面的安装教程基于Ubuntu 18.04 LTS。
1.升级内核到推荐版本(4.15.0-38)
185808v01fqf8c018fmnyz.png
2.重启,检查内容是否安装完
185815vqwltqwprqcec4t4.png
3.安装Mininet和Quagga
185821pyjjn7yaatyl0i0j.png
4.安装最新版的iproute2
185825as5j7sxdt16syn1d.png
5.安装Python的依赖包
185830j55fs650lwoupw6o.png
6.下载实验拓扑的配置文件
185834vssmu3zq3yj3e3lq.png
五、验证场景
5.1 Linux SRv6实现VPN+流量工程
5.1.1 概述
目的:使2台仅支持IPv4的主机(主机a和主机b),通过SRv6实现VPN互通,并实现流量工程。
拓扑如下图所示:
190043f895890hdnj8y69j.png
图1:Linux SRv6实现VPN+流量工程拓扑
图1中路由器R1、R3和R4为支持SRv6的路由器,R2为仅支持IPv6的路由器,通过开源Quagga实现静态路由,路由器与路由器之间仅通过IPv6实现互通。
在这个测试中,我们的目的是让主机a与主机b实现IPv4互通,并让数据包经由R3路由器,从而实现VPN及流量工程。
详细的数据包转发流程及每一跳的报头变化如下图所示,图中报文上的数字表示数据包在网络中的转发顺序。
请注意: 图中的Segment列表是逆序排列的,即排在列表的第一个Segment是路径上的最后一跳,排在列表的最末位Segment是路径的第一跳。
190050bs6ck40u6r6knsr6.png
图2:Linux SRv6实现VPN+流量工程-数据包转发流程
从主机a发出的数据包,到达支持SRv6的路由器R1,R1会根据所配置的操作对数据包进行封装,在外层加上IPv6以及SRH的报头,并进行正常的IPv6转发。在仅支持IPv6的路由器R2,R2根据IPv6报头基于目的IPv6地址进行转发。在R3,R3路由器根据Segment执行End操作,将Segment Left减1,并根据Segment列表更新IPv6的目的地址,将数据包转发至下一跳R4。在支持SRv6的路由器R4,R4根据Segment执行End.DX4操作,剥掉外层的IPv6报头,将内含的IPv4数据包发给主机b,完成转发流程。
5.1.2 具体步骤
1.首先启动实验拓扑
190300cdo0doyp5j7sz5e0.png
2.在R1路由器上配置T.Encaps操作(SRv6流量工程),将去往10.0.2.0/24的数据包,封装入SRv6,并配置SRH包含的Segment列表为(逆序排列)
190305ojvu7hv7j84wt38z.png
后面的步骤会给出Segment fc00:3::bb,fc00:4::bb fc00:4:bb的定义。
3.同时在R1上配置针对回程数据包的End.DX4操作,让去往主机a的数据包在R1做IPv6的解封装,解出IPv4数据包后发送给主机a
190310u5pvm4ins37srrps.png
4.在R3路由器上配置End操作,以让R3在收到R1发来的数据包时,Segment Left减1,并更新IPv6 目的地址为当前Segment Left指定的Segment。
190316j2129a9f00o2p1p1.png
5.最后在R4路由器上配置End.DX4操作,以让R4收到数据包之后能够做IPv6解封装,并转发给指定地址。
190321pwx1xxp4wx2w1hp2.png
6.相应地在R4上配置T.Encaps操作,对Ping回程IPv4数据包进行封装。
190326ggxz8zydhe1fcf6d.png
配置完成后,可以从主机a(10.0.0.1) Ping通主机b(10.0.2.1)。
5.1.3 脚本执行及抓包验证
为了方便,我们将相关的配置都通过Python脚本实现了自动化。代码见 https://github.com/ljm625/srv6_Sandbox
1.R1
在R1上配置SRv6。
190626cs66zscv7z86z63z.png
图3:R1配置脚本
我们从主机a(10.0.0.1) Ping 主机b(10.0.2.1)进行测试。
然后抓包检查,可以看到从主机a发来的IPv4原始数据包。
190631dnxj9zh1xebeu9nx.png
图4:R1上抓包-主机a发出的IPv4数据包
经过R1路由器后,可以看到数据包外层加了IPv6的报头,路由头类型(Routing Header Type)是4(Segment Routing),里面有2个Segment< fc00:4::bb ,fc00:3::bb>,Segment Left=1,所以IPv6目的地址设置为列表位置为1的地址,即fc00:3::bb。
190638bw2p2w1ctt5p83qi.png
图5:R1上抓包-R1生成带有2个Segment的SRv6数据包
2.R3
在R3上配置SRv6。
190757n4l4llgglqtpmblm.png
图6:R3配置脚本
R3从不支持SRv6的路由器R2处收到了R1发来的数据包,根据定义的策略会执行End操作,即Segment Left减1,并更新 IPv6目的地址。
190805bhc4sg141felf0q2.png
图7:R3上抓包-END操作
3.R4
在R4上配置SRv6。
190811iwu9xud9pfnygfgd.png
图8:R4配置脚本
R4上收到R3发来的数据包,由于Segment Left已经被R3 更新为0,R4会根据策略执行End.DX4操作,去掉IPv6外层报头,转发到指定的10.0.2.1主机,从而完成了VPNv4以及流量工程。
190816ngaggxbrh7gg5rb2.png
图9:R4上抓包-END.DX4操作
下图是执行过End.DX4操作后的数据包抓包情况,可见已经还原为原始的IPv4数据包。
190822otss5y1r2410i5ty.png
图10:R4上抓包-END.DX4操作后的数据包
下图是Ping回程数据包抓包情况,可见加了IPv6报头,目的地址是fc00:1:bb,但SRH中没有Segment,这是因为Segment Left=0(此时其实不需要SRH,具体见参考文献2)。
190840hzemd8faqqddznaq.png
图11:R4上抓包-Ping回程数据包
互通验证结果:
190847xdb4ux773sxcs36d.png
图12:主机a Ping主机b结果
5.2 Linux SRv6实现服务链+流量工程
5.2.1 概述
目的:使2台仅支持IPv4的主机(主机a和主机b),通过SRv6实现互通,并实现服务链+流量工程。本文中我们首先验证支持SRv6的服务(SR-aware),不支持SRv6的服务(Non SR-aware)将在第二篇中介绍。
191304p48p8gqq31tdtdp3.png
图13:Linux SRv6实现服务链+流量工程拓扑
拓扑和第一个场景类似,路由器R1、R3和R4为支持SRv6的路由器,R2为仅支持IPv6的路由器,通过开源Quagga实现静态路由,路由器与路由器之间仅通过IPv6互通。R3路由器上面加入了一台支持SRv6的IDS设备(Snort)。
路由器的Loopback地址间通过IPv6路由可达。
主机a到主机b的流量,在R1上新增的SRH要求经由R3进行转发,因此原流量路径如图蓝色路径所示。
在R3路由器上,修改End操作为End.B6.Encaps操作,将流量先引导到IDS进行处理,再回到R3进行正常转发流程。对应的新的流量路径如图红色路径所示。
End.B6.Encaps的功能我们之前已经简单的进行了介绍,该操作在现有IPv6数据包上封装一个新的IPv6的报头,并添加新的SRH报头;而End.B6操作则不会添加新的IPv6报头,而是直接插入新的SRH报头到现有的IPv6报头当中。这两种操作本质上都相当于是Binding-SID。
具体数据包转发流程中报头的变化可参见图14和图15,图中报文上的数字表示数据包在网络中的转发顺序。
191148od4g4g4hmtyrrw0w.png
图14:Linux SRv6实现服务链+流量工程-数据包转发流量(Part1)
图14为数据包的前半部分转发流程,主机a发出IPv4数据包,R1对IPv4数据包进行封装,加入SRv6报头,其中包含2个Segment。数据包首先转发到R3,执行R3::a对应的操作。我们在R3定义R3::a操作为End.B6.Encaps,变化如图右下角,首先Segment Left减1,更新IPv6目的地址,然后在数据包外层增加新的IPv6报头,SRH中添加2个Segment,首先转发到IDS,然后返回R3。
当数据包到达IDS之后,由于IDS支持SRv6,会执行End操作,并检查/过滤数据包内容,当检查完成后进行正常转发,End操作更新最外层IPv6报头,Segment Left减1,目的地址修改为R3::b。
191157akjnzn5gzsugm2ac.png
图15:Linux SRv6实现服务链+流量工程-数据包转发流量(Part2)
图15表示接下来的转发流程。当数据包第二次返回R3时,由于Segment为R3::b,R3将执行不同的操作,在这个场景中为End.DX6。End.DX6操作会将外层的IPv6报头去掉,然后正常转发,变化如图中所示。
R4收到数据包之后,会根据Segment执行End.DX4操作,去掉IPv6报头,将IPv4数据包转发给主机b,完成整个转发流程。
从上述过程可以看出,SR实现服务链本质上是基于自身的流量工程能力,事实上服务节点(或服务代理)本质上只是Segment列表中的一个Segment,这不单适用于本例中支持SR的服务,也适用于不支持SR的服务。
5.2.2 具体步骤
1.下面我们启动拓扑
191642e0l77w3l3118w077.png
Python脚本会自动配置好设备初始配置以及地址。
2.配置R1
配置T.Encaps操作,为IPv4数据包添加IPv6报头和Segment
191647cqwm49o5q9441145.png
为回程数据包执行End.DX4操作,发给主机a
191652wddwvg37jgdgdegr.png
3.配置R3
执行End.B6.Encaps操作,添加新的SRH去往IDS实现服务链
191658kbj686li0jwn8krn.png
对执行完服务链操作的数据包,去掉外层IPv6报头,进行常规的IPv6转发
191703fx1a6owzbeaoaaeh.png
4.配置IDS
执行End操作,IDS的内部应用对数据包进行检测
191708az1elu1zjnmesgm1.png
5.最后配置R4
对收到的数据包执行End.DX4操作,去掉IPv6报头,正常转发给主机b
191713yln3m2n5p4sows5o.png
回程路由直接去往R1
191718nioo4t5qa6z6jo5b.png
配置完成后,从主机a可以Ping通主机b,并且在IDS处可以监测到主机a发往主机b的数据包。
5.2.3 脚本执行及抓包验证
为了方便,我们将相关的配置都通过Python脚本实现了自动化。代码见 https://github.com/ljm625/srv6_Sandbox
1.R1
在R1上配置SRv6。
192659ycvinznbccegzmsq.png
图16:R1配置脚本
2.R3
在R3上配置SRv6。
192704mz2iwiawe2z2wovw.png
图17:R3配置脚本
3.IDS
在IDS上配置SRv6。
192710ohspupzzwoj2bjo3.png
图18:IDS配置脚本
4.R4
在R4上配置SRv6。
192716zsmzim6m57ibi6v0.png
图19:R4配置脚本
我们从主机a(10.0.0.1) Ping 主机b(10.0.2.1)进行测试。
在主机a上Ping主机b的情况:
192720iqqlv9rvmbumq7qn.png
图20:主机a可以ping通主机b
在R3上的抓包情况:
192726xsbxl3qtsst3lxma.png
图21:R3上抓包-执行完End.B6操作之后的数据包
在IDS上的抓包情况:
192731j8afssb6ssoaunf2.png
图22:IDS上抓包-IDS应用执行完操作,准备发给R3的数据包
我们通过在IDS上的Snort进行监测:
192737dsv6g5qsetgtg2ek.png
图23:Snort监测结果
Snort规则配置为对从10.0.0.1去往10.0.2.1的ICMP包进行告警,可以看到Snort可以正确检测到从10.0.0.1去往10.0.2.1的ICMP包。
六、总结与展望
本文基于两个常见的应用场景(VPN+流量工程,服务链+流量工程)测试了Linux 内核对SRv6的支持情况,测试了常用的End操作,包括End、End.DX4、End.B6.Encaps和T.Encaps。
从测试结果来看,Linux内核已经能很好地支持SRv6常用操作,测试结果令人满意。由于条件所限,本文并未进行性能测试。
在下一篇文章中,我们将测试SRv6 End.AD等操作-即使服务不支持SRv6,仍然可以通过End.AD操作实现服务链。
为了提高性能,业界越来越多使用FD.IO,因此后续文章中我们也会介绍采用FD.IO来实现SRv6,并与网络设备结合,构建高性能的虚拟/物理一体、Overlay/Underlay融合的高性能SRv6网络。
本文所有代码见: https://github.com/ljm625/srv6_Sandbox
【参考文献】
1. SRH draft: https://tools.ietf.org/html/draft-ietf-6man-segment-routing-header-15
2. SRv6 draft:https://tools.ietf.org/html/draft-filsfils-spring-srv6-network-programming-06
3. Segment Routing的相关资料:https://segment-routing.net
4. SRv6 Linux的相关资料/教程:https://segment-routing.org
5. SRv6 VPP的实现和教程:https://wiki.fd.io/view/VPP/Segment_Routing_for_IPv6
作者已授权SDNLAB发布此文,本文链接:https://www.sdnlab.com/22842.html
往期回顾
Linux SRv6实战(第二篇): 服务链功能详解
Linux SRv6实战(第三篇):多云环境下Overlay(VPP) 和Underlay整合测试
uSID:SRv6新范式

评论
Rockyw
Spotlight
Spotlight
感谢管理员分享!
yangkai_716
Spotlight
Spotlight
学习了,thanks for sharing
sh666666
Level 10
Level 10
感谢李嘉明 思科系统工程师、苏远超 思科首席工程师、钟庆 思科系统工程师
YilinChen
Spotlight
Spotlight
这个NBlol:lol
wuhao0015
Spotlight
Spotlight
看起来很牛逼~!支持下~~!
moxiuli
Level 9
Level 9
思科论坛技术强 ,赞思科工程师
David Chou
Level 7
Level 7
很厲害的,拜讀一下
zby
Level 1
Level 1
很强啊,学习学习
18653465190
Spotlight
Spotlight
谢谢大神分享
likuo
Spotlight
Spotlight
思科的5G基础架构。
avicairbus
Level 10
Level 10
thank you very much
zeyang0009
Level 1
Level 1
这个看上去很NB,谢谢楼主分享:D:D:D
Gai
Level 1
Level 1

感谢各位思科工程师的分享!
Gai
Level 1
Level 1
启动mininet后敲配置出现以下错误,请问大神这个怎么解决?
170009xacxaeax31xeag3a.png
moxiuli
Level 9
Level 9
再次阅读为准确答题
入门指南

使用上面的搜索栏输入关键字、短语或问题,搜索问题的答案。

我们希望您在这里的旅程尽可能顺利,因此这里有一些链接可以帮助您快速熟悉思科社区:









快捷链接