From 0f03cc467be9c0b37310b7e2a589a86a1771c96f Mon Sep 17 00:00:00 2001 From: Yaroslav Brustinov Date: Wed, 10 Feb 2016 16:32:54 +0200 Subject: update hltapi + functional regression + remove old packet_builder tests --- scripts/automation/regression/hltapi_example.py | 61 ++- scripts/automation/regression/outer_packages.py | 2 + .../functional_tests/hltapi_stream_builder_test.py | 33 +- .../functional_tests/payload_gen_test.py | 125 ------ .../functional_tests/pkt_builder_test.py | 442 --------------------- .../unit_tests/functional_tests/vm_test.py | 77 ---- .../functional_tests/vm_variable_test.py | 63 --- .../trex_control_plane/client/trex_hltapi.py | 392 +++++++++++++----- .../client_utils/general_utils.py | 6 +- .../stl/trex_stl_lib/trex_stl_port.py | 4 +- .../stl/trex_stl_lib/trex_stl_streams.py | 14 +- 11 files changed, 377 insertions(+), 842 deletions(-) delete mode 100755 scripts/automation/regression/unit_tests/functional_tests/payload_gen_test.py delete mode 100755 scripts/automation/regression/unit_tests/functional_tests/pkt_builder_test.py delete mode 100755 scripts/automation/regression/unit_tests/functional_tests/vm_test.py delete mode 100755 scripts/automation/regression/unit_tests/functional_tests/vm_variable_test.py (limited to 'scripts') diff --git a/scripts/automation/regression/hltapi_example.py b/scripts/automation/regression/hltapi_example.py index 0040219a..9e69cb13 100755 --- a/scripts/automation/regression/hltapi_example.py +++ b/scripts/automation/regression/hltapi_example.py @@ -1,25 +1,25 @@ #!/router/bin/python import outer_packages -from client.trex_hltapi import CTRexHltApi +from client.trex_hltapi import CTRexHltApi, CStreamsPerPort import traceback import sys, time from pprint import pprint import argparse +def error(err = None): + if not err: + raise Exception('Unknown exception, look traceback') + if type(err) is str and not err.startswith('[ERR]'): + err = '[ERR] ' + err + print err + sys.exit(1) + def check_res(res): if res['status'] == 0: - print('Encountered error:\n%s' % res['log']) - sys.exit(1) + error('Encountered error:\n%s' % res['log']) return res -def save_streams_id(res, streams_id_arr): - stream_id = res.get('stream_id') - if type(stream_id) in (int, long): - streams_id_arr.append(stream_id) - elif type(stream_id) is list: - streams_id_arr.extend(stream_id) - def print_brief_stats(res): title_str = ' '*3 tx_str = 'TX:' @@ -48,37 +48,66 @@ if __name__ == "__main__": parser.add_argument('--device', dest = 'device', default = 'localhost', help='Address of TRex server') args = parser.parse_args() hlt_client = CTRexHltApi(verbose = int(args.verbose)) - streams_id_arr = [] - + print('Connecting to %s...' % args.device) res = check_res(hlt_client.connect(device = args.device, port_list = [0, 1], username = 'danklei', break_locks = True, reset = True)) port_handle = res['port_handle'] - print('Connected.') + print('Connected, got port handles %s' % port_handle) + ports_streams_dict = CStreamsPerPort(port_handle) + + print('Imix should create 3 streams (forth ratio is 0)') + res = check_res(hlt_client.traffic_config(mode = 'create', l2_encap = 'ethernet_ii_vlan', bidirectional = True, length_mode = 'imix', + port_handle = port_handle, save_to_yaml = '/tmp/d1.yaml')) + ports_streams_dict.add_streams_from_res(res) + + #print ports_streams_dict + #print hlt_client.trex_client._STLClient__get_all_streams(port_id = port_handle[0]) + res = check_res(hlt_client.traffic_config(mode = 'modify', port_handle = port_handle[0], stream_id = ports_streams_dict[0][0], + mac_src = '1-2-3:4:5:6', l4_protocol = 'udp', save_to_yaml = '/tmp/d2.yaml')) + #print hlt_client.trex_client._STLClient__get_all_streams(port_id = port_handle[0]) + #print hlt_client._streams_history + res = check_res(hlt_client.traffic_config(mode = 'modify', port_handle = port_handle[0], stream_id = ports_streams_dict[0][0], + mac_dst = '{ 7 7 7-7:7:7}', save_to_yaml = '/tmp/d3.yaml')) + #print hlt_client.trex_client._STLClient__get_all_streams(port_id = port_handle[0]) + check_res(hlt_client.traffic_config(mode = 'reset', port_handle = port_handle)) + + res = check_res(hlt_client.traffic_config(mode = 'create', bidirectional = True, length_mode = 'fixed', port_handle = port_handle, + transmit_mode = 'single_burst', pkts_per_burst = 100, rate_pps = 100, + mac_src = '1-2-3-4-5-6', + mac_dst = '6:5:4:4:5:6', + save_to_yaml = '/tmp/imix.yaml')) + ports_streams_dict.add_streams_from_res(res) print('Create single_burst 100 packets rate_pps=100 on port 0') - res = check_res(hlt_client.traffic_config(mode = 'create', port_handle = port_handle[0], transmit_mode = 'single_burst', pkts_per_burst = 100, rate_pps = 100)) - #save_streams_id(res, streams_id_arr) + res = check_res(hlt_client.traffic_config(mode = 'create', port_handle = port_handle[0], transmit_mode = 'single_burst', + pkts_per_burst = 100, rate_pps = 100)) + ports_streams_dict.add_streams_from_res(res) # playground - creating various streams on port 1 res = check_res(hlt_client.traffic_config(mode = 'create', port_handle = port_handle[1], save_to_yaml = '/tmp/hlt2.yaml', tcp_src_port_mode = 'decrement', tcp_src_port_count = 10, tcp_dst_port_count = 10, tcp_dst_port_mode = 'random')) + ports_streams_dict.add_streams_from_res(res) res = check_res(hlt_client.traffic_config(mode = 'create', port_handle = port_handle[1], save_to_yaml = '/tmp/hlt3.yaml', l4_protocol = 'udp', udp_src_port_mode = 'decrement', udp_src_port_count = 10, udp_dst_port_count = 10, udp_dst_port_mode = 'random')) + ports_streams_dict.add_streams_from_res(res) res = check_res(hlt_client.traffic_config(mode = 'create', port_handle = port_handle[1], save_to_yaml = '/tmp/hlt4.yaml', length_mode = 'increment', #ip_src_addr = '192.168.1.1', ip_src_mode = 'increment', ip_src_count = 5, ip_dst_addr = '5.5.5.5', ip_dst_mode = 'random', ip_dst_count = 2)) + ports_streams_dict.add_streams_from_res(res) res = check_res(hlt_client.traffic_config(mode = 'create', port_handle = port_handle[1], save_to_yaml = '/tmp/hlt5.yaml', length_mode = 'decrement', frame_size_min = 100, frame_size_max = 3000, #ip_src_addr = '192.168.1.1', ip_src_mode = 'increment', ip_src_count = 5, #ip_dst_addr = '5.5.5.5', ip_dst_mode = 'random', ip_dst_count = 2 )) + ports_streams_dict.add_streams_from_res(res) + # remove the playground check_res(hlt_client.traffic_config(mode = 'reset', port_handle = port_handle[1])) @@ -99,7 +128,7 @@ if __name__ == "__main__": check_res(hlt_client.traffic_control(action = 'stop', port_handle = port_handle[0])) check_res(hlt_client.traffic_config(mode = 'reset', port_handle = port_handle[0])) res = check_res(hlt_client.traffic_config(mode = 'create', port_handle = port_handle[0], rate_pps = 1000)) - save_streams_id(res, streams_id_arr) + ports_streams_dict.add_streams_from_res(res) check_res(hlt_client.traffic_control(action = 'run', port_handle = port_handle[0])) wait_with_progress(5) print('Sample after another 5 seconds (only packets count)') diff --git a/scripts/automation/regression/outer_packages.py b/scripts/automation/regression/outer_packages.py index 05bedc71..6b7c58f9 100755 --- a/scripts/automation/regression/outer_packages.py +++ b/scripts/automation/regression/outer_packages.py @@ -9,6 +9,7 @@ if not TREX_PATH or not os.path.isfile('%s/trex_daemon_server' % TREX_PATH): TREX_PATH = os.path.abspath(os.path.join(CURRENT_PATH, os.pardir, os.pardir)) PATH_TO_PYTHON_LIB = os.path.abspath(os.path.join(TREX_PATH, 'external_libs')) PATH_TO_CTRL_PLANE = os.path.abspath(os.path.join(TREX_PATH, 'automation', 'trex_control_plane')) +PATH_STL_API = os.path.abspath(os.path.join(PATH_TO_CTRL_PLANE, 'stl')) NIGHTLY_MODULES = ['enum34-1.0.4', 'nose-1.3.4', @@ -22,6 +23,7 @@ NIGHTLY_MODULES = ['enum34-1.0.4', def import_nightly_modules (): sys.path.append(TREX_PATH) sys.path.append(PATH_TO_CTRL_PLANE) + sys.path.append(PATH_STL_API) import_module_list(NIGHTLY_MODULES) def import_module_list (modules_list): diff --git a/scripts/automation/regression/unit_tests/functional_tests/hltapi_stream_builder_test.py b/scripts/automation/regression/unit_tests/functional_tests/hltapi_stream_builder_test.py index eefa1947..f79f54fc 100755 --- a/scripts/automation/regression/unit_tests/functional_tests/hltapi_stream_builder_test.py +++ b/scripts/automation/regression/unit_tests/functional_tests/hltapi_stream_builder_test.py @@ -1,10 +1,10 @@ #!/router/bin/python -from client.trex_hltapi import CTRexHltApiPktBuilder +from stl.trex_stl_lib.api import * import os import unittest -gen_stream = CTRexHltApiPktBuilder.generate_stream +gen_stream = CTRexHltApiBuilder.generate_stream def compare_yamls(yaml1, yaml2): if type(yaml1) is not str: @@ -29,8 +29,8 @@ class CTRexHltApi_Test(unittest.TestCase): # Eth/IP/TCP, all values default, no VM instructions def test_default(self): - test_stream = gen_stream() - self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location(), test_stream) + test_stream = gen_stream(name = 'stream-0') + self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location()) self.golden_yaml = ''' - name: stream-0 stream: @@ -57,8 +57,9 @@ class CTRexHltApi_Test(unittest.TestCase): ip_src_count = 5, ip_dst_addr = '5.5.5.5', ip_dst_count = 2, - ip_dst_mode = 'random') - self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location(), test_stream) + ip_dst_mode = 'random', + name = 'stream-0') + self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location()) self.golden_yaml = ''' - name: stream-0 stream: @@ -111,8 +112,9 @@ class CTRexHltApi_Test(unittest.TestCase): tcp_src_port_count = 10, tcp_dst_port_mode = 'random', tcp_dst_port_count = 10, - tcp_dst_port = 1234) - self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location(), test_stream) + tcp_dst_port = 1234, + name = 'stream-0') + self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location()) self.golden_yaml = ''' - name: stream-0 stream: @@ -183,8 +185,9 @@ class CTRexHltApi_Test(unittest.TestCase): udp_src_port = 1234, udp_dst_port_mode = 'increment', udp_dst_port_count = 10, - udp_dst_port = 1234) - self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location(), test_stream) + udp_dst_port = 1234, + name = 'stream-0') + self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location()) self.golden_yaml = ''' - name: stream-0 stream: @@ -244,8 +247,9 @@ class CTRexHltApi_Test(unittest.TestCase): frame_size_max = 3000) test_stream = gen_stream(length_mode = 'decrement', frame_size_min = 100, - frame_size_max = 3000) - self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location(), test_stream) + frame_size_max = 3000, + name = 'stream-0') + self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location()) self.golden_yaml = ''' - name: stream-0 stream: @@ -293,8 +297,9 @@ class CTRexHltApi_Test(unittest.TestCase): test_stream = gen_stream(l4_protocol = 'udp', length_mode = 'random', l3_length_min = 100, - l3_length_max = 400) - self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location(), test_stream) + l3_length_max = 400, + name = 'stream-0') + self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location()) self.golden_yaml = ''' - name: stream-0 stream: diff --git a/scripts/automation/regression/unit_tests/functional_tests/payload_gen_test.py b/scripts/automation/regression/unit_tests/functional_tests/payload_gen_test.py deleted file mode 100755 index 80d2b086..00000000 --- a/scripts/automation/regression/unit_tests/functional_tests/payload_gen_test.py +++ /dev/null @@ -1,125 +0,0 @@ -#!/router/bin/python - -import pkt_bld_general_test -from client_utils.packet_builder import * -from dpkt.ethernet import Ethernet -from dpkt.ip import IP -from dpkt.icmp import ICMP -from nose.tools import assert_equal -from nose.tools import assert_not_equal -from nose.tools import assert_raises -from nose.tools import raises -import re -import binascii - -class CTRexPayloadGen_Test(pkt_bld_general_test.CGeneralPktBld_Test): - - def setUp(self): -# echo = dpkt.icmp.ICMP.Echo() -# echo.id = random.randint(0, 0xffff) -# echo.seq = random.randint(0, 0xffff) -# echo.data = 'hello world' -# -# icmp = dpkt.icmp.ICMP() -# icmp.type = dpkt.icmp.ICMP_ECHO -# icmp.data = echo - - # packet generation is done directly using dpkt package and - self.packet = Ethernet() - ip = IP(src='\x01\x02\x03\x04', dst='\x05\x06\x07\x08', p=1) - icmp = ICMP(type=8, data=ICMP.Echo(id=123, seq=1, data='foobar')) - ip.data = icmp - self.packet.src = "\x00\x00\x55\x55\x00\x00" - self.packet.dst = "\x00\x00\x11\x11\x00\x00" - self.packet.data = ip - self.print_packet(self.packet) - self.max_pkt_size = 1400 - self.pld_gen = CTRexPktBuilder.CTRexPayloadGen(self.packet, self.max_pkt_size) - - @staticmethod - def special_match(strg, search=re.compile(r'[^a-zA-Z0-9]').search): - return not bool(search(strg)) - - @staticmethod - def principal_period(s): - # finds the string the repeats itself in the string - i = (s+s).find(s, 1, -1) - return None if i == -1 else s[:i] - - def test_gen_random_str(self): - generated_str = self.pld_gen.gen_random_str() - # print "\nGenerated string: {}".format(generated_str) - # chech that the generated string is accorsing to rules. - assert CTRexPayloadGen_Test.special_match(generated_str) - assert_equal(len(generated_str), (self.max_pkt_size - len(self.packet))) - - def test_gen_repeat_ptrn(self): - gen_len = self.max_pkt_size - len(self.packet) - # case 1 - repeated string - repeat_str = "HelloWorld" - generated_str = self.pld_gen.gen_repeat_ptrn(repeat_str) - for i in xrange(len(repeat_str)): - if generated_str.endswith(repeat_str[:i+1]): - # remove the string residue, if found - generated_str = generated_str[:-(i+1)] - # print generated_str - break - assert_equal(CTRexPayloadGen_Test.principal_period(generated_str), "HelloWorld") - - # case 2.1 - repeated single number - long number - repeat_num = 0x645564646465 - generated_str = self.pld_gen.gen_repeat_ptrn(repeat_num) - ptrn = binascii.unhexlify(hex(repeat_num)[2:]) - for i in xrange(len(ptrn)): - if generated_str.endswith(ptrn[:i+1]): - # remove the string residue, if found - generated_str = generated_str[:-(i+1)] - break - assert_equal(CTRexPayloadGen_Test.principal_period(generated_str), ptrn) - # case 2.2 - repeated single number - 1 byte - repeat_num = 0x64 - generated_str = self.pld_gen.gen_repeat_ptrn(repeat_num) - ptrn = binascii.unhexlify(hex(repeat_num)[2:]) - assert_equal(CTRexPayloadGen_Test.principal_period(generated_str), ptrn) - assert_equal(len(generated_str), (self.max_pkt_size - len(self.packet))) - # case 3 - repeated sequence - repeat_seq = (0x55, 0x60, 0x65, 0x70, 0x85) - ptrn = binascii.unhexlify(''.join(hex(x)[2:] for x in repeat_seq)) - generated_str = self.pld_gen.gen_repeat_ptrn(repeat_seq) - # ptrn = binascii.unhexlify(hex(repeat_num)[2:]) - for i in xrange(len(ptrn)): - if generated_str.endswith(ptrn[:i+1]): - # remove the string residue, if found - generated_str = generated_str[:-(i+1)] - break - assert_equal(CTRexPayloadGen_Test.principal_period(generated_str), ptrn) - - # in tuples, check that if any of the numbers exceeds limit - assert_raises(ValueError, self.pld_gen.gen_repeat_ptrn, (0x1, -18)) - assert_raises(ValueError, self.pld_gen.gen_repeat_ptrn, (0xFFF, 5)) - # finally, check an exception is thrown in rest of cases - assert_raises(ValueError, self.pld_gen.gen_repeat_ptrn, 5.5) - - - - - - - - - - - - - - - pass - - - def tearDown(self): - pass - - -if __name__ == "__main__": - pass - diff --git a/scripts/automation/regression/unit_tests/functional_tests/pkt_builder_test.py b/scripts/automation/regression/unit_tests/functional_tests/pkt_builder_test.py deleted file mode 100755 index d33d92fe..00000000 --- a/scripts/automation/regression/unit_tests/functional_tests/pkt_builder_test.py +++ /dev/null @@ -1,442 +0,0 @@ -#!/router/bin/python - -import pkt_bld_general_test -from client_utils.packet_builder import * -import dpkt -from nose.tools import assert_equal -from nose.tools import assert_not_equal -from nose.tools import assert_raises -from nose.tools import raises -import os -import random -import pprint - -class CTRexPktBuilderSanity_Test(pkt_bld_general_test.CGeneralPktBld_Test): - - def setUp(self): - pass - - def test_decode_ip_addr(self): - # test ipv4 case - assert_equal(CTRexPktBuilder._decode_ip_addr('1.2.3.4', "ipv4"), '\x01\x02\x03\x04') - assert_equal(CTRexPktBuilder._decode_ip_addr('127.0.0.1', "ipv4"), '\x7F\x00\x00\x01') - assert_raises(CTRexPktBuilder.IPAddressError, CTRexPktBuilder._decode_ip_addr, '1.2.3.4.5', "ipv4") - assert_raises(CTRexPktBuilder.IPAddressError, CTRexPktBuilder._decode_ip_addr, '1.2.3.4', "ipv6") - # test ipv6 case - assert_equal(CTRexPktBuilder._decode_ip_addr("5001::DB8:1:3333:1:1", "ipv6"), - 'P\x01\x00\x00\x00\x00\r\xb8\x00\x0133\x00\x01\x00\x01') - assert_raises(CTRexPktBuilder.IPAddressError, CTRexPktBuilder._decode_ip_addr, - '2001::DB8:1:2222::1:1', "ipv6") - - def test_decode_mac_addr(self): - assert_equal(CTRexPktBuilder._decode_mac_addr('00:de:34:ef:2e:f4'), '\x00\xde4\xef.\xf4') - assert_equal(CTRexPktBuilder._decode_mac_addr('00-de-55-ef-2e-f4'), '\x00\xdeU\xef.\xf4') - assert_raises(CTRexPktBuilder.MACAddressError, CTRexPktBuilder._decode_mac_addr, - '00:de:34:ef:2e:f4:f4') - assert_raises(CTRexPktBuilder.MACAddressError, CTRexPktBuilder._decode_mac_addr, - '1.2.3.4') - assert_raises(CTRexPktBuilder.MACAddressError, CTRexPktBuilder._decode_mac_addr, - '00 de 34 ef 2e f4 f4') - - def test_gen_layer_name(self): - pkt = CTRexPktBuilder() - assert_equal(pkt._gen_layer_name("eth"), "eth_1") - pkt._pkt_by_hdr = {'eth':None} # mock header pointer data - assert_equal(pkt._gen_layer_name("eth"), "eth_1") - pkt._pkt_by_hdr.update({'eth_1':None}) # more mock header pointer data - assert_equal(pkt._gen_layer_name("eth"), "eth_2") - - def test_set_layer_attr_basic(self): - pkt = CTRexPktBuilder() - pkt._pkt_by_hdr['ip'] = dpkt.ip.IP() - # case 1 - test full value assignment - pkt.set_layer_attr('ip', 'src', '\x01\x02\x03\x04') - assert_equal(pkt._pkt_by_hdr['ip'].src, '\x01\x02\x03\x04') - # case 2 - test bit assignment - pkt.set_layer_bit_attr('ip', 'off', dpkt.ip.IP_DF) - pkt.set_layer_bit_attr('ip', 'off', dpkt.ip.IP_MF) - assert_equal(bin(pkt._pkt_by_hdr['ip'].off), '0b110000000000000') - # case 3 - test assignment of not-exist attribute - assert_raises(ValueError, pkt.set_layer_bit_attr, 'ip', 'src_dst', 0) - # case 4.1 - test assignment of data attribute - without dpkt.Packet object - assert_raises(ValueError, pkt.set_layer_bit_attr, 'ip', 'data', "Not a dpkt.Packet object") - # case 4.2 - test assignment of data attribute - with dpkt.Packet object - tested under CTRexPktBuilder_Test class -# tcp = dpkt.tcp.TCP() - self.print_packet(pkt._pkt_by_hdr['ip']) -# pkt.set_layer_attr('ip', 'data', tcp) - # case 5 - test assignment of not-exist layer - assert_raises(KeyError, pkt.set_layer_bit_attr, 'no_such_layer', 'src', 0) - - def tearDown(self): - pass - - -class CTRexPktBuilder_Test(pkt_bld_general_test.CGeneralPktBld_Test): - - def setUp(self): - self.pkt_bld = CTRexPktBuilder() - self.pkt_bld.add_pkt_layer("l2", dpkt.ethernet.Ethernet()) - self.pp = pprint.PrettyPrinter(indent=4) - - def test_add_pkt_layer(self): - ip = dpkt.ip.IP(src='\x01\x02\x03\x04', dst='\x05\x06\x07\x08', p=1) - self.pkt_bld.add_pkt_layer("l3", ip) - tcp = dpkt.tcp.TCP(sport = 8080) - self.pkt_bld.add_pkt_layer("l4_tcp", tcp) - assert_equal(len(self.pkt_bld._pkt_by_hdr), 3) - assert_equal(self.pkt_bld._pkt_by_hdr.keys(), ['l2', 'l3', 'l4_tcp']) - self.print_packet(self.pkt_bld._packet) - assert_raises(ValueError, self.pkt_bld.add_pkt_layer, 'l2', dpkt.ethernet.Ethernet()) - - def test_set_ip_layer_addr(self): - ip = dpkt.ip.IP() - self.pkt_bld.add_pkt_layer("l3", ip) - self.pkt_bld.set_ip_layer_addr("l3", "src", "1.2.3.4") - self.print_packet(self.pkt_bld._packet) - assert_equal(self.pkt_bld._pkt_by_hdr['l3'].src, '\x01\x02\x03\x04') - # check that only IP layer is using this function - assert_raises(ValueError, self.pkt_bld.set_ip_layer_addr, 'l2', "src", "1.2.3.4") - - def test_calc_offset(self): - ip = dpkt.ip.IP() - self.pkt_bld.add_pkt_layer("l3", ip) - assert_equal(self.pkt_bld._calc_offset("l3", "src", 4), (14, 14+12)) - - def test_set_ipv6_layer_addr(self): - ip6 = dpkt.ip6.IP6() - self.pkt_bld.add_pkt_layer("l3", ip6) - self.pkt_bld.set_ipv6_layer_addr("l3", "src", "5001::DB8:1:3333:1:1") - self.print_packet(self.pkt_bld._packet) - assert_equal(self.pkt_bld._pkt_by_hdr['l3'].src, 'P\x01\x00\x00\x00\x00\r\xb8\x00\x0133\x00\x01\x00\x01') - # check that only IP layer is using this function - assert_raises(ValueError, self.pkt_bld.set_ipv6_layer_addr, 'l2', "src", "5001::DB8:1:3333:1:1") - - def test_set_eth_layer_addr(self): - ip = dpkt.ip.IP() - self.pkt_bld.add_pkt_layer("l3", ip) - self.pkt_bld.set_eth_layer_addr("l2", "src", "00:de:34:ef:2e:f4") - self.print_packet(self.pkt_bld._packet) - assert_equal(self.pkt_bld._pkt_by_hdr['l2'].src, '\x00\xde4\xef.\xf4') - # check that only IP layer is using this function - assert_raises(ValueError, self.pkt_bld.set_eth_layer_addr, 'l3', "src", "\x00\xde4\xef.\xf4") - - def test_set_layer_attr(self): - # extend the set_layer_attr_basic test by handling the following case: - # replace some header data with another layer, causing other layers to disconnect - # this also tests the _reevaluate_packet method - ip = dpkt.ip.IP(src='\x01\x02\x03\x04', dst='\x05\x06\x07\x08', p=1) - self.pkt_bld.add_pkt_layer("l3_ip", ip) - tcp = dpkt.tcp.TCP(sport = 8080) - self.pkt_bld.add_pkt_layer("l4_tcp", tcp) - # sanity: try changing data attr with non-dpkt.Packet instance - assert_raises(ValueError, self.pkt_bld.set_layer_attr, 'l2', 'data', "HelloWorld") - # now, add different L3 layer instead of existting one, L4 would disconnect - old_layer_count = len(self.pkt_bld._pkt_by_hdr) - new_ip = dpkt.ip.IP(src='\x05\x06\x07\x08', dst='\x01\x02\x03\x04') - print "\nBefore disconnecting layers:" - print "============================", - self.print_packet(self.pkt_bld._packet) - self.pkt_bld.set_layer_attr('l2', 'data', new_ip) - print "\nAfter disconnecting layers:" - print "===========================", - self.print_packet(self.pkt_bld._packet) - assert_not_equal(old_layer_count, len(self.pkt_bld._pkt_by_hdr)) - assert_equal(len(self.pkt_bld._pkt_by_hdr), 1) # only Eth layer appears - - def test_set_pkt_payload(self): - payload = "HelloWorld" - # test for setting a payload to an empty packet - empty_pkt = CTRexPktBuilder() - assert_raises(AttributeError, empty_pkt.set_pkt_payload, payload) - # add content to packet - ip = dpkt.ip.IP(src='\x01\x02\x03\x04', dst='\x05\x06\x07\x08', p=1) - self.pkt_bld.add_pkt_layer("l3_ip", ip) - tcp = dpkt.tcp.TCP(sport = 8080) - self.pkt_bld.add_pkt_layer("l4_tcp", tcp) - # now, set a payload for the packet - self.pkt_bld.set_pkt_payload(payload) - self.print_packet(self.pkt_bld._packet) - assert_equal(self.pkt_bld._pkt_by_hdr['l4_tcp'].data, payload) - - def test_load_packet(self): - # add content to packet - ip = dpkt.ip.IP(src='\x01\x02\x03\x04', dst='\x05\x06\x07\x08', p=1) - self.pkt_bld.add_pkt_layer("l3_ip", ip) - tcp = dpkt.tcp.TCP(sport = 8080) - self.pkt_bld.add_pkt_layer("l4_tcp", tcp) - self.pkt_bld.set_pkt_payload("HelloWorld") - - new_pkt = CTRexPktBuilder() - new_pkt.load_packet(self.pkt_bld._packet) - self.print_packet(new_pkt._packet) - assert_equal(len(new_pkt._pkt_by_hdr), 4) - assert_equal(new_pkt._pkt_by_hdr.keys(), - ['ip_1', - 'tcp_1', - 'pkt_final_payload', - 'ethernet_1' - ] - ) - assert_equal(new_pkt._pkt_by_hdr['pkt_final_payload'], "HelloWorld") - - def test_get_packet(self): - # get a pointer to the packet - assert(self.pkt_bld.get_packet(get_ptr=True) is self.pkt_bld._packet) - # get a copy of the packet - assert(not(self.pkt_bld.get_packet() is self.pkt_bld._packet)) - - def test_get_layer(self): - assert_equal(self.pkt_bld.get_layer('no_such_layer'), None) - assert(not(self.pkt_bld.get_layer('l2') is self.pkt_bld._packet)) - assert_equal(type(self.pkt_bld.get_layer('l2')).__name__, "Ethernet") - - def test_dump_to_pcap(self): - # set Ethernet layer attributes - self.pkt_bld.set_eth_layer_addr("l2", "src", "00:15:17:a7:75:a3") - self.pkt_bld.set_eth_layer_addr("l2", "dst", "e0:5f:b9:69:e9:22") - self.pkt_bld.set_layer_attr("l2", "type", dpkt.ethernet.ETH_TYPE_IP) - # set IP layer attributes - self.pkt_bld.add_pkt_layer("l3_ip", dpkt.ip.IP()) - self.pkt_bld.set_ip_layer_addr("l3_ip", "src", "21.0.0.2") - self.pkt_bld.set_ip_layer_addr("l3_ip", "dst", "22.0.0.12") - self.pkt_bld.set_layer_attr("l3_ip", "p", dpkt.ip.IP_PROTO_TCP) - # set TCP layer attributes - self.pkt_bld.add_pkt_layer("l4_tcp", dpkt.tcp.TCP()) - self.pkt_bld.set_layer_attr("l4_tcp", "sport", 13311) - self.pkt_bld.set_layer_attr("l4_tcp", "dport", 80) - self.pkt_bld.set_layer_attr("l4_tcp", "flags", 0) - self.pkt_bld.set_layer_attr("l4_tcp", "win", 32768) - self.pkt_bld.set_layer_attr("l4_tcp", "seq", 0) - # set packet payload, for example HTTP GET request - self.pkt_bld.set_pkt_payload('GET /10k_60k HTTP/1.1\r\nHost: 22.0.0.3\r\nConnection: Keep-Alive\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)\r\nAccept: */*\r\nAccept-Language: en-us\r\nAccept-Encoding: gzip, deflate, compress\r\n\r\n') - # finally, set IP header len with relation to payload data - self.pkt_bld.set_layer_attr("l3_ip", "len", len(self.pkt_bld.get_layer('l3_ip'))) - - filepath = 'reports/test%s.pcap' % os.getenv('SETUP_DIR', '') - self.pkt_bld.dump_pkt_to_pcap(filepath) - assert os.path.isfile(filepath) - # remove pcap after ensuring it exists - os.remove(filepath) - filepath = "/not/a/valid/path/test.pcap" - assert_raises(IOError, self.pkt_bld.dump_pkt_to_pcap, filepath) - # check that dump is not available for empty packet - new_pkt = CTRexPktBuilder() - assert_raises(CTRexPktBuilder.EmptyPacketError, new_pkt.dump_pkt_to_pcap, filepath) - - def test_dump_pkt(self): - # check that dump is not available for empty packet - new_pkt = CTRexPktBuilder() - assert_raises(CTRexPktBuilder.EmptyPacketError, new_pkt.dump_pkt) - - # set Ethernet layer attributes - self.pkt_bld.set_eth_layer_addr("l2", "src", "00:15:17:a7:75:a3") - self.pkt_bld.set_eth_layer_addr("l2", "dst", "e0:5f:b9:69:e9:22") - self.pkt_bld.set_layer_attr("l2", "type", dpkt.ethernet.ETH_TYPE_IP) - # set IP layer attributes - self.pkt_bld.add_pkt_layer("l3_ip", dpkt.ip.IP()) - self.pkt_bld.set_ip_layer_addr("l3_ip", "src", "21.0.0.2") - self.pkt_bld.set_ip_layer_addr("l3_ip", "dst", "22.0.0.12") - self.pkt_bld.set_layer_attr("l3_ip", "p", dpkt.ip.IP_PROTO_ICMP) - # set ICMP layer attributes - self.pkt_bld.add_pkt_layer("icmp", dpkt.icmp.ICMP()) - self.pkt_bld.set_layer_attr("icmp", "type", dpkt.icmp.ICMP_ECHO) - # set Echo(ICMP) layer attributes - self.pkt_bld.add_pkt_layer("icmp_echo", dpkt.icmp.ICMP.Echo()) - self.pkt_bld.set_layer_attr("icmp_echo", "id", 24528) - self.pkt_bld.set_layer_attr("icmp_echo", "seq", 11482) - self.pkt_bld.set_pkt_payload('hello world') - - # finally, set IP header len with relation to payload data - self.pkt_bld.set_layer_attr("l3_ip", "len", len(self.pkt_bld.get_layer('l3_ip'))) - - self.print_packet(self.pkt_bld.get_packet()) - assert_equal(self.pkt_bld.dump_pkt(), { - 'binary': '4F+5aekiABUXp3WjCABFAAAnAAAAAEABT8kVAAACFgAADAgA2YZf0CzaaGVsbG8gd29ybGQ=', - 'meta': '', - }) - - def test_set_vm_ip_range_ipv4(self): - # set some mock packet - ip = dpkt.ip.IP() - self.pkt_bld.add_pkt_layer("l3", ip) - self.pkt_bld.add_pkt_layer("l4_tcp", dpkt.tcp.TCP()) - self.pkt_bld.set_pkt_payload("HelloWorld") - - self.pkt_bld.set_vm_ip_range("l3", - "src", - "10.0.0.1", - "10.0.0.255", - "inc") -# self.pkt_bld.set_vm_custom_range(layer_name="l3", -# hdr_field="tos", -# init_val="10", start_val="10", end_val="200", add_val=2, val_size=1, -# operation="inc") - print '' - self.pp.pprint(self.pkt_bld.vm.dump()) - assert_equal(self.pkt_bld.vm.dump(), - { 'instructions': [ { 'init_value': 167772161, - 'max_value': 167772415, - 'min_value': 167772161, - 'name': 'l3__src', - 'op': 'inc', - 'size': 4, - 'type': 'flow_var'}, - { 'add_value': 0, - 'is_big_endian': True, - 'name': 'l3__src', - 'pkt_offset': 26, - 'type': 'write_flow_var'}, - { 'pkt_offset': 14, 'type': 'fix_checksum_ipv4'}], - 'split_by_var': ''} - ) - - def test_set_vm_ip_range_ipv4_no_checksum(self): - # set some mock packet - ip = dpkt.ip.IP() - self.pkt_bld.add_pkt_layer("l3", ip) - self.pkt_bld.add_pkt_layer("l4_tcp", dpkt.tcp.TCP()) - self.pkt_bld.set_pkt_payload("HelloWorld") - - self.pkt_bld.set_vm_ip_range(ip_layer_name="l3", - ip_field="src", - ip_init="10.0.0.1", ip_start="10.0.0.1", ip_end="10.0.0.255", - add_value=1, - operation="inc", - add_checksum_inst=False) - print '' - self.pp.pprint(self.pkt_bld.vm.dump()) - assert_equal(self.pkt_bld.vm.dump(), - { 'instructions': [ { 'init_value': 167772161, - 'max_value': 167772415, - 'min_value': 167772161, - 'name': 'l3__src', - 'op': 'inc', - 'size': 4, - 'type': 'flow_var'}, - { 'add_value': 1, - 'is_big_endian': True, - 'name': 'l3__src', - 'pkt_offset': 26, - 'type': 'write_flow_var'}], - 'split_by_var': ''} - ) - - def test_set_vm_ip_range_ipv6(self): - # set some mock packet - ip6 = dpkt.ip6.IP6() - self.pkt_bld.add_pkt_layer("l3", ip6) - self.pkt_bld.add_pkt_layer("l4_tcp", dpkt.tcp.TCP()) - self.pkt_bld.set_pkt_payload("HelloWorld") - - self.pkt_bld.set_vm_ip_range(ip_layer_name="l3", - ip_field="src", - ip_init="5001::DB8:1:3333:1:1", ip_start="5001::DB8:1:3333:1:1", ip_end="5001::DB8:1:3333:1:F", - add_value=1, - operation="inc", - ip_type="ipv6") - print '' - self.pp.pprint(self.pkt_bld.vm.dump()) - assert_equal(self.pkt_bld.vm.dump(), - { 'instructions': [ { 'init_value': 65537, - 'max_value': 65551, - 'min_value': 65537, - 'name': 'l3__src', - 'op': 'inc', - 'size': 4, - 'type': 'flow_var'}, - { 'add_value': 1, - 'is_big_endian': True, - 'name': 'l3__src', - 'pkt_offset': 34, - 'type': 'write_flow_var'}], - 'split_by_var': ''} - ) - - def test_set_vm_eth_range(self): - pass - - def test_set_vm_custom_range(self): - # set some mock packet - ip = dpkt.ip.IP() - self.pkt_bld.add_pkt_layer("l3", ip) - self.pkt_bld.add_pkt_layer("l4_tcp", dpkt.tcp.TCP()) - self.pkt_bld.set_pkt_payload("HelloWorld") - - self.pkt_bld.set_vm_custom_range(layer_name="l3", - hdr_field="tos", - init_val=10, start_val=10, end_val=200, add_val=2, val_size=1, - operation="inc") - print '' - self.pp.pprint(self.pkt_bld.vm.dump()) - assert_equal(self.pkt_bld.vm.dump(), - { 'instructions': [ { 'init_value': 10, - 'max_value': 200, - 'min_value': 10, - 'name': 'l3__tos', - 'op': 'inc', - 'size': 1, - 'type': 'flow_var'}, - { 'add_value': 2, - 'is_big_endian': True, - 'name': 'l3__tos', - 'pkt_offset': 15, - 'type': 'write_flow_var'}, - { 'pkt_offset': 14, 'type': 'fix_checksum_ipv4'}], - 'split_by_var': ''} - ) - - def test_various_ranges(self): - # set some mock packet - ip = dpkt.ip.IP() - self.pkt_bld.add_pkt_layer("l3", ip) - self.pkt_bld.add_pkt_layer("l4_tcp", dpkt.tcp.TCP()) - self.pkt_bld.set_pkt_payload("HelloWorld") - - self.pkt_bld.set_vm_ip_range("l3", - "src", - "10.0.0.1", - "10.0.0.255", - "inc") - self.pkt_bld.set_vm_custom_range(layer_name="l3", - hdr_field="tos", - init_val=10, start_val=10, end_val=200, add_val=2, val_size=1, - operation="inc") - print '' - self.pp.pprint(self.pkt_bld.vm.dump()) - - assert_equal(self.pkt_bld.vm.dump(), - {'instructions': [{'init_value': 167772161, - 'max_value': 167772415, - 'min_value': 167772161, - 'name': 'l3__src', - 'op': 'inc', - 'size': 4, - 'type': 'flow_var'}, - {'init_value': 10, - 'max_value': 200, - 'min_value': 10, - 'name': 'l3__tos', - 'op': 'inc', - 'size': 1, - 'type': 'flow_var'}, - {'add_value': 2, - 'is_big_endian': True, - 'name': 'l3__tos', - 'pkt_offset': 15, - 'type': 'write_flow_var'}, - {'add_value': 0, - 'is_big_endian': True, - 'name': 'l3__src', - 'pkt_offset': 26, - 'type': 'write_flow_var'}, - {'pkt_offset': 14, 'type': 'fix_checksum_ipv4'}], - 'split_by_var': ''} - ) - - def tearDown(self): - pass - - -if __name__ == "__main__": - pass - diff --git a/scripts/automation/regression/unit_tests/functional_tests/vm_test.py b/scripts/automation/regression/unit_tests/functional_tests/vm_test.py deleted file mode 100755 index f3948d99..00000000 --- a/scripts/automation/regression/unit_tests/functional_tests/vm_test.py +++ /dev/null @@ -1,77 +0,0 @@ -#!/router/bin/python - -import pkt_bld_general_test -from client_utils.packet_builder import * -from nose.tools import assert_equal -from nose.tools import assert_not_equal -from nose.tools import assert_raises -from nose.tools import raises - -class CTRexVM_Test(pkt_bld_general_test.CGeneralPktBld_Test): - - def setUp(self): - self.vm = CTRexPktBuilder.CTRexVM() - - def test_add_flow_man_inst(self): - self.vm.add_flow_man_inst("src_ip") - assert_raises(CTRexPktBuilder.VMVarNameExistsError, self.vm.add_flow_man_inst, "src_ip") - self.vm.add_flow_man_inst("dst_ip", size=8, operation="inc", init_value=5, max_value=100) - assert_equal(self.vm.vm_variables["dst_ip"].dump(), - {"type": "flow_var", - "name": "dst_ip", - "size": 8, - # "big_endian": True, - "op": "inc", -# "split_by_core": False, - "init_value": 5, - "min_value": 1, - "max_value": 100}) - assert_raises(CTRexPktBuilder.VMFieldNameError, self.vm.add_flow_man_inst, "src_mac", no_field=1) - - def test_load_flow_man(self): - vm2 = CTRexPktBuilder.CTRexVM() - vm2.add_flow_man_inst("dst_ip", size=8, operation="inc", init_value=5, max_value=100) - self.vm.load_flow_man(vm2.vm_variables["dst_ip"]) - assert_equal(self.vm.vm_variables["dst_ip"].dump(), - vm2.vm_variables["dst_ip"].dump()) - - def test_set_vm_var_field(self): - self.vm.add_flow_man_inst("src_ip") - self.vm.set_vm_var_field("src_ip", "size", 8) - assert_equal(self.vm.vm_variables["src_ip"].size, 8) - assert_raises(KeyError, self.vm.set_vm_var_field, "no_var", "no_field", 10) - assert_raises(CTRexPktBuilder.VMFieldNameError, self.vm.set_vm_var_field, "src_ip", "no_field", 10) - assert_raises(CTRexPktBuilder.VMFieldValueError, self.vm.set_vm_var_field, "src_ip", "operation", "rand") - - def test_dump(self): - self.vm.add_flow_man_inst("dst_ip", size=8, operation="inc", init_value=5, max_value=100) - self.vm.add_flow_man_inst("src_ip", size=8, operation="dec", init_value=10, min_value=2, max_value=100) - from pprint import pprint - print '' - pprint (self.vm.dump()) - assert_equal(self.vm.dump(), - {'instructions': [{'init_value': 10, - 'max_value': 100, - 'min_value': 2, - 'name': 'src_ip', - 'op': 'dec', - 'size': 8, - 'type': 'flow_var'}, - {'init_value': 5, - 'max_value': 100, - 'min_value': 1, - 'name': 'dst_ip', - 'op': 'inc', - 'size': 8, - 'type': 'flow_var'}], - 'split_by_var': ''} - ) - - - def tearDown(self): - pass - - -if __name__ == "__main__": - pass - diff --git a/scripts/automation/regression/unit_tests/functional_tests/vm_variable_test.py b/scripts/automation/regression/unit_tests/functional_tests/vm_variable_test.py deleted file mode 100755 index 699f1d97..00000000 --- a/scripts/automation/regression/unit_tests/functional_tests/vm_variable_test.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/router/bin/python - -import pkt_bld_general_test -from client_utils.packet_builder import * -from nose.tools import assert_equal -from nose.tools import assert_not_equal -from nose.tools import assert_raises -from nose.tools import raises - -class CTRexVMVariable_Test(pkt_bld_general_test.CGeneralPktBld_Test): - - def setUp(self): - self.vm_var = CTRexPktBuilder.CTRexVM.CTRexVMFlowVariable("test_var") - - def test_var_name(self): - assert_equal(self.vm_var.name, "test_var") - -# @raises(CTRexPktBuilder.VMVarNameError) - def test_set_field(self): - assert_raises(CTRexPktBuilder.VMFieldNameError, self.vm_var.set_field, "no_field", 10) - # test for 'size' field - assert_raises(CTRexPktBuilder.VMFieldTypeError, self.vm_var.set_field, "size", "wrong_type") - assert_raises(CTRexPktBuilder.VMFieldValueError, self.vm_var.set_field, "size", 10) # 10 is illegal size - self.vm_var.set_field("size", 8) - assert_equal(self.vm_var.size, 8) - # test for 'init_value' field - assert_raises(CTRexPktBuilder.VMFieldTypeError, self.vm_var.set_field, "init_value", '123') # 123 is wrong type, should be int - self.vm_var.set_field("init_value", 5) - assert_equal(self.vm_var.init_value, 5) - # test for 'operation' field - assert_raises(CTRexPktBuilder.VMFieldTypeError, self.vm_var.set_field, "operation", 1) # operation is field of type str - assert_raises(CTRexPktBuilder.VMFieldValueError, self.vm_var.set_field, "operation", "rand") # "rand" is illegal option - self.vm_var.set_field("operation", "inc") - assert_equal(self.vm_var.operation, "inc") - # test for 'split_by_core' field -# self.vm_var.set_field("split_by_core", 5) -# assert_equal(self.vm_var.split_by_core, True) - - def test_var_dump (self): - # set VM variable options - self.vm_var.set_field("size", 8) - self.vm_var.set_field("init_value", 5) - self.vm_var.set_field("operation", "inc") -# self.vm_var.set_field("split_by_core", False) - self.vm_var.set_field("max_value", 100) - assert_equal(self.vm_var.dump(), - {"type": "flow_var", - "name": "test_var", - "size": 8, - # "big_endian": True, - "op": "inc", -# "split_by_core": False, - "init_value": 5, - "min_value": 1, - "max_value": 100}) - - def tearDown(self): - pass - - -if __name__ == "__main__": - pass - diff --git a/scripts/automation/trex_control_plane/client/trex_hltapi.py b/scripts/automation/trex_control_plane/client/trex_hltapi.py index c2a08306..fc507497 100755 --- a/scripts/automation/trex_control_plane/client/trex_hltapi.py +++ b/scripts/automation/trex_control_plane/client/trex_hltapi.py @@ -26,12 +26,21 @@ traffic_config_kwargs = { 'transmit_mode': 'continuous', # ( continuous | multi_burst | single_burst ) 'rate_pps': 1, 'stream_id': None, + 'name': None, 'bidirectional': 0, # stream builder parameters 'pkts_per_burst': 1, 'burst_loop_count': 1, 'inter_burst_gap': 12, - 'length_mode': 'fixed', # ( auto | fixed | increment | decrement | random ) + 'length_mode': 'fixed', # ( auto | fixed | increment | decrement | random | imix ) + 'l3_imix1_size': 60, + 'l3_imix1_ratio': 28, + 'l3_imix2_size': 590, + 'l3_imix2_ratio': 20, + 'l3_imix3_size': 1514, + 'l3_imix3_ratio': 4, + 'l3_imix4_size': 9226, + 'l3_imix4_ratio': 0, #L2 'frame_size': 64, 'frame_size_min': 64, @@ -40,6 +49,11 @@ traffic_config_kwargs = { 'l2_encap': 'ethernet_ii', # ( ethernet_ii ) 'mac_src': '00:00:01:00:00:01', 'mac_dst': '00:00:00:00:00:00', + 'mac_src2': '00:00:01:00:00:01', + 'mac_dst2': '00:00:00:00:00:00', + 'vlan_user_priority': 1, + 'vlan_id': 0, + 'vlan_cfi': 1, #L3, IP 'l3_protocol': 'ipv4', # ( ipv4 ) 'ip_tos_field': 0, @@ -60,6 +74,8 @@ traffic_config_kwargs = { 'l3_length_max': 238, 'l3_length_step': 1, # has to be 1 #L3, IPv6 (TODO: add) + 'ipv6_src_addr': None, + 'ipv6_dst_addr': None, #L4, TCP 'l4_protocol': 'tcp', # ( tcp | udp ) 'tcp_src_port': 1024, @@ -108,23 +124,15 @@ traffic_stats_kwargs = { } -#HACK FIX ME START import sys import os CURRENT_PATH = os.path.dirname(os.path.realpath(__file__)) sys.path.append(os.path.join(CURRENT_PATH, '../stl/')) -#HACK FIX ME END from trex_stl_lib.api import * -import trex_stl_lib.api as pkt_bld -#import trex_stl_lib.trex_stl_packet_builder_scapy as pkt_bld -#from trex_stl_lib.trex_stl_packet_builder_scapy import import CTRexVmDescFlowVar, CTRexVmDescWrFlowVar -#from trex_stl_lib.trex_stl_client import STLClient -#from common.trex_streams import * - -import trex_root_path -from client_utils.general_utils import get_integer + +from client_utils.general_utils import get_number import socket import copy from misc_methods import print_r @@ -148,15 +156,100 @@ class HLT_OK(dict): dict.update(self, kwargs) def merge_kwargs(default_kwargs, user_kwargs): - extra_args = [] kwargs = copy.deepcopy(default_kwargs) for key, value in user_kwargs.items(): if key in kwargs: kwargs[key] = value - elif key not in ('save_to_yaml', 'save_to_pcap'): # internal debug arguments - print("Warning: provided parameter '%s' not supported" % key) + elif key in ('save_to_yaml', 'save_to_pcap'): # internal debug arguments + kwargs[key] = value + else: + print("Warning: provided parameter '%s' is not supported" % key) return kwargs +# change MACs from HLT formats {a b c d e f} or a-b-c-d-e-f or a.b.c.d.e.f to Scapy format a:b:c:d:e:f +def correct_macs(kwargs): + list_of_mac_args = ['mac_src', 'mac_dst', 'mac_src2', 'mac_dst2'] + for mac_arg in list_of_mac_args: + if mac_arg in kwargs: + if type(kwargs[mac_arg]) is not str: raise Exception('Argument %s should be str' % mac_arg) + kwargs[mac_arg] = kwargs[mac_arg].replace('{', '').replace('}', '').strip().replace('-', ':').replace(' ', ':').replace('.', ':') + kwargs[mac_arg] = ':'.join(kwargs[mac_arg].split(':')) # remove duplicate ':' if any + try: + mac2str(kwargs[mac_arg]) # verify we are ok + except: + raise Exception('Incorrect MAC %s=%s, please use 01:23:45:67:89:10 or 01-23-45-67-89-10 or 01.23.45.67.89.10 or {01 23 45 67 89 10}' % (mac_arg, kwargs[mac_arg])) + +# dict of streams per port +# hlt_history = False: holds list of stream_id per port +# hlt_history = True: act as dictionary (per port) stream_id -> hlt arguments used for build +class CStreamsPerPort(dict): + def __init__(self, port_list, hlt_history = False): + if type(port_list) is not list: + raise Exception('CStreamsPerPort: should be init with list of ports') + self.hlt_history = hlt_history + if self.hlt_history: + dict.__init__(self, dict((port, {}) for port in port_list)) + else: + dict.__init__(self, dict((port, []) for port in port_list)) + + def get_stream_list(self, ports_list = None): + if self.hlt_history: + if ports_list is None: + ports_list = self.keys() + elif not isinstance(ports_list, list): + ports_list = [ports_list] + ret = {} + for port in ports_list: + ret[port] = self[port].keys() + return ret + else: + return self + + # add to stream_id list per port, no HLT args, res = HLT result + def add_streams_from_res(self, res): + if self.hlt_history: raise Exception('CStreamsPerPort: this object is not meant for HLT history, try init with hlt_history = False') + if not isinstance(res, dict): raise Exception('CStreamsPerPort: res should be dict') + if res.get('status') != 1: raise Exception('CStreamsPerPort: res has status %s' % res.get('status')) + res_streams = res.get('stream_id') + if not isinstance(res_streams, dict): + raise Exception('CStreamsPerPort: stream_id in res should be dict') + for port, port_stream_ids in res_streams.items(): + if port not in self: + raise Exception('CStreamsPerPort: port %s not defined' % port) + if type(port_stream_ids) is not list: + port_stream_ids = [port_stream_ids] + self[port].extend(port_stream_ids) + + # save HLT args to modify streams later + def save_stream_args(self, ports_list, stream_id, stream_hlt_args): + if not self.hlt_history: raise Exception('CStreamsPerPort: this object works only with HLT history, try init with hlt_history = True') + if type(stream_id) not in (int, long): raise Exception('CStreamsPerPort: stream_id should be number') + if not isinstance(stream_hlt_args, dict): raise Exception('CStreamsPerPort: stream_hlt_args should be dict') + if not isinstance(ports_list, list): + ports_list = [ports_list] + for port in ports_list: + if port not in self: + raise Exception('CStreamsPerPort: port %s not defined' % port) + del stream_hlt_args['port_handle'] + if stream_id in self[port]: + self[port][stream_id].update(stream_hlt_args) + else: + self[port][stream_id] = stream_hlt_args + + def remove_stream(self, ports_list, stream_id): + if not isinstance(ports_list, list): + ports_list = [ports_list] + if not isinstance(stream_id, dict): + raise Exception('CStreamsPerPort: stream_hlt_args should be dict') + for port in ports_list: + if port not in self: + raise Exception('CStreamsPerPort: port %s not defined' % port) + if stream_id not in self[port]: + raise Exception('CStreamsPerPort: stream_id %s not found at port %s' % (port, stream_id)) + if self.hlt_history: + del self[port][stream_id] + else: + self[port].pop(stream_id) class CTRexHltApi(object): @@ -164,7 +257,7 @@ class CTRexHltApi(object): self.trex_client = None self.connected = False self.verbose = verbose - self._hlt_streams_history = {} # streams per stream_id in format of HLT arguments for modify later + self._streams_history = {} # streams per stream_id per port in format of HLT arguments for modify later ########################### @@ -190,14 +283,14 @@ class CTRexHltApi(object): return HLT_ERR('Could not init stateless client %s: %s' % (device, e)) try: self.trex_client.connect() - except Exception as e: + #except Exception as e: + except ValueError as e: self.trex_client = None return HLT_ERR('Could not connect to device %s: %s' % (device, e)) # connection successfully created with server, try acquiring ports of TRex try: port_list = self.parse_port_list(kwargs['port_list']) - print kwargs['break_locks'] self.trex_client.acquire(ports = port_list, force = kwargs['break_locks']) except Exception as e: self.trex_client = None @@ -210,13 +303,13 @@ class CTRexHltApi(object): if kwargs['reset']: # remove all port traffic configuration from TRex try: - print 'reseting' self.trex_client.stop(ports = port_list) self.trex_client.reset(ports = port_list) except Exception as e: self.trex_client = None return HLT_ERR('Error in reset traffic: %s' % e) + self._streams_history = CStreamsPerPort(port_handle, hlt_history = True) self.connected = True return HLT_OK(port_handle = port_handle) @@ -245,6 +338,8 @@ class CTRexHltApi(object): return HLT_OK() def interface_config(self, port_handle, mode='config'): + if not self.connected: + return HLT_ERR('connect first') ALLOWED_MODES = ['config', 'modify', 'destroy'] if mode not in ALLOWED_MODES: return HLT_ERR('Mode must be one of the following values: %s' % ALLOWED_MODES) @@ -257,12 +352,18 @@ class CTRexHltApi(object): ########################### def traffic_config(self, **user_kwargs): + if not self.connected: + return HLT_ERR('connect first') + try: + correct_macs(user_kwargs) + except Exception as e: + return HLT_ERR(e) kwargs = merge_kwargs(traffic_config_kwargs, user_kwargs) stream_id = kwargs['stream_id'] if type(stream_id) is list: - del kwargs['stream_id'] for each_stream_id in stream_id: - res = self.traffic_config(stream_id = each_stream_id, **kwargs) + user_kwargs[stream_id] = each_stream_id + res = self.traffic_config(stream_id = each_stream_id, **user_kwargs) if type(res) is HLT_ERR: return res return HLT_OK() @@ -294,73 +395,152 @@ class CTRexHltApi(object): try: self._remove_stream(stream_id, port_handle) except Exception as e: - return HLT_ERR('Could not remove streams with specified by %s, error: %s' % (stream_id, log)) + return HLT_ERR('Could not remove streams with specified by %s, error: %s' % (stream_id, e)) return HLT_OK() #if mode == 'enable': # stream_id = kwargs.get('stream_id') # if stream_id is None: # return HLT_ERR('Please specify stream_id to enable.') - # if stream_id not in self._hlt_streams_history: + # if stream_id not in self._streams_history: # return HLT_ERR('This stream_id (%s) was not used before, please create new.' % stream_id) - # self._hlt_streams_history[stream_id].update(kwargs) # <- the modification + # self._streams_history[stream_id].update(kwargs) # <- the modification if mode == 'modify': # we remove stream and create new one with same stream_id stream_id = kwargs.get('stream_id') if stream_id is None: return HLT_ERR('Please specify stream_id to modify.') - if stream_id not in self._hlt_streams_history: - return HLT_ERR('This stream_id (%s) was not used before, please create new.' % stream_id) - self._hlt_streams_history[stream_id].update(kwargs) # <- the modification - #for port_id in port_handle: - # if stream_id not in self.trex_client.get_stream_id_list(port_id): - # return HLT_ERR('Port %s does not have stream_id %s.' % (port_id, stream_id)) + + if len(port_handle) > 1: + for port in port_handle: + user_kwargs[port_handle] = port + res = self.traffic_config(**user_kwargs) # recurse per port, each port can have different stream with such id + else: + if type(port_handle) is list: + port = port_handle[0] + else: + port = port_handle + if port not in self._streams_history: + return HLT_ERR('Port %s was not used/acquired' % port) + if stream_id not in self._streams_history[port]: + return HLT_ERR('This stream_id (%s) was not used before at port %s, please create new.' % (stream_id, port)) + kwargs.update(self._streams_history[port][stream_id]) + kwargs.update(user_kwargs) try: self.trex_client.remove_streams(stream_id, port_handle) - except Exception as e: - return HLT_ERR('Could not remove streams specified by %s: %s' % (stream_id, e)) + #except Exception as e: + except ValueError as e: + return HLT_ERR('Could not remove stream(s) %s from port(s) %s: %s' % (stream_id, port_handle, e)) if mode == 'create' or mode == 'modify': # create a new stream with desired attributes, starting by creating packet - + streams_per_port = CStreamsPerPort(port_handle) if kwargs['bidirectional']: # two streams with opposite directions - del kwargs['bidirectional'] - del kwargs['port_handle'] + del user_kwargs['bidirectional'] + save_to_yaml = user_kwargs.get('save_to_yaml') bidirect_err = 'When using bidirectional flag, ' if len(port_handle) != 2: return HLT_ERR(bidirect_err + 'number of ports should be exactly 2') try: - res1 = self.traffic_config(port_handle = port_handle[0], **kwargs) - kwargs['mac_src'] = kwargs['mac_src2'] - kwargs['mac_dst'] = kwargs['mac_dst2'] - kwargs['ip_src_addr'] = kwargs['ip_dst_addr'] - kwargs['ip_dst_addr'] = kwargs['ip_src_addr'] - kwargs['ipv6_src_addr'] = kwargs['ipv6_dst_addr'] - kwargs['ipv6_dst_addr'] = kwargs['ipv6_src_addr'] - res2 = self.traffic_config(port_handle = port_handle[1], **kwargs) + if save_to_yaml and type(save_to_yaml) is str: + user_kwargs['save_to_yaml'] = save_to_yaml.replace('.yaml', '_bi1.yaml') + user_kwargs['port_handle'] = port_handle[0] + res1 = self.traffic_config(**user_kwargs) + if res1['status'] == 0: + raise Exception('Could not create bidirectional stream 1: %s' % res1['log']) + streams_per_port.add_streams_from_res(res1) + user_kwargs['mac_src'] = kwargs['mac_src2'] + user_kwargs['mac_dst'] = kwargs['mac_dst2'] + user_kwargs['ip_src_addr'] = kwargs['ip_dst_addr'] + user_kwargs['ip_dst_addr'] = kwargs['ip_src_addr'] + user_kwargs['ipv6_src_addr'] = kwargs['ipv6_dst_addr'] + user_kwargs['ipv6_dst_addr'] = kwargs['ipv6_src_addr'] + if save_to_yaml and type(save_to_yaml) is str: + user_kwargs['save_to_yaml'] = save_to_yaml.replace('.yaml', '_bi2.yaml') + user_kwargs['port_handle'] = port_handle[1] + res2 = self.traffic_config(**user_kwargs) + if res2['status'] == 0: + raise Exception('Could not create bidirectional stream 2: %s' % res2['log']) + streams_per_port.add_streams_from_res(res2) except Exception as e: return HLT_ERR('Could not generate bidirectional traffic: %s' % e) - return HLT_OK(stream_id = {port_handle[0]: res1['stream_id'], port_handle[1]: res2['stream_id']}) - stream_obj = CTRexHltApiPktBuilder.generate_stream(**kwargs) + return HLT_OK(stream_id = streams_per_port) + + if kwargs['length_mode'] == 'imix': # several streams with given length + user_kwargs['length_mode'] = 'fixed' + if kwargs['l3_imix1_size'] < 32 or kwargs['l3_imix2_size'] < 32 or kwargs['l3_imix3_size'] < 32 or kwargs['l3_imix4_size'] < 32: + return HLT_ERR('l3_imix*_size should be at least 32') + total_rate = kwargs['l3_imix1_ratio'] + kwargs['l3_imix2_ratio'] + kwargs['l3_imix3_ratio'] + kwargs['l3_imix4_ratio'] + if total_rate == 0: + return HLT_ERR('Used length_mode imix, but all the ratio are 0') + save_to_yaml = kwargs.get('save_to_yaml') + rate_pps = float(kwargs['rate_pps']) + try: + if kwargs['l3_imix1_ratio'] > 0: + if save_to_yaml and type(save_to_yaml) is str: + user_kwargs['save_to_yaml'] = save_to_yaml.replace('.yaml', '_imix1.yaml') + user_kwargs['frame_size'] = kwargs['l3_imix1_size'] + user_kwargs['rate_pps'] = rate_pps * kwargs['l3_imix1_ratio'] / total_rate + res = self.traffic_config(**user_kwargs) + if res['status'] == 0: + return HLT_ERR('Could not create stream imix1: %s' % res['log']) + streams_per_port.add_streams_from_res(res) + + if kwargs['l3_imix2_ratio'] > 0: + if save_to_yaml and type(save_to_yaml) is str: + user_kwargs['save_to_yaml'] = save_to_yaml.replace('.yaml', '_imix2.yaml') + user_kwargs['frame_size'] = kwargs['l3_imix2_size'] + user_kwargs['rate_pps'] = rate_pps * kwargs['l3_imix2_ratio'] / total_rate + res = self.traffic_config(**user_kwargs) + if res['status'] == 0: + return HLT_ERR('Could not create stream imix2: %s' % res['log']) + streams_per_port.add_streams_from_res(res) + if kwargs['l3_imix3_ratio'] > 0: + if save_to_yaml and type(save_to_yaml) is str: + kwargs['save_to_yaml'] = save_to_yaml.replace('.yaml', '_imix3.yaml') + user_kwargs['frame_size'] = kwargs['l3_imix3_size'] + user_kwargs['rate_pps'] = rate_pps * kwargs['l3_imix3_ratio'] / total_rate + res = self.traffic_config(**user_kwargs) + if res['status'] == 0: + return HLT_ERR('Could not create stream imix3: %s' % res['log']) + streams_per_port.add_streams_from_res(res) + if kwargs['l3_imix4_ratio'] > 0: + if save_to_yaml and type(save_to_yaml) is str: + user_kwargs['save_to_yaml'] = save_to_yaml.replace('.yaml', '_imix4.yaml') + user_kwargs['frame_size'] = kwargs['l3_imix4_size'] + user_kwargs['rate_pps'] = rate_pps * kwargs['l3_imix4_ratio'] / total_rate + res = self.traffic_config(**user_kwargs) + if res['status'] == 0: + return HLT_ERR('Could not create stream imix4: %s' % res['log']) + streams_per_port.add_streams_from_res(res) + except Exception as e: + return HLT_ERR('Could not generate imix streams: %s' % e) + return HLT_OK(stream_id = streams_per_port) try: - stream_obj = CTRexHltApiPktBuilder.generate_stream(**kwargs) + stream_obj = CTRexHltApiBuilder.generate_stream(**kwargs) except Exception as e: return HLT_ERR('Could not create stream: %s' % e) - stream_id = stream_obj.get_id() # try adding the stream per ports try: - self.trex_client.add_streams(streams=stream_obj, - ports=port_handle) - self._hlt_streams_history[stream_id] = kwargs + stream_id_arr = self.trex_client.add_streams(streams=stream_obj, + ports=port_handle) + #print stream_id_arr, port_handle + #print self._streams_history + for port in port_handle: + #print type(user_kwargs) + self._streams_history.save_stream_args(port_handle, stream_id_arr[0], user_kwargs) + #print 'done' except Exception as e: return HLT_ERR('Could not add stream to ports: %s' % e) - return HLT_OK(stream_id = stream_obj.get_id()) + return HLT_OK(stream_id = dict((port, stream_id_arr) for port in port_handle)) return HLT_ERR('Got to the end of traffic_config, mode not implemented or forgot "return" function somewhere.') def traffic_control(self, **user_kwargs): + if not self.connected: + return HLT_ERR('connect first') kwargs = merge_kwargs(traffic_control_kwargs, user_kwargs) action = kwargs['action'] port_handle = kwargs['port_handle'] @@ -392,6 +572,8 @@ class CTRexHltApi(object): return HLT_ERR("Probably action '%s' is not implemented" % action) def traffic_stats(self, **user_kwargs): + if not self.connected: + return HLT_ERR('connect first') kwargs = merge_kwargs(traffic_stats_kwargs, user_kwargs) mode = kwargs['mode'] port_handle = kwargs['port_handle'] @@ -399,7 +581,7 @@ class CTRexHltApi(object): if mode not in ALLOWED_MODES: return HLT_ERR("'mode' must be one of the following values: %s" % ALLOWED_MODES) if mode == 'streams': - return HLT_ERR("'mode = streams' not implemented'") + return HLT_ERR("mode 'streams' not implemented'") if mode in ('all', 'aggregate'): hlt_stats_dict = {} try: @@ -407,7 +589,7 @@ class CTRexHltApi(object): except Exception as e: return HLT_ERR('Could not retrieve stats: %s' % e) for port_id, stat_dict in stats.iteritems(): - if type(port_id) is int: + if type(port_id) in (int, long): hlt_stats_dict[port_id] = { 'aggregate': { 'tx': { @@ -439,21 +621,22 @@ class CTRexHltApi(object): # * list - list of stream_id values or strings (see below) # * string - exact stream_id value, mix of ranges/list separated by comma: 2, 4-13 def _remove_stream(self, stream_id, port_handle): - if get_integer(stream_id) is not None: # exact value of int or str - self.trex_client.remove_stream(get_integer(stream_id), port_handle) # actual remove + if get_number(stream_id) is not None: # exact value of int or str + self.trex_client.remove_streams(get_number(stream_id), port_handle) # actual remove + return if type(stream_id) is list: # list of values/strings for each_stream_id in stream_id: - self._remove_stream(each_stream_id, port_handle) # recurse + self._remove_stream(each_stream_id, port_handle) # recurse return if type(stream_id) is str: # range or list in string if stream_id.find(',') != -1: for each_stream_id_element in stream_id.split(','): - self._remove_stream(each_stream_id_element, port_handle) # recurse + self._remove_stream(each_stream_id_element, port_handle) # recurse return if stream_id.find('-') != -1: stream_id_min, stream_id_max = stream_id.split('-', 1) - stream_id_min = get_integer(stream_id_min) - stream_id_max = get_integer(stream_id_max) + stream_id_min = get_number(stream_id_min) + stream_id_max = get_number(stream_id_max) if stream_id_min is None: raise Exception('_remove_stream: wrong range param %s' % stream_id_min) if stream_id_max is None: @@ -461,7 +644,7 @@ class CTRexHltApi(object): if stream_id_max < stream_id_min: raise Exception('_remove_stream: right range param is smaller than left one: %s-%s' % (stream_id_min, stream_id_max)) for each_stream_id in xrange(stream_id_min, stream_id_max + 1): - self._remove_stream(each_stream_id, port_handle) # recurse + self._remove_stream(each_stream_id, port_handle) # recurse return raise Exception('_remove_stream: wrong param %s' % stream_id) @@ -495,27 +678,27 @@ class CTRexHltApi(object): return '\n'. join([str(response) for response in responses]) return responses -class CTRexHltApiPktBuilder: +class CTRexHltApiBuilder: @staticmethod def generate_stream(**user_kwargs): kwargs = merge_kwargs(traffic_config_kwargs, user_kwargs) try: - packet = CTRexHltApiPktBuilder.generate_packet(**kwargs) - except Exception as e: + packet = CTRexHltApiBuilder.generate_packet(**kwargs) + #except Exception as e: + except ValueError as e: raise Exception('Could not generate packet: %s' % e) try: transmit_mode = kwargs['transmit_mode'] rate_pps = kwargs['rate_pps'] pkts_per_burst = kwargs['pkts_per_burst'] - burst_loop_count = kwargs['burst_loop_count'] - inter_burst_gap = kwargs['inter_burst_gap'] if transmit_mode == 'continuous': transmit_mode_class = STLTXCont(pps = rate_pps) elif transmit_mode == 'single_burst': transmit_mode_class = STLTXSingleBurst(pps = rate_pps, total_pkts = pkts_per_burst) elif transmit_mode == 'multi_burst': - transmit_mode_class = STLTXMultiBurst(pps = rate_pps, total_pkts = pkts_per_burst, count = burst_loop_count, ibg = inter_burst_gap) + transmit_mode_class = STLTXMultiBurst(pps = rate_pps, total_pkts = pkts_per_burst, + count = kwargs['burst_loop_count'], ibg = kwargs['inter_burst_gap']) else: raise Exception('transmit_mode %s not supported/implemented') except Exception as e: @@ -527,30 +710,41 @@ class CTRexHltApiPktBuilder: #self_start = True, mode = transmit_mode_class, #rx_stats = rx_stats, - #next_stream_id = -1 + #next_stream_id = -1, + stream_id = kwargs.get('stream_id'), + name = kwargs.get('name'), ) except Exception as e: raise Exception('Could not create stream: %s' % e) debug_filename = kwargs.get('save_to_yaml') if type(debug_filename) is str: - STLProfile(stream_obj).dump_to_yaml(debug_filename) + stream_obj.dump_to_yaml(debug_filename) return stream_obj @staticmethod def generate_packet(**user_kwargs): kwargs = merge_kwargs(traffic_config_kwargs, user_kwargs) - pkt = pkt_bld.CScapyTRexPktBuilder() + pkt = STLPktBuilder() vm_cmds = [] fix_ipv4_checksum = False ### L2 ### - if kwargs['l2_encap'] == 'ethernet_ii': + if kwargs['l2_encap'] in ('ethernet_ii', 'ethernet_ii_vlan'): #fields_desc = [ MACField("dst","00:00:00:01:00:00"), # MACField("src","00:00:00:02:00:00"), # XShortEnumField("type", 0x9000, ETHER_TYPES) ] - l2_layer = pkt_bld.Ether(src = kwargs['mac_src'], dst = kwargs['mac_dst']) + l2_layer = Ether(src = kwargs['mac_src'], dst = kwargs['mac_dst']) + if kwargs['l2_encap'] == 'ethernet_ii_vlan': + #fields_desc = [ BitField("prio", 0, 3), + # BitField("id", 0, 1), + # BitField("vlan", 1, 12), + # XShortEnumField("type", 0x0000, ETHER_TYPES) ] + l2_layer /= Dot1Q(prio = kwargs['vlan_user_priority'], + vlan = kwargs['vlan_id'], + id = kwargs['vlan_cfi'], + ) else: raise NotImplementedError("l2_encap does not support the desired encapsulation '%s'" % kwargs['l2_encap']) base_pkt = l2_layer @@ -572,15 +766,15 @@ class CTRexHltApiPktBuilder: # Emph(IPField("src", "16.0.0.1")), # Emph(IPField("dst", "48.0.0.1")), # PacketListField("options", [], IPOption, length_from=lambda p:p.ihl*4-20) ] - l3_layer = pkt_bld.IP(tos = kwargs['ip_tos_field'], - len = None if kwargs['length_mode'] == 'auto' else kwargs['l3_length'], - id = kwargs['ip_id'], - frag = kwargs['ip_fragment_offset'], - ttl = kwargs['ip_ttl'], - chksum = kwargs['ip_checksum'], - src = kwargs['ip_src_addr'], - dst = kwargs['ip_dst_addr'] - ) + l3_layer = IP(tos = kwargs['ip_tos_field'], + len = None if kwargs['length_mode'] == 'auto' else kwargs['l3_length'], + id = kwargs['ip_id'], + frag = kwargs['ip_fragment_offset'], + ttl = kwargs['ip_ttl'], + chksum = kwargs['ip_checksum'], + src = kwargs['ip_src_addr'], + dst = kwargs['ip_dst_addr'], + ) # IPv4 VM if kwargs['ip_src_mode'] != 'fixed': fix_ipv4_checksum = True @@ -588,7 +782,7 @@ class CTRexHltApiPktBuilder: raise Exception('ip_src_step has to be 1 (TRex limitation)') if kwargs['ip_src_count'] < 1: raise Exception('ip_src_count has to be at least 1') - ip_src_addr_num = pkt_bld.ipv4_str_to_num(pkt_bld.is_valid_ipv4(kwargs['ip_src_addr'])) + ip_src_addr_num = ipv4_str_to_num(is_valid_ipv4(kwargs['ip_src_addr'])) if kwargs['ip_src_mode'] == 'increment': vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_src', size = 4, op = 'inc', min_value = ip_src_addr_num, @@ -611,7 +805,7 @@ class CTRexHltApiPktBuilder: raise Exception('ip_dst_step has to be 1 (TRex limitation)') if kwargs['ip_dst_count'] < 1: raise Exception('ip_dst_count has to be at least 1') - ip_dst_addr_num = pkt_bld.ipv4_str_to_num(pkt_bld.is_valid_ipv4(kwargs['ip_dst_addr'])) + ip_dst_addr_num = ipv4_str_to_num(is_valid_ipv4(kwargs['ip_dst_addr'])) if kwargs['ip_dst_mode'] == 'increment': vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_dst', size = 4, op = 'inc', min_value = ip_dst_addr_num, @@ -651,16 +845,16 @@ class CTRexHltApiPktBuilder: 'A' if kwargs['tcp_ack_flag'] else '' + 'U' if kwargs['tcp_urg_flag'] else '') - l4_layer = pkt_bld.TCP(sport = kwargs['tcp_src_port'], - dport = kwargs['tcp_dst_port'], - seq = kwargs['tcp_seq_num'], - ack = kwargs['tcp_ack_num'], - dataofs = kwargs['tcp_data_offset'], - flags = tcp_flags, - window = kwargs['tcp_window'], - chksum = kwargs['tcp_checksum'], - urgptr = kwargs['tcp_urgent_ptr'], - ) + l4_layer = TCP(sport = kwargs['tcp_src_port'], + dport = kwargs['tcp_dst_port'], + seq = kwargs['tcp_seq_num'], + ack = kwargs['tcp_ack_num'], + dataofs = kwargs['tcp_data_offset'], + flags = tcp_flags, + window = kwargs['tcp_window'], + chksum = kwargs['tcp_checksum'], + urgptr = kwargs['tcp_urgent_ptr'], + ) # TCP VM if kwargs['tcp_src_port_count'] != 1: fix_ipv4_checksum = True @@ -712,10 +906,10 @@ class CTRexHltApiPktBuilder: # ShortEnumField("dport", 53, UDP_SERVICES), # ShortField("len", None), # XShortField("chksum", None), ] - l4_layer = pkt_bld.UDP(sport = kwargs['udp_src_port'], - dport = kwargs['udp_dst_port'], - len = kwargs['udp_length'], - chksum = kwargs['udp_checksum']) + l4_layer = UDP(sport = kwargs['udp_src_port'], + dport = kwargs['udp_dst_port'], + len = kwargs['udp_length'], + chksum = kwargs['udp_checksum']) # UDP VM if kwargs['udp_src_port_count'] != 1: fix_ipv4_checksum = True @@ -768,6 +962,8 @@ class CTRexHltApiPktBuilder: payload_len = 0 elif kwargs['length_mode'] == 'fixed': payload_len = kwargs['frame_size'] - len(base_pkt) + elif kwargs['length_mode'] == 'imix': + raise Exception("Should not use length_mode 'imix' directly in packet building, convert it to other mode at higher levels (stream?)") else: fix_ipv4_checksum = True if kwargs['frame_size_step'] != 1 or kwargs['l3_length_step'] != 1: @@ -784,7 +980,7 @@ class CTRexHltApiPktBuilder: min_value = kwargs['l3_length_min'] + len(l2_layer), max_value = kwargs['l3_length_max'] + len(l2_layer))) payload_len = kwargs['l3_length_max'] + len(l2_layer) - len(base_pkt) - vm_cmds.append(pkt_bld.CTRexVmDescTrimPktSize('fv_rand')) + vm_cmds.append(CTRexVmDescTrimPktSize('fv_rand')) if l3_layer.name == 'IP' or l4_layer.name == 'UDP': # add here other things need to fix due to size change if l3_layer.name == 'IP': vm_cmds.append(CTRexVmDescWrFlowVar(fv_name = 'fv_rand', pkt_offset = 'IP.len', add_val = -len(l2_layer))) @@ -797,9 +993,9 @@ class CTRexHltApiPktBuilder: pkt.set_packet(base_pkt) if fix_ipv4_checksum and l3_layer.name == 'IP' and kwargs['ip_checksum'] is None: - vm_cmds.append(pkt_bld.CTRexVmDescFixIpv4(offset = 'IP')) + vm_cmds.append(CTRexVmDescFixIpv4(offset = 'IP')) if vm_cmds: - pkt.add_command(pkt_bld.CTRexScRaw(vm_cmds)) + pkt.add_command(CTRexScRaw(vm_cmds)) # debug (only the base packet, without VM) debug_filename = kwargs.get('save_to_pcap') diff --git a/scripts/automation/trex_control_plane/client_utils/general_utils.py b/scripts/automation/trex_control_plane/client_utils/general_utils.py index 3d55bc3e..9a510ec5 100755 --- a/scripts/automation/trex_control_plane/client_utils/general_utils.py +++ b/scripts/automation/trex_control_plane/client_utils/general_utils.py @@ -90,9 +90,11 @@ def id_count_gen(): yield return_id return_id += 1 -# try to get integer from input, return None in case of fail -def get_integer(input): +# try to get number from input, return None in case of fail +def get_number(input): try: + if type(input) in (int, long): + return input return int(input) except: return None diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py index 732cfc1e..b1cf9ebc 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py @@ -52,7 +52,7 @@ class Port(object): self.port_stats = trex_stl_stats.CPortStats(self) - self.next_available_id = 1 + self.next_available_id = long(1) def err(self, msg): @@ -132,7 +132,7 @@ class Port(object): # TODO: handle syncing the streams into stream_db - self.next_available_id = rc.data()['max_stream_id'] + self.next_available_id = long(rc.data()['max_stream_id']) return self.ok() diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py index 1ed55e4c..33e958dd 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py @@ -90,7 +90,7 @@ class STLTXMultiBurst(STLTXMode): class STLStream(object): def __init__ (self, - name = random_name(8), + name = None, packet = None, mode = STLTXCont(1), enabled = True, @@ -120,7 +120,7 @@ class STLStream(object): raise STLError("continuous stream cannot have a next stream ID") # tag for the stream and next - can be anything - self.name = name + self.name = name if name else random_name(8) self.next = next self.set_id(stream_id) @@ -179,7 +179,15 @@ class STLStream(object): def to_yaml (self): return {'name': self.name, 'stream': self.fields} + def dump_to_yaml (self, yaml_file = None): + yaml_dump = yaml.dump([self.to_yaml()], default_flow_style = False) + + # write to file if provided + if yaml_file: + with open(yaml_file, 'w') as f: + f.write(yaml_dump) + return yaml_dump class YAMLLoader(object): @@ -303,7 +311,7 @@ class STLProfile(object): streams = [streams] if not all([isinstance(stream, STLStream) for stream in streams]): - raise STLArgumentError('streams', streams) + raise STLArgumentError('streams', streams, valid_values = STLStream) self.streams = streams -- cgit 1.2.3-korg