前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >利用vpp和内核协议栈通信机制实现虚拟机上网

利用vpp和内核协议栈通信机制实现虚拟机上网

作者头像
dpdk-vpp源码解读
发布2023-03-07 17:19:47
1.7K0
发布2023-03-07 17:19:47
举报
文章被收录于专栏:DPDK VPP源码分析DPDK VPP源码分析

本文参考博客(https://blog.csdn.net/illina/article/details/81669944)来学习一下利用vpp实现虚拟机上网功能。主要是为了学习虚拟网卡功能在vpn场景中应用比较广泛。

使用vpp通过tap/tun方式访问网络

vpp提供了创建tap口的命令行如下(参数比较多没有详细研究):

代码语言:javascript
复制
create tap {id <if-id>} [hw-addr <mac-address>] [num-rx-queues <n>] [rx-ring-size <size>] [tx-ring-size <size>] [host-ns <netns>] [host-bridge <bridge-name>] [host-ip4-addr <ip4addr/mask>] [host-ip6-addr <ip6-addr>] [host-ip4-gw <ip4-addr>] [host-ip6-gw <ip6-addr>] [host-mac-addr <host-mac-address>] [host-if-name <name>] [host-mtu-size <size>] [no-gso|gso [gro-coalesce]|csum-offload] [persist] [attach] [tun] [packed] [in-order]

说明:Id:是vpp内部管理的ID,一般情况创建以0开头,这样linux系统也创景一个类似名字的tap0口。 host-if-name:这个意思应该是Linux已经存在一个tap口,vpp创建的tap接口和linux host-if-name口进行绑定,可以实现1对1通信。

下图是在本地环境使用Vmware虚拟机使用vpp实现上网的功能:

配置命令如下:

代码语言:javascript
复制
#1、创建tap0网卡,创建完后对应在linux系统下也生成一个tap0接口
vppctl create tap id 0
vppctl set int l2 bridge GigabitEthernet2/3/0 1
vppctl set int state GigabitEthernet2/3/0 up
vppctl set int l2 bridge tap0 1
vppctl set int state tap0 up
#2、配置linux tap0接口ip 地址(这里本地环境网关是192.168.124.1)
ifconfig tap0 192.168.124.18/24

在虚拟机上ping www.baidu.com 然后在vpp上进行trace抓包查询转发流程处理。

代码语言:javascript
复制
#1、在虚拟机上来ping 百度,能ping通
[root@localhost ~]# ping www.baidu.com
PING www.baidu.com (182.61.200.6) 56(84) bytes of data.
64 bytes from 182.61.200.6 (182.61.200.6): icmp_seq=1 ttl=52 time=6.43 ms

# 2、设置trace 抓包:
vpp#clear trace
vpp#travppce add virtio-input 100
vpp#show trace
#3、抓取访问百度的报文
Packet 5
04:18:45:691575: virtio-input
  virtio: hw_if_index 3 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
04:18:45:691582: ethernet-input
  IP4: 02:fe:0e:90:87:26 -> 04:d7:a5:5e:fc:f9
04:18:45:691587: l2-input
  l2-input: sw_if_index 3 dst 04:d7:a5:5e:fc:f9 src 02:fe:0e:90:87:26
04:18:45:691589: l2-learn
  l2-learn: sw_if_index 3 dst 04:d7:a5:5e:fc:f9 src 02:fe:0e:90:87:26 bd_index 1
04:18:45:691592: l2-fwd
  l2-fwd:   sw_if_index 3 dst 04:d7:a5:5e:fc:f9 src 02:fe:0e:90:87:26 bd_index 1 result [0x1910000000001, 1] none
04:18:45:691594: l2-output
  l2-output: sw_if_index 1 dst 04:d7:a5:5e:fc:f9 src 02:fe:0e:90:87:26 data 08 00 45 00 00 54 ba 7c 40 00 40 01
04:18:45:691596: GigabitEthernet2/3/0-output
  GigabitEthernet2/3/0
  IP4: 02:fe:0e:90:87:26 -> 04:d7:a5:5e:fc:f9
  ICMP: 192.168.124.18 -> 182.61.200.6
    tos 0x00, ttl 64, length 84, checksum 0xc52d dscp CS0 ecn NON_ECN
    fragment id 0xba7c, flags DONT_FRAGMENT
  ICMP echo_request checksum 0xcaf8
04:18:45:691598: GigabitEthernet2/3/0-tx
  GigabitEthernet2/3/0 tx queue 0
  buffer 0x9e135: current data 0, length 98, buffer-pool 0, ref-count 1, totlen-nifb 0, trace handle 0x4
                  l2-hdr-offset 0 l3-hdr-offset 14
  PKT MBUF: port 65535, nb_segs 1, pkt_len 98
    buf_len 2176, data_len 98, ol_flags 0x0, data_off 128, phys_addr 0xad84dc0
    packet_type 0x0 l2_len 0 l3_len 0 outer_l2_len 0 outer_l3_len 0
    rss 0x0 fdir.hi 0x0 fdir.lo 0x0
  IP4: 02:fe:0e:90:87:26 -> 04:d7:a5:5e:fc:f9
  ICMP: 192.168.124.18 -> 182.61.200.6
    tos 0x00, ttl 64, length 84, checksum 0xc52d dscp CS0 ecn NON_ECN
    fragment id 0xba7c, flags DONT_FRAGMENT
  ICMP echo_request checksum 0xcaf8

在vpn业务上应用比较广泛,可以利用vpp来创建gre、ipsec隧道。来看下图的流程:

假设192.168.0.5发出了一个对192.168.0.3的ARP请求,该ARP请求在网络中经过的路径如下: 1、192.168.0.5发出ARP请求,询问192.168.0.3的MAC地址。 2、该ARP请求将被发送到以太网交换机上。 3、以太网交换机对该请求进行泛洪,发送到其包括Eth1在内的所有端口上。 4、由于Eth1被加入了VPN主机上的Linux Bridge,因此Linux Bridge收到该ARP请求。 5、Linux Bridge对该ARP请求进行泛洪,发送到连到其上面的Tap虚拟网卡上。 6、VPN程序通过/dev/net/tun字符设备读取到该ARP请求,然后封装到TCP/UDP包中,发送到对端站点的VPN主机。 7、对端站点的VPN程序通过监听TCP/UDP端口接收到封装的ARP请求,将ARP请求通过/dev/net/tun字符设备写入到Tap设备中。 8、Linux Bridge泛洪,将ARP请求发送往Eth1,由于Eth1连接到了以太网交换机上,以太网交换机接收到了该ARP请求。 9、以太网交换机进行泛洪,将ARP请求发送给了包括192.168.0.3的所有主机。 10、192.168.0.3收到了APR请求,判断iP地址和自己相同,对此请求进行响应。 11、同理,ARP响应包也可以按照该路径返回到图左边包括192.168.0.5在内的站点中。

veth-pair实现虚拟机上网

veth-pair 就是一对的虚拟设备接口,和 tap/tun 设备不同的是,它都是成对出现的。一端连着协议栈,一端彼此相连着。配置组网如下:

代码语言:javascript
复制
#虚拟机配置如下:
ip link add veth0 type veth peer name veth1
ifconfig veth0 192.168.124.18
#需要添加缺省网关,否则路由可能不通,导致无法上网。
route add default gw 192.168.124.1
#Vpp 配置如下:
vppctl set int l2 bridge GigabitEthernet2/3/0 1
vppctl set int state GigabitEthernet2/3/0 up
vppctl create host-interface name veth1
vppctl set int l2 bridge host-veth1 1
vppctl set int state host-veth1 up

veth-pair实现虚拟机上网

veth-pair 就是一对的虚拟设备接口,和 tap/tun 设备不同的是,它都是成对出现的。一端连着协议栈,一端彼此相连着。

代码语言:javascript
复制
#设置trace抓包,注意这里需要设置af-packet-input类型。
vpp# clear trace
vpp# trace add af-packet-input 100
vpp# show trace
------------------- Start of thread 0 vpp_main -------------------
05:33:26:350890: af-packet-input
  af_packet: hw_if_index 3 next-index 4
    tpacket2_hdr:
      status 0x20000009 len 118 snaplen 118 mac 66 net 80
      sec 0x5fe67880 nsec 0xcf238a0 vlan 0 vlan_tpid 0
05:33:26:350898: ethernet-input
  IP4: 2a:28:c7:53:7d:37 -> c8:b2:9b:90:ee:08
05:33:26:350901: l2-input
  l2-input: sw_if_index 3 dst c8:b2:9b:90:ee:08 src 2a:28:c7:53:7d:37
05:33:26:350903: l2-learn
  l2-learn: sw_if_index 3 dst c8:b2:9b:90:ee:08 src 2a:28:c7:53:7d:37 bd_index 1
05:33:26:350904: l2-fwd
  l2-fwd:   sw_if_index 3 dst c8:b2:9b:90:ee:08 src 2a:28:c7:53:7d:37 bd_index 1 result [0x1910000000001, 1] none
05:33:26:350906: l2-output
  l2-output: sw_if_index 1 dst c8:b2:9b:90:ee:08 src 2a:28:c7:53:7d:37 data 08 00 45 10 00 68 4e b7 40 00 40 06
05:33:26:350907: GigabitEthernet2/3/0-output
  GigabitEthernet2/3/0
  IP4: 2a:28:c7:53:7d:37 -> c8:b2:9b:90:ee:08
  TCP: 192.168.124.18 -> 192.168.124.13
    tos 0x10, ttl 64, length 104, checksum 0x7258 dscp unknown ecn NON_ECN
    fragment id 0x4eb7, flags DONT_FRAGMENT
  TCP: 22 -> 53774
    seq. 0x7f5bdb61 ack 0x3ad89b33
    flags 0x18 PSH ACK, tcp header: 20 bytes
    window 324, checksum 0x0000
05:33:26:350909: GigabitEthernet2/3/0-tx
  GigabitEthernet2/3/0 tx queue 0
  buffer 0x9c1d3: current data 0, length 118, buffer-pool 0, ref-count 1, totlen-nifb 0, trace handle 0x2
                  ip4 offload-tcp-cksum l2-hdr-offset 0 l3-hdr-offset 14
  PKT MBUF: port 65535, nb_segs 1, pkt_len 118
    buf_len 2176, data_len 118, ol_flags 0x90000000000000, data_off 128, phys_addr 0xad07540
    packet_type 0x0 l2_len 14 l3_len 20 outer_l2_len 0 outer_l3_len 0
    rss 0x0 fdir.hi 0x0 fdir.lo 0x0
    Packet Offload Flags
      PKT_TX_TCP_CKSUM (0x0000) TCP cksum of TX pkt. computed by NIC
  IP4: 2a:28:c7:53:7d:37 -> c8:b2:9b:90:ee:08
  TCP: 192.168.124.18 -> 192.168.124.13
    tos 0x10, ttl 64, length 104, checksum 0x7258 dscp unknown ecn NON_ECN
    fragment id 0x4eb7, flags DONT_FRAGMENT
  TCP: 22 -> 53774
    seq. 0x7f5bdb61 ack 0x3ad89b33
    flags 0x18 PSH ACK, tcp header: 20 bytes
    window 324, checksum 0x79cb

参考资料

1、VPP和Linux内核协议栈通信的方法 https://blog.csdn.net/illina/article/details/81669944 2、Linux Tun/Tap 介绍 https://zhaohuabing.com/post/2020-02-24-linux-taptun/ 3、Linux Veth设备简介 https://www.cnblogs.com/bakari/p/10613710.html

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 使用vpp通过tap/tun方式访问网络
  • veth-pair实现虚拟机上网
  • veth-pair实现虚拟机上网
  • 参考资料
相关产品与服务
VPN 连接
VPN 连接(VPN Connections)是一种基于网络隧道技术,实现本地数据中心与腾讯云上资源连通的传输服务,它能帮您在 Internet 上快速构建一条安全、可靠的加密通道。VPN 连接具有配置简单,云端配置实时生效、可靠性高等特点,其网关可用性达到 99.95%,保证稳定、持续的业务连接,帮您轻松实现异地容灾、混合云部署等复杂业务场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档