参考文献:
https://www.jianshu.com/p/2229854a0d38
https://blog.csdn.net/jonlylinux/article/details/76474545
https://blog.csdn.net/mohan90118/article/details/79399319
https://blog.csdn.net/cloudvtech/article/details/80359825
https://www.cnblogs.com/ZCplayground/p/9329133.html
如有侵权,请联系删除
相关版本配置信息
CenOS 7.2.1511
2核2线程 (4 lcores)
内存4GB
3 NICS
DPDK 17.08
PKTGEN 3.4.2
PKTGEN有两种形式,一种是直接由linux系统自带的内核模块进行发包(也就是略过协议栈,直接控制发包),另一种是依赖于dpdk的pktgen也就是本文主要讲的,需要进行稍微复杂的编译
依赖内核模块的pktgen
modprobe pktgen 载入模块
lsmod |grep -i pktgen 查看是否成功加载
echo "add_device eth0" > /proc/net/pktgen/kpktgend_0 绑定设备
cat /proc/net/pktgen/eth0 查看绑定情况
cat /proc/net/pktgen/pgctrl 查看命令
echo "min_pkt_size 64" > /proc/net/pktgen/eth0 设置最小的包大小
echo "max_pkt_size 9000" > /proc/net/pktgen/eth0 设置最大的包大小
echo "dst_mac 0A:C8:7A:CF:64:44" > /proc/net/pktgen/eth0 设置目的mac地址
echo "count 0" > /proc/net/pktgen/eth0 设置发送的数据包量
echo "dst_min X.X.X.X" > /proc/net/pktgen/eth0 设置目的IP的范围(最小值,包含)
echo "dst_max X.X.X.X " > /proc/net/pktgen/eth0 设置目的IP的范围(最大值,不包含)
echo "start" > /proc/net/pktgen/pgctrl 开始执行
modprobe pktgen
在/proc/net/pktgen看到以下文件:
kpktgend_0 kpktgend_1 kpktgend_2 kpktgend_3 pgctrl
其中kpktgen_*的多少是根据你的CPU的个数决定的,如我的机子的CPU数目为4,则有四个此文件。
通过命令cat /proc/net/pktgen/pgctrl可以查看pktgen的版本等信息:
注:也有使用insmod的,和modprobe的区别是:比如需要安装b模块,但是b依赖于a模块,因此使用insmod安装就需要先安装a模块再安装b模块;如果使用modprobe的话,就可以直接安装b模块,默认将安装a模块
基本上设置完成后就可以进行测试,要查看是否有流量,可以使用ifstat,tcpdump工具查看,使用应用层的抓包工具是无法看到的
依赖dpdk的pktgen
- 编译安装
pktgen-dpdk是用于对DPDK进行高速数据包测试的工具。下载点这里
- 把DPDK那一套流程走一遍(环境变量设置、设置userspace I/O态、挂载大页、绑定网卡)
- pktgen就是基于dpdk开发的应用,所以只要能成功编译dpdk就可以编译pktgen。
wget http://git.dpdk.org/apps/pktgen-dpdk/refs/pktgen-3.4.2.tar.xz
tar -xvJf pktgen-3.4.2.tar.xz
cd pktgen-3.4.2
make
- 命令行方式执行
-P 和 -m 这两个参数是必要的!
./app/build/pktgen [EAL options] -- [-h] [-P] [-G] [-T] [-f cmd_file] [-l log_file] [-s P:PCAP_file] [-m ]
-s P: file PCAP packet stream file, 'P' is the port number
-f filename Command file (.pkt) to execute or a Lua script (.lua) file
-l filename Write log to filename
-P Enable PROMISCUOUS mode on all ports
-g address Optional IP address and port number default is (localhost:0x5606)If -g is used that enable socket support as a server application
-G Enable socket support using default server values localhost:0x5606
-N Enable NUMA support
-T Enable the color output
--crc-strip Strip CRC on all ports
-h Display the help information
关键参数介绍
-c 用于指定运行程序的CPU内核掩码。研究了一下大概是这样的,假如我的虚拟机CPU有5个核,那么就按照 5 4 3 2 1来进行排位,然后从右自左,每4位组成一个16进制数值(二进制1111-> 0xf),不够的补0,算出分配给pktgen使用5个核的掩码就是0x1f,假设我们有10个核,想分配给pktgen使用8个,那么掩码就是0xff。
-n 用来指定内存通道。
-s : 如果你想用pktgen发送pcap文件 例如 [-s P:PCAP_file] -s 0 : 1.pcap 0表示在第0个网卡,1.pcap及文件名
-f : 在运行pktgen时可以运行指定的脚步文件,进行初始化配置
-P : 启动所有网卡,并进入混杂模式,想指定特定网卡 用 -p mask
-G : 让pktgen成为服务器,之后后可以进行远程控制 默认是 localhost:0x5606
-g : 让pktgen成为服务器,之后后可以进行远程控制 可以进行IP和端口的设置
-m : 指定lcore和port的映射关系
参数中,最复杂的是 -m <string>
-m <string> 配置端口到逻辑核的映射关系,使用类似BNF类语法.映射的逻辑核要与 [EAL options]中的逻辑核要一致。
运行命令./app/x86_64-native-linuxapp-gcc/pktgen -l 0-2 -n 3 -- -P -m "[1].0, [2].1"
- 修改配置文件,run.py方式执行
cd pktgen-3.4.2/cfg
cp default.cfg default.backup 备份
vi default.cfg
官方的default.cfg内容如下:
description = 'A Pktgen default simple configuration'
# Setup configuration
setup = {
'exec': (
'sudo',
'-E'
),
'devices': (
'81:00.0 81:00.1 81:00.2 81:00.3', #绑定网卡设备PCI号
'85:00.0 85:00.1 85:00.2 85:00.3'
),
'opts': (
'-b igb_uio'
)
}
# Run command and options
run = {
'exec': (
'sudo',
'-E'
),
# Application name and use app_path to help locate the app
'app_name': 'pktgen',
# using (sdk) or (target) for specific variables
# add (app_name) of the application
# Each path is tested for the application
'app_path': (
'./app/%(target)s/%(app_name)s',
'%(sdk)s/%(target)s/app/%(app_name)s',
),
'dpdk': (
'-l 14,15-22', #使用的逻辑核
'-n 4', #内存通道数为4
'--proc-type auto',
'--log-level 7',
'--socket-mem 2048,2048', #大页为2048
'--file-prefix pg'
),
'blacklist': (
#'-b 81:00.0 -b 81:00.1 -b 81:00.2 -b 81:00.3',
#'-b 85:00.0 -b 85:00.1 -b 85:00.2 -b 85:00.3',
'-b 81:00.0 -b 81:00.1',
'-b 85:00.0 -b 85:00.1',
'-b 83:00.0'
),
'app': (
'-T',
'-P',
'--crc-strip',
'-m [15:16].0',
'-m [17:18].1',
'-m [19:20].2',
'-m [21:22].3'
),
'misc': (
'-f',
'themes/black-yellow.theme'
)
}
需要修改的地方有三处:
- 网卡设备的PCI号,可以用dpdk的usertools查看。
- DPDK EAL 的 command line arguments。改成与你系统对应的参数。参照DPDK的文档。
- pktgen 的 command line arguments,参照pktgen的文档。
贴上我的版本作为参考:
#..................
'devices': (
'02:02.0 02:03.0' #只绑定了两个网卡
),
#..................
'dpdk': (
'-l 0-3', #使用了四个逻辑核
'-n 4', #内存通道数为4
'--proc-type auto',
'--log-level 7',
'--socket-mem 1024', #大页为1024
'--file-prefix pg'
),
#..................
'app': (
'-T',
'-P',
'--crc-strip',
'-m [1].0',
'-m [2].1',
#'-m [15:16].0',
#'-m [17:18].1',
#'-m [19:20].2',
#'-m [21:22].3'
),
修改完后即可执行。
cd pktgen-3.4.2
./tools/dpdk-run.py -s default # setup system using the cfg/default.cfg file
./tools/dpdk-run.py default
pktgen-dpdk向testpmd发送数据
-
测试环境
两个虚拟机 VM1 VM2
-
运行testpmd
./build/app/testpmd -l 0-1 -n 1 -- -i
将网卡设为只读模式、非混杂模式(这样就只收pktgen发来的包)后开始收包
set fwd rxonly
set promisc all off
show port stats all
start
- 运行pktgen
./app/x86_64-native-linuxapp-gcc/pktgen -l 0-1 -n 3 -- -P -m "[1].0"
set 0 dst ip 192.168.74.132
set 0 dst mac 00:0c:29:45:e2:b9
set 0 count 100
start 0
图中port1和port2已经有明显区别,收包数相差100个包
用pkggen再发1000个包
set 0 count 1000
str
收包数相差1100个
测试结果与预期一致,分别执行
quit
退出。