简介
pktgen是Linux内核内置的好性能测试工具,是当前测试网卡发送速率的最好工具,也可以用来构造包来测试其他网络设备,尤其是测试使用Linux网络协议栈的路由器和交换机。由于pktgen是内核内置的,使用内核空间,所以它可以达到高带宽、高发包速率,以此更好地测试路由器、交换机和其他网络设备。
准备工作
运行pktgen有两种方式:
- 在内核空间运行程序
- 作为模块加载使用
推荐将其作为模块使用,这也最常用的。加载以及卸载命令如下,切记要使用root身份运行。
modprobe pktgen // 加载模块
rmmod pktgen // 卸载模块
一旦加载pktgen模块后,会自动为每一个CPU创建一个内核线程,并将该线程绑定在对应的CPU上。与此同时,在/proc/net/pktgen/目录下,为每一个线程创建一个kpktgend_X文件(其中的X为CPU编号),用来控制和监控这些线程,以及一个pgctrl文件,用来控制pktgen程序。当卸载pktgen模块时,/proc/net/pktgen文件夹会被自动删除。
同时,当将某个网卡绑定在某个线程时,也会在/proc/net/pktgen/目录下自动创建以该网卡名称为名的文件,用于记录此网卡设备的配置信息和运行信息。
例如,在一个双核系统中,在/proc/net/pktgen/目录下会自动创建如下文件:kpktgend_0、kpktgend_1和pgctrl。将设备(例如eth0、eth1)绑定在kpktgend_X(X=0、1)线程上后,该目录下会自动创建eth0、eth1这两个文件。
测试程序可以配置成一直运行,或者在发送固定数量的包之后结束。也可以使用快捷键Ctrl+C终止运行。
运行过程以及运行结束后,可以通过/proc/net/pktgen/目录下的文件查看设备运行信息。
配置命令
Pgcontrol commands
命令 | 含义 |
---|---|
start | Starts sending on all threads |
stop | Aborts packet injection. Ctrl-C also aborts generator. Note: Use count 0 (forever) and stop the run with Ctrl-C when multiple devices are assigned to one pktgen thread. This avoids some devices finishing before others and skewing the results. We are primarily interested in how many packets all devices can send at the same time, not absolute number of packets each NIC sent. |
Threads commands
命令 | 含义 |
---|---|
add_device | Add a device to thread i.e eth0 |
rem_device_all | Removes all devices from this thread |
max_before_softirq | do_softirq() after sending a number of packets |
Device commands
命令 | 含义 |
---|---|
debug | |
clone_skb | Number of identical copies of the same packet 0 means alloc for each skb. For DoS etc we must alloc new skb’s. |
clear_counters ` | normally handled automatically |
pkt_size | Link packet size minus CRC (4) |
min_pkt_size | Range pkt_size setting If < max_pkt_size, then cycle through the port range. |
max_pkt_size | |
frags | Number of fragments for a packet |
count | Number of packets to send. Use zero for continious sending |
delay | Artificial gap inserted between packets in nanoseconds |
dst | IP destination address i.e 10.0.0.1 |
dst_min | Same as dst If < dst_max, then cycle through the port range. |
dst_max | Maximum destination IP. i.e 10.0.0…1 |
src_min | Minimum (or only) source IP. i.e. 10.0.0.254 If < src_max, then cycle through the port range. |
src_max | Maximum source IP. |
dst6 | IPV6 destination address i.e fec0::1 |
src6 | IPV6 source address i.e fec0::2 |
dstmac | MAC destination adress 00:00:00:00:00:00 |
srcmac | MAC source adress. If omitted it’s automatically taken from source device |
src_mac_count | Number of MACs we’ll range through. Minimum’ MAC is what you set with srcmac. |
dst_mac_count | Number of MACs we’ll range through. Minimum’ MAC is what you set with dstmac. |
udp_src_min | UDP source port min, If < udp_src_max, then cycle through the port range. |
udp_src_max | UDP source port max. |
udp_dst_min | UDP destination port min, If < udp_dst_max, then cycle through the port range. |
udp_dst_max | UDP destination port max. |
flows | Number of concurrent flows |
flowlen | Length of a flow |
rate 300M | set rate to 300 Mb/s |
ratep 1000000 | set rate to 1Mpps |
Flags
命令 | 含义 |
---|---|
IPSRC_RND | IP Source is random (between min/max), |
IPDST_RND Etc | |
TXSIZE_RND | |
UDPSRC_RND | |
UDPDST_RND | |
MACSRC_RND | |
MACDST_RND |
配置示例
以下是一个单CPU单NIC的实例。
#!/bin/sh
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
}
# Config Start Here -------------------------------------
# thread config
# Each CPU has own thread. Two CPU exammple.
# We add eth1, eth2 respectively.
PGDEV=/proc/net/pktgen/kpktgend_0
echo "Removing all devices"
pgset "rem_device_all"
echo "Adding ens38"
pgset "add_device ens38"
echo "Setting max_before_softirq 10000"
pgset "max_before_softirq 10000"
# device config
# delay is inter packet gap. 0 means maximum speed.
CLONE_SKB="clone_skb 000000"
# NIC adds 4 bytes CRC
PKT_SIZE="pkt_size 60"
# COUNT 0 means forever
#COUNT="count 0"
COUNT="count 10000000"
delay="delay 0"
PGDEV=/proc/net/pktgen/ens38
echo "Configuring $PGDEV"
pgset "$COUNT"
pgset "$CLONE_SKB"
pgset "$PKT_SIZE"
pgset "$delay"
pgset "dst 10.10.11.2"
pgset "dst_mac 00:04:23:08:91:dc"
# Time to run
PGDEV=/proc/net/pktgen/pgctrl
echo "Running... ctrl^C to stop"
pgset "start"
echo "Done"
# Result can be vieved in /proc/net/pktgen/ens38
结果展示
运行完成后,查看ems38文件,如下图所示:
此时,发包速率为155131pps,74Mbps,感觉有点慢,这是因为包太小了。将60改为10000,重新测试,截图如下:
此时,发包速率为2252pps,18016Mbps。我这里是用虚拟机跑的,具体能跑多快,还是和设备硬件有关。