首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >learning vpp: svs基于源地址的路由选择的插件

learning vpp: svs基于源地址的路由选择的插件

作者头像
dpdk-vpp源码解读
发布2024-11-23 08:29:14
发布2024-11-23 08:29:14
28300
代码可运行
举报
文章被收录于专栏:DPDK VPP源码分析DPDK VPP源码分析
运行总次数:0
代码可运行
源 VRF 选择(Source VRF Select 简称SVS )功能使得路由器可以根据数据包的源 IP 地址来选择不同的 VRF 表进行路由查找。这意味着路由器可以在多 VRF 环境中根据数据包的来源决定如何处理和转发数据包。通过SVS,可以在不同的 VRF 实例之间实现更严格的隔离,这对于多租户环境中的网络隔离尤其重要。

单纯的SVS功能有下面2个好处:增强路由灵活性:SVS 允许路由器根据数据包的源 IP 地址来选择不同的 VRF(Virtual Routing and Forwarding)实例进行路由查找。这意味着网络可以更加灵活地处理不同的流量类型,特别是在多租户环境中,每个租户可能有自己的 VRF 实例。提高安全性:通过 SVS,网络管理员可以根据数据包的源地址来控制哪些流量可以访问特定的网络资源。这种基于源地址的路由选择有助于防止未经授权的访问,并增加了网络的整体安全性。

下面就搭建环境了解一下具体的使用。以下是我们搭建的组网环境。具体步骤如下:

  • 内核创建2个netns tap1和tap2
代码语言:javascript
代码运行次数:0
运行
复制
ip netns add tap1
ip netns add tap2
  • 在vpp上创建2个tap接口,tap1 加入vrf 1,tap2 加入vrf2 ,并配置对应的ip地址.
代码语言:javascript
代码运行次数:0
运行
复制
create tap id 1 host-if-name tap1 host-ip4-addr 192.168.10.2/24 host-ip4-gw 192.168.10.1 host-ns tap1
ip table add 1
set interface ip table tap1 1
set interface state tap1 up
set interface ip addr tap1 192.168.10.1/2

create tap id 2 host-if-name tap2 host-ip4-addr 192.168.20.2/24 host-ip4-gw 192.168.20.1 host-ns tap2
ip table add 2
set interface ip table tap2 2
set interface state tap2 up
set interface ip addr tap2 192.168.20.1/2

在创建tap接口时,我们设置以下参数用于指定在内核tap接口的信息: host-ip4-gw :设置内核缺省网关地址。 host-ip4-addr:设置内核接口地址。 host-if-name:设置tap接口对应内核接口名称。 netns tap1 :设置接口加入netns tap1

  • 创建svs vrf表,并将接口tap1和tap2 分别绑定不同vrf表中
代码语言:javascript
代码运行次数:0
运行
复制
svs table ip4 table-id 3
svs enable ip4 table-id 3 tap1
svs table ip4 table-id 4
svs enable ip4 table-id 4 tap2

设置完成之后,我们分别查询接口和vrf绑定情况:tap1绑定到vrf3表中,tap2绑定到vrf 4表中。

代码语言:javascript
代码运行次数:0
运行
复制
dpdk-vpp源码分析: show svs
Source VRF select interface to fib-index mappings:
 ipv4
  tap1 -> 3
  tap2 -> 4
 ipv6

接下来查询一下在vrf 3和vrf4中默认路由的转发表情况:

vrf 3表中的默认路由转发表中可以看到基于源ip地址查询到vrf时1,vrf 1 就是接口tap1 默认的vrf表"src-address,unicast lookup in ipv4-VRF:1",也就是说tap1收到的报文,基于源ip查询得到vrf 1 ,然后在vrf 1中基于DIP查询路由转发。

vrf 4表中的默认路由转发表中可以看到基于源ip地址查询到vrf时2,vrf 2 就是接口tap2 默认的vrf表 "src-address,unicast lookup in ipv4-VRF:2"也就是说tap2收到的报文,基于源ip查询得到vrf 2 ,然后在vrf 2中基于DIP查询路由转发。‍

上面配置可以保证 tap接口对应网段下的子网都可以ping通网关地址。

代码语言:javascript
代码运行次数:0
运行
复制
dpdk-vpp源码分析: show ip fib table 3 0.0.0.0/0
ipv4-VRF:3, fib_index:3, flow hash:[src dst sport dport proto flowlabel ] epoch:0 flags:none locks:[svs:1, ]
0.0.0.0/0 fib:3 index:23 locks:3
  svs refs:1 entry-flags:exclusive, src-flags:added,contributing,active,
    path-list:[40] locks:2 flags:exclusive, uPRF-list:34 len:0 itfs:[]
      path:[44] pl-index:40 ip4 weight=1 pref=0 exclusive:  oper-flags:resolved, cfg-flags:exclusive,
        [@0]: src-address,unicast lookup in ipv4-VRF:1

  default-route refs:1 entry-flags:drop, src-flags:added,
    path-list:[34] locks:1 flags:drop, uPRF-list:28 len:0 itfs:[]
      path:[38] pl-index:34 ip4 weight=1 pref=0 special:  cfg-flags:drop,
        [@0]: dpo-drop ip4

 forwarding:   unicast-ip4-chain
  [@0]: dpo-load-balance: [proto:ip4 index:25 buckets:1 uRPF:34 to:[0:0]]
    [0] [@13]: src-address,unicast lookup in ipv4-VRF:1
dpdk-vpp源码分析: show ip fib table 4 0.0.0.0/0
ipv4-VRF:4, fib_index:4, flow hash:[src dst sport dport proto flowlabel ] epoch:0 flags:none locks:[svs:1, ]
0.0.0.0/0 fib:4 index:28 locks:3
  svs refs:1 entry-flags:exclusive, src-flags:added,contributing,active,
    path-list:[46] locks:2 flags:exclusive, uPRF-list:40 len:0 itfs:[]
      path:[50] pl-index:46 ip4 weight=1 pref=0 exclusive:  oper-flags:resolved, cfg-flags:exclusive,
        [@0]: src-address,unicast lookup in ipv4-VRF:2

  default-route refs:1 entry-flags:drop, src-flags:added,
    path-list:[41] locks:1 flags:drop, uPRF-list:35 len:0 itfs:[]
      path:[45] pl-index:41 ip4 weight=1 pref=0 special:  cfg-flags:drop,
        [@0]: dpo-drop ip4

 forwarding:   unicast-ip4-chain
  [@0]: dpo-load-balance: [proto:ip4 index:30 buckets:1 uRPF:40 to:[0:0]]
    [0] [@13]: src-address,unicast lookup in ipv4-VRF:2
  • 接下来配置svs 路由表 设置src ip地址192.168.10.2的报文,在vrf 3表中进行srcip地址查询到vrf 2。然后再根据DIP+vrf2 进行路由查询转发。
代码语言:javascript
代码运行次数:0
运行
复制
svs route add table-id 3 192.168.10.2/32 src-table-id 2
#在vrf 3 中根据源ip查询 vrf情况:
192.168.10.2/32
  unicast-ip4-chain
  [@0]: dpo-load-balance: [proto:ip4 index:35 buckets:1 uRPF:41 to:[0:0]]
    [0] [@13]: src-address,unicast lookup in ipv4-VRF:2

设置src ip地址192.168.20.2的报文,在vrf 4表中进行srcip地址查询到vrf 1。然后再根据DIP+vrf1 进行路由查询转发。

代码语言:javascript
代码运行次数:0
运行
复制
svs route add table-id 4 192.168.20.2/32 src-table-id 1
#在vrf 3 中根据源ip查询 vrf情况:
192.168.20.2/32
  unicast-ip4-chain
  [@0]: dpo-load-balance: [proto:ip4 index:36 buckets:1 uRPF:42 to:[0:0]]
    [0] [@13]: src-address,unicast lookup in ipv4-VRF:1

下面我们在netns tap1 中ping 192.168.20.2的地址,可以正常ping通。

代码语言:javascript
代码运行次数:0
运行
复制
PING 192.168.20.2 (192.168.20.2) 56(84) bytes of data.
64 bytes from 192.168.20.2: icmp_seq=2 ttl=63 time=0.154 ms
64 bytes from 192.168.20.2: icmp_seq=3 ttl=63 time=0.142 ms

抓取trace如下:通过trace流程可以看到svs核心功能只有一个svs-ip4的node节点,挂接在ip4-input节点之后。作用就是基于sip地址查询到转发的vrf 索引,然后再送到ip4-lookup接口,基于DIP+ vrf进行路由查询。

代码语言:javascript
代码运行次数:0
运行
复制
# ping 请求报文

00:09:28:340186: virtio-input
  virtio: hw_if_index 1 next-index 4 vring 0 len 98
    hdr: flags 0x00 gso_type 0x00 hdr_len 0 gso_size 0 csum_start 0 csum_offset 0 num_buffers 1
00:09:28:340199: ethernet-input
  frame: flags 0x1, hw-if-index 1, sw-if-index 1
  IP4: 02:fe:01:fc:15:f6 -> 02:fe:5b:93:d9:cd
00:09:28:340209: ip4-input
  ICMP: 192.168.10.2 -> 192.168.20.2
    tos 0x00, ttl 64, length 84, checksum 0x2a34 dscp CS0 ecn NON_ECN
    fragment id 0x7120, flags DONT_FRAGMENT
  ICMP echo_request checksum 0xe5e id 54797
00:09:28:340218: svs-ip4
   fib_index 2
00:09:28:340222: ip4-lookup
  fib 2 dpo-idx 5 flow hash: 0x00000000
  ICMP: 192.168.10.2 -> 192.168.20.2
    tos 0x00, ttl 64, length 84, checksum 0x2a34 dscp CS0 ecn NON_ECN
    fragment id 0x7120, flags DONT_FRAGMENT
  ICMP echo_request checksum 0xe5e id 54797
00:09:28:340231: ip4-rewrite
  tx_sw_if_index 2 dpo-idx 5 : ipv4 via 192.168.20.2 tap2: mtu:9000 next:4 flags:[] 02fe6f5e6e2102fe29fe4f130800 flow hash: 0x00000000
  00000000: 02fe6f5e6e2102fe29fe4f13080045000054712040003f012b34c0a80a02c0a8
  00000020: 140208000e5ed60d00387047096700000000d5da0500000000001011
00:09:28:340234: tap2-output
  tap2 flags 0x00180005
  IP4: 02:fe:29:fe:4f:13 -> 02:fe:6f:5e:6e:21
  ICMP: 192.168.10.2 -> 192.168.20.2
    tos 0x00, ttl 63, length 84, checksum 0x2b34 dscp CS0 ecn NON_ECN
    fragment id 0x7120, flags DONT_FRAGMENT
  ICMP echo_request checksum 0xe5e id 54797
00:09:28:340241: tap2-tx
    buffer 0x9ed29: current data 0, length 98, buffer-pool 0, ref-count 1, trace handle 0x0
                    l2-hdr-offset 0 l3-hdr-offset 14
  hdr-sz 0 l2-hdr-offset 0 l3-hdr-offset 14 l4-hdr-offset 0 l4-hdr-sz 0
  IP4: 02:fe:29:fe:4f:13 -> 02:fe:6f:5e:6e:21
  ICMP: 192.168.10.2 -> 192.168.20.2
    tos 0x00, ttl 63, length 84, checksum 0x2b34 dscp CS0 ecn NON_ECN
    fragment id 0x7120, flags DONT_FRAGMENT
  ICMP echo_request checksum 0xe5e id 54797

# ping回应报文

00:09:28:340293: virtio-input
  virtio: hw_if_index 2 next-index 4 vring 0 len 98
    hdr: flags 0x00 gso_type 0x00 hdr_len 0 gso_size 0 csum_start 0 csum_offset 0 num_buffers 1
00:09:28:340295: ethernet-input
  frame: flags 0x1, hw-if-index 2, sw-if-index 2
  IP4: 02:fe:6f:5e:6e:21 -> 02:fe:29:fe:4f:13
00:09:28:340298: ip4-input
  ICMP: 192.168.20.2 -> 192.168.10.2
    tos 0x00, ttl 64, length 84, checksum 0xe45b dscp CS0 ecn NON_ECN
    fragment id 0xf6f8
  ICMP echo_reply checksum 0x165e id 54797
00:09:28:340300: svs-ip4
   fib_index 1
00:09:28:340301: ip4-lookup
  fib 1 dpo-idx 4 flow hash: 0x00000000
  ICMP: 192.168.20.2 -> 192.168.10.2
    tos 0x00, ttl 64, length 84, checksum 0xe45b dscp CS0 ecn NON_ECN
    fragment id 0xf6f8
  ICMP echo_reply checksum 0x165e id 54797
00:09:28:340303: ip4-rewrite
  tx_sw_if_index 1 dpo-idx 4 : ipv4 via 192.168.10.2 tap1: mtu:9000 next:3 flags:[] 02fe01fc15f6
02fe5b93d9cd0800 flow hash: 0x00000000
  00000000: 02fe01fc15f602fe5b93d9cd080045000054f6f800003f01e55bc0a81402c0a8
  00000020: 0a020000165ed60d00387047096700000000d5da0500000000001011
00:09:28:340305: tap1-output
  tap1 flags 0x00180005
  IP4: 02:fe:5b:93:d9:cd -> 02:fe:01:fc:15:f6
  ICMP: 192.168.20.2 -> 192.168.10.2
    tos 0x00, ttl 63, length 84, checksum 0xe55b dscp CS0 ecn NON_ECN
    fragment id 0xf6f8
  ICMP echo_reply checksum 0x165e id 54797
00:09:28:340308: tap1-tx
    buffer 0x9c650: current data 0, length 98, buffer-pool 0, ref-count 1, trace handle 0x1
                    l2-hdr-offset 0 l3-hdr-offset 14
  hdr-sz 0 l2-hdr-offset 0 l3-hdr-offset 14 l4-hdr-offset 0 l4-hdr-sz 0
  IP4: 02:fe:5b:93:d9:cd -> 02:fe:01:fc:15:f6
  ICMP: 192.168.20.2 -> 192.168.10.2
    tos 0x00, ttl 63, length 84, checksum 0xe55b dscp CS0 ecn NON_ECN
    fragment id 0xf6f8
  ICMP echo_reply checksum 0x165e id 54797

至此,我们介绍了svs的基本配置并了解其业务处理逻辑。SVS 作为一种基于源地址的路由选择机制,在多 VRF 环境中提供了灵活性、安全性和可扩展性。它与传统的路由功能的主要区别在于路由选择的依据,SVS 通过源地址来动态选择不同的 VRF 实例,从而更好地适应现代网络中复杂的路由需求。在实际业务中使用场景还不是很明了。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-10-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DPDK VPP源码分析 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档