定义
pktgen是一种在Linux内核中直接构造并高速发送数据包的工具,常被称作Linux数据包生成器[1]。它的作用对象是网络设备与协议栈本身,用户可以通过配置指定包长、目标地址、发送数量等参数,由内核线程按配置持续发出数据包[2]。由于发包路径尽量绕开了用户态与部分协议栈开销,pktgen能被用来逼近网卡与驱动在收发方向上的性能上限。
它与另一同名软件Pktgen-DPDK需要区分:后者不在内核中运行,而是依托DPDK框架在用户态做数据包收发,两者名称相近但实现路径不同[3]。
原理
pktgen以内核模块形式加载,启用编译选项CONFIG_NET_PKTGEN后即可在内核内建或编译成独立模块,官方文档认为模块方式更便于使用[2]。模块运行后,系统为每个CPU各创建一个内核线程,线程与该CPU绑定,从而在多核机器上并行发包[1]。
配置与观测都通过proc文件系统完成。其中pgctrl用于整体启停,形如kpktgend_X的文件对应各内核线程,形如ethX的文件对应被分配到线程的网络设备;添加设备时内核会为该设备生成一个对应的proc文件,因此设备名必须唯一,同一设备也可以借助“@”后缀挂到多个线程上以配合多队列网卡[2]。
设备文件中包含Params、Current与Result三段:前者是已配置参数,中段是运行中的统计,后者在运行结束或中断后打印结果,给出包数、每秒包数(pps)与带宽等指标。常用的可调项包括count(发送数量,为0表示持续发送)、clone_skb(同一数据包副本数)、pkt_size(包长)、frags(分片数)、delay(发送延迟)、rate与ratep(限速)等;flags则由一组标志位控制行为,如随机源IP、随机目的IP、随机UDP端口、IPv6、MPLS、IPsec封装等[4]。
发送路径上还可以启用硬件级突发(burst)与xmit_more机制,把同一数据包的多个副本一次排队、只更新一次硬件发送队列尾指针;发送模式可设为start_xmit(常规发送)或netif_receive(把数据包注入协议栈接收路径)[4]。
发展历程
内核文档给出的pktgen版本日期为2004年12月21日,说明这一工具至迟在2004年已以现在的基本形态存在[5]。文档记载,其早期工作伴随2004年在埃尔朗根举办的Linux-Kongress上的一篇论文,测试脚本与资料则长期挂在瑞典农业科学大学的FTP站点上。
工具的能力随后持续扩充。内核文档中陆续出现了burst、queue_map_min与queue_map_max、skb_priority、tos与traffic_class、xmit_mode以及rate、ratep等命令与选项,反映出对多队列网卡、限速发送和把数据包注入接收路径等需求的支持[4]。
示例脚本体系也在演进。2015年,Jesper Dangaard Brouer提交了samples/pktgen下的辅助函数,提供pg_ctrl()、pg_thread()与pg_set()3个Shell函数,分别对应pktgen的控制面、内核线程与设备配置[6];随后又加入按pktgen_sampleNN顺序编号的示例脚本,取代了早期以pktgen.conf-X-Y命名的脚本[6]。
内核文档本身也从早期的纯文本文件pktgen.txt改写为pktgen.rst,与内核文档向reStructuredText格式迁移的整体安排一致[7]。
应用
pktgen最主要的用途是网络性能测试:以尽可能接近线速的方式注入数据包,度量网卡、驱动和主机在收发方向上的吞吐与包速。内核文档给出的运行结果表明,该工具会输出每秒包数与比特率等指标,例如某次运行记录为6480562 pps、3110 Mb/s、0 errors,便于横向比较不同配置或不同硬件[4]。
工具也用于构造多样化的流量。借助dst_min/dst_max、src_min/src_max、MAC地址范围以及UDP端口范围等参数,可以生成地址或端口不断变化的流量,再配合IPSRC_RND、IPDST_RND、UDPSRC_RND、MACDST_RND等标志位产生随机化字段,用于检验多流场景下网卡与协议栈的表现[2]。此外,通过VLAN与SVLAN、MPLS标签、IPsec封装等选项,还能构造带封装头的报文[4]。
在测试环境搭建上,内核示例脚本覆盖了单CPU单设备、单CPU双设备、双CPU单设备与双CPU双设备等组合,并提供IPv6和多流版本的脚本,运行后自动完成配置与发送。为减少释放数据包缓冲区时的缓存抖动,文档建议在把设备绑定到某个CPU时,同时设置中断的亲和性,使发送中断落在同一CPU上,并可配合QUEUE_MAP_CPU标志让发送队列跟随当前线程所在的CPU[2]。
局限
pktgen的默认发包方式与真实业务的流量特征并不相同,内核文档称其为“人为过载”式基准测试,网卡默认设置通常并未针对这种情形优化,调整发送环形缓冲区等操作可能提升pktgen成绩,却会损害日常使用场景。文档还指出,加大会给通用场景带来两方面代价:环形缓冲区可能超出CPU的L1、L2缓存容量,以及在网卡硬件层积累更多排队[2]。
性能数据本身也需要谨慎解读。文档提醒,硬件发送环形队列中出现数据包或描述符未必意味着产生延迟,因为驱动出于性能考虑常会延迟清理环形缓冲区,看起来滞留在队列中的包可能只是在等待清理;这一问题在以Intel 82599芯片为例的ixgbe驱动上尤为典型,该驱动将发送与接收的清理合并处理。
使用上还有若干限制:一个设备同一时刻只能归属于一个内核线程,若要用多队列网卡把同一设备分配到多个线程,必须借助“@”后缀为设备创建不同名称[2]。配置与观测全部依赖proc文件系统,设备名需要保持唯一,扩容和自动化都需借助脚本完成[1]。
参见
-
Linux内核 —— pktgen以内核模块形式提供,依赖内核的网络收发路径。
-
DPDK —— Pktgen-DPDK在用户态实现数据包收发的依赖框架。
-
网卡 —— pktgen主要测试的对象,其队列与中断配置直接影响测试结果。
-
proc文件系统 —— pktgen配置与监控所依托的接口。
-
reStructuredText —— 内核文档改版后pktgen文档采用的标记格式。
参考资料
- networking:pktgen [Wiki] [引用日期2026-10-14]
- HOWTO for the linux packet generator [引用日期2026-10-14]
- readthedocs.io 上的文件 [引用日期2026-10-14]
- softwareheritage.org 上的网页 [引用日期2026-10-14]
- softwareheritage.org 上的网页 [引用日期2026-10-14]
- samples [引用日期2026-10-14]
- softwareheritage.org 上的网页 [引用日期2026-10-14]