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 process.
18 !!! OUTDATED 1.88 T-REX STATELESS API, USE WITH CAUTION !!!
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
27 ##################### Example of /etc/trex_cfg.yaml ##########################
28 - port_limit : 2 # numbers of ports to use
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 ##############################################################################
39 1. Configure traffic on running T-REX instance
40 2. Clear statistics on all ports
41 3. Ctart traffic with specified duration
48 sys.path.insert(0, "/opt/trex-core-1.88/scripts/api/stl/")
50 from trex_stl_api import *
56 def generate_payload(length):
58 alphabet_size = len(string.letters)
59 for i in range(length):
60 word += string.letters[(i % alphabet_size)]
63 def create_packets(traffic_options, frame_size=64):
66 print "Packet min. size is 64B"
70 pkt_a = STLPktBuilder()
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')))
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']
95 pkt_a.set_eth_layer_addr(layer_name="l2",
98 pkt_a.set_eth_layer_addr(layer_name="l2",
101 pkt_b.set_eth_layer_addr(layer_name="l2",
104 pkt_b.set_eth_layer_addr(layer_name="l2",
108 # set IP range for pkt and split it by multiple cores
109 pkt_a.set_vm_ip_range(ip_layer_name="l3_ip",
111 ip_start=p1_src_start_ip, ip_end=p1_src_end_ip,
115 pkt_a.set_vm_ip_range(ip_layer_name="l3_ip",
117 ip_start=p1_dst_start_ip, ip_end=p1_dst_end_ip,
121 # build B side packet
122 pkt_b.set_vm_ip_range(ip_layer_name="l3_ip",
124 ip_start=p2_src_start_ip, ip_end=p2_src_end_ip,
128 pkt_b.set_vm_ip_range(ip_layer_name="l3_ip",
130 ip_start=p2_dst_start_ip, ip_end=p2_dst_end_ip,
135 def simple_burst(pkt_a, pkt_b, duration=10, rate="1mpps",
136 warmup=True, warmup_time=5):
143 # turn this on for some information
144 #c.set_verbose("high")
147 s1 = STLStream(packet=pkt_a,
148 mode=STLTXCont(pps=100))
150 # second stream with a phase of 1ms (inter stream gap)
151 s2 = STLStream(packet=pkt_b,
153 mode=STLTXCont(pps=100))
159 # prepare our ports (my machine has 0 <--> 1 with static route)
160 c.reset(ports=[0, 1])
162 # add both streams to ports
163 c.add_streams(s1, ports=[0])
164 c.add_streams(s2, ports=[1])
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"]
180 print "\npackets lost from 0 --> 1: {0} pkts".format(lost_a)
181 print "packets lost from 1 --> 0: {0} pkts".format(lost_b)
184 # clear the stats before injecting
187 # choose rate and start traffic
188 c.start(ports=[0, 1], mult=rate, duration=duration)
191 c.wait_on_traffic(ports=[0, 1])
193 # read the stats after the test
194 stats = c.get_stats()
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)
202 lost_a = stats["port 0"]["opackets"] - stats["port 1"]["ipackets"]
203 lost_b = stats["port 1"]["opackets"] - stats["port 0"]["ipackets"]
205 total_sent = stats["port 0"]["opackets"] + stats["port 1"]["opackets"]
206 total_rcvd = stats["port 0"]["ipackets"] + stats["port 1"]["ipackets"]
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)
213 if (lost_a == 0) and (lost_b == 0):
218 except STLError as e:
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>"
248 _traffic_options = {}
251 opts, args = getopt.getopt(argv, "hd:s:r:o:",
265 except getopt.GetoptError:
268 for opt, arg in opts:
269 if opt in ('-h', "--help"):
275 _frame_size = int(arg)
278 elif opt.startswith( "--p" ):
279 _traffic_options[opt[2:]] = arg
281 print _traffic_options
282 if len(_traffic_options) != 12:
283 print "Expected all 12 traffic options"
287 pkt_a, pkt_b = create_packets(_traffic_options,
288 frame_size=_frame_size)
290 simple_burst(pkt_a, pkt_b, duration=_duration, rate=_rate)
292 if __name__ == "__main__":