zoukankan      html  css  js  c++  java
  • pktgen网络测试工具介绍

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

      1.pktgen简介

      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的写入数据功能。

      2.使用pktgen进行发包实验

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

    1
    #modprobe pktgen

      然后你将在你的电脑的/proc/net/pktgen看到以下文件:

    1
    kpktgend_0  kpktgend_1  kpktgend_2  kpktgend_3  pgctrl

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

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

    1
    #cat /proc/net/pktgen/pgctrl<br>Packet Generator for packet performance testing. Version: 2.74

      2.1使用pktgen一些需要注意的地方

      1)中断亲和力

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

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


    # cat /proc/interrupts | grep eth3

    47: 45836 0 0 0 PCI-MSI-edge eth3-TxRx-0
    48: 45836 0 0 0 PCI-MSI-edge eth3-TxRx-1
    49: 45836 0 0 0 PCI-MSI-edge eth3-TxRx-2
    50: 45836 0 0 0 PCI-MSI-edge eth3-TxRx-3
    51: 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

    在文件 /proc/irq/51/smp_affinity里面,使用的是16进制数,从低位到高位分别表示CPU0-->CPUn,1表示绑定,0表示不绑定。1就是0001,表示只绑定cpu0,如果是5,就是0101,表示绑定cpu0和cpu2

    当然若你分开绑定的话,在大数据流的时候可以均摊CPU的负担,可能对最高性能有所提升,具体就不清楚了,这个应该还和Intel网卡的多队列相关了,有关分析有待进一步实验。

    Robert测试结果说明,正确的中断亲和力绑定,对发送速率有60%的提升。

      2)clone_skb:限制内存的分配(clone_skb应该只是复制skb的结构体,不复制数据区)

        此部分还没有看懂,应该是跟cpu高速缓存相关,先放着,不懂并不影响后面的实验。

      3)延时:减小发送速率

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

      2.2搭建实验环境

     1)实验拓扑如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    1
    +-----------+           +-----------+
    2
    | Host1     |           |  Host2     |
    3
    |       eth1 +-----------+nf0       |
    4
    |           |           |           |
    5
    |           |           |           |
    6
    7
    +-----------+           +-----------+

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

    复制代码
    #!/bin/sh
    # pktgen.conf -- Sample configuration for send on two devices on a UP system
    
    #modprobe pktgen
    
    if [[ `lsmod | grep pktgen` == "" ]];then
       modprobe pktgen
    fi
    
    if [[ $1 == "" ]];then
       pktsize=550
    else
       pktsize=$1
    fi
    
    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
    }
    
    # On UP systems only one thread exists -- so just add devices
    # We use eth1, eth1
    
    echo "Adding devices to run".
    
    PGDEV=/proc/net/pktgen/kpktgend_0
    pgset "rem_device_all"
    pgset "add_device eth1"
    pgset "max_before_softirq 1"
    
    # Configure the individual devices
    echo "Configuring devices"
    
    PGDEV=/proc/net/pktgen/eth1
    
    pgset "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 run
    
    PGDEV=/proc/net/pktgen/pgctrl
    echo "pkgsize:$pktsize"
    echo "Running... ctrl^C to stop"
    
    pgset "start"
    
    echo "Done"
    复制代码

     

      2)pktgen所有命令解释如下

    pktgen命令

    Pktgen控制命令

    start

    所有的线程开始发送

    stop

    停止

    线程的控制命令

    add_device

    添加某个端口到某个线程

    rem_device_all

    删除绑定在某个线程的所有端口

    max_before_softirq

    在最多发送多少个数据包后,执行do_softirq()

    端口命令

    debug

    调试

    clone_skb

    对每个skb进行多少个复制,0表示不复制。对于Dos等测试必须至零

    clear_counters

    清空计数器,一般程序自动清空

    pkt_size

    链路包的大小(前去CRC的值)

    min_pkt_size

    数据包最小值

    max_pkt_size

          最大值

    flags

    包的分片数量?

    count

    发送数据包的个数,0 表示一直发送

    delay

    发送两个数据包之间的延时

    dst

    目的IP

    dst_min

    目的IP的最小值

    dst_max

             最大值

    src_min

    源IP最小值

    src_max

         最大值

    dst6

    目的IPv6地址

    src6

    源IPv6地址

    dstmac

    目的mac

    srcmac

    源mac

    src_mac_count

    源mac的数量,从srcmac设置的mac开始轮询

    dst_mac_count

    同上

    udp_src_min

    最小源udp端口号

    udp_src_max

    最大源udp端口号

    udp_dst_min

    最小目的udp端口号

    udp_dst_max

    最大目的udp端口号

    flows

    并发流的个数

    flowlen

    流的长度

    Flags

    IPSRC_RND

    IPDST_RND

    TXSIZE_RND

    UDPSRC_RND

    UDPDST_RND

    MACSRC_RND

    MACDST_RND

    PSRC_RND 源IP随机发送

      

      3)配置实例

      通过/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_0
    pgset "rem_device_all"
    pgset "add_device eth1"
    pgset "add_device eth2"

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

    复制代码
    PGDEV=/proc/net/pktgen/kpktgend_0
    pgset "rem_device_all"
    pgset "add_device eth1"
    
    PGDEV=/proc/net/pktgen/kpktgend_1
    pgset "rem_device_all"
    pgset "add_device eth2"
    复制代码

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

    复制代码
    PGDEV=/proc/net/pktgen/kpktgend_0
    pgset "rem_device_all"
    pgset "add_device eth1"
    pgset  "add_device eth2"
    
    PGDEV=/proc/net/pktgen/kpktgend_1
    pgset "rem_device_all"
    复制代码

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

    PGDEV=/proc/net/pktgen/eth1
    pgset "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/eth1
    pgset "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 pkts
    pgset "flows 8192"
    pgset "flowlen 4"
    复制代码

      最后贴一个比较复杂的脚本:

    复制代码
    #Script contributed by Grant Grundler
    # <grundler@parisc-linux.org>
    # Note! 10 devices
    PGDEV=/proc/net/pktgen/kpktgend_0
    pgset "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_1
    pgset "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 devices
    for i in 2 3 4 5 6 7 8 9 10 11
    do
    PGDEV=/proc/net/pktgen/eth$i
    echo "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"
    done
    echo "Running... CTRL-C to stop"
    PGDEV=/proc/net/pktgen/pgctrl
    pgset "start"
    tail -2 /proc/net/pktgen/eth*
    复制代码
  • 相关阅读:
    (二)ABP+MetroNic--- 用户管理及角色管理的实现
    BootstrapValidator 自定义服务端验证
    ASP.Net Web API 的参数绑定[翻译]
    ABP webapi IDInput传参
    JqueryTable ServerSide Ajax 数据加载及样式设置
    JqueryTable踩过的坑
    Lambda 表达式中 动态解析OrderbyLinQ语句的实现
    jenkins问题整理
    maven profile实现多环境配置
    Spring 发送内嵌图片的邮件 遇到的问题
  • 原文地址:https://www.cnblogs.com/flyfish919/p/7279377.html
Copyright © 2011-2022 走看看