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:
8 # http://www.apache.org/licenses/LICENSE-2.0
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.
16 """This script uses T-REX stateless API to drive t-rex instance.
19 - T-REX: https://github.com/cisco-system-traffic-generator/trex-core
20 - compiled and running T-REX process (eg. ./t-rex-64 -i -c 4)
21 - trex_stl_lib.api library
22 - Script must be executed on a node with T-REX instance
23 - 2 interfaces must be configured in configuretion file /etc/trex_cfg.yaml
25 ##################### Example of /etc/trex_cfg.yaml ##########################
26 - port_limit : 2 # numbers of ports to use
28 interfaces : ["84:00.0","84:00.1"] # PCI address of interfaces
29 port_info : # set eth mac addr
30 - dest_mac : [0x90,0xe2,0xba,0x1f,0x97,0xd5] # port 0
31 src_mac : [0x90,0xe2,0xba,0x1f,0x97,0xd4]
32 - dest_mac : [0x90,0xe2,0xba,0x1f,0x97,0xd4] # port 1
33 src_mac : [0x90,0xe2,0xba,0x1f,0x97,0xd5]
34 ##############################################################################
37 1. Configure traffic on running T-REX instance
38 2. Clear statistics on all ports
39 3. Ctart traffic with specified duration
40 4. Print statistics to stdout
46 sys.path.insert(0, "/opt/trex-core-1.91/scripts/automation/trex_control_plane/stl/")
48 from trex_stl_lib.api import *
54 def generate_payload(length):
56 alphabet_size = len(string.letters)
57 for i in range(length):
58 word += string.letters[(i % alphabet_size)]
61 def create_packets(traffic_options, frame_size=64):
64 print "Packet min. size is 64B"
67 fsize_no_fcs = frame_size - 4 # no FCS
69 #p1_src_mac = traffic_options['p1_src_mac']
70 #p1_dst_mac = traffic_options['p1_dst_mac']
71 p1_src_start_ip = traffic_options['p1_src_start_ip']
72 p1_src_end_ip = traffic_options['p1_src_end_ip']
73 p1_dst_start_ip = traffic_options['p1_dst_start_ip']
74 #p1_dst_end_ip = traffic_options['p1_dst_end_ip']
75 #p2_src_mac = traffic_options['p2_src_mac']
76 #p2_dst_mac = traffic_options['p2_dst_mac']
77 p2_src_start_ip = traffic_options['p2_src_start_ip']
78 p2_src_end_ip = traffic_options['p2_src_end_ip']
79 p2_dst_start_ip = traffic_options['p2_dst_start_ip']
80 #p2_dst_end_ip = traffic_options['p2_dst_end_ip']
82 base_pkt_a = Ether()/IP(src=p1_src_start_ip, dst=p1_dst_start_ip)/UDP(dport=12, sport=1025, chksum=0)
83 base_pkt_b = Ether()/IP(src=p2_src_start_ip, dst=p2_dst_start_ip)/UDP(dport=12, sport=1025, chksum=0)
85 vm1 = CTRexScRaw([STLVmTupleGen(ip_min=p1_src_start_ip, ip_max=p1_src_end_ip,
86 name="tuple"), # define tuple gen
88 STLVmWrFlowVar(fv_name="tuple.ip", pkt_offset="IP.src"), # write ip to packet IP.src
89 STLVmFixIpv4(offset="IP"), # fix checksum
91 , split_by_field="tuple") # split to cores base on the tuple generator
93 vm2 = CTRexScRaw([STLVmTupleGen(ip_min=p2_src_start_ip, ip_max=p2_src_end_ip,
94 name="tuple"), # define tuple gen
96 STLVmWrFlowVar(fv_name="tuple.ip", pkt_offset="IP.src"), # write ip to packet IP.src
97 STLVmFixIpv4(offset="IP"), # fix checksum
99 , split_by_field="tuple") # split to cores base on the tuple generator
101 pkt_a = STLPktBuilder(pkt=base_pkt_a/generate_payload(fsize_no_fcs-len(base_pkt_a)), vm=vm1)
102 pkt_b = STLPktBuilder(pkt=base_pkt_b/generate_payload(fsize_no_fcs-len(base_pkt_b)), vm=vm2)
106 def simple_burst(pkt_a, pkt_b, duration=10, rate="1mpps",
107 warmup=True, warmup_time=5):
114 # turn this on for some information
115 #c.set_verbose("high")
118 s1 = STLStream(packet=pkt_a,
119 mode=STLTXCont(pps=100))
121 # second stream with a phase of 10ns (inter stream gap)
122 s2 = STLStream(packet=pkt_b,
124 mode=STLTXCont(pps=100))
130 # prepare our ports (my machine has 0 <--> 1 with static route)
131 c.reset(ports=[0, 1])
133 # add both streams to ports
134 c.add_streams(s1, ports=[0])
135 c.add_streams(s2, ports=[1])
140 c.start(ports=[0, 1], mult=rate, duration=warmup_time)
141 c.wait_on_traffic(ports=[0, 1])
142 stats = c.get_stats()
144 print "#####warmup statistics#####"
145 print json.dumps(stats, indent=4,
146 separators=(',', ': '), sort_keys=True)
147 lost_a = stats[0]["opackets"] - stats[1]["ipackets"]
148 lost_b = stats[1]["opackets"] - stats[0]["ipackets"]
150 print "\npackets lost from 0 --> 1: {0} pkts".format(lost_a)
151 print "packets lost from 1 --> 0: {0} pkts".format(lost_b)
154 # clear the stats before injecting
157 # choose rate and start traffic
158 c.start(ports=[0, 1], mult=rate, duration=duration)
161 c.wait_on_traffic(ports=[0, 1])
163 # read the stats after the test
164 stats = c.get_stats()
166 print "#####statistics#####"
167 print json.dumps(stats, indent=4,
168 separators=(',', ': '), sort_keys=True)
170 lost_a = stats[0]["opackets"] - stats[1]["ipackets"]
171 lost_b = stats[1]["opackets"] - stats[0]["ipackets"]
173 total_sent = stats[0]["opackets"] + stats[1]["opackets"]
174 total_rcvd = stats[0]["ipackets"] + stats[1]["ipackets"]
176 print "\npackets lost from 0 --> 1: {0} pkts".format(lost_a)
177 print "packets lost from 1 --> 0: {0} pkts".format(lost_b)
178 print "rate={0}, totalReceived={1}, totalSent={2}, frameLoss={3}"\
179 .format(rate, total_rcvd, total_sent, lost_a+lost_b)
181 if (lost_a == 0) and (lost_b == 0):
186 except STLError as e:
195 print "args: [-h] -d <duration> -s <size of frame in bytes>"+\
196 " [-r] <traffic rate with unit: %, mpps> "+\
197 "--p1_src_mac <port1_src_mac> "+\
198 "--p1_dst_mac <port1_dst_mac> "+\
199 "--p1_src_start_ip <port1_src_start_ip> "+\
200 "--p1_src_end_ip <port1_src_end_ip> "+\
201 "--p1_dst_start_ip <port1_dst_start_ip> "+\
202 "--p1_dst_end_ip <port1_dst_end_ip> "+\
203 "--p2_src_mac <port2_src_mac> "+\
204 "--p2_dst_mac <port2_dst_mac> "+\
205 "--p2_src_start_ip <port2_src_start_ip> "+\
206 "--p2_src_end_ip <port2_src_end_ip> "+\
207 "--p2_dst_start_ip <port2_dst_start_ip> "+\
208 "--p2_dst_end_ip <port2_dst_end_ip>"
216 _traffic_options = {}
219 opts, args = getopt.getopt(argv, "hd:s:r:o:",
233 except getopt.GetoptError:
236 for opt, arg in opts:
237 if opt in ('-h', "--help"):
243 _frame_size = int(arg)
246 elif opt.startswith("--p"):
247 _traffic_options[opt[2:]] = arg
249 print _traffic_options
250 if len(_traffic_options) != 6:
251 print "Supported only: src_start_ip, src_end_ip, dst_start_ip"
255 pkt_a, pkt_b = create_packets(_traffic_options,
256 frame_size=_frame_size)
258 simple_burst(pkt_a, pkt_b, duration=_duration, rate=_rate)
260 if __name__ == "__main__":