Removed link-up/link-down from if state setup
[csit.git] / resources / tools / t-rex-stateless-1.88.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 """This script uses T-REX stateless API to drive t-rex process.
17
18 !!! OUTDATED 1.88 T-REX STATELESS API, USE WITH CAUTION !!!
19
20 Requirements:
21 - T-REX: https://github.com/cisco-system-traffic-generator/trex-core 
22  - compiled and running T-REX process (eg. ./t-rex-64 -i -c 4)
23  - trex_stl_lib.api library
24 - Script must be executed on a node with T-REX instance
25 - 2 interfaces must be configured in configuretion file /etc/trex_cfg.yaml
26
27 ##################### Example of /etc/trex_cfg.yaml ##########################
28 - port_limit      : 2 # numbers of ports to use
29   version         : 2
30   interfaces      : ["84:00.0","84:00.1"] # PCI address of interfaces
31   port_info       :  # set eth mac addr 
32           - dest_mac        :   [0x90,0xe2,0xba,0x1f,0x97,0xd5]  # port 0
33             src_mac         :   [0x90,0xe2,0xba,0x1f,0x97,0xd4]
34           - dest_mac        :   [0x90,0xe2,0xba,0x1f,0x97,0xd4]  # port 1
35             src_mac         :   [0x90,0xe2,0xba,0x1f,0x97,0xd5]
36 ##############################################################################
37
38 Functionality:
39 1. Configure traffic on running T-REX instance
40 2. Clear statistics on all ports
41 3. Ctart traffic with specified duration
42 4. Print statistics
43
44 """
45
46
47 import sys, getopt
48 sys.path.insert(0, "/opt/trex-core-1.88/scripts/api/stl/")
49
50 from trex_stl_api import *
51
52 import dpkt
53 import json
54 import string
55
56 def generate_payload(length):
57     word = ''
58     alphabet_size = len(string.letters)
59     for i in range(length):
60         word += string.letters[(i % alphabet_size)]
61     return word
62
63 def create_packets(traffic_options, frame_size=64):
64
65     if frame_size < 64:
66         print "Packet min. size is 64B"
67         sys.exit(2)
68
69     # build A side packet
70     pkt_a = STLPktBuilder()
71
72     pkt_a.add_pkt_layer("l2", dpkt.ethernet.Ethernet())
73     pkt_a.add_pkt_layer("l3_ip", dpkt.ip.IP())
74     pkt_a.add_pkt_layer("l4_udp", dpkt.udp.UDP())
75     pkt_a.set_pkt_payload(generate_payload(frame_size -
76                                            pkt_a.get_packet_length()))
77     pkt_a.set_layer_attr("l3_ip", "len", len(pkt_a.get_layer('l3_ip')))
78
79     # build B side packet
80     pkt_b = pkt_a.clone()
81
82     p1_src_mac = traffic_options['p1_src_mac']
83     p1_dst_mac = traffic_options['p1_dst_mac']
84     p1_src_start_ip = traffic_options['p1_src_start_ip']
85     p1_src_end_ip = traffic_options['p1_src_end_ip']
86     p1_dst_start_ip = traffic_options['p1_dst_start_ip']
87     p1_dst_end_ip = traffic_options['p1_dst_end_ip']
88     p2_src_mac = traffic_options['p2_src_mac']
89     p2_dst_mac = traffic_options['p2_dst_mac']
90     p2_src_start_ip = traffic_options['p2_src_start_ip']
91     p2_src_end_ip = traffic_options['p2_src_end_ip']
92     p2_dst_start_ip = traffic_options['p2_dst_start_ip']
93     p2_dst_end_ip = traffic_options['p2_dst_end_ip']
94
95     pkt_a.set_eth_layer_addr(layer_name="l2",
96                              attr="src",
97                              mac_addr=p1_src_mac)
98     pkt_a.set_eth_layer_addr(layer_name="l2",
99                              attr="dst",
100                              mac_addr=p1_dst_mac)
101     pkt_b.set_eth_layer_addr(layer_name="l2",
102                              attr="src",
103                              mac_addr=p2_src_mac)
104     pkt_b.set_eth_layer_addr(layer_name="l2",
105                              attr="dst",
106                              mac_addr=p2_dst_mac)
107
108     # set IP range for pkt and split it by multiple cores
109     pkt_a.set_vm_ip_range(ip_layer_name="l3_ip",
110                           ip_field="src",
111                           ip_start=p1_src_start_ip, ip_end=p1_src_end_ip,
112                           operation="inc",
113                           split=True)
114
115     pkt_a.set_vm_ip_range(ip_layer_name="l3_ip",
116                           ip_field="dst",
117                           ip_start=p1_dst_start_ip, ip_end=p1_dst_end_ip,
118                           operation="inc")
119
120
121     # build B side packet
122     pkt_b.set_vm_ip_range(ip_layer_name="l3_ip",
123                           ip_field="src",
124                           ip_start=p2_src_start_ip, ip_end=p2_src_end_ip,
125                           operation="inc",
126                           split=True)
127
128     pkt_b.set_vm_ip_range(ip_layer_name="l3_ip",
129                           ip_field="dst",
130                           ip_start=p2_dst_start_ip, ip_end=p2_dst_end_ip,
131                           operation="inc")
132
133     return(pkt_a, pkt_b)
134
135 def simple_burst(pkt_a, pkt_b, duration=10, rate="1mpps",
136                  warmup=True, warmup_time=5):
137
138     # create client
139     c = STLClient()
140     passed = True
141
142     try:
143         # turn this on for some information
144         #c.set_verbose("high")
145
146         # create two streams
147         s1 = STLStream(packet=pkt_a,
148                        mode=STLTXCont(pps=100))
149
150         # second stream with a phase of 1ms (inter stream gap)
151         s2 = STLStream(packet=pkt_b,
152                        isg=1000,
153                        mode=STLTXCont(pps=100))
154
155
156         # connect to server
157         c.connect()
158
159         # prepare our ports (my machine has 0 <--> 1 with static route)
160         c.reset(ports=[0, 1])
161
162         # add both streams to ports
163         c.add_streams(s1, ports=[0])
164         c.add_streams(s2, ports=[1])
165
166         #warmup phase
167         if warmup == True:
168             c.clear_stats()
169             c.start(ports=[0, 1], mult=rate, duration=warmup_time)
170             c.wait_on_traffic(ports=[0, 1])
171             stats = c.get_stats()
172             print "#####warmup statistics#####"
173             print json.dumps(stats["port 0"], indent=4,
174                              separators=(',', ': '), sort_keys=True)
175             print json.dumps(stats["port 1"], indent=4,
176                              separators=(',', ': '), sort_keys=True)
177             lost_a = stats["port 0"]["opackets"] - stats["port 1"]["ipackets"]
178             lost_b = stats["port 1"]["opackets"] - stats["port 0"]["ipackets"]
179
180             print "\npackets lost from 0 --> 1:   {0} pkts".format(lost_a)
181             print "packets lost from 1 --> 0:   {0} pkts".format(lost_b)
182
183
184         # clear the stats before injecting
185         c.clear_stats()
186
187         # choose rate and start traffic
188         c.start(ports=[0, 1], mult=rate, duration=duration)
189
190         # block until done
191         c.wait_on_traffic(ports=[0, 1])
192
193         # read the stats after the test
194         stats = c.get_stats()
195
196         print "#####statistics#####"
197         print json.dumps(stats["port 0"], indent=4,
198                          separators=(',', ': '), sort_keys=True)
199         print json.dumps(stats["port 1"], indent=4,
200                          separators=(',', ': '), sort_keys=True)
201
202         lost_a = stats["port 0"]["opackets"] - stats["port 1"]["ipackets"]
203         lost_b = stats["port 1"]["opackets"] - stats["port 0"]["ipackets"]
204
205         total_sent = stats["port 0"]["opackets"] + stats["port 1"]["opackets"]
206         total_rcvd = stats["port 0"]["ipackets"] + stats["port 1"]["ipackets"]
207
208         print "\npackets lost from 0 --> 1:   {0} pkts".format(lost_a)
209         print "packets lost from 1 --> 0:   {0} pkts".format(lost_b)
210         print "rate={0}, totalReceived={1}, totalSent={2}, frameLoss={3}"\
211               .format(rate, total_rcvd, total_sent, lost_a+lost_b)
212
213         if (lost_a == 0) and (lost_b == 0):
214             passed = True
215         else:
216             passed = False
217
218     except STLError as e:
219         passed = False
220         print e
221
222     finally:
223         c.disconnect()
224
225 def print_help():
226
227     print "args: [-h] -d <duration> -s <size of frame in bytes>"+\
228     " [-r] <traffic rate with unit: %, mpps> "+\
229     "--p1_src_mac <port1_src_mac> "+\
230     "--p1_dst_mac <port1_dst_mac> "+\
231     "--p1_src_start_ip <port1_src_start_ip> "+\
232     "--p1_src_end_ip <port1_src_end_ip> "+\
233     "--p1_dst_start_ip <port1_dst_start_ip> "+\
234     "--p1_dst_end_ip <port1_dst_end_ip> "+\
235     "--p2_src_mac <port2_src_mac> "+\
236     "--p2_dst_mac <port2_dst_mac> "+\
237     "--p2_src_start_ip <port2_src_start_ip> "+\
238     "--p2_src_end_ip <port2_src_end_ip> "+\
239     "--p2_dst_start_ip <port2_dst_start_ip> "+\
240     "--p2_dst_end_ip <port2_dst_end_ip>"
241
242
243 def main(argv):
244
245     _duration = 10
246     _frame_size = 64
247     _rate = '1mpps'
248     _traffic_options = {}
249
250     try:
251         opts, args = getopt.getopt(argv, "hd:s:r:o:",
252                                    ["help",
253                                     "p1_src_mac=",
254                                     "p1_dst_mac=",
255                                     "p1_src_start_ip=",
256                                     "p1_src_end_ip=",
257                                     "p1_dst_start_ip=",
258                                     "p1_dst_end_ip=",
259                                     "p2_src_mac=",
260                                     "p2_dst_mac=",
261                                     "p2_src_start_ip=",
262                                     "p2_src_end_ip=",
263                                     "p2_dst_start_ip=",
264                                     "p2_dst_end_ip="])
265     except getopt.GetoptError:
266         print_help()
267         sys.exit(2)
268     for opt, arg in opts:
269         if opt in ('-h', "--help"):
270             print_help()
271             sys.exit()
272         elif opt == '-d':
273             _duration = int(arg)
274         elif opt == '-s':
275             _frame_size = int(arg)
276         elif opt == '-r':
277             _rate = arg
278         elif opt.startswith( "--p" ):
279             _traffic_options[opt[2:]] = arg
280
281     print _traffic_options
282     if len(_traffic_options) != 12:
283         print "Expected all 12 traffic options"
284         print_help()
285         sys.exit(2)
286
287     pkt_a, pkt_b = create_packets(_traffic_options,
288                                   frame_size=_frame_size)
289
290     simple_burst(pkt_a, pkt_b, duration=_duration, rate=_rate)
291
292 if __name__ == "__main__":
293     main(sys.argv[1:])
294