4. pktgen 工具介绍:原理、加载、接口与核心参数
pktgen 是 Linux 内核内置的高性能数据包生成器,专为内核网络协议栈的极限压测设计。它运行在内核态,绕过用户态协议栈的开销,能够以接近线速的速率发送数据包,是评估网卡驱动、软中断处理、路由转发和 netfilter 等内核模块性能的首选工具。
适用场景: 网卡吞吐量极限测试、多队列 RSS 均衡性验证、XDP/DPDK 对比基准、内核协议栈转发性能(PPS)评估。
4.1 pktgen 工作原理
pktgen 作为内核线程运行,每个 CPU 可以绑定一个 kpktgend 线程。线程从预配置的设备列表读取发包参数,直接构造二层/三层帧头,通过 dev_queue_xmit() 将数据包注入驱动层,完全绕过 socket 层和 TCP/IP 协议栈的复杂处理路径。
4.2 内核模块加载
pktgen 以内核模块形式存在,默认不加载。使用前需要手动插入模块,或编译进内核(CONFIG_NET_PKTGEN=y)。
# 加载 pktgen 内核模块
modprobe pktgen
# 验证模块是否加载成功
lsmod | grep pktgen
# 查看内核线程是否启动(每个 CPU 一个)
ps aux | grep kpktgend
加载成功后,系统会出现 /proc/net/pktgen 目录,这是 pktgen 唯一的用户态控制接口。
注意事项: 在虚拟化环境(如 VMware、VirtualBox)中,pktgen 可能无法达到线速,因为虚拟网卡驱动和宿主机调度会引入额外开销。建议在物理机或具备 SR-IOV 直通的环境中进行性能测试。
4.3 用户态接口:/proc/net/pktgen
pktgen 通过 /proc/net/pktgen 下的虚拟文件与用户态交互,采用“写配置、读统计”的模型。核心文件包括:
| 文件路径 | 类型 | 作用 |
|---|---|---|
/proc/net/pktgen/pgctrl |
控制 | 写入 start / stop / reset 控制整个测试流程 |
/proc/net/pktgen/kpktgend_X |
线程 | 每个 CPU 对应一个,写入 add_device eth0 绑定发包设备 |
/proc/net/pktgen/eth0 |
设备 | 写入发包参数(包大小、速率、源/目的 IP 等),读取统计结果 |
典型配置流程:
- 重置所有配置:
echo reset > /proc/net/pktgen/pgctrl - 绑定设备到线程:
echo add_device eth0 > /proc/net/pktgen/kpktgend_0 - 配置发包参数: 向
/proc/net/pktgen/eth0写入参数 - 启动测试:
echo start > /proc/net/pktgen/pgctrl - 读取统计:
cat /proc/net/pktgen/eth0
4.4 核心参数解析
设备文件(如 /proc/net/pktgen/eth0)支持数十个参数,以下是最常用的核心参数:
| 参数名 | 类型 | 示例值 | 说明 |
|---|---|---|---|
pkt_size |
整数 | 64 |
数据包大小(字节),包含 MAC 头(14B)和 CRC(4B) |
count |
整数 | 1000000 |
发送包总数,0 表示无限发送 |
clone_skb |
整数 | 1000 |
skb 克隆次数,减少内存分配开销,提升 PPS |
dst_ip |
IP | 192.168.1.2 |
目的 IP 地址,支持 @ 分隔的递增范围 |
src_ip |
IP | 192.168.1.1 |
源 IP 地址,支持递增范围 |
dst_mac |
MAC | 00:11:22:33:44:55 |
目的 MAC 地址,必须与下一跳网关或对端一致 |
udp_src_min |
端口 | 1024 |
UDP 源端口最小值,配合 udp_src_max 实现端口范围 |
udp_dst_min |
端口 | 9 |
UDP 目的端口最小值(默认 9 = discard 端口) |
rate |
字符串 | 100m |
限速,支持 100m(Mbps)、10g(Gbps) |
delay |
整数 | 0 |
包间延迟(纳秒),用于精确控速 |
4.5 完整配置示例
以下是一个完整的 pktgen 配置脚本,演示如何对 eth0 进行 64 字节小包压测:
#!/bin/bash
# pktgen 配置示例:64B 小包压测
PGCTRL=/proc/net/pktgen/pgctrl
DEV=eth0
# 1. 重置
echo reset > $PGCTRL
# 2. 绑定设备到 CPU0
echo add_device $DEV > /proc/net/pktgen/kpktgend_0
# 3. 配置设备参数
echo pkt_size 64 > /proc/net/pktgen/$DEV
echo count 10000000 > /proc/net/pktgen/$DEV
echo clone_skb 1000 > /proc/net/pktgen/$DEV
echo dst_ip 192.168.1.2 > /proc/net/pktgen/$DEV
echo src_ip 192.168.1.1 > /proc/net/pktgen/$DEV
echo dst_mac 00:11:22:33:44:55 > /proc/net/pktgen/$DEV
echo udp_dst_min 9 > /proc/net/pktgen/$DEV
# 4. 启动
echo start > $PGCTRL
# 5. 等待完成
sleep 10
# 6. 查看统计
cat /proc/net/pktgen/$DEV | grep -E "pps|pkts"
性能调优提示: 使用
clone_skb 参数可以显著提升 PPS。当 clone_skb=0 时,每个包都分配新 skb,内存分配成为瓶颈;设置为 1000 以上时,skb 被复用,PPS 可提升 3-5 倍。但注意,clone 模式不支持修改包内容,适用于纯吞吐测试。
4.6 统计输出解读
测试完成后,读取设备文件可获取详细统计信息。关键字段如下:
| 统计字段 | 含义 | 示例值 |
|---|---|---|
pkts_sent |
已发送包总数 | 10000000 |
pkts_dropped |
驱动层丢弃的包数(通常为 0) | 0 |
result |
测试结果状态 | OK: 10000000(c000000+d0) |
pps |
每秒发包数(关键性能指标) | 1488095 |
mbps |
吞吐量(Mbps) | 761 |
关键指标解读: 64 字节小包下,1Gbps 网卡的理论极限约为 1.488 Mpps(百万包/秒)。如果实测 PPS 远低于此值,说明 CPU 软中断或驱动存在瓶颈。pktgen 的
pps 字段直接反映内核协议栈的包处理能力,是衡量网络性能的核心指标。