4. Pktgen 源码编译与安装:下载 Pktgen、依赖库安装、编译 Pktgen、验证安装
Pktgen 作为 DPDK 生态中最常用的流量生成器,其安装过程需要严格遵循依赖顺序。本章将引导你完成从源码下载、依赖库配置、编译构建到最终验证的完整流程。正确的安装环境是后续实现线速发包的基础,请务必按步骤操作。
4.1 环境准备与依赖库安装
在编译 Pktgen 之前,必须确保系统中已安装 DPDK 及其编译依赖。Pktgen 直接调用 DPDK 的 rte_ring、rte_mbuf 和 rte_ethdev 等库,因此 DPDK 的版本与编译选项必须与 Pktgen 对齐。
4.1.1 基础依赖清单
| 依赖项 | 版本要求 | 安装命令(Ubuntu/Debian) | 说明 |
|---|---|---|---|
| Linux Kernel | ≥ 4.15 | — | 支持 hugepage 和 uio 驱动 |
| GCC | ≥ 7.0 | apt install gcc g++ |
支持 C11 标准 |
| DPDK | 21.11 LTS 或 22.11 | 源码编译安装 | 必须开启 librte_pdump 和 librte_port |
| libpcap | ≥ 1.9 | apt install libpcap-dev |
用于抓包和回放功能 |
| lua5.3 | ≥ 5.3 | apt install lua5.3 liblua5.3-dev |
Pktgen 脚本引擎依赖 |
| numactl | ≥ 2.0 | apt install libnuma-dev |
NUMA 内存绑定支持 |
rte_eth_dev_info 结构体字段缺失错误。
4.1.2 DPDK 环境变量设置
编译 Pktgen 前,必须导出 DPDK 的安装路径。假设 DPDK 已编译并安装到 /opt/dpdk 目录:
export RTE_SDK=/opt/dpdk
export RTE_TARGET=x86_64-native-linuxapp-gcc
将上述两行添加到 ~/.bashrc 中可永久生效。验证环境变量:
echo $RTE_SDK
echo $RTE_TARGET
4.2 下载 Pktgen 源码
Pktgen 官方仓库托管在 DPDK 的 GitLab 上。推荐使用 git clone 获取稳定分支:
git clone https://dpdk.org/git/apps/pktgen-dpdk
cd pktgen-dpdk
git checkout pktgen-22.03.2 # 切换到稳定版本
若网络受限,也可从 DPDK 官方归档页面 下载 tar.gz 压缩包。下载后解压:
wget https://git.dpdk.org/apps/pktgen-dpdk/snapshot/pktgen-dpdk-22.03.2.tar.gz
tar xzf pktgen-dpdk-22.03.2.tar.gz
cd pktgen-dpdk-22.03.2
4.3 编译 Pktgen
Pktgen 的编译系统基于 DPDK 的 mk 框架。在 RTE_SDK 和 RTE_TARGET 正确设置的前提下,执行:
make
编译过程会依次执行以下步骤:
- 配置检测: 检查 DPDK 库路径、libpcap 和 Lua 头文件是否存在。
- 依赖编译: 编译
lib/common、lib/pg_ether等内部库。 - 主程序编译: 编译
app/pktgen主程序,链接 DPDK 动态库。 - 脚本安装: 将 Lua 脚本模板复制到
scripts/目录。
编译成功后,终端会输出类似信息:
== Build app/pktgen
LD pktgen
INSTALL-APP pktgen
INSTALL-MAP pktgen.map
生成的可执行文件位于 app/pktgen。若编译过程中出现错误,请参考下表排查:
| 错误信息 | 可能原因 | 解决方案 |
|---|---|---|
Cannot open <rte_common.h> |
RTE_SDK 路径错误或 DPDK 未编译 |
检查 echo $RTE_SDK 是否指向 DPDK 根目录 |
undefined reference to rte_eth_dev_count_avail |
DPDK 版本与 Pktgen 不匹配 | 切换 Pktgen 分支或升级 DPDK |
lua.h: No such file or directory |
Lua 开发库未安装 | apt install liblua5.3-dev |
pcap.h: No such file or directory |
libpcap 开发库未安装 | apt install libpcap-dev |
make 使用 -O2 优化级别。若在虚拟机或低配硬件上编译,可改用 make EXTRA_CFLAGS="-O0 -g" 关闭优化以加速编译,但生成的可执行文件性能会下降。生产环境务必使用 -O2 或 -O3。
4.4 验证安装
编译完成后,通过以下步骤验证 Pktgen 是否可正常运行:
4.4.1 基本运行测试
使用 -h 参数查看帮助信息:
./app/pktgen -h
正常输出应包含 DPDK EAL 选项和 Pktgen 特有参数,如 -T(终端模式)、-P(混杂模式)等。
4.4.2 版本信息确认
./app/pktgen -v
输出示例:
Pktgen: version 22.03.2 (DPDK 21.11.0)
4.4.3 白盒验证:检查链接库
使用 ldd 确认 Pktgen 正确链接了 DPDK 动态库:
ldd ./app/pktgen | grep -E "rte|pcap|lua"
预期输出应包含 librte_ethdev.so、librte_mbuf.so、libpcap.so 和 liblua5.3.so 等。
4.4.4 最小化启动测试(无网卡)
即使没有 DPDK 兼容网卡,也可使用 --no-pci 参数测试 Pktgen 的初始化流程:
./app/pktgen -l 0-1 -n 2 --no-pci -- -T -P
若输出包含 Pktgen: started 且无段错误,则证明编译安装成功。
- ✅
./app/pktgen -h输出帮助信息 - ✅
./app/pktgen -v显示版本号 - ✅
ldd显示所有 DPDK 库已链接 - ✅
--no-pci模式启动无报错
4.5 编译与依赖关系架构图
下图展示了 Pktgen 编译过程中各组件之间的依赖关系与数据流向:
4.6 常见安装问题与对策
| 问题现象 | 根本原因 | 快速修复 |
|---|---|---|
编译时提示 multiple definition of main |
DPDK 示例程序与 Pktgen 的 main 函数冲突 | 确保 RTE_TARGET 指向干净的 DPDK 编译目录,不包含示例代码 |
运行时报 EAL: Cannot create lock on /var/run/dpdk/... |
DPDK 运行时文件权限不足 | sudo mkdir -p /var/run/dpdk && sudo chmod 777 /var/run/dpdk |
Port 0: link status: DOWN |
网卡未绑定 DPDK 驱动或未插线 | 使用 dpdk-devbind.py 绑定 igb_uio/vfio-pci 驱动 |
Lua 脚本执行报 attempt to call a nil value |
Lua 版本不匹配(5.2 vs 5.3) | 安装 lua5.3 并重新编译 Pktgen |
make 前设置 export CONFIG_RTE_BUILD_SHARED_LIB=n,编译出的 Pktgen 将完全静态链接 DPDK 库,提升启动速度和运行稳定性。