searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

DPDK Pktgen RFC2544测试指导文档

2025-03-28 06:19:31
14
0

 

1.  简介

Pktgen-DPDK 是一个基于 DPDKData Plane Development Kit)的高性能数据包生成器。它主要用于网络性能测试、基准测试和流量发生器,可以在高速网络上生成大量的数据包,用于测试网络设备、协议栈和应用程序的性能,支持多种常见的网络协议(如 IPv4IPv6TCPUDP)以及自定义报文格式,可以灵活地模拟不同类型的流量,同时也可以借助于pktgen测试rfc2544的性能,在无专业测试仪的情况下以对性能进行初步摸底。本篇文章将介绍该工具的编译安装以及rfc2544测试方法等方面的内容。

2.  版本使用

l  DPDK20.11.10

l  Pktgen 20.12.0

  注意:Pktgen对应DPDK使用版本的依赖比较苛刻,需要匹配合适的版本才能编译通过

3.  环境依赖

l  meson>= 0.47.1

l  ninja>= 1.7.1

l  Pktgen编译过程中碰到的其他所需依赖:

yum install libpcap-devel

yum install numactl-devel

yum install numactl-libs

pip3 install pyelftools

yum install lua lua-devel

4.  获取DPDKPktgen-DPDK

git clone github.com/DPDK/dpdk.git

git clone github.com/pktgen/Pktgen-DPDK.git

5.  编译dpdk

cd dpdk

mkdir install_dir       # 安装目录

mkdir build     # 构建目录

meson -Denable_kmods=true -Dprefix=$(pwd)/install_dir build

cd build

ninja

ninja install    # 安装在dpdk/install_dir

6.  编译pktgen

l  设置PKG_CONFIG_PATH变量,需要指定libdpdknuma所对应pkgconfig路径,否则meson build会报错

# 查找到numa库的pkgconfig路径为/usr/lib64/pkgconfig

export PKG_CONFIG_PATH=<YOUR PATH>/dpdk/install_dir/lib64/pkgconfig:/usr/lib64/pkgconfig

cd Pktgen-DPDK

meson–Denable_lua=true build #构建并使能lua功能

cd build

ninja #编译

编译完成后运行程序在build/app/目录下

7.  运行环境初始化

l  查看网卡并进行网卡绑定

#模块
modprobe uio 

insmod <your path>/igb_uio.ko

#查看网卡信息

dpdk-devbind.py –s


     #网卡绑定

dpdk-devbind.py -b igb_uio <pci info>

dpdk-devbind.py -b igb_uio <pci info>

注:本次使用的是麦洛斯cx6网卡,无需绑定igb_uio

#大页内存初始化

第一种是在grub.cfg中增加如下命令:

default_hugepagesz=1G hugepagesz=1G hugepages=64

重启系统,此种方式的好处是每次重启都会自动初始化无需手动再次配置,弊端是必须重启系统,如果不想重启系统可使用一下方法:

第二种方式临时配置大页内存,命令如下:

echo 128 > /sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages

mkdir /mnt/huge

mount -t hugetlbfs nodev /mnt/huge

8.  运行pktgen

l  相关目录

可执行文件目录:Pktgen-DPDK/build/app/pktgen

Lua脚本目录:Pktgen-DPDK/ scripts

l  运行命令(命令行方式)

./app/pktgen -l 96-112 -n 4 --proc-type auto -a ab:00.0 -a ab:00.1 --file-prefix=pktgen1 -- -P -m "[97-100:101-104].0,[105-108:109-112].1"

参数解释:

-l 96-112:使用core 96-112

-n 4:使用4个内存通道

--proc-type auto:进程运行类型为自动模式,即如果有其他dpdk程序,则作为secondary运行,否则以primary运行

-a ab:00.0:绑定使用的接口

--file-prefix=pktgen1:大页内存文件名前缀

--:后面跟pktgen运行配置参数,包括队列数量、核分配等

-P:使能接口的混杂模式

-m "[97-100:101-104].0,[105-108:109-112].1":port0rx绑定核97-100port0tx绑定核101-104port1rx绑定核105-108port1tx绑定核109-112

l  运行结果:

默认显示page main,成功根据配置文件参数执行pktgen

l  随机发包帮助说明

-- Setup the packet range values --

     note: SMMI = start|min|max|inc (start, minimum, maximum, increment)

 

 

range <portlist> src|dst mac <SMMI> <etheraddr> - Set destination/source MAC address

      e.g: range 0 src mac start 00:00:00:00:00:00

           range 0 dst mac max 00:12:34:56:78:90

      or  range 0 src mac 00:00:00:00:00:00 00:00:00:00:00:00 00:12:34:56:78:90 00:00:00:01:01:01

range <portlist> src|dst ip <SMMI> <ipaddr>   - Set source IP start address

      e.g: range 0 dst ip start 0.0.0.0

           range 0 dst ip min 0.0.0.0

           range 0 dst ip max 1.2.3.4

           range 0 dst ip inc 0.0.1.0

       or  range 0 dst ip 0.0.0.0 0.0.0.0 1.2.3.4 0.0.1.0

range <portlist> type ipv4|ipv6               - Set the range packet type to IPv4 or IPv6

range <portlist> proto tcp|udp                - Set the IP protocol type

range <portlist> tcp flag set <flag>          - Set the TCP flag

range <portlist> tcp flag clr <flag>          - Clear the TCP flag

range <portlist> tcp seq <SMMI> <value>       - Set the TCP sequence number

       or  range <portlist> tcp seq <start> <min> <max> <inc>

range <portlist> tcp ack <SMMI> <value>       - Set the TCP acknowledge number

       or  range <portlist> tcp ack <start> <min> <max> <inc>

range <portlist> src|dst port <SMMI> <value>  - Set UDP/TCP source/dest port number

       or  range <portlist> src|dst port <start> <min> <max> <inc>

range <portlist> vlan <SMMI> <value>          - Set vlan id start address

      or  range <portlist> vlan <start> <min> <max> <inc>

range <portlist> size <SMMI> <value>          - Set pkt size start address

      or  range <portlist> size <start> <min> <max> <inc>

range <portlist> teid <SMMI> <value>          - Set TEID value

      or  range <portlist> teid <start> <min> <max> <inc>

range <portlist> mpls entry <hex-value>       - Set MPLS entry value

range <portlist> qinq index <val1> <val2>     - Set QinQ index values

range <portlist> gre key <value>              - Set GRE key value

range <portlist> cos <SMMI> <value>           - Set cos value

range <portlist> tos <SMMI> <value>           - Set tos value

range <portlist> ttl <SMMI> <value>           - Set TTL

range <portlist> hop_limits <SMMI> <value>    - Set Hop Limits

range <portlist> traffic_class <SMMI> <value> - Set Traffic Class value

l  配置实例

range 0 type ipv4  #设置发包类型

range 0 src ip 192.168.1.1 192.168.1.1 192.168.1.100 0.0.0.1 #配置发包源ip段,以及发包步长

range 0 src port 1000 1000 65534 1 #配置发包源端口范围,以及端口步长

range 0 dst mac start E0:28:61:cc:bb:aa #配置发包起始目的mac

range 0 dst mac max E0:28:61:cc:bb:aa #配置发包最大目的mac

range 0 dst ip 192.168.1.101 192.168.1.101 192.168.1.200 0.0.0.1 #配置发包目的ip段,以及发包步长

range 0 dst port 5011 5011 5011 0 #配置发包目的端口范围,以及端口步长

range 0 proto udp #配置报文协议类型为udp

range 0 size 64 64 64 0 #配置发包大小为64字节

set 0 rate 100 #设置按照接口速率的100%发包

enable 0 range #使能range功能

l  查看range配置

page range

l  开始发包

start 0 #如果启用所有接口,可以使用start all

    注:也可以使用单ip,单端口的方式发包,在pktgen命令行输入settab键即可查看相关命令

l  运行命令(lua脚本方式)

./app/pktgen -l 96-112 -n 17 --proc-type auto -a ab:00.0 -a ab:00.1 --file-prefix=pktgen1 -- -P -m "[97-104].0,[105-112].1" –f rfc2544_final.lua

参数解释:

-l 96-112:使用core 96-112

-n 17:使用17core

--proc-type auto:进程运行类型为自动模式,即如果有其他dpdk程序,则作为secondary运行,否则以primary运行

-a ab:00.0:绑定使用的接口

--file-prefix=pktgen1:大页内存文件名前缀

--:后面跟pktgen运行配置参数,包括队列数量、核分配等

-P:使能接口的混杂模式

-m "[97-100:101-104].0,[105-108:109-112].1":port0rx绑定核97-100port0tx绑定核101-104port1rx绑定核105-108port1tx绑定核109-112

-f rfc2544_final.lua:指定lua脚本

l  Lua脚本

 

package.path = package.path ..";?.lua;test/?.lua;app/?.lua;../?.lua"
 
require "Pktgen";
 
-- define packet sizes to test
local pkt_sizes = {  64 };
 
-- Time in seconds to transmit for
local duration = 10000; --每次发包持续时间
local confirmDuration = 60000; --不丢包后确认速率的发包时间
local pauseTime = 1000; --发包结束的时间间隔
 
-- define the ports in use
local sendport = "0"; --发包接口
local recvport = "1"; --收包接口
 
local initialRate = 50 ; --发包初始速率
 
local function setupTraffic()
 
pktgen.range.dst_mac("all", "start", "d431:27e5:293f"); --目的mac配置
        pktgen.range.src_mac("all", "start", "c470:bd89:8b0c"); --源目的mac配置
 
        pktgen.delay(1000);
        pktgen.range.dst_ip("all", "start", "55.125.3.221"); --目的起始ip配置
        pktgen.range.dst_ip("all", "inc", "0.0.0.0"); --目的ip步长
        pktgen.range.dst_ip("all", "min", "55.125.3.221"); --目的ip最小值
        pktgen.range.dst_ip("all", "max", "55.125.3.221"); --目的ip最大值
 
        pktgen.delay(1000);
        pktgen.range.src_ip("all", "start", "55.125.3.217"); --源起始ip配置
        pktgen.range.src_ip("all", "inc", "0.0.0.0"); --源ip步长
        pktgen.range.src_ip("all", "min", "55.125.3.217"); --源ip最小值
        pktgen.range.src_ip("all", "max", "55.125.3.217"); --源ip最大值
 
        pktgen.delay(1000);
        pktgen.range.dst_port("all", "start", 1234); --目的起始端口配置
        pktgen.range.dst_port("all", "inc", 1); --目的端口步长
        pktgen.range.dst_port("all", "min", 1234); --目的端口最小值
        pktgen.range.dst_port("all", "max", 1297); --目的端口最大值
 
        pktgen.delay(1000);
        pktgen.range.src_port("all", "start", 5678); --源起始端口配置
        pktgen.range.src_port("all", "inc", 0); --源端口步长
        pktgen.range.src_port("all", "min", 5678); --源端口最小值
        pktgen.range.src_port("all", "max", 5678); --源端口最大值
 
       pktgen.delay(1000);
       pktgen.range.vlan_id("all", "start", 301); --设置起始vlan id
       pktgen.range.vlan_id("all", "inc", 0); --设置vlan id 步长
       pktgen.range.vlan_id("all", "min", 301); --设置vlan id最小值
       pktgen.range.vlan_id("all", "max", 301); --设置vlan id最大值
 
       pktgen.delay(1000);
       pktgen.range.ip_proto("all", "udp"); --设置发送报文类型
 
end
 
local function runTrial(pkt_size, rate, duration, count)
local num_tx, num_rx, num_dropped;
 
pktgen.clr();
pktgen.set(sendport, "rate", rate); --设置发送速率
pktgen.set(sendport, "size", pkt_size); --设置发包包长
pktgen.delay(1000);
pktgen.range.pkt_size("all", "start", pkt_size); --设置发送起始包长
pktgen.range.pkt_size("all", "inc", 0); --设置发送包长步长
pktgen.range.pkt_size("all", "min", pkt_size); --设置发送最小包长
pktgen.range.pkt_size("all", "max", pkt_size); --设置发送最大包长
pktgen.delay(1000);
pktgen.set_range("0", "on"); --使能range功能
pktgen.delay(1000);
pktgen.start(sendport); --开始发包
--pktgen.start(recvport);
print("Running trial " .. count .. ". % Rate: " .. rate .. ". Packet Size: " .. pkt_size .. ". Duration (mS):" .. duration);
file:write("Running trial " .. count .. ". % Rate: " .. rate .. ". Packet Size: " .. pkt_size .. ". Duration (mS):" .. duration .. "\n");
pktgen.delay(duration);
pktgen.stop(sendport); --停止发包
    --pktgen.stop(recvport);
 
pktgen.delay(pauseTime);
 
statTx = pktgen.portStats(sendport, "port")[tonumber(sendport)]; --获取接口统计
statRx = pktgen.portStats(recvport, "port")[tonumber(recvport)]; --获取接口统计
num_tx = statTx.opackets; --获取发送包数量
num_rx = statRx.ipackets; --获取接收包数量
num_dropped = num_tx*0.99 - num_rx;
 
print("Tx: " .. num_tx .. ". Rx: " .. num_rx .. ". Dropped: " .. num_dropped);
file:write("Tx: " .. num_tx .. ". Rx: " .. num_rx .. ". Dropped: " .. num_dropped .. "\n");
pktgen.delay(pauseTime);
 
return num_dropped;
end
 
local function runThroughputTest(pkt_size)
local num_dropped, max_rate, min_rate, trial_rate;
 
max_rate = 100;
min_rate = 1;
trial_rate = initialRate;
for count=1, 10, 1
do
num_dropped = runTrial(pkt_size, trial_rate, duration, count);
if num_dropped <= 1
then
min_rate = trial_rate;
else
max_rate = trial_rate;
end
trial_rate = min_rate + ((max_rate - min_rate)/2);
end
 
-- Ensure we test confirmation run with the last succesfull zero-drop rate
trial_rate = min_rate;
 
-- confirm throughput rate for at least 60 seconds
num_dropped = runTrial(pkt_size, trial_rate, confirmDuration, "Confirmation");
if num_dropped <= 1
then
print("Max rate for packet size "  .. pkt_size .. "B is: " .. trial_rate);
file:write("Max rate for packet size "  .. pkt_size .. "B is: " .. trial_rate .. "\n\n");
else
print("Max rate of " .. trial_rate .. "% could not be confirmed for 60 seconds as required by rfc2544.");
file:write("Max rate of " .. trial_rate .. "% could not be confirmed for 60 seconds as required by rfc2544." .. "\n\n");
end
end
 
function main()
file = io.open("RFC2544_throughput_results.txt", "w");
setupTraffic();
for _,size in pairs(pkt_sizes)
do
runThroughputTest(size);
end
file:close();
end
 
main();

9.  使用场景

l  验证网卡的最大吞吐,吞吐峰值


l  采用变ip或者变端口的方式验证rss散列的有效性

l  快捷的发包工具,可使用该工具快速制造大量的数据包

l  支持多类型的数据包ipv4ipv6arpgre等等

l  测试rfc2544(近似达到测试仪的效果)

注:在实际测试过程中可能存在一些与预期不同的问题,例如发包速率与设置不一致,包长不一致等不同情况的发生,可通过调整lua脚本参数或者在pktgen源码中增加相关调试信息进行调试解决

10. 使用限制

l  设置的发包速率受实际运行环境的影响,可能不能够达到理想值,如cpu性能影响无法发送指定速率的报文,如果达不到可能会降低

l  使用该工具测试延时不够精准

pktgen测试时延的方式,是在数据包中添加一个时间戳,然后发送。接收端需要将这个数据包原路返回,让发送端再次收到这个数据包发送端再次从系统中获取时间,与数据包中的时延对比,计算出数据包的往返时延。

接收端为什么不能直接计算时延呢?原因在于,接收端若想计算时延,需要接收端的时钟和发送端的时钟保持高度一致(精确到1us级别,数据包的时延往往是us级别),这是现在的时间同步手段难以做到的(现在的时间同步手段只能做到ms级别)。

另外,还要注意以下问题:

测试过程中不能丢包,否则无法测试出精确时延。

数据包必须有足够的空间容纳时间戳,大约是64字节以上。

数据包原路返回时,源、目的MACIPPort需要恰好相反或者保持不变,不能随意变化。否则哈希值会发生变化,导致正反数据包不能命中同一个core,从而无法计算时延。

11. 总结

dpdk-pktgen在使用中存在一定成本,除熟悉文档之外,最好的办法就是掌握dpdk-pktgen的发包原理,并跟踪代码,根据测试需求,修改代码,才能最大程度发挥工具本身的价值。

另外,也需要对运行环境的底层约束和实现原理进行调研和分析,保证测试方法和工具能够满足工作的要求。

0条评论
0 / 1000
情怀程序猿
1文章数
0粉丝数
情怀程序猿
1 文章 | 0 粉丝
情怀程序猿
1文章数
0粉丝数
情怀程序猿
1 文章 | 0 粉丝
原创

DPDK Pktgen RFC2544测试指导文档

2025-03-28 06:19:31
14
0

 

1.  简介

Pktgen-DPDK 是一个基于 DPDKData Plane Development Kit)的高性能数据包生成器。它主要用于网络性能测试、基准测试和流量发生器,可以在高速网络上生成大量的数据包,用于测试网络设备、协议栈和应用程序的性能,支持多种常见的网络协议(如 IPv4IPv6TCPUDP)以及自定义报文格式,可以灵活地模拟不同类型的流量,同时也可以借助于pktgen测试rfc2544的性能,在无专业测试仪的情况下以对性能进行初步摸底。本篇文章将介绍该工具的编译安装以及rfc2544测试方法等方面的内容。

2.  版本使用

l  DPDK20.11.10

l  Pktgen 20.12.0

  注意:Pktgen对应DPDK使用版本的依赖比较苛刻,需要匹配合适的版本才能编译通过

3.  环境依赖

l  meson>= 0.47.1

l  ninja>= 1.7.1

l  Pktgen编译过程中碰到的其他所需依赖:

yum install libpcap-devel

yum install numactl-devel

yum install numactl-libs

pip3 install pyelftools

yum install lua lua-devel

4.  获取DPDKPktgen-DPDK

git clone github.com/DPDK/dpdk.git

git clone github.com/pktgen/Pktgen-DPDK.git

5.  编译dpdk

cd dpdk

mkdir install_dir       # 安装目录

mkdir build     # 构建目录

meson -Denable_kmods=true -Dprefix=$(pwd)/install_dir build

cd build

ninja

ninja install    # 安装在dpdk/install_dir

6.  编译pktgen

l  设置PKG_CONFIG_PATH变量,需要指定libdpdknuma所对应pkgconfig路径,否则meson build会报错

# 查找到numa库的pkgconfig路径为/usr/lib64/pkgconfig

export PKG_CONFIG_PATH=<YOUR PATH>/dpdk/install_dir/lib64/pkgconfig:/usr/lib64/pkgconfig

cd Pktgen-DPDK

meson–Denable_lua=true build #构建并使能lua功能

cd build

ninja #编译

编译完成后运行程序在build/app/目录下

7.  运行环境初始化

l  查看网卡并进行网卡绑定

#模块
modprobe uio 

insmod <your path>/igb_uio.ko

#查看网卡信息

dpdk-devbind.py –s


     #网卡绑定

dpdk-devbind.py -b igb_uio <pci info>

dpdk-devbind.py -b igb_uio <pci info>

注:本次使用的是麦洛斯cx6网卡,无需绑定igb_uio

#大页内存初始化

第一种是在grub.cfg中增加如下命令:

default_hugepagesz=1G hugepagesz=1G hugepages=64

重启系统,此种方式的好处是每次重启都会自动初始化无需手动再次配置,弊端是必须重启系统,如果不想重启系统可使用一下方法:

第二种方式临时配置大页内存,命令如下:

echo 128 > /sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages

mkdir /mnt/huge

mount -t hugetlbfs nodev /mnt/huge

8.  运行pktgen

l  相关目录

可执行文件目录:Pktgen-DPDK/build/app/pktgen

Lua脚本目录:Pktgen-DPDK/ scripts

l  运行命令(命令行方式)

./app/pktgen -l 96-112 -n 4 --proc-type auto -a ab:00.0 -a ab:00.1 --file-prefix=pktgen1 -- -P -m "[97-100:101-104].0,[105-108:109-112].1"

参数解释:

-l 96-112:使用core 96-112

-n 4:使用4个内存通道

--proc-type auto:进程运行类型为自动模式,即如果有其他dpdk程序,则作为secondary运行,否则以primary运行

-a ab:00.0:绑定使用的接口

--file-prefix=pktgen1:大页内存文件名前缀

--:后面跟pktgen运行配置参数,包括队列数量、核分配等

-P:使能接口的混杂模式

-m "[97-100:101-104].0,[105-108:109-112].1":port0rx绑定核97-100port0tx绑定核101-104port1rx绑定核105-108port1tx绑定核109-112

l  运行结果:

默认显示page main,成功根据配置文件参数执行pktgen

l  随机发包帮助说明

-- Setup the packet range values --

     note: SMMI = start|min|max|inc (start, minimum, maximum, increment)

 

 

range <portlist> src|dst mac <SMMI> <etheraddr> - Set destination/source MAC address

      e.g: range 0 src mac start 00:00:00:00:00:00

           range 0 dst mac max 00:12:34:56:78:90

      or  range 0 src mac 00:00:00:00:00:00 00:00:00:00:00:00 00:12:34:56:78:90 00:00:00:01:01:01

range <portlist> src|dst ip <SMMI> <ipaddr>   - Set source IP start address

      e.g: range 0 dst ip start 0.0.0.0

           range 0 dst ip min 0.0.0.0

           range 0 dst ip max 1.2.3.4

           range 0 dst ip inc 0.0.1.0

       or  range 0 dst ip 0.0.0.0 0.0.0.0 1.2.3.4 0.0.1.0

range <portlist> type ipv4|ipv6               - Set the range packet type to IPv4 or IPv6

range <portlist> proto tcp|udp                - Set the IP protocol type

range <portlist> tcp flag set <flag>          - Set the TCP flag

range <portlist> tcp flag clr <flag>          - Clear the TCP flag

range <portlist> tcp seq <SMMI> <value>       - Set the TCP sequence number

       or  range <portlist> tcp seq <start> <min> <max> <inc>

range <portlist> tcp ack <SMMI> <value>       - Set the TCP acknowledge number

       or  range <portlist> tcp ack <start> <min> <max> <inc>

range <portlist> src|dst port <SMMI> <value>  - Set UDP/TCP source/dest port number

       or  range <portlist> src|dst port <start> <min> <max> <inc>

range <portlist> vlan <SMMI> <value>          - Set vlan id start address

      or  range <portlist> vlan <start> <min> <max> <inc>

range <portlist> size <SMMI> <value>          - Set pkt size start address

      or  range <portlist> size <start> <min> <max> <inc>

range <portlist> teid <SMMI> <value>          - Set TEID value

      or  range <portlist> teid <start> <min> <max> <inc>

range <portlist> mpls entry <hex-value>       - Set MPLS entry value

range <portlist> qinq index <val1> <val2>     - Set QinQ index values

range <portlist> gre key <value>              - Set GRE key value

range <portlist> cos <SMMI> <value>           - Set cos value

range <portlist> tos <SMMI> <value>           - Set tos value

range <portlist> ttl <SMMI> <value>           - Set TTL

range <portlist> hop_limits <SMMI> <value>    - Set Hop Limits

range <portlist> traffic_class <SMMI> <value> - Set Traffic Class value

l  配置实例

range 0 type ipv4  #设置发包类型

range 0 src ip 192.168.1.1 192.168.1.1 192.168.1.100 0.0.0.1 #配置发包源ip段,以及发包步长

range 0 src port 1000 1000 65534 1 #配置发包源端口范围,以及端口步长

range 0 dst mac start E0:28:61:cc:bb:aa #配置发包起始目的mac

range 0 dst mac max E0:28:61:cc:bb:aa #配置发包最大目的mac

range 0 dst ip 192.168.1.101 192.168.1.101 192.168.1.200 0.0.0.1 #配置发包目的ip段,以及发包步长

range 0 dst port 5011 5011 5011 0 #配置发包目的端口范围,以及端口步长

range 0 proto udp #配置报文协议类型为udp

range 0 size 64 64 64 0 #配置发包大小为64字节

set 0 rate 100 #设置按照接口速率的100%发包

enable 0 range #使能range功能

l  查看range配置

page range

l  开始发包

start 0 #如果启用所有接口,可以使用start all

    注:也可以使用单ip,单端口的方式发包,在pktgen命令行输入settab键即可查看相关命令

l  运行命令(lua脚本方式)

./app/pktgen -l 96-112 -n 17 --proc-type auto -a ab:00.0 -a ab:00.1 --file-prefix=pktgen1 -- -P -m "[97-104].0,[105-112].1" –f rfc2544_final.lua

参数解释:

-l 96-112:使用core 96-112

-n 17:使用17core

--proc-type auto:进程运行类型为自动模式,即如果有其他dpdk程序,则作为secondary运行,否则以primary运行

-a ab:00.0:绑定使用的接口

--file-prefix=pktgen1:大页内存文件名前缀

--:后面跟pktgen运行配置参数,包括队列数量、核分配等

-P:使能接口的混杂模式

-m "[97-100:101-104].0,[105-108:109-112].1":port0rx绑定核97-100port0tx绑定核101-104port1rx绑定核105-108port1tx绑定核109-112

-f rfc2544_final.lua:指定lua脚本

l  Lua脚本

 

package.path = package.path ..";?.lua;test/?.lua;app/?.lua;../?.lua"
 
require "Pktgen";
 
-- define packet sizes to test
local pkt_sizes = {  64 };
 
-- Time in seconds to transmit for
local duration = 10000; --每次发包持续时间
local confirmDuration = 60000; --不丢包后确认速率的发包时间
local pauseTime = 1000; --发包结束的时间间隔
 
-- define the ports in use
local sendport = "0"; --发包接口
local recvport = "1"; --收包接口
 
local initialRate = 50 ; --发包初始速率
 
local function setupTraffic()
 
pktgen.range.dst_mac("all", "start", "d431:27e5:293f"); --目的mac配置
        pktgen.range.src_mac("all", "start", "c470:bd89:8b0c"); --源目的mac配置
 
        pktgen.delay(1000);
        pktgen.range.dst_ip("all", "start", "55.125.3.221"); --目的起始ip配置
        pktgen.range.dst_ip("all", "inc", "0.0.0.0"); --目的ip步长
        pktgen.range.dst_ip("all", "min", "55.125.3.221"); --目的ip最小值
        pktgen.range.dst_ip("all", "max", "55.125.3.221"); --目的ip最大值
 
        pktgen.delay(1000);
        pktgen.range.src_ip("all", "start", "55.125.3.217"); --源起始ip配置
        pktgen.range.src_ip("all", "inc", "0.0.0.0"); --源ip步长
        pktgen.range.src_ip("all", "min", "55.125.3.217"); --源ip最小值
        pktgen.range.src_ip("all", "max", "55.125.3.217"); --源ip最大值
 
        pktgen.delay(1000);
        pktgen.range.dst_port("all", "start", 1234); --目的起始端口配置
        pktgen.range.dst_port("all", "inc", 1); --目的端口步长
        pktgen.range.dst_port("all", "min", 1234); --目的端口最小值
        pktgen.range.dst_port("all", "max", 1297); --目的端口最大值
 
        pktgen.delay(1000);
        pktgen.range.src_port("all", "start", 5678); --源起始端口配置
        pktgen.range.src_port("all", "inc", 0); --源端口步长
        pktgen.range.src_port("all", "min", 5678); --源端口最小值
        pktgen.range.src_port("all", "max", 5678); --源端口最大值
 
       pktgen.delay(1000);
       pktgen.range.vlan_id("all", "start", 301); --设置起始vlan id
       pktgen.range.vlan_id("all", "inc", 0); --设置vlan id 步长
       pktgen.range.vlan_id("all", "min", 301); --设置vlan id最小值
       pktgen.range.vlan_id("all", "max", 301); --设置vlan id最大值
 
       pktgen.delay(1000);
       pktgen.range.ip_proto("all", "udp"); --设置发送报文类型
 
end
 
local function runTrial(pkt_size, rate, duration, count)
local num_tx, num_rx, num_dropped;
 
pktgen.clr();
pktgen.set(sendport, "rate", rate); --设置发送速率
pktgen.set(sendport, "size", pkt_size); --设置发包包长
pktgen.delay(1000);
pktgen.range.pkt_size("all", "start", pkt_size); --设置发送起始包长
pktgen.range.pkt_size("all", "inc", 0); --设置发送包长步长
pktgen.range.pkt_size("all", "min", pkt_size); --设置发送最小包长
pktgen.range.pkt_size("all", "max", pkt_size); --设置发送最大包长
pktgen.delay(1000);
pktgen.set_range("0", "on"); --使能range功能
pktgen.delay(1000);
pktgen.start(sendport); --开始发包
--pktgen.start(recvport);
print("Running trial " .. count .. ". % Rate: " .. rate .. ". Packet Size: " .. pkt_size .. ". Duration (mS):" .. duration);
file:write("Running trial " .. count .. ". % Rate: " .. rate .. ". Packet Size: " .. pkt_size .. ". Duration (mS):" .. duration .. "\n");
pktgen.delay(duration);
pktgen.stop(sendport); --停止发包
    --pktgen.stop(recvport);
 
pktgen.delay(pauseTime);
 
statTx = pktgen.portStats(sendport, "port")[tonumber(sendport)]; --获取接口统计
statRx = pktgen.portStats(recvport, "port")[tonumber(recvport)]; --获取接口统计
num_tx = statTx.opackets; --获取发送包数量
num_rx = statRx.ipackets; --获取接收包数量
num_dropped = num_tx*0.99 - num_rx;
 
print("Tx: " .. num_tx .. ". Rx: " .. num_rx .. ". Dropped: " .. num_dropped);
file:write("Tx: " .. num_tx .. ". Rx: " .. num_rx .. ". Dropped: " .. num_dropped .. "\n");
pktgen.delay(pauseTime);
 
return num_dropped;
end
 
local function runThroughputTest(pkt_size)
local num_dropped, max_rate, min_rate, trial_rate;
 
max_rate = 100;
min_rate = 1;
trial_rate = initialRate;
for count=1, 10, 1
do
num_dropped = runTrial(pkt_size, trial_rate, duration, count);
if num_dropped <= 1
then
min_rate = trial_rate;
else
max_rate = trial_rate;
end
trial_rate = min_rate + ((max_rate - min_rate)/2);
end
 
-- Ensure we test confirmation run with the last succesfull zero-drop rate
trial_rate = min_rate;
 
-- confirm throughput rate for at least 60 seconds
num_dropped = runTrial(pkt_size, trial_rate, confirmDuration, "Confirmation");
if num_dropped <= 1
then
print("Max rate for packet size "  .. pkt_size .. "B is: " .. trial_rate);
file:write("Max rate for packet size "  .. pkt_size .. "B is: " .. trial_rate .. "\n\n");
else
print("Max rate of " .. trial_rate .. "% could not be confirmed for 60 seconds as required by rfc2544.");
file:write("Max rate of " .. trial_rate .. "% could not be confirmed for 60 seconds as required by rfc2544." .. "\n\n");
end
end
 
function main()
file = io.open("RFC2544_throughput_results.txt", "w");
setupTraffic();
for _,size in pairs(pkt_sizes)
do
runThroughputTest(size);
end
file:close();
end
 
main();

9.  使用场景

l  验证网卡的最大吞吐,吞吐峰值


l  采用变ip或者变端口的方式验证rss散列的有效性

l  快捷的发包工具,可使用该工具快速制造大量的数据包

l  支持多类型的数据包ipv4ipv6arpgre等等

l  测试rfc2544(近似达到测试仪的效果)

注:在实际测试过程中可能存在一些与预期不同的问题,例如发包速率与设置不一致,包长不一致等不同情况的发生,可通过调整lua脚本参数或者在pktgen源码中增加相关调试信息进行调试解决

10. 使用限制

l  设置的发包速率受实际运行环境的影响,可能不能够达到理想值,如cpu性能影响无法发送指定速率的报文,如果达不到可能会降低

l  使用该工具测试延时不够精准

pktgen测试时延的方式,是在数据包中添加一个时间戳,然后发送。接收端需要将这个数据包原路返回,让发送端再次收到这个数据包发送端再次从系统中获取时间,与数据包中的时延对比,计算出数据包的往返时延。

接收端为什么不能直接计算时延呢?原因在于,接收端若想计算时延,需要接收端的时钟和发送端的时钟保持高度一致(精确到1us级别,数据包的时延往往是us级别),这是现在的时间同步手段难以做到的(现在的时间同步手段只能做到ms级别)。

另外,还要注意以下问题:

测试过程中不能丢包,否则无法测试出精确时延。

数据包必须有足够的空间容纳时间戳,大约是64字节以上。

数据包原路返回时,源、目的MACIPPort需要恰好相反或者保持不变,不能随意变化。否则哈希值会发生变化,导致正反数据包不能命中同一个core,从而无法计算时延。

11. 总结

dpdk-pktgen在使用中存在一定成本,除熟悉文档之外,最好的办法就是掌握dpdk-pktgen的发包原理,并跟踪代码,根据测试需求,修改代码,才能最大程度发挥工具本身的价值。

另外,也需要对运行环境的底层约束和实现原理进行调研和分析,保证测试方法和工具能够满足工作的要求。

文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0