pktgen使用简明教程

网上有很多讲解pktgen的文章,但总是不够全面细致,看完之后自己还是不会写pktgen测试脚本,为此本文对pktgen进行详细的阐述,让大家看完本文后能够自己动手写pktgen shell.

简介

pktgen是一个位于linux内核层的高性能网络测试工具,由瑞士皇家理工大学的TSlab实验室的Robert Olsson开发的(现在应该不在皇家理工了),主要用来测试网络驱动与网卡设备,支持多线程,能够产生随机mac地址、IP地址、UDP端口号的数据包,pktgen 的作者使用多CPU处理器在不同的PCI总线(pci 、pcie等总线)上用千兆以太网卡做过测试(pktgen的表现依赖于CPU处理速率、内存延时、pci总线速率等硬件参数),发送数据速率甚至可以大于10GBit/s。可见是可以满足大多数的网卡等测试需求。

pktgen的配置与统计信息查看都使用/proc文件系统完成,/proc文件系统是一种特殊的,有软件创建的文件系统,内核使用/proc文件系统向外界导出信息,外界也可以通过它配置内核态的一些进程的参数,如ps top uptime等linux发行版中的很多工具就是通过/proc实现的.在大多情况下,我们只用/proc读出数据(用于调试内核驱动等),而在pktgen中配置命令就用到了/proc的写入数据功能。

发包实验

现在版本的linux发行版大多加入了pktgen,使用以下命令加载pktgen模块:

然后你将在你的电脑的/proc/net/pktgen看到以下文件:```shellkpktgend_0  kpktgend_1  kpktgend_2  kpktgend_3  pgctrl

其中kpktgen_*的多少是根据你的CPU的个数决定的,如我的机子的CPU数目为4,则有四个此文件。

通过命令cat /proc/net/pktgen/pgctrl可以查看pktgen的版本等信息:

# cat /proc/net/pktgen/pgctrlPacket Generator for packet performance testing. Version: 2.74

中断亲和力

当使用某个线程(kpktgend_x)通过某个端口(ethx)发送(接受)数据时,我们应该把这个端口所对应的中断绑定到某一个CPU上,从而防止CPU的变动(操作系统引起的)导致CPU缓存的丢失。具体做法如下

首先,通过以下命令查看ethx所对应的中断,在这里我们以eth3为例

# cat /proc/interrupts | grep eth347: 45836 0 0 0 PCI-MSI-edge eth3-TxRx-048: 45836 0 0 0 PCI-MSI-edge eth3-TxRx-149: 45836 0 0 0 PCI-MSI-edge eth3-TxRx-250: 45836 0 0 0 PCI-MSI-edge eth3-TxRx-351: 0 0 0 0 PCI-MSI-edge eth3:lsc

由上可以看出eth3使用了五个中断号,为47-51,我们在这里将其都绑定在CPU0上

# echo 1 /proc/irq/47/smp_affinity# echo 1 /proc/irq/48/smp_affinity# echo 1 /proc/irq/49/smp_affinity# echo 1 /proc/irq/50/smp_affinity# echo 1 /proc/irq/51/smp_affinity

当然若你分开绑定的话,在大数据流的时候可以均摊CPU的负担,可能对最高性能有所提升,具体就不清楚了,这个应该还和Intel网卡的多队列相关了,有关分析有待进一步实验。Robert测试结果说明,正确的中断亲和力绑定,对发送速率有60%的提升。

  • clone_skb:限制内存的分配(clone_skb应该只是复制skb的结构体,不复制数据区) 此部分还没有看懂,应该是跟cpu高速缓存相关,先放着,不懂并不影响后面的实验。

  • 延时:减小发送速率 在发送一个数据包后延时一会,延时的单位是ns级,从而达到减小发送速率的目的。若延时时间大于发送时间,应该是可以通过此功能达到每秒发送特定数据包个数的效果,即安特定的频率发送数据包。

实验环境

实验拓扑如下

1+-----------+           +-----------+2| Host1     |           |  Host2     |3|       eth1 +-----------+nf0       |4|           |           |           |5|           |           |           |67+-----------+           +-----------+

首先我们看下一个简单代码,对pktgen的shell 控制有个直观感受,你可以先试着看看此代码,也可以直接跳过,先看看下面的内容,然后再回过来看此代码

#!/bin/sh# pktgen.conf -- Sample configuration for send on two devices on a UP system#modprobe pktgenif [[ lsmod | grep pktgen == "" ]];then   modprobe pktgenfiif [[ $1 == "" ]];then   pktsize=550else   pktsize=$1fifunction 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}# On UP systems only one thread exists -- so just add devices# We use eth1, eth1echo "Adding devices to run".PGDEV=/proc/net/pktgen/kpktgend_0pgset "rem_device_all"pgset "add_device eth1"pgset "max_before_softirq 1"# Configure the individual devicesecho "Configuring devices"PGDEV=/proc/net/pktgen/eth1pgset "clone_skb 1000"pgset "pkt_size $pktsize"pgset "src_mac 00:1B:21:90:4B:E4"pgset "flag IPSRC_RND"pgset "src_min 10.0.0.2"pgset "src_max 10.0.0.255"pgset "dst 10.0.0.1"pgset "dst_mac  00:4E:46:31:30:00"pgset "count 0"# Time to runPGDEV=/proc/net/pktgen/pgctrlecho "pkgsize:$pktsize"echo "Running... ctrl^C to stop"pgset "start"echo "Done"

配置实例

通过/proc接口配置pktgen,首先为了方便起见定义两个配置函数

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}

pktgen.conf-1 :在当CPU系统中将eth1 eth2 绑定到线程0,部分代码如下

PGDEV=/proc/net/pktgen/kpktgend_0pgset "rem_device_all"pgset "add_device eth1"pgset "add_device eth2"

pktgen.conf-2: eth1使用线程0 eth2使用线程1发送,部分代码如下

PGDEV=/proc/net/pktgen/kpktgend_0pgset "rem_device_all"pgset "add_device eth1"PGDEV=/proc/net/pktgen/kpktgend_1pgset "rem_device_all"pgset "add_device eth2"

pktgen.conf-3:在双cpu系统中 eth1 eth2都使用线程0发送,部分代码如下

PGDEV=/proc/net/pktgen/kpktgend_0pgset "rem_device_all"pgset "add_device eth1"pgset  "add_device eth2"PGDEV=/proc/net/pktgen/kpktgend_1pgset "rem_device_all"

pktgen.conf-4:用于Dos测试的脚本,注意clone_skb 0,部分代码如下

PGDEV=/proc/net/pktgen/eth1pgset "clone_skb 0"pgset "flag IPDST_RND"pgset "dst_min 10.0.0.0"pgset "dst_max 10.255.255.255"

pktgen.conf-5:用于路由流测试的脚本,同样注意 clone_skb 0

PGDEV=/proc/net/pktgen/eth1pgset "clone_skb 0"pgset "flag IPDST_RND"pgset "dst_min 10.0.0.0"pgset "dst_max 10.255.255.255"#8k concurrent flows at 4 pktspgset "flows 8192"pgset "flowlen 4"

完整示例

#Script contributed by Grant Grundler# # Note! 10 devicesPGDEV=/proc/net/pktgen/kpktgend_0pgset "rem_device_all"pgset "add_device eth3"pgset "add_device eth5"pgset "add_device eth7"pgset "add_device eth9"pgset "add_device eth11"pgset "max_before_softirq 10000"PGDEV=/proc/net/pktgen/kpktgend_1pgset "rem_device_all"pgset "add_device eth2"pgset "add_device eth4"pgset "add_device eth6"pgset "add_device eth8"pgset "add_device eth10"pgset "max_before_softirq 10000"# Configure the individual devicesfor i in 2 3 4 5 6 7 8 9 10 11doPGDEV=/proc/net/pktgen/eth$iecho "Configuring $PGDEV"pgset "clone_skb 500000"pgset "min_pkt_size 60"pgset "max_pkt_size 60"pgset "dst 192.168.3.10$i"pgset "dst_mac 01:02:03:04:05:0$i"pgset "count 0"doneecho "Running... CTRL-C to stop"PGDEV=/proc/net/pktgen/pgctrlpgset "start"tail -2 /proc/net/pktgen/eth*

参考

Was this helpful?

0 / 0

发表回复 0