Last bulk update of CSIT.
[csit.git] / resources / tools / t-rex-stateless.py
1 #!/usr/bin/python
2
3 # Copyright (c) 2016 Cisco and/or its affiliates.
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at:
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16
17 import sys, getopt
18 sys.path.insert(0, "/opt/trex-core-1.88/scripts/api/stl/")
19
20 from trex_stl_api import *
21
22 import dpkt
23 import json
24 import string
25
26 def generate_payload(length):
27     word = ''
28     alphabet_size = len(string.letters)
29     for i in range(length):
30         word += string.letters[(i % alphabet_size)]
31     return word
32
33 def create_packets(traffic_options, frame_size=64):
34
35     if frame_size < 64:
36         print "Packet min. size is 64B"
37         sys.exit(2)
38
39     # build A side packet
40     pkt_a = STLPktBuilder()
41
42     pkt_a.add_pkt_layer("l2", dpkt.ethernet.Ethernet())
43     pkt_a.add_pkt_layer("l3_ip", dpkt.ip.IP())
44     pkt_a.add_pkt_layer("l4_udp", dpkt.udp.UDP())
45     pkt_a.set_pkt_payload(generate_payload(frame_size -
46                                            pkt_a.get_packet_length()))
47     pkt_a.set_layer_attr("l3_ip", "len", len(pkt_a.get_layer('l3_ip')))
48
49     # build B side packet
50     pkt_b = pkt_a.clone()
51
52     p1_src_mac = traffic_options['p1_src_mac']
53     p1_dst_mac = traffic_options['p1_dst_mac']
54     p1_src_start_ip = traffic_options['p1_src_start_ip']
55     p1_src_end_ip = traffic_options['p1_src_end_ip']
56     p1_dst_start_ip = traffic_options['p1_dst_start_ip']
57     p1_dst_end_ip = traffic_options['p1_dst_end_ip']
58     p2_src_mac = traffic_options['p2_src_mac']
59     p2_dst_mac = traffic_options['p2_dst_mac']
60     p2_src_start_ip = traffic_options['p2_src_start_ip']
61     p2_src_end_ip = traffic_options['p2_src_end_ip']
62     p2_dst_start_ip = traffic_options['p2_dst_start_ip']
63     p2_dst_end_ip = traffic_options['p2_dst_end_ip']
64
65     pkt_a.set_eth_layer_addr(layer_name="l2",
66                              attr="src",
67                              mac_addr=p1_src_mac)
68     pkt_a.set_eth_layer_addr(layer_name="l2",
69                              attr="dst",
70                              mac_addr=p1_dst_mac)
71     pkt_b.set_eth_layer_addr(layer_name="l2",
72                              attr="src",
73                              mac_addr=p2_src_mac)
74     pkt_b.set_eth_layer_addr(layer_name="l2",
75                              attr="dst",
76                              mac_addr=p2_dst_mac)
77
78     # set IP range for pkt and split it by multiple cores
79     pkt_a.set_vm_ip_range(ip_layer_name="l3_ip",
80                           ip_field="src",
81                           ip_start=p1_src_start_ip, ip_end=p1_src_end_ip,
82                           operation="inc",
83                           split=True)
84
85     pkt_a.set_vm_ip_range(ip_layer_name="l3_ip",
86                           ip_field="dst",
87                           ip_start=p1_dst_start_ip, ip_end=p1_dst_end_ip,
88                           operation="inc")
89
90
91     # build B side packet
92     pkt_b.set_vm_ip_range(ip_layer_name="l3_ip",
93                           ip_field="src",
94                           ip_start=p2_src_start_ip, ip_end=p2_src_end_ip,
95                           operation="inc",
96                           split=True)
97
98     pkt_b.set_vm_ip_range(ip_layer_name="l3_ip",
99                           ip_field="dst",
100                           ip_start=p2_dst_start_ip, ip_end=p2_dst_end_ip,
101                           operation="inc")
102
103     return(pkt_a, pkt_b)
104
105 def simple_burst(pkt_a, pkt_b, duration=10, rate="1mpps",
106                  warmup=True, warmup_time=5):
107
108     # create client
109     c = STLClient()
110     passed = True
111
112     try:
113         # turn this on for some information
114         #c.set_verbose("high")
115
116         # create two streams
117         s1 = STLStream(packet=pkt_a,
118                        mode=STLTXCont(pps=100))
119
120         # second stream with a phase of 1ms (inter stream gap)
121         s2 = STLStream(packet=pkt_b,
122                        isg=1000,
123                        mode=STLTXCont(pps=100))
124
125
126         # connect to server
127         c.connect()
128
129         # prepare our ports (my machine has 0 <--> 1 with static route)
130         c.reset(ports=[0, 1])
131
132         # add both streams to ports
133         c.add_streams(s1, ports=[0])
134         c.add_streams(s2, ports=[1])
135
136         #warmup phase
137         if warmup == True:
138             c.clear_stats()
139             c.start(ports=[0, 1], mult=rate, duration=warmup_time)
140             c.wait_on_traffic(ports=[0, 1])
141             stats = c.get_stats()
142             print "#####warmup statistics#####"
143             print json.dumps(stats["port 0"], indent=4,
144                              separators=(',', ': '), sort_keys=True)
145             print json.dumps(stats["port 1"], indent=4,
146                              separators=(',', ': '), sort_keys=True)
147             lost_a = stats["port 0"]["opackets"] - stats["port 1"]["ipackets"]
148             lost_b = stats["port 1"]["opackets"] - stats["port 0"]["ipackets"]
149
150             print "\npackets lost from 0 --> 1:   {0} pkts".format(lost_a)
151             print "packets lost from 1 --> 0:   {0} pkts".format(lost_b)
152
153
154         # clear the stats before injecting
155         c.clear_stats()
156
157         # choose rate and start traffic
158         c.start(ports=[0, 1], mult=rate, duration=duration)
159
160         # block until done
161         c.wait_on_traffic(ports=[0, 1])
162
163         # read the stats after the test
164         stats = c.get_stats()
165
166         print "#####statistics#####"
167         print json.dumps(stats["port 0"], indent=4,
168                          separators=(',', ': '), sort_keys=True)
169         print json.dumps(stats["port 1"], indent=4,
170                          separators=(',', ': '), sort_keys=True)
171
172         lost_a = stats["port 0"]["opackets"] - stats["port 1"]["ipackets"]
173         lost_b = stats["port 1"]["opackets"] - stats["port 0"]["ipackets"]
174
175         total_sent = stats["port 0"]["opackets"] + stats["port 1"]["opackets"]
176         total_rcvd = stats["port 0"]["ipackets"] + stats["port 1"]["ipackets"]
177
178         print "\npackets lost from 0 --> 1:   {0} pkts".format(lost_a)
179         print "packets lost from 1 --> 0:   {0} pkts".format(lost_b)
180         print "rate={0}, totalReceived={1}, totalSent={2}, frameLoss={3}"\
181               .format(rate, total_rcvd, total_sent, lost_a+lost_b)
182
183         if (lost_a == 0) and (lost_b == 0):
184             passed = True
185         else:
186             passed = False
187
188     except STLError as e:
189         passed = False
190         print e
191
192     finally:
193         c.disconnect()
194
195 def print_help():
196
197     print "args: [-h] -d <duration> -s <size of frame in bytes>"+\
198     " [-r] <traffic rate with unit: %, mpps> "+\
199     "--p1_src_mac <port1_src_mac> "+\
200     "--p1_dst_mac <port1_dst_mac> "+\
201     "--p1_src_start_ip <port1_src_start_ip> "+\
202     "--p1_src_end_ip <port1_src_end_ip> "+\
203     "--p1_dst_start_ip <port1_dst_start_ip> "+\
204     "--p1_dst_end_ip <port1_dst_end_ip> "+\
205     "--p2_src_mac <port2_src_mac> "+\
206     "--p2_dst_mac <port2_dst_mac> "+\
207     "--p2_src_start_ip <port2_src_start_ip> "+\
208     "--p2_src_end_ip <port2_src_end_ip> "+\
209     "--p2_dst_start_ip <port2_dst_start_ip> "+\
210     "--p2_dst_end_ip <port2_dst_end_ip>"
211
212
213 def main(argv):
214
215     _duration = 10
216     _frame_size = 64
217     _rate = '1mpps'
218     _traffic_options = {}
219
220     try:
221         opts, args = getopt.getopt(argv, "hd:s:r:o:",
222                                    ["help",
223                                     "p1_src_mac=",
224                                     "p1_dst_mac=",
225                                     "p1_src_start_ip=",
226                                     "p1_src_end_ip=",
227                                     "p1_dst_start_ip=",
228                                     "p1_dst_end_ip=",
229                                     "p2_src_mac=",
230                                     "p2_dst_mac=",
231                                     "p2_src_start_ip=",
232                                     "p2_src_end_ip=",
233                                     "p2_dst_start_ip=",
234                                     "p2_dst_end_ip="])
235     except getopt.GetoptError:
236         print_help()
237         sys.exit(2)
238     for opt, arg in opts:
239         if opt in ('-h', "--help"):
240             print_help()
241             sys.exit()
242         elif opt == '-d':
243             _duration = int(arg)
244         elif opt == '-s':
245             _frame_size = int(arg)
246         elif opt == '-r':
247             _rate = arg
248         elif opt.startswith( "--p" ):
249             _traffic_options[opt[2:]] = arg
250
251     print _traffic_options
252     if len(_traffic_options) != 12:
253         print "Expected all 12 traffic options"
254         print_help()
255         sys.exit(2)
256
257     pkt_a, pkt_b = create_packets(_traffic_options,
258                                   frame_size=_frame_size)
259
260     simple_burst(pkt_a, pkt_b, duration=_duration, rate=_rate)
261
262 if __name__ == "__main__":
263     main(sys.argv[1:])
264