Merge "run_traffic: capture and exit gracefully if crash in trex run_traffic"
[yardstick.git] / yardstick / benchmark / scenarios / networking / pktgen_benchmark.bash
1 #!/bin/sh
2
3 ##############################################################################
4 # Copyright (c) 2015 Ericsson AB and others.
5 #
6 # All rights reserved. This program and the accompanying materials
7 # are made available under the terms of the Apache License, Version 2.0
8 # which accompanies this distribution, and is available at
9 # http://www.apache.org/licenses/LICENSE-2.0
10 ##############################################################################
11
12 set -e
13
14 # Commandline arguments
15 DST_IP=$1         # destination IP address
16 NUM_PORTS=$2      # number of source ports
17 PKT_SIZE=$3       # packet size
18 DURATION=$4       # test duration (seconds)
19 TRXQUEUE=$5       # number of RX/TX queues to use
20 PPS=$6            # packets per second to send
21
22 # Configuration
23 UDP_SRC_MIN=1000                               # UDP source port min
24 UDP_SRC_MAX=$(( UDP_SRC_MIN + NUM_PORTS - 1 )) # UDP source port max
25 UDP_DST_MIN=1000                               # UDP destination port min
26 UDP_DST_MAX=$(( UDP_DST_MIN + NUM_PORTS ))     # UDP destination port max
27
28 # helper function to send commands to pktgen
29 pgset()
30 {
31     local result
32
33     echo $1 > $PGDEV
34
35     result=$(cat $PGDEV | fgrep "Result: OK:")
36     if [ "$result" = "" ]; then
37         cat $PGDEV | fgrep "Result:" >/dev/stderr
38         exit 1
39     fi
40 }
41
42 # remove all devices from thread
43 pgclean()
44 {
45     COUNTER=0
46     while [ ${COUNTER} -lt ${TRXQUEUE} ]; do
47         #
48         # Thread commands
49         #
50
51         PGDEV=/proc/net/pktgen/kpktgend_${COUNTER}
52
53         # Remove all devices from this thread
54         pgset "rem_device_all"
55         let COUNTER=COUNTER+1
56     done
57 }
58
59 # configure pktgen (see pktgen doc for details)
60 pgconfig()
61 {
62     pps=$(( PPS / TRXQUEUE ))
63     COUNTER=0
64     while [ ${COUNTER} -lt ${TRXQUEUE} ]; do
65         #
66         # Thread commands
67         #
68
69         PGDEV=/proc/net/pktgen/kpktgend_${COUNTER}
70
71         # Add device to thread
72         pgset "add_device $DEV@${COUNTER}"
73
74         #
75         # Device commands
76         #
77
78         PGDEV=/proc/net/pktgen/$DEV@${COUNTER}
79
80         # 0 means continious sends untill explicitly stopped
81         pgset "count 0"
82
83         # set pps count to test with an explicit number. if 0 will try with bandwidth
84         if [ ${pps} -gt 0 ]
85         then
86             pgset "ratep ${pps}"
87         fi
88
89         pgset "clone_skb 10"
90
91         # use different queue per thread
92         pgset "queue_map_min ${COUNTER}"
93         pgset "queue_map_max ${COUNTER}"
94
95         # packet size, NIC adds 4 bytes CRC
96         pgset "pkt_size $PKT_SIZE"
97
98         # random address within the min-max range
99         pgset "flag UDPDST_RND"
100         pgset "flag UDPSRC_RND"
101         pgset "flag IPDST_RND"
102
103         # destination IP
104         pgset "dst_min $DST_IP"
105         pgset "dst_max $DST_IP"
106
107         # destination MAC address
108         pgset "dst_mac $MAC"
109
110         # source UDP port range
111         pgset "udp_src_min $UDP_SRC_MIN"
112         pgset "udp_src_max $UDP_SRC_MAX"
113
114         # destination UDP port range
115         pgset "udp_dst_min $UDP_DST_MIN"
116         pgset "udp_dst_max $UDP_DST_MAX"
117
118         let COUNTER=COUNTER+1
119
120     done
121 }
122
123 # run pktgen
124 pgrun()
125 {
126     # Time to run, result can be viewed in /proc/net/pktgen/$DEV
127     PGDEV=/proc/net/pktgen/pgctrl
128     # Will hang, Ctrl-C or SIGINT to stop
129     pgset "start" start
130
131     COUNTER=0
132     while [ ${COUNTER} -lt ${TRXQUEUE} ]; do
133         taskset -c ${COUNTER} kpktgend_${COUNTER}
134         let COUNTER=COUNTER+1
135     done
136 }
137
138 # run pktgen for ${DURATION} seconds
139 run_test()
140 {
141     pgrun &
142     pid=$!
143
144     sleep $DURATION
145
146     kill -INT $pid
147
148     wait; sleep 1
149 }
150
151 # write the result to stdout in json format
152 output_json()
153 {
154     sent=0
155     result_pps=0
156     errors=0
157     PGDEV=/proc/net/pktgen/$DEV@
158     COUNTER=0
159     while [ ${COUNTER} -lt ${TRXQUEUE} ]; do
160         sent=$(($sent + $(awk '/^Result:/{print $5}' <$PGDEV${COUNTER})))
161         result_pps=$(($result_pps + $(awk 'match($0,/'\([0-9]+\)pps'/, a) {print a[1]}' <$PGDEV${COUNTER})))
162         errors=$(($errors + $(awk '/errors:/{print $5}' <$PGDEV${COUNTER})))
163         let COUNTER=COUNTER+1
164     done
165
166     flows=$(( NUM_PORTS * (NUM_PORTS + 1) ))
167
168     echo '{ "packets_sent"':${sent} , '"packets_per_second"':${result_pps}, '"flows"':${flows}, '"errors"':${errors} '}'
169 }
170
171 # main entry
172 main()
173 {
174     modprobe pktgen
175     pgclean
176
177     ping -c 3 $DST_IP >/dev/null
178
179     # destination MAC address
180     MAC=`arp -n | grep -w $DST_IP | awk '{print $3}'`
181
182     # outgoing interface
183     DEV=`arp -n | grep -w $DST_IP | awk '{print $5}'`
184
185     # setup the test
186     pgconfig
187
188     # run the test
189     run_test
190
191     PGDEV=/proc/net/pktgen/$DEV@
192
193     # check result
194     COUNTER=0
195     while [  ${COUNTER} -lt ${TRXQUEUE} ]; do
196         result=$(cat $PGDEV${COUNTER} | fgrep "Result: OK:")
197         if [ "$result" = "" ]; then
198             cat $PGDEV${COUNTER} | fgrep Result: >/dev/stderr
199             exit 1
200         fi
201         let COUNTER=COUNTER+1
202     done
203
204     # output result
205     output_json
206 }
207
208 main
209