FD.io VPP环境下运行用户应用程序教程

FD.io VPP环境下运行用户应用程序教程


RToax
2020年9月

相关文章:《FD.io VPP利用iperf3进行UDP灌包测试-英特尔X520万兆网卡

1. VPP简介

VPP是思科矢量数据包处理(VPP)技术的开源版本:一种高性能的数据包处理协议栈。具体介绍请阅读相关文档,此处不做VPP介绍相关内容。

2. VPP协议栈架构

DPDK用户态驱动接管10G网卡,VPP内嵌DPDK插件(plugin)组成一套完整的用户态网络协议栈。通过使用VCL库,VPP可以重定向应用程序的接口函数,当然,要通过LD_PRELOAD。
在这里插入图片描述

3. DPDK配置

VPP我们选择的20.05版本,DPDK也选择了响应的20.05兼容版本。

3.1. 编译

编译步骤一般在部署环境过程中已经完成,不用再次编译。

进入dpdk目录:

cd /opt/dpdk-20.05/

执行脚本:

./usertools/dpdk-setup.sh 

DPDK支持的架构越来越丰富,这里,我们选择[38]:

[34] x86_64-native-bsdapp-gcc
[35] x86_64-native-freebsd-clang
[36] x86_64-native-freebsd-gcc
[37] x86_64-native-linuxapp-clang
[38] x86_64-native-linuxapp-gcc
[39] x86_64-native-linuxapp-icc
[40] x86_64-native-linux-clang
[41] x86_64-native-linux-gcc
[42] x86_64-native-linux-icc

3.2. 设置环境变量

进入dpdk目录:

cd /opt/dpdk-20.05/
cat DPDKGNUenv.sh

内容如下:

#!/bin/bash
# <*! 添加 DPDK-20.05 环境变量> rongtao@sylincom.com

export RTE_SDK=/opt/dpdk-20.05
export RTE_TARGET=x86_64-native-linuxapp-gcc

环境变量我编写了对应20.05版本的脚本,直接执行source使其生效。

source DPDKGNUenv.sh

或者为了方便,将其加入/etc/profile中,使其登录生效,在/etc/profile(或者只在当前用户生效的~/.bashrc)中添加如下内容:

# 添加DPDK-20.05环境变量
source /opt/dpdk-20.05/DPDKGNUenv.sh

3.3. 加载驱动

进入dpdk目录:

cd /opt/dpdk-20.05/

执行脚本:

./usertools/dpdk-setup.sh 

有如下内容:

----------------------------------------------------------
 Step 2: Setup linux environment
----------------------------------------------------------
[45] Insert IGB UIO module
[46] Insert VFIO module
[47] Insert KNI module
[48] Setup hugepage mappings for non-NUMA systems
[49] Setup hugepage mappings for NUMA systems
[50] Display current Ethernet/Baseband/Crypto device settings
[51] Bind Ethernet/Baseband/Crypto device to IGB UIO module
[52] Bind Ethernet/Baseband/Crypto device to VFIO module
[53] Setup VFIO permissions

分别执行[45]、[46]、[47],以[45]为例:

Option: 45

Unloading any existing DPDK UIO module
Loading uio module
Loading DPDK UIO module

Press enter to continue ...

3.4. 大页内存的配置

关于大页内存的配置([48]、[49]),在部署环境过程中已经完成,此处不做介绍。

3.5. 网卡绑定

进入dpdk目录:

cd /opt/dpdk-20.05/

执行脚本:

./usertools/dpdk-setup.sh 

有如下内容:

----------------------------------------------------------
 Step 2: Setup linux environment
----------------------------------------------------------
[45] Insert IGB UIO module
[46] Insert VFIO module
[47] Insert KNI module
[48] Setup hugepage mappings for non-NUMA systems
[49] Setup hugepage mappings for NUMA systems
[50] Display current Ethernet/Baseband/Crypto device settings
[51] Bind Ethernet/Baseband/Crypto device to IGB UIO module
[52] Bind Ethernet/Baseband/Crypto device to VFIO module
[53] Setup VFIO permissions

这里我们使用igb_uio驱动[51]选项:

Option: 51


Network devices using kernel driver
===================================
0000:18:00.0 'NetXtreme BCM5720 Gigabit Ethernet PCIe 165f' if=em1 drv=tg3 unused=igb_uio *Active*
0000:18:00.1 'NetXtreme BCM5720 Gigabit Ethernet PCIe 165f' if=em2 drv=tg3 unused=igb_uio 
0000:19:00.0 'NetXtreme BCM5720 Gigabit Ethernet PCIe 165f' if=em3 drv=tg3 unused=igb_uio 
0000:19:00.1 'NetXtreme BCM5720 Gigabit Ethernet PCIe 165f' if=em4 drv=tg3 unused=igb_uio 

Other Network devices
=====================
0000:3b:00.0 'Ethernet 10G 2P X520 Adapter 154d' unused=ixgbe,igb_uio
0000:3b:00.1 'Ethernet 10G 2P X520 Adapter 154d' unused=ixgbe,igb_uio

No 'Baseband' devices detected
==============================

No 'Crypto' devices detected
============================

No 'Eventdev' devices detected
==============================

No 'Mempool' devices detected
=============================

No 'Compress' devices detected
==============================

No 'Misc (rawdev)' devices detected
===================================

Enter PCI address of device to bind to IGB UIO driver: 

根据网卡型号,服务器中安装了Ethernet 10G 2P X520 Adapter 154d网卡,所以绑定这两个网口即可:

Enter PCI address of device to bind to IGB UIO driver: 0000:3b:00.0
OK

Press enter to continue ...

同样的方式绑定另一个网口。

然后,再次输入选项[51],如下:

Option: 51

Network devices using DPDK-compatible driver
============================================
0000:3b:00.0 'Ethernet 10G 2P X520 Adapter 154d' drv=igb_uio unused=ixgbe
0000:3b:00.1 'Ethernet 10G 2P X520 Adapter 154d' drv=igb_uio unused=ixgbe

证明网卡绑定成功。

当然也可以使用./usertools/dpdk-devbind.py,查询、绑定、取消绑定网卡。
To display current device status:
dpdk-devbind.py --status
To display current network device status:
dpdk-devbind.py --status-dev net
To bind eth1 from the current driver and move to use igb_uio
dpdk-devbind.py --bind=igb_uio eth1
To unbind 0000:01:00.0 from using any driver
dpdk-devbind.py -u 0000:01:00.0
To bind 0000:02:00.0 and 0000:02:00.1 to the ixgbe kernel driver
dpdk-devbind.py -b ixgbe 02:00.0 02:00.1

截至目前,VPP环境的DPDK设置已经完成。下面进行VPP的设置。

4. VPP的配置

因为我们采用VCL的方式使用VPP,并不是采用编写插件、GraphNode的形式,我们不需要添加修改VPP源代码。By the way,我们的VPP源码环境目录位于/opt/vpp-stable-2005目录下,对于VPP的编译安装,这里不做说明解释。

5. VPP启动配置文件startup.conf

启动配置文件在部署环境过程中会作出对应的修改,基本上,不需要作出修改,但这里有必要对关键参数进行说明。
vpp的默认配置启动文件为/etc/vpp/startup.conf,当然,VPP也支持传入配置文件名,使用-c参数传入,例如:vpp -c startup-myconf.conf。下面就启动配置文件作出一些说明。

5.1. unix{}参数

先给出示例配置:

unix {
  nodaemon
  log /var/log/vpp/vpp.log
  full-coredump
  # cli-listen /run/vpp/cli.sock
  gid vpp
  coredump-size unlimited
  cli-listen localhost:5002
  cli-prompt RToax-VPP#
  cli-history-limit 100
  cli-pager-buffer-limit 5000
  pidfile /run/vpp/vpp.pid
  startup-config /usr/share/vpp/scripts/startup.txt
}

nodaemon:不以守护进程的形式运行VPP;
cli-listen:VPP命令行,localhost:5002为监听5002端口,用户可以使用telnet [host address] 5002进行命令行接入;也可以设置成cli-listen /run/vpp/cli.sock,这是,可以使用vppctl接入命令行。

VPP命令行在下文中会做简单的介绍。

值得注意的是startup-config选项,该选项会在VPP初始化结束后实行对应文件中的VPP命令行指令。比如说,我们在startup.conf中指定了dpdk网卡、队列等,可以使用startup-config选项,在初始化后,执行网卡启动指令将网卡up。
执行的vpp命令函脚本/usr/share/vpp/scripts/startup.txt内容简介。

设置VPP网卡IP

set interface ip address dpdk0 10.170.7.169/24

上面的网卡名dpdk0在启动配置文件startup.conf中命名。
启动VPP网卡

set interface state dpdk0 up

设置路由

ip route add 10.170.7.0/24 via 10.170.7.254
ip route add 10.170.6.0/24 via 10.170.7.254
ip route add 10.37.8.0/24 via 10.170.7.254

开启网卡混杂模式

set interface promiscuous on dpdk0

5.2. cpu{}参数

只介绍几个关键参数,详情请见相关文档。

cpu {
	main-core 1
	workers 2
	scheduler-policy fifo
	scheduler-priority 50
	thread-prefix vpp
}

设置主CPU,注意,这个CPU不能是其他线程绑定的,需要被VPP独占

main-core 1

设置从CPU,同样需要被VPP独占

workers 2

5.3. dpdk{}参数

dpdk {
	log-level debug
	dev 0000:3b:00.0 {
		name dpdk0
	}
	dev 0000:3b:00.1 {
		name dpdk1
	}
	no-multi-seg 
	dev default {
		num-rx-queues 2
		num-tx-queues 2
	}

	# igb_uio, vfio-pci 
	uio-driver igb_uio
}

设置总线地址为0000:3b:00.0的网卡名为dpdk0

name dpdk0

设置默认的接收发送队列个数

num-rx-queues 2
num-tx-queues 2

设置网卡的驱动程序类型,这里需要与上一章节中的网卡绑定:igb_uio驱动[51]选项相对应,

uio-driver igb_uio

6. VPP VCL配置文件vcl.conf

VPP VCL配置文件vcl.conf的默认路径为/etc/vpp/vcl.conf,这了当然也可以执行,但是我们不做处理。

这部分内容不需要做出修改。

7. VPP的启动

7.1. systemctl的启动方式(不采用)

若vpp的启动配置文件均采用默认配置,使用/etc/vpp/startup.conf,VCL的配置文件使用/etc/vpp/vcl.conf命名,那么,我们可以使用systemctl来控制vpp的启动、重启、停止。当然,如果修改vpp.service文件的话,也可以修改使用systemctl启动vpp的默认配置文件,但为了保证尽可能少的修改vpp原始配置,这里我们不使用。

如果采用systemctl启动的话,vpp遵从status、start、restart、stop、enable、disable等操作,但目前我们处于调试阶段,尚不再用这种方法,采用手动启动vpp软件。

7.2. 手动启动VPP(采用)

这里的配置文件名称我们命名为startup-iperf3.conf,其内容如下(10.170.7.166):

## Filename:		startup-iperf3.conf
## Introduction:	VPP start up configure file
## File History:	
##	2020.09	rongtao		New
## 
unix { 
	nodaemon
	gid vpp 
	cli-listen localhost:5002
	startup-config /usr/share/vpp/scripts/startup.txt
}
session { evt_qs_memfd_seg  }
socksvr { socket-name /tmp/vpp-api.sock}
api-trace { on }
cpu {
	main-core 1
	workers 2
	scheduler-policy fifo
	scheduler-priority 50
	thread-prefix vpp
}

buffers {
	buffers-per-numa 128000
}

dpdk {
	log-level debug

	dev 0000:3b:00.0 {
		name dpdk0
	}
	dev 0000:3b:00.1 {
		name dpdk1
	}
	no-multi-seg 
	dev default {
		num-rx-queues 1
		num-tx-queues 1
		num-rx-desc 1024
	}
	# igb_uio, vfio-pci 
	uio-driver igb_uio

	# socket-mem 2048,2048

	no-tx-checksum-offload
}

plugins {
	## Adjusting the plugin path depending on where the VPP plugins are
	path /opt/vpp-stable-2005/build-root/install-vpp-native/vpp/lib/vpp_plugins

	## Disable all plugins by default and then selectively enable specific plugins
	 plugin default { disable }
	 plugin dpdk_plugin.so { enable }
	 plugin acl_plugin.so { enable }

	## Enable all plugins by default and then selectively disable specific plugins
	# plugin dpdk_plugin.so { disable }
	# plugin acl_plugin.so { disable }
 }

文件startup-iperf3.conf不需要做出修改。

下面启动VPP软件:

vpp -c startup-iperf3.conf

输出内容如下:

[root@localhost vpp]# vpp -c startup-iperf3.conf 
vpp[33021]: vlib_sort_init_exit_functions:160: order constraint fcn 'dns_init' not found
vpp[33021]: vnet_feature_arc_init:271: feature node 'nat44-in2out-output' not found (before 'ip4-dvr-reinject', arc 
'ip4-output')vpp[33021]: dpdk: EAL init args: -c e -n 4 --in-memory --log-level debug --file-prefix vpp -w 0000:3b:00.0 -w 0000:3
b:00.1 --master-lcore 1 Thread 1 (vpp_wk_0):
  node dpdk-input:
    dpdk0 queue 0 (polling)
Thread 2 (vpp_wk_1):
  node dpdk-input:
    dpdk1 queue 0 (polling)

这时候可以进入VPP的命令行,打开一个终端,使用telnet命令连接命令行:

[root@localhost ~]# telnet 0 5002
Trying 0.0.0.0...
Connected to 0.
Escape character is '^]'.
    _______    _        _   _____  ___ 
 __/ __/ _ \  (_)__    | | / / _ \/ _ \
 _/ _// // / / / _ \   | |/ / ___/ ___/
 /_/ /____(_)_/\___/   |___/_/  /_/    

vpp# 

查看配置的dpdk网口信息状态

vpp# show interface address
dpdk0 (up):
  L3 10.170.7.169/24
dpdk1 (up):
local0 (dn):

查看网卡收发包情况

vpp# show interface 
              Name               Idx    State  MTU (L3/IP4/IP6/MPLS)     Counter          Count     
dpdk0                             1      up          9000/0/0/0     rx packets                   539
                                                                    rx bytes                   46170
                                                                    tx packets                     3
                                                                    tx bytes                     126
                                                                    drops                        485
                                                                    punt                          54
                                                                    ip4                           96
                                                                    ip6                           12
dpdk1                             2      up          9000/0/0/0     rx packets                   534
                                                                    rx bytes                   45754
                                                                    drops                        480
                                                                    punt                          54
                                                                    ip4                           93
                                                                    ip6                           12
local0                            0     down          0/0/0/0  

这时,VPP启动成功。

8. 基于VCL库运行用户应用程序

8.1. VPP VCL库简介

VCL库提供一种将可执行程序中的函数接口重定向至VPP中,整体架构如下:

在这里插入图片描述

如上图可知,我们可以在不修改VPP代码和应用程序代码的基础上,在VPP环境下运行应用程序,目前已经测试成功的为iperf3应用程序在VPP下运行。

基于VPP的iperf3灌包测试见下文。

8.2. 设置环境变量

进入VPP目录

cd /opt/vpp-stable-2005/

这里我为大家写好了一个配置环境变量的脚本,执行下面的命令:

source ld_preload.sh

这时,在此终端下运行的指令,只要有vcl支持的接口函数都会被重定向到VPP的VCL库中。

接下来,你在这个终端(bash)下运行的所有指令,指令中相关的函数接口都将被重定向到VCL库中去。

9. 在VPP环境下的iperf3灌包测试

在以上的配置下来后,开启一个终端,最好是另一台服务器,并且与运行VPP的服务器网络通畅。

在需要配置VPP路由表时,请配置路由表。

在另一台服务器上于小宁iperf3服务端(10.170.6.66):

[root@localhost ~]# iperf3 -s 
-----------------------------------------------------------
Server listening on 5201
-----------------------------------------------------------

在部署、启动并设置了VCL环境变量的VPP的环境下(10.170.7.166),运行iperf3 UDP客户端进行灌包测试:

[root@localhost ~]# iperf3 --bind 10.170.7.169 -c 10.170.6.66 -b 30G -u

在服务端(10.170.6.66),速率为:

Accepted connection from 10.170.7.169, port 45251
[  5] local 10.170.6.66 port 5201 connected to 10.170.7.169 port 40774
[ ID] Interval           Transfer     Bitrate         Jitter    Lost/Total Datagrams
[  5]   0.00-1.01   sec  11.5 MBytes  95.2 Mbits/sec  0.875 ms  1409578/1417807 (99%)  
[  5]   1.01-2.01   sec  9.22 MBytes  77.7 Mbits/sec  0.768 ms  1434748/1441372 (1e+02%)  
[  5]   2.01-3.01   sec  9.15 MBytes  76.6 Mbits/sec  0.805 ms  1444889/1451464 (1e+02%)  
[  5]   3.01-4.00   sec  13.1 MBytes   110 Mbits/sec  0.644 ms  1433329/1442738 (99%)  
[  5]   4.00-5.01   sec  10.2 MBytes  85.1 Mbits/sec  0.898 ms  1445632/1452944 (99%)  
[  5]   5.01-6.01   sec  9.01 MBytes  75.6 Mbits/sec  0.687 ms  1446563/1453033 (1e+02%)  
[  5]   6.01-7.01   sec  11.1 MBytes  93.6 Mbits/sec  0.630 ms  1436834/1444831 (99%)  
[  5]   7.01-8.00   sec  11.6 MBytes  97.5 Mbits/sec  0.787 ms  1431028/1439352 (99%)  
[  5]   8.00-9.00   sec  10.7 MBytes  89.8 Mbits/sec  0.717 ms  1437719/1445388 (99%)  
[  5]   9.00-10.00  sec  15.3 MBytes   128 Mbits/sec  0.515 ms  1450464/1461435 (99%)  
[  5]  10.00-10.27  sec  1.34 MBytes  43.1 Mbits/sec  0.040 ms  22743/23707 (96%)  
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Jitter    Lost/Total Datagrams
[  5]   0.00-10.27  sec   112 MBytes  91.6 Mbits/sec  0.040 ms  14393527/14474071 (99%)  receiver

在客户端(10.170.7.166),灌包速率为:

Connecting to host 10.170.6.66, port 5201
[ 33] local 10.170.7.169 port 40774 connected to 10.170.6.66 port 5201
[ ID] Interval           Transfer     Bandwidth       Total Datagrams
[ 33]   0.00-1.00   sec  1.97 GBytes  16.9 Gbits/sec  1447697  
[ 33]   1.00-2.00   sec  1.97 GBytes  16.9 Gbits/sec  1447854  
[ 33]   2.00-3.00   sec  1.97 GBytes  16.9 Gbits/sec  1448529  
[ 33]   3.00-4.00   sec  1.97 GBytes  16.9 Gbits/sec  1447631  
[ 33]   4.00-5.00   sec  1.97 GBytes  16.9 Gbits/sec  1448475  
[ 33]   5.00-6.00   sec  1.97 GBytes  16.9 Gbits/sec  1448486  
[ 33]   6.00-7.00   sec  1.97 GBytes  16.9 Gbits/sec  1447945  
[ 33]   7.00-8.00   sec  1.97 GBytes  16.9 Gbits/sec  1448170  
[ 33]   8.00-9.00   sec  1.97 GBytes  16.9 Gbits/sec  1447847  
[ 33]   9.00-10.00  sec  1.97 GBytes  16.9 Gbits/sec  1447870  
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth       Jitter    Lost/Total Datagrams
[ 33]   0.00-10.00  sec  19.7 GBytes  16.9 Gbits/sec  0.040 ms  14393527/14474071 (99%)  
[ 33] Sent 14474071 datagrams

后续,我又部署了一套vpp环境(10.37.8.37),进行联合测试的结果如下图:

在这里插入图片描述

10. 在VPP环境下运行基站程序

这与上一节一样,将iperf3换成我们的应用程序即可。

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值