diff options
Diffstat (limited to 'resources/tools/t-rex/t-rex-stateless.py')
-rwxr-xr-x | resources/tools/t-rex/t-rex-stateless.py | 214 |
1 files changed, 129 insertions, 85 deletions
diff --git a/resources/tools/t-rex/t-rex-stateless.py b/resources/tools/t-rex/t-rex-stateless.py index 46c67cc829..d32fd96dd7 100755 --- a/resources/tools/t-rex/t-rex-stateless.py +++ b/resources/tools/t-rex/t-rex-stateless.py @@ -16,7 +16,7 @@ """This script uses T-REX stateless API to drive t-rex instance. Requirements: -- T-REX: https://github.com/cisco-system-traffic-generator/trex-core +- T-REX: https://github.com/cisco-system-traffic-generator/trex-core - compiled and running T-REX process (eg. ./t-rex-64 -i -c 4) - trex_stl_lib.api library - Script must be executed on a node with T-REX instance @@ -26,7 +26,7 @@ Requirements: - port_limit : 2 # numbers of ports to use version : 2 interfaces : ["84:00.0","84:00.1"] # PCI address of interfaces - port_info : # set eth mac addr + port_info : # set eth mac addr - dest_mac : [0x90,0xe2,0xba,0x1f,0x97,0xd5] # port 0 src_mac : [0x90,0xe2,0xba,0x1f,0x97,0xd4] - dest_mac : [0x90,0xe2,0xba,0x1f,0x97,0xd4] # port 1 @@ -41,105 +41,141 @@ Functionality: """ - +import json +import string import sys, getopt -sys.path.insert(0, "/opt/trex-core-1.91/scripts/automation/trex_control_plane/stl/") +sys.path.insert(0, "/opt/trex-core-2.00/scripts/automation/"+\ + "trex_control_plane/stl/") from trex_stl_lib.api import * -import dpkt -import json -import string def generate_payload(length): + """Generate random payload. + + :param length: Length of payload. + :type length: int + :return: Payload filled with random chars. + :rtype string + """ + word = '' alphabet_size = len(string.letters) for i in range(length): word += string.letters[(i % alphabet_size)] + return word def create_packets(traffic_options, frame_size=64): + """Create two IP packets to be used in stream. + + :param traffic_options: Parameters for packets. + :param frame_size: Size of L2 frame. + :type traffic_options: list + :type frame_size: int + :return: Packet instances. + :rtype STLPktBuilder + """ if frame_size < 64: - print "Packet min. size is 64B" - sys.exit(2) + print_error("Packet min. size is 64B") + sys.exit(1) fsize_no_fcs = frame_size - 4 # no FCS - #p1_src_mac = traffic_options['p1_src_mac'] - #p1_dst_mac = traffic_options['p1_dst_mac'] p1_src_start_ip = traffic_options['p1_src_start_ip'] p1_src_end_ip = traffic_options['p1_src_end_ip'] p1_dst_start_ip = traffic_options['p1_dst_start_ip'] - #p1_dst_end_ip = traffic_options['p1_dst_end_ip'] - #p2_src_mac = traffic_options['p2_src_mac'] - #p2_dst_mac = traffic_options['p2_dst_mac'] p2_src_start_ip = traffic_options['p2_src_start_ip'] p2_src_end_ip = traffic_options['p2_src_end_ip'] p2_dst_start_ip = traffic_options['p2_dst_start_ip'] - #p2_dst_end_ip = traffic_options['p2_dst_end_ip'] base_pkt_a = Ether()/IP(src=p1_src_start_ip, dst=p1_dst_start_ip, proto=61) base_pkt_b = Ether()/IP(src=p2_src_start_ip, dst=p2_dst_start_ip, proto=61) - vm1 = CTRexScRaw([STLVmTupleGen(ip_min=p1_src_start_ip, ip_max=p1_src_end_ip, - name="tuple"), # define tuple gen - - STLVmWrFlowVar(fv_name="tuple.ip", pkt_offset="IP.src"), # write ip to packet IP.src - STLVmFixIpv4(offset="IP"), # fix checksum - ] - , split_by_field="tuple") # split to cores base on the tuple generator - - vm2 = CTRexScRaw([STLVmTupleGen(ip_min=p2_src_start_ip, ip_max=p2_src_end_ip, - name="tuple"), # define tuple gen - - STLVmWrFlowVar(fv_name="tuple.ip", pkt_offset="IP.src"), # write ip to packet IP.src - STLVmFixIpv4(offset="IP"), # fix checksum - ] - , split_by_field="tuple") # split to cores base on the tuple generator - - pkt_a = STLPktBuilder(pkt=base_pkt_a/generate_payload(fsize_no_fcs-len(base_pkt_a)), vm=vm1) - pkt_b = STLPktBuilder(pkt=base_pkt_b/generate_payload(fsize_no_fcs-len(base_pkt_b)), vm=vm2) + # The following code applies raw instructions to packet (IP src increment). + # It splits the generated traffic by "ip_src" variable to cores and fix + # IPv4 header checksum. + vm1 = STLScVmRaw([STLVmFlowVar(name="src", + min_value=p1_src_start_ip, + max_value=p1_src_end_ip, + size=4, op="inc"), + STLVmWrFlowVar(fv_name="src", pkt_offset="IP.src"), + STLVmFixIpv4(offset="IP"), + ], split_by_field="src") + + # The following code applies raw instructions to packet (IP src increment). + # It splits the generated traffic by "ip_src" variable to cores and fix + # IPv4 header checksum. + vm2 = STLScVmRaw([STLVmFlowVar(name="src", + min_value=p2_src_start_ip, + max_value=p2_src_end_ip, + size=4, op="inc"), + STLVmWrFlowVar(fv_name="src", pkt_offset="IP.src"), + STLVmFixIpv4(offset="IP"), + ], split_by_field="src") + + pkt_a = STLPktBuilder(pkt=base_pkt_a/generate_payload( + max(0, fsize_no_fcs-len(base_pkt_a))), vm=vm1) + pkt_b = STLPktBuilder(pkt=base_pkt_b/generate_payload( + max(0, fsize_no_fcs-len(base_pkt_b))), vm=vm2) return(pkt_a, pkt_b) -def simple_burst(pkt_a, pkt_b, duration=10, rate="1mpps", - warmup=True, warmup_time=5): +def simple_burst(pkt_a, pkt_b, duration=10, rate="1mpps", warmup_time=5): + """Run the traffic with specific parameters. + + :param pkt_a: Base packet for stream 1. + :param pkt_b: Base packet for stream 2. + :param duration: Duration of traffic run in seconds. + :param rate: Rate of traffic run [percentage, pps, bps]. + :param warmup_time: Warm up duration. + :type pkt_a: STLPktBuilder + :type pkt_b: STLPktBuilder + :type duration: int + :type rate: string + :type warmup_time: int + :return: nothing + """ # create client - c = STLClient() - passed = True + client = STLClient() + + total_rcvd = 0 + total_sent = 0 + lost_a = 0 + lost_b = 0 try: - # turn this on for some information - #c.set_verbose("high") + # turn this off if too many logs + #client.set_verbose("high") # create two streams - s1 = STLStream(packet=pkt_a, - mode=STLTXCont(pps=100)) + stream1 = STLStream(packet=pkt_a, + mode=STLTXCont(pps=100)) # second stream with a phase of 10ns (inter stream gap) - s2 = STLStream(packet=pkt_b, - isg=10.0, - mode=STLTXCont(pps=100)) + stream2 = STLStream(packet=pkt_b, + isg=10.0, + mode=STLTXCont(pps=100)) # connect to server - c.connect() + client.connect() # prepare our ports (my machine has 0 <--> 1 with static route) - c.reset(ports=[0, 1]) + client.reset(ports=[0, 1]) # add both streams to ports - c.add_streams(s1, ports=[0]) - c.add_streams(s2, ports=[1]) + client.add_streams(stream1, ports=[0]) + client.add_streams(stream2, ports=[1]) #warmup phase - if warmup == True: - c.clear_stats() - c.start(ports=[0, 1], mult=rate, duration=warmup_time) - c.wait_on_traffic(ports=[0, 1]) - stats = c.get_stats() + if warmup_time is not None: + client.clear_stats() + client.start(ports=[0, 1], mult=rate, duration=warmup_time) + client.wait_on_traffic(ports=[0, 1], timeout=(duration+30)) + stats = client.get_stats() print stats print "#####warmup statistics#####" print json.dumps(stats, indent=4, @@ -152,16 +188,16 @@ def simple_burst(pkt_a, pkt_b, duration=10, rate="1mpps", # clear the stats before injecting - c.clear_stats() + client.clear_stats() # choose rate and start traffic - c.start(ports=[0, 1], mult=rate, duration=duration) + client.start(ports=[0, 1], mult=rate, duration=duration) # block until done - c.wait_on_traffic(ports=[0, 1], timeout=(duration+30)) + client.wait_on_traffic(ports=[0, 1], timeout=(duration+30)) # read the stats after the test - stats = c.get_stats() + stats = client.get_stats() print "#####statistics#####" print json.dumps(stats, indent=4, @@ -175,22 +211,19 @@ def simple_burst(pkt_a, pkt_b, duration=10, rate="1mpps", print "\npackets lost from 0 --> 1: {0} pkts".format(lost_a) print "packets lost from 1 --> 0: {0} pkts".format(lost_b) - print "rate={0}, totalReceived={1}, totalSent={2}, frameLoss={3}"\ - .format(rate, total_rcvd, total_sent, lost_a+lost_b) - - if (lost_a == 0) and (lost_b == 0): - passed = True - else: - passed = False - except STLError as e: - passed = False - print e + except STLError as ex_error: + print_error(str(ex_error)) + sys.exit(1) finally: - c.disconnect() + client.disconnect() + print "rate={0}, totalReceived={1}, totalSent={2}, frameLoss={3}"\ + .format(rate, total_rcvd, total_sent, lost_a+lost_b) + def print_help(): + """Print help on stdout.""" print "args: [-h] -d <duration> -s <size of frame in bytes>"+\ " [-r] <traffic rate with unit: %, mpps> "+\ @@ -207,8 +240,19 @@ def print_help(): "--p2_dst_start_ip <port2_dst_start_ip> "+\ "--p2_dst_end_ip <port2_dst_end_ip>" +def print_error(msg): + """Print error message on stderr. + + :param msg: Error message to print. + :type msg: string + :return: nothing + """ + + sys.stderr.write(msg+'\n') + def main(argv): + """Main function.""" _duration = 10 _frame_size = 64 @@ -216,23 +260,23 @@ def main(argv): _traffic_options = {} try: - opts, args = getopt.getopt(argv, "hd:s:r:o:", - ["help", - "p1_src_mac=", - "p1_dst_mac=", - "p1_src_start_ip=", - "p1_src_end_ip=", - "p1_dst_start_ip=", - "p1_dst_end_ip=", - "p2_src_mac=", - "p2_dst_mac=", - "p2_src_start_ip=", - "p2_src_end_ip=", - "p2_dst_start_ip=", - "p2_dst_end_ip="]) + opts, _ = getopt.getopt(argv, "hd:s:r:o:", + ["help", + "p1_src_mac=", + "p1_dst_mac=", + "p1_src_start_ip=", + "p1_src_end_ip=", + "p1_dst_start_ip=", + "p1_dst_end_ip=", + "p2_src_mac=", + "p2_dst_mac=", + "p2_src_start_ip=", + "p2_src_end_ip=", + "p2_dst_start_ip=", + "p2_dst_end_ip="]) except getopt.GetoptError: print_help() - sys.exit(2) + sys.exit(1) for opt, arg in opts: if opt in ('-h', "--help"): print_help() @@ -248,9 +292,9 @@ def main(argv): print _traffic_options if len(_traffic_options) != 6: - print "Supported only: src_start_ip, src_end_ip, dst_start_ip" + print_error("Supported only: src_start_ip, src_end_ip, dst_start_ip") print_help() - sys.exit(2) + sys.exit(1) pkt_a, pkt_b = create_packets(_traffic_options, frame_size=_frame_size) |