2016年3月31日 星期四

封包產生器 - pktgen

1. pktgen是一個Linux核心中的一個模組,可以用來產生大量封包,測量設備的網路效能,相較於User space的iperf,pktgen是一個更精準的測試工具。

2. 參數說明
Pgcontrol commands
    start Starts sending on all threads
    stop

Threads commands
    add_device: Add a device to thread i.e eth0
    rem_device_all: Removes all devices from this thread
    max_before_softirq: do_softirq() after sending a number of packets

Device commands
    debug
    clone_skb: Number of identical copies of the same packet 0 means alloc for each skb. For DoS etc we must alloc new skb’s.
    clear_counters: normally handled automatically
    pkt_size: Link packet size minus CRC (4)
    min_pkt_size: Range pkt_size setting If < max_pkt_size, then cycle through the port range.
    max_pkt_size
    frags: Number of fragments for a packet
    count: Number of packets to send. Use zero for continious sending
    delay: Artificial gap inserted between packets in nanoseconds
    dst: IP destination address i.e 10.0.0.1
    dst_min: Same as dst If < dst_max, then cycle through the port range.
    dst_max: Maximum destination IP. i.e 10.0.0..1
    src_min: Minimum (or only) source IP. i.e. 10.0.0.254 If < src_max, then cycle through the port range.
    src_max: Maximum source IP.
    dst6: IPV6 destination address i.e fec0::1
    src6: IPV6 source address i.e fec0::2
    dstmac: MAC destination adress 00:00:00:00:00:00
    srcmac: MAC source adress. If omitted it’s automatically taken from source device
    src_mac_count: Number of MACs we’ll range through. Minimum’ MAC is what you set with srcmac.
    dst_mac_count: Number of MACs we’ll range through. Minimum’ MAC is what you set with dstmac.

Flags
    IPSRC_RND IP Source is random (between min/max),
    IPDST_RND Etc
    TXSIZE_RND
    UDPSRC_RND
    UDPDST_RND
    MACSRC_RND
    MACDST_RND
    udp_src_min UDP source port min, If < udp_src_max, then cycle through the port range.
    udp_src_max UDP source port max.
    udp_dst_min UDP destination port min, If < udp_dst_max, then cycle through the port range.
    udp_dst_max UDP destination port max.
    stop Aborts packet injection. Ctrl-C also aborts generator. Note: Use count 0 (forever) and stop the run with Ctrl-C when multiple devices are assigned to one pktgen thread. This avoids some devices finishing before others and
skewing the results. We are primarily interested in how many packets all devices can send at the same time, not absolute number of packets each NIC sent.
    flows Number of concurrent flows
    flowlen Length of a flow
3. 掛載pktgen模組,一般Linux都有內建
$ sudo modprobe pktgen
4. 掛載完後,pktgen是透過proc entry去設定與控制,
$ ls /proc/net/pktgen/
kpktgend_0  kpktgend_1  kpktgend_2  kpktgend_3  pgctrl
kpktgend_0, kpktgend_1, kpktgend_2, kpktgend_3: 表示你的硬體有幾個CPU核心,pktgen可以指定由哪個CPU來處理網路流量。
pgctrl: 主要是用來啟動網路流量
5. 將eth0網路介面,指定由CPU0來處理
$ sudo bash -c 'echo "add_device eth0" > /proc/net/pktgen/kpktgend_0'
6. 指定完後,會出現一個新的proc entry為eth0介面,此時可以透過cat命令,來取得eth0介面目前的設定
$ ls /proc/net/pktgen/
eth0  kpktgend_0  kpktgend_1  kpktgend_2  kpktgend_3  pgctrl


$ sudo cat /proc/net/pktgen/eth0
Params: count 1000  min_pkt_size: 0  max_pkt_size: 0
     frags: 0  delay: 0  clone_skb: 0  ifname: eth0
     flows: 0 flowlen: 0
     queue_map_min: 0  queue_map_max: 0
     dst_min:   dst_max:
        src_min:   src_max:
     src_mac: b8:27:eb:01:37:78 dst_mac: 00:00:00:00:00:00
     udp_src_min: 9  udp_src_max: 9  udp_dst_min: 9  udp_dst_max: 9
     src_mac_count: 0  dst_mac_count: 0
     Flags:
Current:
     pkts-sofar: 0  errors: 0
     started: 0us  stopped: 0us idle: 0us
     seq_num: 0  cur_dst_mac_offset: 0  cur_src_mac_offset: 0
     cur_saddr: 0.0.0.0  cur_daddr: 0.0.0.0
     cur_udp_dst: 0  cur_udp_src: 0
     cur_queue_map: 0
     flows: 0
Result: Idle
7. pkt_size: 設定網路封包的大小,一般為46 bytes ~ 1500 bytes
count: 設定網路封包的數量,當Count 設成 0,表示系統會不斷送出封包,直到按下 Ctrl+C 手動終止程式
$ sudo bash -c 'echo "count 10000" > /proc/net/pktgen/eth0'
$ sudo bash -c 'echo "pkt_size 1400" > /proc/net/pktgen/eth0'
8. 啟動網路流量
$ sudo bash -c 'echo "start" > /proc/net/pktgen/pgctrl'
9. 取得測試結果
$ sudo cat /proc/net/pktgen/eth0
Params: count 10000  min_pkt_size: 1400  max_pkt_size: 1400
     frags: 0  delay: 0  clone_skb: 0  ifname: eth0
     flows: 0 flowlen: 0
     queue_map_min: 0  queue_map_max: 0
     dst_min:   dst_max:
        src_min:   src_max:
     src_mac: b8:27:eb:01:37:78 dst_mac: 00:00:00:00:00:00
     udp_src_min: 9  udp_src_max: 9  udp_dst_min: 9  udp_dst_max: 9
     src_mac_count: 0  dst_mac_count: 0
     Flags:
Current:
     pkts-sofar: 10000  errors: 0
     started: 11124860059us  stopped: 11126011505us idle: 13620us
     seq_num: 10001  cur_dst_mac_offset: 0  cur_src_mac_offset: 0
     cur_saddr: 169.254.31.88  cur_daddr: 0.0.0.0
     cur_udp_dst: 9  cur_udp_src: 9
     cur_queue_map: 0
     flows: 0
Result: OK: 1151445(c1137825+d13620) usec, 10000 (1400byte,0frags)
  8684pps 97Mb/sec (97260800bps) errors: 0
10. 一般測試範例,產生10000個封包,大小為1400 bytes
$ sudo modprobe pktgen

$ sudo bash -c 'echo "add_device eth0" > /proc/net/pktgen/kpktgend_0'

$ sudo bash -c 'echo "count 10000" > /proc/net/pktgen/eth0'
$ sudo bash -c 'echo "pkt_size 1400" > /proc/net/pktgen/eth0'

$ sudo bash -c 'echo "start" > /proc/net/pktgen/pgctrl'

$ sudo cat /proc/net/pktgen/eth0
11. 壓力測試範例,產生大量封包,大小為1400 bytes
$ sudo modprobe pktgen
$ sudo bash -c 'echo "add_device eth0" > /proc/net/pktgen/kpktgend_0'

$ sudo bash -c 'echo "count 0" > /proc/net/pktgen/eth0'
$ sudo bash -c 'echo "pkt_size 1400" > /proc/net/pktgen/eth0'

$ sudo bash -c 'echo "start" > /proc/net/pktgen/pgctrl'

$ sudo cat /proc/net/pktgen/eth0
11. 一個Script的範例
#!/bin/sh

#modprobe 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
}

# Config Start Here -------------------------------------
# thread config
# Each CPU has own thread. Two CPU exammple.
# We add eth1, eth2 respectively.
PGDEV=/proc/net/pktgen/kpktgend_0
echo "Removing all devices"
pgset "rem_device_all"
echo "Adding eth1"
pgset "add_device eth1"
echo "Setting max_before_softirq 10000"
pgset "max_before_softirq 10000"

# device config
# delay is inter packet gap. 0 means maximum speed.
CLONE_SKB="clone_skb 1000000"

# NIC adds 4 bytes CRC
PKT_SIZE="pkt_size 60"

# COUNT 0 means forever
#COUNT="count 0"
COUNT="count 10000000"
delay="delay 0"

PGDEV=/proc/net/pktgen/eth1
echo "Configuring $PGDEV"
pgset "$COUNT"
pgset "$CLONE_SKB"
pgset "$PKT_SIZE"
pgset "$delay"
pgset "dst 10.10.11.2"
pgset "dst_mac 00:04:23:08:91:dc"

# Time to run
PGDEV=/proc/net/pktgen/pgctrl
echo "Running... ctrl^C to stop"
pgset "start"
echo "Done"

# Result can be vieved in /proc/net/pktgen/eth1
4. 參考來源
https://www.kernel.org/doc/Documentation/networking/pktgen.txt
https://www.kernel.org/doc/ols/2005/ols2005v2-pages-19-32.pdf http://benjr.tw/93300

沒有留言:

張貼留言