Pktgen-dpdk
Pktgen-dpdk(Packet Generator)是一个基于 DPDK 开发的发包工具,因此也可以认为是一个实例,详询 官方文档。 https://pktgen-dpdk.readthedocs.io/en/latest/commands.html Github: https://github.com/pktgen/Pktgen-DPDK/blob/main/doc/source/index.rst
pktgen的两种方式: DPDK PKTGEN使用 - 简书 方式1.直接由linux系统自带的内核模块进行发包 参考: 内核pkgen 的脚本写法: pktgen使用详细教程
方式2.依赖于dpdk的pktgen 参考: DPDK-Pktgen的使用 DPDK pktgen usage Running Script Files — Pktgen 3.2.4 documentation (pktgen-dpdk.readthedocs.io)
2. 依赖内核模块的pktgen
脚本:./pktgen.sh
(此脚本使用网卡的多队列数个cpu打流, 默认打流数为虚拟机的cpu数量) 用法: 修改脚本中网卡的名字 vmNic=被测网卡的名字
bash pktgen.sh $vmIp $vmMac
另外开窗口查看 网卡的收发包情况: "sar -n DEV 1"
3. 依赖dpdk的pktgen
软件包: 带补充
1. 配置(宿主机)的大页内存
修改/etc/default/grub,在GRUB_CMDLINE_LINUX里增加
**iommu=pt intel_iommu=on** default_hugepagesz=1G hugepagesz=1G hugepages=8
保存后根据启动方式执行grub2-mkconfig -o /boot/grub2/grub.cfg 或者 grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg
再reboot
2.1 测试PF卡 在裸金属上安装mlnx 网卡驱动
2.2 测试virtio-net 卡,需要绑定vfio-pci 驱动,每次重启后需要重新绑定
modprobe vfio-pci;dpdk-devbind.py -u xxx; ifconfig ensxx 0; dpdk-devbind.py -b vfio-pci _ensxx_
3. 若环境中有dpdk, 则跳过此步。 下载dpdk的源码包进行编译, dpdk-testpmd作为收包工具
rpm -hiv dpdk-20.11-2.ctl2.src.rpm
cd /root/rpmbuild/SPECS
rpmbuild -bb dpdk.spec
cd /root/rpmbuild/RPMS/x86_64/; **rpm -ihv *.rpm --force (一定要装dpdk-20.11-2.x86_64.rpm和dpdk-devel-20.11-2.x86_64.rpm)**
yum install -y python34-3.4.5-4.el7.x86_64
4. 上传 pktgen压缩包,待补充
源码包,使用用户态的pktgen 作为发包工具
tar -xzf pktgen-21.01.0.tar.gz
cd pktgen-21.01.0 ; make
cd pktgen-21.01.0/usr/local/bin; ./pktgen --help
make时报错说找不到libdpdk时, cd /root/rpmbuild/RPMS/x86_64/; rpm -ihv dpdk-devel-20.11-2.x86_64.rpm)
make时报错说“C library 'numa' not found”的解决办法:
确保安装了以下几个包:
[root@G]# rpm -qa | grep numa
numad-0.5-31.ctl2.x86_64
numactl-libs-2.0.13-4.ctl2.x86_64
numactl-2.0.13-4.ctl2.x86_64
在/usr/lib64/下执行 ln -s libnuma.so.1 libnuma.so
5. 用法示例 ./pktgen -a 0000:b1:00.1 -l 12-23 -n 8 -- -P -m "[13:14-21].0"
6. 参数说明 参考 Pktgen command line directory format
-l 使用12-23这几个core
-n 内存通道数为8
-- 命令行参数分解为DPDK环境抽象层(EAL)的参数和应用程序本身的参数, 两组参数用 -- 约定分开
-P: 是否开始混杂模式.
-m <string>: DPDK网卡和逻辑核之间的矩阵映射, 表示 core 13 处理 port 0 rx, core 14-21 处理 port 0 tx
常用设置命令:
设置所有端口协议数据包协议: set all proto udp
为特定端口设置src/dst mac: set 0 dst mac 00:30:64:58:8B:3A
为特定端口设置src/dst mac: set 1 src mac 00:30:64:58:8B:3A
设置所有端口发包速率(40Gbps):set all rate 40
启动特定端口发包: start 0
关闭端口发包: stp
清屏: clr
range设置
设置range所有端口数据包协议:range all proto udp
设置range所有端口数据包大小:range all size 1326 1326 1326 0
设置特定端口的srcip地址range:range 0 src ip 192.168.0.1 192.168.0.1 192.168.0.3 0.0.0.1
启动range: enable all range
退出pktgen: quit
使用举例:
./pktgen -a 0000:88:00.1 -l 24-33 -n 8 -- -P -m "[25:26-33].0"
page range (进入range设置界面)
range all proto udp
enable all range
range 0 src ip 10.4.7.163 10.4.7.163 10.4.7.163 0.0.0.0
range 0 dst ip 10.4.7.34 10.4.7.34 10.4.7.34 0.0.0.0
range 0 src mac fa:16:3e:a9:b2:9e fa:16:3e:a9:b2:9e fa:16:3e:a9:b2:9e 00:00:00:00:00:00
range 0 dst mac fa:16:3e:46:9f:02 fa:16:3e:46:9f:02 fa:16:3e:46:9f:02 00:00:00:00:00:00
range all src port 1 1 1000 20
range all dst port 1 1 1000 20
start 0
page main (从页面显示观察发送PPS)
手动运行命令
pktgen脚本
#!/bin/sh
# pktgen.conf -- Sample configuration for send on two devices on a UP system
#modprobe pktgen
if [[ `lsmod | grep pktgen` == "" ]];then
modprobe pktgen
fi
if [[ $1 == "" ]];then
pktsize=550
else
pktsize=$1
fi
function pgset() {
local result
echo $1 > $PGDEV
result=`cat $PGDEV | fgrep "Result: OK:"`
if [ "$result" = "" ]; then
cat $PGDEV | fgrep Result:
fi
}
function pg() {
echo inject > $PGDEV
cat $PGDEV
}
# On UP systems only one thread exists -- so just add devices
# We use eth1, eth1
echo "Adding devices to run".
PGDEV=/proc/net/pktgen/kpktgend_0
pgset "rem_device_all"
pgset "add_device eth1"
pgset "max_before_softirq 1"
# Configure the individual devices
echo "Configuring devices"
PGDEV=/proc/net/pktgen/eth1
pgset "clone_skb 1000"
pgset "pkt_size $pktsize"
pgset "src_mac 00:1B:21:90:4B:E4"
pgset "flag IPSRC_RND"
pgset "src_min 10.0.0.2"
pgset "src_max 10.0.0.255"
pgset "dst 10.0.0.1"
pgset "dst_mac 00:4E:46:31:30:00"
pgset "count 0"
# Time to run
PGDEV=/proc/net/pktgen/pgctrl
echo "pkgsize:$pktsize"
echo "Running... ctrl^C to stop"
pgset "start"
echo "Done"
bash
echo "rem_device_all" > /proc/net/pktgen/kpktgend_0
echo "add_device eth0" > /proc/net/pktgen/kpktgend_0
echo "pkt_size 1000" > /proc/net/pktgen/eth0
echo "count 1000" > /proc/net/pktgen/eth0
echo "delay 1" > /proc/net/pktgen/eth0
echo "src 10.180.80.179" > /proc/net/pktgen/eth0
echo "dst 10.180.80.181" > /proc/net/pktgen/eth0
echo "start" > /proc/net/pktgen/pgctrl
pkt_size
:包长count
:发包个数delay
:时间间隔,单位是纳秒
- 也可使用命令构建脚本
常见命令
控制命令
命令 | 说明 |
---|---|
start | 所有线程开始发送 |
stop | 停止 |
线程的控制命令
命令 | 说明 |
---|---|
add_device | 添加某个端口到某个线程 |
rem_device_all | 删除绑定在某个线程的所有端口 |
max_before_softirq | 在最多发送多少个数据包后,执行 do_softirq() |
端口命令
命令 | 说明 |
---|---|
debug | 调试 |
clone_skb | 对每个 skb 进行多少个复制,0 表示不复制 |
clear_counters | 清空计数器,默认自动清空 |
pkt_size | 链路包的大小(除去CRC的值) |
min_pkt_size | 数据包最小值 |
max_pkt_size | 数据包最大值 |
flags | 包的分片数量 |
count | 发送数据包的个数,0 表示一直发送 |
delay | 发送两个数据包之间的延时 |
dst | 目的 IP |
dst_min | 目的 IP 的最小值 |
dst_max | 目的 IP 的最大值 |
src_min | 源 IP 最小值 |
src_max | 源 IP 最大值 |
dst6 | 目的 IPv6 地址 |
src6 | 源 IPv6 地址 |
dstmac | 目的 MAC |
srcmac | 源 MAC |
src_mac_count | 源 MAC 的数量,从 srcmac 的 MAC 开始轮询 |
dst_mac_count | 目的 MAC 的数量,从 srcmac 的 MAC 开始轮询 |
udp_src_min | 最小源 UDP 端口号 |
udp_src_max | 最大源 UDP 端口号 |
udp_dst_min | 最小目的 UDP 端口号 |
udp_dst_max | 最大目的 UDP 端口号 |
flows | 并发流的个数 |
flowlen | 流的长度 |
Flags
命令 | 说明 |
---|---|
IPSRC_RND | PSRC_RND 源 IP 随机发送 |
IPDST_RND | IPDST_RND 源 IP 随机发送 |
TXSIZE_RND | YXSIZE_RND 源 IP 随机发送 |
UDPSRC_RND | UDPSRC_RND 源 IP 随机发送 |
UDPDST_RND | UDPDST_RND 源 IP 随机发送 |
MACSRC_RND | MACSRC_RND 源 IP 随机发送 |
MACDST_RND | MACDST_RND 源 IP 随机发送 |
评论区