Linux高性能网络测试工具 | pktgen

一、pktgen概述

pktgenLinux内核自带的高性能网络测试工具(高性能发包工具),可实现在内核高速发包。主要用来测试网络驱动与网卡设备,支持多线程,能够产生随机MAC地址、IP地址、UDP端口号的数据包。由于pktgen是内核内置的,使用内核空间,所以它可以达到高带宽、高发包速率,可用于测试网卡发送速率,也可以用来测试其他网络设备(如路由器和交换机)。

pktgen的配置与统计信息查看都通过/proc文件系统完成,/proc文件系统是一种特殊的,由软件创建的文件系统,内核使用/proc文件系统向外界导出信息,外界也可以通过它配置内核态的一些进程的参数,如ps、top、 uptimeLinux发行版中的很多工具就是通过/proc实现的。在大多情况下,我们只用/proc读出数据(用于调试内核驱动等),而在pktgen中配置命令就用到了/proc的写入数据功能。

注意

  • pktgen是一个Linux内核模块,非用户态工具,不能通过命令行的方式直接运行pktgen

  • pktgen不是全能的发包工具,目前仅支持UDP报文。

二、pktgen加载

在 Linux系统中,你并不能直接找到pktgen命令。因为pktgen作为一个内核线程来运行,需要你加载pktgen内核模块后,再通过/proc文件系统来交互。pktgen作为内核内置的模块,它的加载有两种方式,一种是在命令行直接通过modprobe加载,另一种是通过源码编译出pktgen.ko模块,再insmodmodprobe加载。

1、直接加载

目前,有些Linux机器上自带了pktgen.ko文件,而有些Linux机器上则没有该文件,网上的说法是如果内核的/boot/config-$(uname -r)文件中含有CONFIG_NET_PKTGEN=m,则内核默认会编译出pktgen.ko文件,但我发现实际却并非如此,也不知道这个说法是怎么来的,果然实践才能出真知。

我们可以直接在命令行执行modprobe pktgen命令,如果在Linux系统中自带了pktgen.ko文件,则可直接加载成功,如果Linux中没有pktgen.ko文件,则会直接报找不到该文件的错误。我分别在两个Linux系统机器中进行了实验,如下:

#机器一
[root@localhost ~]# modprobe pktgen
[root@localhost ~]# lsmod | grep pktgen
pktgen 61440 0

#机器二
[root@localhost ~]# modprobe pktgen
modprobe: FATAL: Module pktgen not found in directory /lib/modules/4.18.0-394.el8.x86_64

注意Linux系统pktgen.ko文件的默认存放目录/lib/modules/$(uname -r)/kernel/net/core/,如果在默认存放目录下有pktgen.ko文件,则可直接modprobe加载。

如果该Linux系统中没有自带pktgen.ko文件,则我们可以通过方法二来自己编译pktgen.ko文件,然后进行加载安装。

2、源码编译加载

通过yum install kernel-devel-$(uname -r) 命令安装内核开发包。默认安装目录为/usr/src/kernels。下载pktgen.c(https://github.com/torvalds/linux/blob/master/net/core/pktgen.c)源码文件,在pktgen.c文件所在目录创建Makefile文件,内容如下:

#关闭模块签名验证功能
CONFIG_MODULE_SIG=n

obj-m += pktgen.o
KDIR := /lib/modules/$(shell uname -r)/build

all:
        make -C $(KDIR) M=$(PWD) modules

clean:
        make -C $(KDIR) M=$(PWD) clean

注意:动态安装模块的时候可能会出现insmod error required key not available,即内核签名问题,因此,建议在Makefile文件中设置CONFIG_MODULE_SIG=n

pktgen.c文件所在目录执行make指令编译内核模块,如下:

[root@localhost pktgen_source]# ls
Makefile pktgen.c
[root@localhost pktgen_source]#
[root@localhost pktgen_source]# make
make -C /lib/modules/4.18.0-500.el8.x86_64/build M=/home/lxy/pktgen_source modules
make[1]: Entering directory '/usr/src/kernels/4.18.0-500.el8.x86_64'
CC [M] /home/lxy/pktgen_source/pktgen.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/lxy/pktgen_source/pktgen.mod.o
LD [M] /home/lxy/pktgen_source/pktgen.ko
make[1]: Leaving directory '/usr/src/kernels/4.18.0-500.el8.x86_64'
[root@localhost pktgen_source]#
[root@localhost pktgen_source]# ls
Makefile modules.order Module.symvers pktgen.c pktgen.ko pktgen.mod.c pktgen.mod.o pktgen.o
[root@localhost pktgen_source]# insmod ./pktgen.ko
[root@localhost pktgen_source]# lsmod | grep pktgen
pktgen 57344 0
[root@localhost pktgen_source]# ls -l /proc/net/pktgen/
total 0
-rw-------. 1 root root 0 Nov 2 17:20 kpktgend_0
-rw-------. 1 root root 0 Nov 2 17:20 kpktgend_1
-rw-------. 1 root root 0 Nov 2 17:20 kpktgend_10
-rw-------. 1 root root 0 Nov 2 17:20 kpktgend_11
-rw-------. 1 root root 0 Nov 2 17:20 kpktgend_12
-rw-------. 1 root root 0 Nov 2 17:20 kpktgend_13
-rw-------. 1 root root 0 Nov 2 17:20 kpktgend_14
-rw-------. 1 root root 0 Nov 2 17:20 kpktgend_15
-rw-------. 1 root root 0 Nov 2 17:20 kpktgend_2
-rw-------. 1 root root 0 Nov 2 17:20 kpktgend_3
-rw-------. 1 root root 0 Nov 2 17:20 kpktgend_4
-rw-------. 1 root root 0 Nov 2 17:20 kpktgend_5
-rw-------. 1 root root 0 Nov 2 17:20 kpktgend_6
-rw-------. 1 root root 0 Nov 2 17:20 kpktgend_7
-rw-------. 1 root root 0 Nov 2 17:20 kpktgend_8
-rw-------. 1 root root 0 Nov 2 17:20 kpktgend_9
-rw-------. 1 root root 0 Nov 2 17:20 pgctrl

加载pktgen.ko模块后,可以发现/proc/net/pktgen目录下生成了多个kpktgend_*文件,其中kpktgen_*的多少是根据你的CPU的个数决定的,如我的机子的CPU数目为16,则有16个此文件。kpktgend_*是内核数据包生产线程, 每个CPU都会启动一个相应的线程,如果要添加某个测试网卡, 可以通过向该文件节点写入add_device ethXpgctrl用于控制网卡性能测试状态,需要在对应的线程执行网卡的吞吐量测试, 有start/stop/reset三种状态。

通过命令cat /proc/net/pktgen/pgctrl可以查看pktgen的版本等信息:

[root@localhost pktgen_source]# cat /proc/net/pktgen/pgctrl
Packet Generator for packet performance testing. Version: 2.75

三、pktgen实战

1、实验拓扑

Linux高性能网络测试工具 | pktgen

因服务器资源有限,故本文使用网络命名空间模拟2台虚拟机,使用VF模拟虚拟机的网卡,网络拓扑图如上图所示。其中,ens4f0v0ens4f0v1为物理网卡ens4f0np0虚拟出的两个VF,通过命令行添加到网络命名空间ns1ns2中,如下:
# 构建2个VF
[root@localhost pktgen]# echo 2 > /sys/class/net/ens4f0np0/device/sriov_numvfs
[root@localhost pktgen]# list-iface-info.sh
eno1np0 bnxt_en P 0 p0
ens4f0np0 nfp P 0 p0
ens5f0np0 nfp P 0 p0
eno2np1 bnxt_en P 1 p1
ens4f1np1 nfp P 1 p1
ens5f1np1 nfp P 1 p1
eno3 tg3 PCI 0000:01:00.0
eno4 tg3 PCI 0000:01:00.1
ens4f0v0 nfp_netvf PCI 0000:af:00.4
ens4f0v1 nfp_netvf PCI 0000:af:00.5
# 创建网络命名空间模拟虚拟机
[root@localhost pktgen]# ip netns add ns1
[root@localhost pktgen]# ip netns add ns2

# 添加VF到网络命名空间中
[root@localhost pktgen]# ip link set ens4f0v0 netns ns1
[root@localhost pktgen]# ip link set ens4f0v1 netns ns2

#查看网络命名空间ns1中的网卡
[root@localhost pktgen]# ip netns exec ns1 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
55: ens4f0v0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether ea:0c:48:be:43:09 brd ff:ff:ff:ff:ff:ff

# 配置网络命名空间中网卡的IP地址
[root@localhost pktgen]# ip netns exec ns1 ifconfig ens4f0v0 192.168.1.11/24 up
[root@localhost pktgen]# ip netns exec ns2 ifconfig ens4f0v1 192.168.1.12/24 up
[root@localhost pktgen]#
[root@localhost pktgen]# ip netns exec ns1 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
55: ens4f0v0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether ea:0c:48:be:43:09 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.11/24 brd 192.168.1.255 scope global ens4f0v0
valid_lft forever preferred_lft forever
inet6 fe80::e80c:48ff:febe:4309/64 scope link
valid_lft forever preferred_lft forever
[root@localhost pktgen]#
[root@localhost pktgen]# ip netns exec ns2 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
56: ens4f0v1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 7e:6c:0c:13:80:a6 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.12/24 brd 192.168.1.255 scope global ens4f0v1
valid_lft forever preferred_lft forever
inet6 fe80::7c6c:cff:fe13:80a6/64 scope link
valid_lft forever preferred_lft forever

#查看两个网络命名空间是否连通
[root@localhost pktgen]# ip netns exec ns2 ping -I ens4f0v1 192.168.1.11
PING 192.168.1.11 (192.168.1.11) from 192.168.1.12 ens4f0v1: 56(84) bytes of data.
64 bytes from 192.168.1.11: icmp_seq=1 ttl=64 time=0.496 ms
64 bytes from 192.168.1.11: icmp_seq=2 ttl=64 time=0.247 ms
^C
--- 192.168.1.11 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1046ms
rtt min/avg/max/mdev = 0.247/0.371/0.496/0.125 ms

2、配置pktgen实例

在使用 pktgen 测试网络性能时,需要先给每个内核线程 kpktgend_X 以及测试网卡配置 pktgen 选项,然后再通过 pgctrl 启动测试。将虚拟机ns1中的网口ens4f0v0放到对应kpktgend_0内核线程中,并配置发送报文字段,以发包测试为例,假设发包机器ns1使用的网卡是 ens4f0v0,而目标机器的 IP 地址为 192.168.1.12MAC 地址为 7e:6c:0c:13:80:a6

1) 构建发送特定数量数据包

构造pktgen配置脚本pktgen_start.sh如下:

# 定义一个工具函数,方便后面配置各种测试选项
function pgset() {
    local result
    echo $1 > $PGDEV

    result=`cat $PGDEV | fgrep "Result: OK:"`
    if [ "$result" = "" ]; then
         cat $PGDEV | fgrep Result:
    fi
}

#
 为0号线程绑定ens4f0v0网卡
PGDEV=/proc/net/pktgen/kpktgend_0
echo "Removing all devices"
pgset "rem_device_all"   # 清空网卡绑定
echo "Adding ens4f0v0"
pgset "add_device ens4f0v0"  # 添加ens4f0v0网卡
echo "Setting max_before_softirq 10000"
pgset "max_before_softirq 10000"

#
 配置ens4f0v0网卡的测试选项
PGDEV=/proc/net/pktgen/ens4f0v0
pgset "count 1000000"    # 总发包数量,0 表示一直发送
pgset "delay 5000"       # 不同包之间的发送延迟(单位纳秒)
pgset "clone_skb 0"      # SKB包复制,表示复制多少数据包,clone_skb=1000,克隆1000报文;clone_skb=0表示不克隆,就是一直发送同一个报文。
pgset "pkt_size 64"      # 网络包大小
pgset "dst 192.168.1.12" # 目的IP
pgset "src_mac ea:0c:48:be:43:09"  # 源MAC
pgset "dst_mac 7e:6c:0c:13:80:a6"  # 目的MAC

#
 启动测试
PGDEV=/proc/net/pktgen/pgctrl
echo "Running... ctrl^C to stop"
pgset "start"
echo "Done"

执行pktgen_start.sh脚本,如下:

[root@localhost pktgen]# ./pktgen_start.sh
Removing all devices
Adding ens4f0v0
Setting max_before_softirq 10000
Running... ctrl^C to stop
Done

等待片刻,测试完成后,结果可以从 /proc 文件系统中获取。通过下面代码段中的内容,我们可以查看到刚才的测试报告:

[root@localhost pktgen]# cat /proc/net/pktgen/ens4f0v0
Params: count 1000000 min_pkt_size: 64 max_pkt_size: 64
frags: 0 delay: 5000 clone_skb: 0 ifname: ens4f0v0
flows: 0 flowlen: 0
queue_map_min: 0 queue_map_max: 0
dst_min: 192.168.1.12 dst_max:
src_min: src_max:
src_mac: ea:0c:48:be:43:09 dst_mac: 7e:6c:0c:13:80:a6
udp_src_min: 9 udp_src_max: 9 udp_dst_min: 9 udp_dst_max: 9
src_mac_count: 0 dst_mac_count: 0
Flags:
Current:
pkts-sofar: 1000000 errors: 0
started: 1910279455101us stopped: 1910284455352us idle: 4381728us
seq_num: 1000001 cur_dst_mac_offset: 0 cur_src_mac_offset: 0
cur_saddr: 192.168.1.11 cur_daddr: 192.168.1.12
cur_udp_dst: 9 cur_udp_src: 9
cur_queue_map: 0
flows: 0
Result: OK: 5000250(c618521+d4381728) usec, 1000000 (64byte,0frags)
199989pps 102Mb/sec (102394368bps) errors: 0

测试报告主要分为三个部分:

  • 第一部分的 Params 是测试选项;
  • 第二部分的 Current 是测试进度,其中, packts so far(pkts-sofar)表示已经发送了 100 万个包,也就表明测试已完成。
  • 第三部分的 Result 是测试结果,包含测试所用时间、网络包数量和分片、PPS、吞吐量以及错误数;其中测试用时5000250纳秒,总共1000000 64 字节包,每秒 199989 包,吞吐量 102Mb/s0 错误。
2) 构建一直发送数据包

构造pktgen配置脚本pktgen_start.sh如下:

# 定义一个工具函数,方便后面配置各种测试选项
function pgset() {
    local result
    echo $1 > $PGDEV

    result=`cat $PGDEV | fgrep "Result: OK:"`
    if [ "$result" = "" ]; then
         cat $PGDEV | fgrep Result:
    fi
}

#
 为0号线程绑定ens4f0v0网卡
PGDEV=/proc/net/pktgen/kpktgend_0
echo "Removing all devices"
pgset "rem_device_all"   # 清空网卡绑定
echo "Adding ens4f0v0"
pgset "add_device ens4f0v0"  # 添加ens4f0v0网卡
echo "Setting max_before_softirq 10000"
pgset "max_before_softirq 10000"

#
 配置ens4f0v0网卡的测试选项
PGDEV=/proc/net/pktgen/ens4f0v0
pgset "count 0"    # 总发包数量,0 表示一直发送
pgset "delay 5000"       # 不同包之间的发送延迟(单位纳秒)
pgset "clone_skb 0"      # SKB包复制,表示复制多少数据包,clone_skb=1000,克隆1000报文;clone_skb=0表示不克隆,就是一直发送同一个报文。
pgset "pkt_size 64"      # 网络包大小
pgset "dst 192.168.1.12" # 目的IP
pgset "src_mac ea:0c:48:be:43:09"  # 源MAC
pgset "dst_mac 7e:6c:0c:13:80:a6"  # 目的MAC

#
 启动测试
PGDEV=/proc/net/pktgen/pgctrl
echo "Running... ctrl^C to stop"
pgset "start"
echo "Done"

执行pktgen_start.sh脚本,如下:

[root@localhost pktgen]# ./pktgen_start.sh
Removing all devices
Adding ens4f0v0
Setting max_before_softirq 10000
Running... ctrl^C to stop
^C
#注意这里需要进入ns1命名空间,后续top和sar方可生效
[root@localhost ~]# ip netns exec ns1 bash
# top查看kpktgend_0线程,CPU利用率100%
[root@localhost ~]# top
top - 16:51:30 up 22 days, 2:45, 4 users, load average: 0.45, 0.11, 0.04
Tasks: 1154 total, 2 running, 1152 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 1.3 sy, 0.0 ni, 98.2 id, 0.0 wa, 0.0 hi, 0.5 si, 0.0 st
MiB Mem : 95004.3 total, 78765.2 free, 3082.3 used, 13156.7 buff/cache
MiB Swap: 10240.0 total, 10240.0 free, 0.0 used. 91041.1 avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1025692 root 20 0 0 0 0 R 100.0 0.0 0:44.83 kpktgend_0
1026886 root 20 0 66672 6180 4160 R 1.0 0.0 0:00.28 top
2257 root 20 0 542808 79216 55736 S 0.3 0.1 20:03.38 tuned
38797 root 20 0 0 0 0 I 0.3 0.0 57:13.30 kworker/43:2-events
737227 root 20 0 0 0 0 I 0.3 0.0 0:00.38 kworker/1:1-events
1025407 root 20 0 0 0 0 S 0.3 0.0 0:00.13 kpktgend_45
1025421 root 20 0 0 0 0 S 0.3 0.0 0:00.09 kpktgend_59
1025837 root 20 0 0 0 0 S 0.3 0.0 0:00.09 kpktgend_64
1026889 setroub+ 20 0 545408 130552 20008 S 0.3 0.1 0:00.86 setroubleshootd
1 root 20 0 240916 13656 8788 S 0.0 0.0 0:42.28 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:01.06 kthreadd

#查看ns1命名空间中,各个端口收发包情况
[root@localhost ~]# sar -n DEV 1
Linux 4.18.0-348.7.1.el8_5.x86_64 (localhost.localdomain) 11/03/2023 _x86_64_ (80 CPU)

08:25:41 PM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil
08:25:42 PM lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
08:25:42 PM ens4f0v0 1.00 200020.00 0.09 12501.25 0.00 0.00 0.00 0.41

08:25:42 PM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil
08:25:43 PM lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
08:25:43 PM ens4f0v0 1.00 200007.00 0.09 12500.44 0.00 0.00 0.00 0.41

08:25:43 PM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil
08:25:44 PM lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
08:25:44 PM ens4f0v0 1.00 200036.00 0.09 12502.25 0.00 0.00 0.00 0.41

等待片刻,通过Ctrl C 终止测试后,结果可以从 /proc 文件系统中获取。通过下面代码段中的内容,我们可以查看到刚才的测试报告:

[root@localhost pktgen]# cat /proc/net/pktgen/ens4f0v0
Params: count 0 min_pkt_size: 64 max_pkt_size: 64
frags: 0 delay: 5000 clone_skb: 0 ifname: ens4f0v0
flows: 0 flowlen: 0
queue_map_min: 0 queue_map_max: 0
dst_min: 192.168.1.12 dst_max:
src_min: src_max:
src_mac: ea:0c:48:be:43:09 dst_mac: 7e:6c:0c:13:80:a6
udp_src_min: 9 udp_src_max: 9 udp_dst_min: 9 udp_dst_max: 9
src_mac_count: 0 dst_mac_count: 0
Flags:
Current:
pkts-sofar: 9637001 errors: 0
started: 1910680695090us stopped: 1910728880086us idle: 42081825us
seq_num: 9637002 cur_dst_mac_offset: 0 cur_src_mac_offset: 0
cur_saddr: 192.168.1.11 cur_daddr: 192.168.1.12
cur_udp_dst: 9 cur_udp_src: 9
cur_queue_map: 0
flows: 0
Result: OK: 48184996(c6103170+d42081825) usec, 9637001 (64byte,0frags)
200000pps 102Mb/sec (102400000bps) errors: 0

测试报告主要分为三个部分:

  • 第一部分的 Params 是测试选项;
  • 第二部分的 Current 是测试进度,其中, packts so far(pkts-sofar)表示终止时已经发送了960 万个包。
  • 第三部分的 Result 是测试结果,包含测试所用时间、网络包数量和分片、PPS、吞吐量以及错误数;其中测试用时48184996纳秒,总共9637001 64 字节包,每秒 200000 包,吞吐量 102Mb/s0 错误。

根据上面的结果,我们发现,PPS 为 20 万,吞吐量为 102 Mb/s,没有发生错误。那么20 万的 PPS 好不好呢?作为对比,你可以计算一下千兆交换机的 PPS。交换机可以达到线速(满负载时,无差错转发),它的 PPS 就是 1000Mbit 除以以太网帧的大小,即 1000Mbps/((64+20)*8bit) = 1.5 Mpps(其中,20B 为以太网帧前导和帧间距的大小)。

四、pktgen官方脚本

前面的配置稍微有些复杂,可能用起来不是特别的便捷,Linux 内核提供了更为方便的pktgen的脚本,在Linux内核源码的linux/samples/pktgen/ 目录下,如下所示:

[root@localhost pktgen]# ls -l /linux/samples/pktgen/
total 52
-rw-r--r--. 1 xf xf 8841 Jun 15 14:52 functions.sh
-rw-rw-r--. 1 xf xf 3767 Jun 15 14:52 parameters.sh
-rwxrwxr-x. 1 xf xf 3390 Jun 15 14:52 pktgen_bench_xmit_mode_netif_receive.sh
-rwxrwxr-x. 1 xf xf 2563 Jun 15 14:52 pktgen_bench_xmit_mode_queue_xmit.sh
-rwxrwxr-x. 1 xf xf 2818 Jun 15 14:52 pktgen_sample01_simple.sh
-rwxrwxr-x. 1 xf xf 3145 Jun 15 14:52 pktgen_sample02_multiqueue.sh
-rwxrwxr-x. 1 xf xf 3382 Jun 15 14:52 pktgen_sample03_burst_single_flow.sh
-rwxrwxr-x. 1 xf xf 3418 Jun 15 14:52 pktgen_sample04_many_flows.sh
-rwxrwxr-x. 1 xf xf 3096 Jun 15 14:52 pktgen_sample05_flow_per_thread.sh
-rwxrwxr-x. 1 xf xf 3981 Jun 15 14:52 pktgen_sample06_numa_awared_queue_irq_affinity.sh
-rw-rw-r--. 1 xf xf 2663 Jun 15 14:52 README.rst

注意:可以通过git clone git@github.com:torvalds/linux.git,从github上获得Linux官方内核源码,其中即含有pktgen_*系列脚本以供直接使用。

上一节中的配置就可以简单化成一条命令,如下:

./pktgen_sample01_simple.sh -i ens4f0v0 -m  7e:6c:0c:13:80:a6 -d 192.168.1.12 -t 0 -n 1000

该脚本是通用脚本,部分参数不支持,需要做简单修改,参数含义如下:

Usage: ./pktgen_sample01_simple.sh [-vx] -i ethX
-i : ($DEV) output interface/device (required)
-s : ($PKT_SIZE) packet size
-d : ($DEST_IP) destination IP
-m : ($DST_MAC) destination MAC-addr
-t : ($THREADS) threads to start
-f : ($F_THREAD) index of first thread (zero indexed CPU number)
-c : ($SKB_CLONE) SKB clones send before alloc new SKB
-n : ($COUNT) num messages to send per thread, 0 means indefinitely
-b : ($BURST) HW level bursting of SKBs
-v : ($VERBOSE) verbose
-x : ($DEBUG) debug
-6 : ($IP6) IPv6

该命令的执行结果如下:

[root@localhost pktgen]# ./pktgen_sample01_simple.sh -i ens4f0v0 -m  7e:6c:0c:13:80:a6 -d 192.168.1.12 -t 0 -n 1000
Running... ctrl^C to stop
Done
Result device: ens4f0v0
Params: count 1000 min_pkt_size: 60 max_pkt_size: 60
frags: 0 delay: 0 clone_skb: 0 ifname: ens4f0v0
flows: 0 flowlen: 0
queue_map_min: 0 queue_map_max: 0
dst_min: 192.168.1.12 dst_max: 192.168.1.12
src_min: src_max:
src_mac: ea:0c:48:be:43:09 dst_mac: 7e:6c:0c:13:80:a6
udp_src_min: 9 udp_src_max: 109 udp_dst_min: 9 udp_dst_max: 9
src_mac_count: 0 dst_mac_count: 0
Flags: UDPSRC_RND NO_TIMESTAMP
Current:
pkts-sofar: 1000 errors: 0
started: 1929289439111us stopped: 1929289440886us idle: 422us
seq_num: 1001 cur_dst_mac_offset: 0 cur_src_mac_offset: 0
cur_saddr: 192.168.1.11 cur_daddr: 192.168.1.12
cur_udp_dst: 9 cur_udp_src: 51
cur_queue_map: 0
flows: 0
Result: OK: 1774(c1352+d422) usec, 1000 (60byte,0frags)
563629pps 270Mb/sec (270541920bps) errors: 0

是不是比上一节中手动修改脚本方便多了,就是下载这个脚本有些麻烦,如果从github下载内核整个的源码比较困难,可以直接在github上把需要的脚本的内容拷贝下来,手动创建相应脚本。

注意:如果是单独复制pktgen_sample01_simple.sh脚本,则一定要将该目录下的functions.shparameters.sh脚本一同复制到同一目录下,否则执行pktgen_sample01_simple.sh脚本时会出现如下错误:

[root@localhost pktgen]# ./pktgen_sample01_simple.sh -i ens4f0v0 -m  7e:6c:0c:13:80:a6 -d 192.168.1.12 -t 0 -n 1000
./pktgen_sample01_simple.sh: line 9: ./functions.sh: No such file or directory
./pktgen_sample01_simple.sh: line 10: root_check_run_with_sudo: command not found
./pktgen_sample01_simple.sh: line 15: ./parameters.sh: No such file or directory
./pktgen_sample01_simple.sh: line 23: usage: command not found
./pktgen_sample01_simple.sh: line 26: validate_addr: command not found
./pktgen_sample01_simple.sh: line 27: parse_addr: command not found
./pktgen_sample01_simple.sh: line 40: pg_ctrl: command not found
./pktgen_sample01_simple.sh: line 44: pg_thread: command not found
./pktgen_sample01_simple.sh: line 45: pg_thread: command not found
./pktgen_sample01_simple.sh: line 48: pg_set: command not found
./pktgen_sample01_simple.sh: line 52: pg_set: command not found
./pktgen_sample01_simple.sh: line 55: pg_set: command not found
./pktgen_sample01_simple.sh: line 58: pg_set: command not found
./pktgen_sample01_simple.sh: line 61: pg_set: command not found
./pktgen_sample01_simple.sh: line 64: pg_set: command not found
./pktgen_sample01_simple.sh: line 65: pg_set: command not found
./pktgen_sample01_simple.sh: line 66: pg_set: command not found
./pktgen_sample01_simple.sh: line 78: pg_set: command not found
./pktgen_sample01_simple.sh: line 79: pg_set: command not found
./pktgen_sample01_simple.sh: line 80: pg_set: command not found
Running... ctrl^C to stop
./pktgen_sample01_simple.sh: line 94: pg_ctrl: command not found
Done
Result device:
cat: /proc/net/pktgen/: Is a directory

这里只演示 pktgen_sample01_simple.sh脚本的使用方法,其他pktgen_sample*脚本大家可以自行研究摸索。

五、pktgen常用命令

1、控制命令

名称 含义
start 所有的线程开始发送
stop 停止

2、线程命令

名称 含义
add_device 添加某个网卡到某个线程
rem_device_all 删除绑定在某个线程的所有网卡
max_before_softirq 在最多发送多少个数据包后执行do_softirq()

3、端口命令

名称 含义
count 发送数据包的个数,0 表示一直发送
clone_skb 对每个skb进行多少个复制,0表示不复制。对于Dos等测试必须至零
debug 调试
frags 数据包的片段数量
delay 发送两个数据包之间的延时
src_mac_count 源mac的数量,从src mac设置的mac开始轮询
dst_mac_count 目的mac的数量,从dst mac设置的mac开始轮询
pkt_size 链路包的大小(前去CRC的值)
min_pkt_size 数据包最小值
max_pkt_size 数据包最大值
udp_src_min 最小源udp端口号
udp_src_max 最大源udp端口号
udp_dst_min 最小目的udp端口号
udp_dst_max 最大目的udp端口号
flag
IPSRC_RND
TXSIZE_RND
IPDST_RND
UDPSRC_RND
UDPDST_RND
MACSRC_RND
MACDST_RND
PSRC_RND 源IP随机发送
dst_min 目的IP的最小值
dst_max 目的IP的最大值
src_min 源IP最小值
src_max 源IP最大值
dst_mac 目的mac
src_mac 源mac
clear_counters 清空计数器,一般程序自动清空
dst6 目的IPv6地址
src6 源IPv6地址
flows 并发流的个数
flowlen 流的长度

注意:如果不想使用第三节中提供的pktgen_start.sh脚本,则可以自己手动按照如下方式进行设置,这里举两个例子供参考:

  • 添加网卡至线程

    echo "add_device eth0" > /proc/net/pktgen/kpktgend_0  
  • 添加目的MAC地址

    echo "dst_mac aa:bb:cc:dd:ee:ff" > /proc/net/pktgen/eth0

六、pktgen总结

pktgen测试的组网和iperf测试基本相同,客户端安装pktgen来发包,接收端通过sar命令(Linux系统)来查看端口统计信息,进而获得测试网络的吞吐和PPS等性能指标,通过对比收发两端的速率来判断是否有丢包。


原文始发于微信公众号(Linux二进制):Linux高性能网络测试工具 | pktgen

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之家整理,本文链接:https://www.bmabk.com/index.php/post/302122.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之家——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!