一、目的:
使2台仅支持IPv4的主机(主机a和主机b),通过SRv6实现VPN互通,并实现流量工程。拓扑如下图所示:
图1:Linux SRv6实现VPN+流量工程拓扑
图1中路由器R1、R3和R4为支持SRv6的路由器,R2为仅支持IPv6的路由器,通过开源Quagga实现静态路由,路由器与路由器之间仅通过IPv6实现互通。在这个测试中,我们的目的是让主机a与主机b实现IPv4互通,并让数据包经由R3路由器,从而实现VPN及流量工程。
详细的数据包转发流程及每一跳的报头变化如下图所示,图中报文上的数字表示数据包在网络中的转发顺序。请注意: 图中的Segment列表是逆序排列的,即排在列表的第一个Segment是路径上的最后一跳,排在列表的最末位Segment是路径的第一跳。
图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,完成转发流程。
二、具体步骤
-
首先启动实验拓扑
ip route add 10.0.0.0/24 encap seg6 mode encap segs fc00:1::bb dev r4-eth1
配置完成后,可以从主机a(10.0.0.1) Ping通主机b(10.0.2.1)。
三、脚本执行及抓包验证
图3:R1配置脚本
我们从主机a(10.0.0.1) Ping 主机b(10.0.2.1)进行测试。然后抓包检查,可以看到从主机a发来的IPv4原始数据包。
图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。
图5:R1上抓包-R1生成带有2个Segment的SRv6数据包
2. R3
在R3上配置SRv6。
图6:R3配置脚本
R3从不支持SRv6的路由器R2处收到了R1发来的数据包,根据定义的策略会执行End操作,即Segment Left减1,并更新 IPv6目的地址。
图7:R3上抓包-END操作
3. R4
图8:R4配置脚本
R4上收到R3发来的数据包,由于Segment Left已经被R3 更新为0,R4会根据策略执行End.DX4操作,去掉IPv6外层报头,转发到指定的10.0.2.1主机,从而完成了VPNv4以及流量工程。
图8:R4上抓包-END.DX4操作
下图是执行过End.DX4操作后的数据包抓包情况,可见已经还原为原始的IPv4数据包。
图9:R4上抓包-END.DX4操作后的数据包
下图是Ping回程数据包抓包情况,可见加了IPv6报头,目的地址是fc00:1:bb,但SRH中没有Segment,这是因为Segment Left=0(此时其实不需要SRH)。
图10:R4上抓包-Ping回程数据包
互通验证结果:
图11:主机a Ping主机b结果。