diff options
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/api/stl/examples/stl_bi_dir_flows.py | 8 | ||||
-rw-r--r-- | scripts/api/stl/examples/stl_simple_burst.py | 4 | ||||
-rwxr-xr-x | scripts/automation/regression/CPlatform.py | 10 | ||||
-rwxr-xr-x | scripts/automation/regression/aggregate_results.py | 24 | ||||
-rwxr-xr-x | scripts/automation/regression/hltapi_example.py | 74 | ||||
-rwxr-xr-x | scripts/automation/regression/stateless_example.py | 47 | ||||
-rwxr-xr-x | scripts/automation/regression/unit_tests/trex_general_test.py | 1 | ||||
-rwxr-xr-x | scripts/automation/trex_control_plane/client/trex_hltapi.py | 658 | ||||
-rw-r--r-- | scripts/automation/trex_control_plane/client/trex_port.py | 38 | ||||
-rwxr-xr-x | scripts/automation/trex_control_plane/client/trex_stateless_client.py | 105 | ||||
-rwxr-xr-x | scripts/automation/trex_control_plane/client_utils/general_utils.py | 7 | ||||
-rwxr-xr-x | scripts/automation/trex_control_plane/common/trex_streams.py | 5 | ||||
-rwxr-xr-x | scripts/automation/trex_control_plane/console/trex_console.py | 8 | ||||
-rw-r--r-- | scripts/ko/3.19.0-25-generic/igb_uio.ko | bin | 0 -> 16711 bytes |
14 files changed, 672 insertions, 317 deletions
diff --git a/scripts/api/stl/examples/stl_bi_dir_flows.py b/scripts/api/stl/examples/stl_bi_dir_flows.py index 429445e6..38cb36dd 100644 --- a/scripts/api/stl/examples/stl_bi_dir_flows.py +++ b/scripts/api/stl/examples/stl_bi_dir_flows.py @@ -90,11 +90,11 @@ def simple_burst (): # read the stats after the test stats = c.get_stats() - print json.dumps(stats["port 0"], indent = 4, separators=(',', ': '), sort_keys = True) - print json.dumps(stats["port 1"], indent = 4, separators=(',', ': '), sort_keys = True) + print json.dumps(stats[0], indent = 4, separators=(',', ': '), sort_keys = True) + print json.dumps(stats[1], indent = 4, separators=(',', ': '), sort_keys = True) - lost_a = stats["port 0"]["opackets"] - stats["port 1"]["ipackets"] - lost_b = stats["port 1"]["opackets"] - stats["port 0"]["ipackets"] + lost_a = stats[0]["opackets"] - stats[1]["ipackets"] + lost_b = stats[1]["opackets"] - stats[0]["ipackets"] print "\npackets lost from 0 --> 1: {0} pkts".format(lost_a) print "packets lost from 1 --> 0: {0} pkts".format(lost_b) diff --git a/scripts/api/stl/examples/stl_simple_burst.py b/scripts/api/stl/examples/stl_simple_burst.py index 3b394d10..2ca71b44 100644 --- a/scripts/api/stl/examples/stl_simple_burst.py +++ b/scripts/api/stl/examples/stl_simple_burst.py @@ -37,7 +37,7 @@ def simple_burst (): try: - #c.logger.set_verbose(c.logger.VERBOSE_NORMAL) + #c.set_verbose("high") # create two bursts and link them s1 = STLStream(packet = pkt_bld, @@ -56,7 +56,7 @@ def simple_burst (): c.reset(ports = [0, 1]) # add both streams to ports - c.add_streams([s1, s2], ports = [0, 1]) + stream_ids = c.add_streams([s1, s2], ports = [0, 1]) # run 5 times for i in xrange(1, 6): diff --git a/scripts/automation/regression/CPlatform.py b/scripts/automation/regression/CPlatform.py index 09c99566..6741d5c1 100755 --- a/scripts/automation/regression/CPlatform.py +++ b/scripts/automation/regression/CPlatform.py @@ -651,7 +651,7 @@ class CPlatform(object): response = self.cmd_link.run_single_command(command, timeout = 10) if CShowParser.parse_image_existence(response, img_name): self.needed_image_path = '%s:%s' % (search_drive, img_name) - print 'Found image in platform:', self.needed_image_path + print('Found image in platform:', self.needed_image_path) return True return False @@ -707,8 +707,8 @@ class CPlatform(object): progress_thread.start() response = self.cmd_link.run_single_command(cache, timeout = 900, read_until = ['\?', '\#']) - print "RESPONSE:" - print response + print("RESPONSE:") + print(response) progress_thread.join() copy_ok = CShowParser.parse_file_copy(response) @@ -865,7 +865,7 @@ class CStaticRouteConfig(object): def dump_config (self): import yaml - print yaml.dump( self.static_route_dict , default_flow_style=False) + print(yaml.dump( self.static_route_dict , default_flow_style=False)) class CNatConfig(object): @@ -901,7 +901,7 @@ class CNatConfig(object): def dump_config (self): import yaml - print yaml.dump( self.nat_dict , default_flow_style=False) + print(yaml.dump( self.nat_dict , default_flow_style=False)) if __name__ == "__main__": diff --git a/scripts/automation/regression/aggregate_results.py b/scripts/automation/regression/aggregate_results.py index 0ef3b5af..2a21b4be 100755 --- a/scripts/automation/regression/aggregate_results.py +++ b/scripts/automation/regression/aggregate_results.py @@ -17,6 +17,13 @@ ERROR_CATEGORY = 'Error' def pad_tag(text, tag): return '<%s>%s</%s>' % (tag, text, tag) +def add_color_string(text, color, is_bold = False): + string = '<font color=%s>%s</font>' % (color, text) + if is_bold: + return pad_tag(string, 'b') + return string + + def is_functional_test_name(testname): #if testname.startswith(('platform_', 'misc_methods_', 'vm_', 'payload_gen_', 'pkt_builder_')): # return True @@ -316,6 +323,17 @@ if __name__ == '__main__': test.attrib['classname'] = job aggregated_root.append(test) + total_tests_count = int(aggregated_root.attrib.get('tests', 0)) + error_tests_count = int(aggregated_root.attrib.get('errors', 0)) + failure_tests_count = int(aggregated_root.attrib.get('failures', 0)) + skipped_tests_count = int(aggregated_root.attrib.get('skip', 0)) + passed_tests_count = total_tests_count - error_tests_count - failure_tests_count - skipped_tests_count + tests_count_string = 'Total: %s, ' % total_tests_count + tests_count_string += add_color_string('Passed: %s' % passed_tests_count, 'green', error_tests_count + failure_tests_count > 0) + ', ' + tests_count_string += add_color_string('Error: %s' % error_tests_count, 'red', error_tests_count > 0) + ', ' + tests_count_string += add_color_string('Failure: %s' % failure_tests_count, 'red', failure_tests_count > 0) + ', ' + tests_count_string += add_color_string('Skipped: %s' % skipped_tests_count, 'blue') + ##### save output xml print('Writing output file: %s' % args.output_xmlfile) @@ -371,8 +389,9 @@ if __name__ == '__main__': with open(start_time_file) as f: start_time = int(f.read()) total_time = int(time.time()) - start_time - html_output += add_th_td('Regression start:', datetime.datetime.fromtimestamp(start_time).strftime('%d/%m/%Y %H:%M:%S')) + html_output += add_th_td('Regression start:', datetime.datetime.fromtimestamp(start_time).strftime('%d/%m/%Y %H:%M')) html_output += add_th_td('Regression duration:', datetime.timedelta(seconds = total_time)) + html_output += add_th_td('Tests count:', tests_count_string) for key in trex_info_dict: if key == 'Git SHA': continue @@ -488,8 +507,9 @@ if __name__ == '__main__': with open(start_time_file) as f: start_time = int(f.read()) total_time = int(time.time()) - start_time - mail_output += add_th_td('Regression start:', datetime.datetime.fromtimestamp(start_time).strftime('%d/%m/%Y %H:%M:%S')) + mail_output += add_th_td('Regression start:', datetime.datetime.fromtimestamp(start_time).strftime('%d/%m/%Y %H:%M')) mail_output += add_th_td('Regression duration:', datetime.timedelta(seconds = total_time)) + mail_output += add_th_td('Tests count:', tests_count_string) for key in trex_info_dict: if key == 'Git SHA': continue diff --git a/scripts/automation/regression/hltapi_example.py b/scripts/automation/regression/hltapi_example.py new file mode 100755 index 00000000..750d7c2b --- /dev/null +++ b/scripts/automation/regression/hltapi_example.py @@ -0,0 +1,74 @@ +#!/router/bin/python + +import outer_packages +from client.trex_hltapi import CTRexHltApi +import traceback +import sys, time +from pprint import pprint + +def check_response(res): + if res['status'] == 0: + print 'Encountered error:\n%s' % res['log'] + sys.exit(1) + +if __name__ == "__main__": + try: + is_verbose = 2 if '--verbose' in sys.argv else 1 + hlt_client = CTRexHltApi(verbose = is_verbose) + + print 'Connecting...' + res = hlt_client.connect(device = 'csi-trex-04', port_list = [0], username = 'danklei', break_locks = True, reset = True) + check_response(res) + port_handle = res['port_handle'] + print 'Connected.' + + res = hlt_client.traffic_config('reset', port_handle = port_handle[:], ip_src_addr='1.1.1.1') + print res + check_response(res) + + res = hlt_client.traffic_config('create', port_handle = port_handle[:], ip_src_addr='1.1.1.1') + print res + check_response(res) + + + res = hlt_client.traffic_config('create', port_handle = port_handle[0], ip_src_addr='2.2.2.2') + check_response(res) + + + res = hlt_client.get_stats() + res = hlt_client.traffic_config('modify', port_handle = port_handle[0], stream_id = 1, ip_src_addr='6.6.6.6') + check_response(res) + #for stream_id, stream_data in hlt_client.get_port_streams(0).iteritems(): + # print '>>>>>>>>> %s: %s' % (stream_id, stream_data) + + + check_response(hlt_client.traffic_config('create', port_handle = port_handle[1], ip_src_addr='3.3.3.3')) + check_response(hlt_client.traffic_config('create', port_handle = port_handle[1], ip_src_addr='4.4.4.4')) + print '2' + check_response(htl_client.traffic_config('create', port_handle = port_handle[:], stream_id = 999, ip_src_addr='5.5.5.5')) + check_response(hlt_client.traffic_config('modify', port_handle = port_handle[0], stream_id = 1, ip_src_addr='6.6.6.6')) + print '3' + check_response(hlt_client.traffic_config('modify', port_handle = port_handle[1], stream_id = 1)) + +# res = hlt_client.traffic_config('create', port_handle = port_handle[1])#, ip_src_addr='2000.2.2') +# if res['status'] == 0: +# fail(res['log']) + + print 'got to running!' + check_response(hlt_client.traffic_control('run', port_handle = port_handle[1], mul = {'type': 'raw', 'op': 'abs', 'value': 10}, duration = 15)) + for i in range(0, 15): + print '.', + time.sleep(1) + + print 'stop the traffic!' + check_response(hlt_client.traffic_control('stop', port_handle = port_handle[1])) + + + except Exception as e: + print traceback.print_exc() + print e + raise + finally: + print 'Done.' + #if hlt_client.trex_client: + # res = hlt_client.teardown() diff --git a/scripts/automation/regression/stateless_example.py b/scripts/automation/regression/stateless_example.py deleted file mode 100755 index 93fb2703..00000000 --- a/scripts/automation/regression/stateless_example.py +++ /dev/null @@ -1,47 +0,0 @@ -#!/router/bin/python - -import outer_packages -from client.trex_hltapi import CTRexHltApi -import traceback -import sys, time - -def fail(reason): - print 'Encountered error:\n%s' % reason - sys.exit(1) - -if __name__ == "__main__": - port_list = [0, 1] - #port_list = 1 - try: - print 'init' - hlt_client = CTRexHltApi() - - print 'connecting' - con = hlt_client.connect("localhost", port_list, "danklei", sync_port = 4501, async_port = 4500, break_locks=True, reset=True)#, port=6666) - print 'connected?', hlt_client.connected - if not hlt_client.trex_client or not hlt_client.connected: - fail(con['log']) - print 'connect result:', con - - res = hlt_client.traffic_config("create", 0)#, ip_src_addr="2000.2.2") - print 'traffic_config result:', res - - res = hlt_client.traffic_config("create", 1)#, ip_src_addr="2000.2.2") - print res - print 'got to running!' - #sys.exit(0) - res = hlt_client.traffic_control("run", 1, mul = {'type': 'raw', 'op': 'abs', 'value': 1}, duration = 15)#, ip_src_addr="2000.2.2") - print res - time.sleep(2) - res = hlt_client.traffic_control("stop", 1)#, ip_src_addr="2000.2.2") - print res - - - - except Exception as e: - raise - finally: - #pass - if hlt_client.trex_client: - res = hlt_client.cleanup_session(port_list) - print res diff --git a/scripts/automation/regression/unit_tests/trex_general_test.py b/scripts/automation/regression/unit_tests/trex_general_test.py index 9bcccaab..170baf84 100755 --- a/scripts/automation/regression/unit_tests/trex_general_test.py +++ b/scripts/automation/regression/unit_tests/trex_general_test.py @@ -54,6 +54,7 @@ class CTRexScenario(): router_image = None trex_version = None scripts_path = None + benchmark = None report_dir = 'reports' # logger = None diff --git a/scripts/automation/trex_control_plane/client/trex_hltapi.py b/scripts/automation/trex_control_plane/client/trex_hltapi.py index c25c73cb..4a43f66b 100755 --- a/scripts/automation/trex_control_plane/client/trex_hltapi.py +++ b/scripts/automation/trex_control_plane/client/trex_hltapi.py @@ -1,252 +1,426 @@ #!/router/bin/python +''' +Supported function/arguments: +connect() + device + port_list + username + reset + break_locks + +cleanup_session() + maintain_lock + port_list + port_handle + +traffic_config() + mode ( create | modify | remove | reset ) + port_handle + transmit_mode ( continuous | multi_burst | single_burst ) + rate_pps + stream_id + bidirectional + l2_encap + mac_src + mac_dst + l3_protocol + ip_src_addr + ip_dst_addr + l3_length + l4_protocol + +traffic_control() + action ( run | stop ) + port_handle + +traffic_stats() + mode ( aggregate ) + port_handle + +''' + + + import trex_root_path from client_utils.packet_builder import CTRexPktBuilder from trex_stateless_client import STLClient from common.trex_streams import * -from client_utils.general_utils import id_count_gen +from client_utils.general_utils import get_integer import dpkt +import socket +from misc_methods import print_r +import traceback + +class HLT_ERR(dict): + def __init__(self, log = 'Unknown error', **kwargs): + dict.__init__(self, {'status': 0}) + if type(log) is dict: + dict.update(self, log) + elif type(log) is str and not log.startswith('[ERR]'): + self['log'] = '[ERR] ' + log + else: + self['log'] = log + dict.update(self, kwargs) + +class HLT_OK(dict): + def __init__(self, init_dict = {}, **kwargs): + dict.__init__(self, {'status': 1, 'log': None}) + dict.update(self, init_dict) + dict.update(self, kwargs) class CTRexHltApi(object): - def __init__(self): + def __init__(self, verbose = 1): self.trex_client = None self.connected = False - # self._stream_db = CStreamList() - self._port_data = {} + self.verbose = verbose + self._hlt_streams_history = {} # streams per stream_id in format of HLT arguments for modify later + + +########################### +# Session functions # +########################### - # ----- session functions ----- # - # sync = RPC, async = ZMQ - def connect(self, device, port_list, username, sync_port = 4501, async_port = 4500, reset=False, break_locks=False): - ret_dict = {"status": 0} - self.trex_client = STLClient(username, device, sync_port, async_port) + # device: ip or hostname + def connect(self, device, port_list, username='', reset=False, break_locks=False): - rc = self.trex_client.connect() - if rc.bad(): + try: + device = socket.gethostbyname(device) # work with ip + except: # give it another try + try: + device = socket.gethostbyname(device) + except Exception as e: + return HLT_ERR('Could not translate hostname "%s" to IP: %s' % (device, e)) + try: + # sync = RPC, async = ZMQ + self.trex_client = STLClient(username, device, sync_port = 4501, async_port = 4500, verbose_level = self.verbose) + except Exception as e: self.trex_client = None - ret_dict.update({"log": rc.err()}) - return ret_dict - # arrived here, connection successfully created with server - # next, try acquiring ports of TRex - port_list = self.parse_port_list(port_list) - response = self.trex_client.acquire(port_list, force=break_locks) - res_ok, log = CTRexHltApi.process_response(port_list, response) - if not res_ok: - self.trex_client.disconnect() + return HLT_ERR('Could not init stateless client %s: %s' % (device, e)) + try: + self.trex_client.connect() + except Exception as e: self.trex_client = None - ret_dict.update({"log": log}) - # TODO: should revert taken ports?! - return ret_dict + 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(port_list) + self.trex_client.acquire(ports = port_list, force = break_locks) + except Exception as e: + self.trex_client = None + return HLT_ERR('Could not acquire ports %s: %s' % (port_list, e)) + + # since only supporting single TRex at the moment, 1:1 map + port_handle = self.trex_client.get_acquired_ports() + # arrived here, all desired ports were successfully acquired - print log if reset: # remove all port traffic configuration from TRex - response = self.trex_client.remove_all_streams(port_list) - res_ok, log = CTRexHltApi.process_response(port_list, response) - if not res_ok: - self.trex_client.disconnect() + try: + self.trex_client.reset(ports = port_list) + except Exception as e: self.trex_client = None - ret_dict.update({"log": log}) - return ret_dict - print log - port_handle = {device: {port: port # since only supporting single TRex at the moment, 1:1 map - for port in port_list} - } - ret_dict.update({"status": 1, - "log": None, - "port_handle": port_handle, - "offline": 0}) # ports are online + return HLT_ERR('Error in reset traffic: %s' % e) + self.connected = True - self._port_data_init(port_list) - return ret_dict + return HLT_OK(port_handle = port_handle) - def cleanup_session(self, port_list, maintain_lock=False): - ret_dict = {"status": 0} + def cleanup_session(self, maintain_lock = False, **kwargs): if not maintain_lock: # release taken ports - if port_list == "all": - port_list = self.trex_client.get_acquired_ports() - else: - port_list = self.parse_port_list(port_list) - response = self.trex_client.release(port_list) - res_ok, log = CTRexHltApi.process_response(port_list, response) - if not res_ok: - ret_dict.update({"log": log}) - return ret_dict - ret_dict.update({"status": 1, - "log": None}) - self.trex_client.disconnect() + port_list = kwargs.get('port_list', kwargs.get('port_handle', 'all')) + try: + if port_list == 'all': + port_list = self.trex_client.get_acquired_ports() + else: + port_list = self.parse_port_list(port_list) + except Exception as e: + return HLT_ERR('Unable to determine which ports to release: %s' % e) + try: + self.trex_client.release(port_list) + except Exception as e: + return HLT_ERR('Unable to release ports %s: %s' % (port_list, e)) + try: + self.trex_client.disconnect(stop_traffic = False, release_ports = False) + except Exception as e: + return HLT_ERR('Error disconnecting: %s' % e) self.trex_client = None self.connected = False - return ret_dict + return HLT_OK() - def interface_config(self, port_handle, mode="config"): - ALLOWED_MODES = ["config", "modify", "destroy"] + def interface_config(self, port_handle, mode='config'): + ALLOWED_MODES = ['config', 'modify', 'destroy'] if mode not in ALLOWED_MODES: - raise ValueError("mode must be one of the following values: {modes}".format(modes=ALLOWED_MODES)) + return HLT_ERR('Mode must be one of the following values: %s' % ALLOWED_MODES) # pass this function for now... - return {"status": 1, "log": None} - - # ----- traffic functions ----- # - def traffic_config(self, mode, port_list, - l2_encap="ethernet_ii", mac_src="00:00:01:00:00:01", mac_dst="00:00:00:00:00:00", - l3_protocol="ipv4", ip_src_addr="0.0.0.0", ip_dst_addr="192.0.0.1", l3_length=110, - transmit_mode="continuous", rate_pps=100, - **kwargs): - if type(port_list) is not list(): - port_list = [port_list] - ALLOWED_MODES = ["create", "modify", "remove", "enable", "disable", "reset"] + return HLT_ERR('interface_config not implemented yet') + + +########################### +# Traffic functions # +########################### + + def traffic_config(self, mode, port_handle, **kwargs): + stream_id = kwargs.get('stream_id') + if type(stream_id) is list: + del kwargs['stream_id'] + for each_stream_id in stream_id: + res = self.traffic_config(mode, port_handle, stream_id = each_stream_id, **kwargs) + if type(res) is HLT_ERR: + return res + return HLT_OK() + + if type(port_handle) is not list: + port_handle = [port_handle] + ALLOWED_MODES = ['create', 'modify', 'remove', 'enable', 'disable', 'reset'] if mode not in ALLOWED_MODES: - raise ValueError("mode must be one of the following values: {modes}".format(modes=ALLOWED_MODES)) - if mode == "create": + return HLT_ERR('Mode must be one of the following values: %s' % ALLOWED_MODES) + + if mode == 'reset': + try: + self.trex_client.remove_all_streams(port_handle) + return HLT_OK() + except Exception as e: + return HLT_ERR('Could not reset streams at ports %s: %s' % (port_handle, e)) + + if mode == 'remove': + if stream_id is None: + return HLT_ERR('Please specify stream_id to remove.') + if type(stream_id) is str and stream_id == 'all': + try: + self.trex_client.remove_all_streams(port_handle) + except Exception as e: + return HLT_ERR('Could not remove all streams at ports %s: %s' % (port_handle, e)) + else: + 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_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: + # 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 + + + 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 + kwargs = self._hlt_streams_history[stream_id] + #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)) + 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)) + + if mode == 'create' or mode == 'modify': # create a new stream with desired attributes, starting by creating packet + + if 'bidirectional' in kwargs: # two streams with opposite src and dst MAC + del kwargs['bidirectional'] + bidirect_err = 'When using bidirectional flag, ' + if len(port_handle) != 2: + return HLT_ERR(bidirect_err + 'number of ports should be exactly 2') + if mac_src not in kwargs or mac_dst not in kwargs: + return HLT_ERR(bidirect_err + 'mac_src and mac_dst should be specified') + try: + res1 = self.traffic_config(mode, port_handle[0], **kwargs) + res2 = self.traffic_config(mode, port_handle[1], mac_src = kwargs['mac_dst'], mac_dst = kwargs['mac_src'], **kwargs) + except Exception as e: + return HLT_ERR('Could not generate bidirectional traffic: %s' % e) + return HLT_OK(stream_id = [res1['stream_id'], res2['stream_id']]) + + try: + packet = CTRexHltApi._generate_stream(**kwargs) + except Exception as e: + return HLT_ERR('Could not generate stream: %s' % e) + # set transmission attributes + #try: + # tx_mode = CTxMode(type = transmit_mode, pps = rate_pps, **kwargs) + #except Exception as e: + # return HLT_ERR('Could not init CTxMode: %s' % e) + try: - packet = CTRexHltApi.generate_stream(l2_encap, mac_src, mac_dst, - l3_protocol, ip_src_addr, ip_dst_addr, l3_length) - # set transmission attributes - tx_mode = CTxMode(transmit_mode, rate_pps, **kwargs) # set rx_stats - rx_stats = CRxStats() # defaults with disabled + #rx_stats = CRxStats() # defaults with disabled + rx_stats = None + except Exception as e: + return HLT_ERR('Could not init CTxMode: %s' % e) + + try: + transmit_mode = kwargs.get('transmit_mode', 'continuous') + rate_pps = kwargs.get('rate_pps', 1) + pkts_per_burst = kwargs.get('pkts_per_burst', 1) + burst_loop_count = kwargs.get('burst_loop_count', 1) + inter_burst_gap = kwargs.get('inter_burst_gap', 12) + 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) + else: + return HLT_ERR('transmit_mode %s not supported/implemented') + except Exception as e: + # some exception happened during the stream creation + return HLT_ERR('Could not create transmit_mode class %s: %s' % (transmit_mode, e)) + + try: # join the generated data into stream - stream_obj = CStream() - stream_obj_params = {"enabled": True, - "self_start": True, - "next_stream_id": -1, - "isg": 0.0, - "mode": tx_mode, - "rx_stats": rx_stats, - "packet": packet} # vm is excluded from this list since CTRexPktBuilder obj is passed - stream_obj.load_data(**stream_obj_params) + + stream_obj = STLStream(packet = packet, + #enabled = True, + #self_start = True, + mode = transmit_mode_class, + rx_stats = rx_stats, + #next_stream_id = -1 + ) + # using CStream + #stream_obj_params = {'enabled': False, + # 'self_start': True, + # 'next_stream_id': -1, + # 'isg': 0.0, + # 'mode': tx_mode, + # 'rx_stats': rx_stats, + # 'packet': packet} # vm is excluded from this list since CTRexPktBuilder obj is passed + #stream_obj.load_data(**stream_obj_params) + #print stream_obj.get_id() except Exception as e: # some exception happened during the stream creation - return {"status": 0, "log": str(e)} - # try adding the stream per port, until free stream_id is found - for port_id in port_list: - port_data = self._port_data.get(port_id) - id_candidate = None - # TODO: change this to better implementation - while True: - id_candidate = port_data["stream_id_gen"].next() - response = self.trex_client.add_stream(stream_id=id_candidate, - stream_obj=stream_obj.dump(), - port_id_list=port_id) - res_ok, log = CTRexHltApi.process_response(port_id, response) - if res_ok: - # found non-taken stream_id on server - # save it for modifying needs - port_data["streams"].update({id_candidate: stream_obj}) - break - else: - print log - # proceed to another iteration to use another id - print 'need another iteration?' - continue - return {"status": 1, - "stream_id": id_candidate, - "log": None} + return HLT_ERR(e) - else: - raise NotImplementedError("mode '{0}' is not supported yet on TRex".format(mode)) + stream_id = stream_obj.get_id() + #print stream_obj + # 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 + 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_ERR('Got to the end of traffic_config, mode not implemented or forgot "return" function somewhere.') def traffic_control(self, action, port_handle, **kwargs): - ALLOWED_ACTIONS = ["clear_stats", "run", "stop", "sync_run"] + ALLOWED_ACTIONS = ['clear_stats', 'run', 'stop', 'sync_run'] if action not in ALLOWED_ACTIONS: - raise ValueError("action must be one of the following values: {actions}".format(actions=ALLOWED_ACTIONS)) - # ret_dict = {"status": 0, "stopped": 1} - port_list = self.parse_port_list(port_handle) - if type(port_list) is not list(): - port_list = [port_list] - if action == "run": - if not set(kwargs.keys()) >= set(['mul', 'duration']): - raise ValueError("For 'run' action should be specified mul and duration arguments") - response = self.trex_client.start_traffic(kwargs['mul'], kwargs['duration'], port_id_list=port_list) - res_ok, log = CTRexHltApi.process_response(port_list, response) - if res_ok: - return {"status": 1, - "stopped": 0, - "log": None} - else: - print log - elif action == "stop": - response = self.trex_client.stop_traffic(port_id_list=port_list) - res_ok, log = CTRexHltApi.process_response(port_list, response) - if res_ok: - return {"status": 1, - "stopped": 1, - "log": None} + return HLT_ERR('Action must be one of the following values: {actions}'.format(actions=ALLOWED_ACTIONS)) + if type(port_handle) is not list: + port_handle = [port_handle] + + if action == 'run': + + try: + self.trex_client.start(duration = kwargs.get('duration', -1), ports = port_handle) + except Exception as e: + return HLT_ERR('Could not start traffic: %s' % e) + return HLT_OK(stopped = 0) + + elif action == 'stop': + + try: + self.trex_client.stop(ports = port_handle) + except Exception as e: + return HLT_ERR('Could not start traffic: %s' % e) + return HLT_OK(stopped = 1) else: - raise NotImplementedError("action '{0}' is not supported yet on TRex".format(action)) + return HLT_ERR("Action '{0}' is not supported yet on TRex".format(action)) # if we arrived here, this means that operation FAILED! - return {"status": 0, - "log": log} - + return HLT_ERR("Probably action '%s' is not implemented" % action) def traffic_stats(self, port_handle, mode): - ALLOWED_MODES = ["aggregate", "streams", "all"] + ALLOWED_MODES = ['aggregate', 'streams', 'all'] if mode not in ALLOWED_MODES: - raise ValueError("mode must be one of the following values: {modes}".format(modes=ALLOWED_MODES)) - # pass this function for now... - if mode == "aggregate": - # create a new stream with desired attributes, starting by creating packet + return HLT_ERR("'mode' must be one of the following values: %s" % ALLOWED_MODES) + if mode == 'streams': + return HLT_ERR("'mode = streams' not implemented'") + if mode in ('all', 'aggregate'): + hlt_stats_dict = {} try: - packet = CTRexHltApi.generate_stream(l2_encap, mac_src, mac_dst, - l3_protocol, ip_src_addr, ip_dst_addr, l3_length) - # set transmission attributes - tx_mode = CTxMode(transmit_mode, rate_pps, **kwargs) - # set rx_stats - rx_stats = CRxStats() # defaults with disabled - # join the generated data into stream - stream_obj = CStream() - stream_obj_params = {"enabled": True, - "self_start": True, - "next_stream_id": -1, - "isg": 0.0, - "mode": tx_mode, - "rx_stats": rx_stats, - "packet": packet} # vm is excluded from this list since CTRexPktBuilder obj is passed - stream_obj.load_data(**stream_obj_params) + stats = self.trex_client.get_stats(port_handle) except Exception as e: - # some exception happened during the stream creation - return {"status": 0, "log": str(e)} - # try adding the stream, until free stream_id is found - port_data = self._port_data.get(port_handle) - id_candidate = None - # TODO: change this to better implementation - while True: - id_candidate = port_data["stream_id_gen"].next() - response = self.trex_client.add_stream(stream_id=id_candidate, - stream_obj=stream_obj, - port_id=port_handle) - res_ok, log = CTRexHltApi.process_response(port_handle, response) - if res_ok: - # found non-taken stream_id on server - # save it for modifying needs - port_data["streams"].update({id_candidate: stream_obj}) - break - else: - # proceed to another iteration to use another id - continue - return {"status": 1, - "stream_id": id_candidate, - "log": None} - else: - raise NotImplementedError("mode '{0}' is not supported yet on TRex".format(mode)) + return HLT_ERR('Could not retrieve stats: %s' % e) + for port_id, stat_dict in stats.iteritems(): + if type(port_id) is int: + hlt_stats_dict[port_id] = { + 'aggregate': { + 'tx': { + 'pkt_bit_rate': stat_dict.get('tx_bps'), + 'pkt_byte_count': stat_dict.get('obytes'), + 'pkt_count': stat_dict.get('opackets'), + 'pkt_rate': stat_dict.get('tx_pps'), + 'total_pkt_bytes': stat_dict.get('obytes'), + 'total_pkt_rate': stat_dict.get('tx_pps'), + 'total_pkts': stat_dict.get('opackets'), + }, + 'rx': { + 'pkt_bit_rate': stat_dict.get('rx_bps'), + 'pkt_byte_count': stat_dict.get('ibytes'), + 'pkt_count': stat_dict.get('ipackets'), + 'pkt_rate': stat_dict.get('rx_pps'), + 'total_pkt_bytes': stat_dict.get('ibytes'), + 'total_pkt_rate': stat_dict.get('rx_pps'), + 'total_pkts': stat_dict.get('ipackets'), + } + } + } + return HLT_OK(hlt_stats_dict) + - def get_aggregate_port_stats(self, port_handle): - return self.traffic_stats(port_handle, mode="aggregate") + # remove streams from given port(s). + # stream_id can be: + # * int - exact stream_id value + # * 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 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 + 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 + 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) + if stream_id_min is None: + raise Exception('_remove_stream: wrong range param %s' % stream_id_min) + if stream_id_max is None: + raise Exception('_remove_stream: wrong range param %s' % stream_id_max) + 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 + return + raise Exception('_remove_stream: wrong param %s' % stream_id) - def get_stream_stats(self, port_handle): - return self.traffic_stats(port_handle, mode="streams") - # ----- internal functions ----- # - def _port_data_init(self, port_list): - for port in port_list: - self._port_data[port] = {"stream_id_gen": id_count_gen(), - "streams": {}} +########################### +# Private functions # +########################### + # obsolete @staticmethod def process_response(port_list, response): log = response.data() if response.good() else response.err() @@ -268,51 +442,91 @@ class CTRexHltApi(object): @staticmethod def join_batch_response(responses): if type(responses) is list(): - return "\n". join([str(response) for response in responses]) + return '\n'. join([str(response) for response in responses]) return responses @staticmethod - def generate_stream(l2_encap, mac_src, mac_dst, - l3_protocol, ip_src_addr, ip_dst_addr, l3_length): - ALLOWED_L3_PROTOCOL = {"ipv4": dpkt.ethernet.ETH_TYPE_IP, - "ipv6": dpkt.ethernet.ETH_TYPE_IP6, - "arp": dpkt.ethernet.ETH_TYPE_ARP} - ALLOWED_L4_PROTOCOL = {"tcp": dpkt.ip.IP_PROTO_TCP, - "udp": dpkt.ip.IP_PROTO_UDP, - "icmp": dpkt.ip.IP_PROTO_ICMP, - "icmpv6": dpkt.ip.IP_PROTO_ICMP6, - "igmp": dpkt.ip.IP_PROTO_IGMP, - "rtp": dpkt.ip.IP_PROTO_IRTP, - "isis": dpkt.ip.IP_PROTO_ISIS, - "ospf": dpkt.ip.IP_PROTO_OSPF} + def _generate_stream(l2_encap = 'ethernet_ii', mac_src = '00:00:01:00:00:01', mac_dst = '00:00:00:00:00:00', + l3_protocol = 'ipv4', ip_src_addr = '0.0.0.0', ip_dst_addr = '192.0.0.1', l3_length = 110, + l4_protocol = 'tcp', + **kwards): + ALLOWED_L3_PROTOCOL = {'ipv4': dpkt.ethernet.ETH_TYPE_IP, + 'ipv6': dpkt.ethernet.ETH_TYPE_IP6, + 'arp': dpkt.ethernet.ETH_TYPE_ARP} + ALLOWED_L4_PROTOCOL = {'tcp': dpkt.ip.IP_PROTO_TCP, + 'udp': dpkt.ip.IP_PROTO_UDP, + 'icmp': dpkt.ip.IP_PROTO_ICMP, + 'icmpv6': dpkt.ip.IP_PROTO_ICMP6, + 'igmp': dpkt.ip.IP_PROTO_IGMP, + 'rtp': dpkt.ip.IP_PROTO_IRTP, + 'isis': dpkt.ip.IP_PROTO_ISIS, + 'ospf': dpkt.ip.IP_PROTO_OSPF} pkt_bld = CTRexPktBuilder() - if l2_encap == "ethernet_ii": - pkt_bld.add_pkt_layer("l2", dpkt.ethernet.Ethernet()) + if l2_encap == 'ethernet_ii': + #('dst', '6s', ''), + #('src', '6s', ''), + #('type', 'H', ETH_TYPE_IP) + pkt_bld.add_pkt_layer('l2', dpkt.ethernet.Ethernet()) # set Ethernet layer attributes - pkt_bld.set_eth_layer_addr("l2", "src", mac_src) - pkt_bld.set_eth_layer_addr("l2", "dst", mac_dst) + pkt_bld.set_eth_layer_addr('l2', 'src', mac_src) + pkt_bld.set_eth_layer_addr('l2', 'dst', mac_dst) else: raise NotImplementedError("l2_encap does not support the desired encapsulation '{0}'".format(l2_encap)) # set l3 on l2 if l3_protocol not in ALLOWED_L3_PROTOCOL: - raise ValueError("l3_protocol must be one of the following: {0}".format(ALLOWED_L3_PROTOCOL)) - pkt_bld.set_layer_attr("l2", "type", ALLOWED_L3_PROTOCOL[l3_protocol]) + raise ValueError('l3_protocol must be one of the following: {0}'.format(ALLOWED_L3_PROTOCOL)) + pkt_bld.set_layer_attr('l2', 'type', ALLOWED_L3_PROTOCOL[l3_protocol]) # set l3 attributes - if l3_protocol == "ipv4": - pkt_bld.add_pkt_layer("l3", dpkt.ip.IP()) - pkt_bld.set_ip_layer_addr("l3", "src", ip_src_addr) - pkt_bld.set_ip_layer_addr("l3", "dst", ip_dst_addr) - pkt_bld.set_layer_attr("l3", "len", l3_length) + if l3_protocol == 'ipv4': + #('v_hl', 'B', (4 << 4) | (20 >> 2)), + #('tos', 'B', 0), + #('len', 'H', 20), + #('id', 'H', 0), + #('off', 'H', 0), + #('ttl', 'B', 64), + #('p', 'B', 0), + #('sum', 'H', 0), + #('src', '4s', '\x00' * 4), + #('dst', '4s', '\x00' * 4) + pkt_bld.add_pkt_layer('l3', dpkt.ip.IP()) + pkt_bld.set_ip_layer_addr('l3', 'src', ip_src_addr) + pkt_bld.set_ip_layer_addr('l3', 'dst', ip_dst_addr) + pkt_bld.set_layer_attr('l3', 'len', l3_length) else: raise NotImplementedError("l3_protocol '{0}' is not supported by TRex yet.".format(l3_protocol)) - pkt_bld.dump_pkt_to_pcap("stream_test.pcap") + # set l4 on l3 + if l4_protocol not in ALLOWED_L4_PROTOCOL: + raise ValueError('l4_protocol must be one of the following: {0}'.format(ALLOWED_L3_PROTOCOL)) + pkt_bld.set_layer_attr('l3', 'p', ALLOWED_L4_PROTOCOL[l4_protocol]) + + # set l4 attributes + if l4_protocol == 'tcp': + pkt_bld.add_pkt_layer('l4', dpkt.tcp.TCP()) + #('sport', 'H', 0xdead), + #('dport', 'H', 0), + #('seq', 'I', 0xdeadbeefL), + #('ack', 'I', 0), + #('off_x2', 'B', ((5 << 4) | 0)), + #('flags', 'B', TH_SYN), + #('win', 'H', TCP_WIN_MAX), + #('sum', 'H', 0), + #('urp', 'H', 0) + #pkt_bld.set_ip_layer_addr('l4', 'sport', ip_src_addr) + #pkt_bld.set_ip_layer_addr('l4', 'dport', ip_dst_addr) + else: + raise NotImplementedError("l4_protocol '{0}' is not supported by TRex yet.".format(l3_protocol)) + + pkt_bld.set_pkt_payload('Hello, World' + '!'*58) + + # debug + #pkt_bld.dump_pkt_to_pcap('stream_test.pcap') return pkt_bld -if __name__ == "__main__": +if __name__ == '__main__': pass diff --git a/scripts/automation/trex_control_plane/client/trex_port.py b/scripts/automation/trex_control_plane/client/trex_port.py index c8147faf..eaf64ac2 100644 --- a/scripts/automation/trex_control_plane/client/trex_port.py +++ b/scripts/automation/trex_control_plane/client/trex_port.py @@ -177,40 +177,57 @@ class Port(object): # remove stream from port - def remove_stream (self, stream_id): + def remove_streams (self, stream_id_list): if not self.is_acquired(): return self.err("port is not owned") - if not stream_id in self.streams: + if not self.is_port_writable(): + return self.err("Please stop port before attempting to remove streams") + + # single element to list + stream_id_list = stream_id_list if isinstance(stream_id_list, list) else [stream_id_list] + + # verify existance + if not all([stream_id in self.streams for stream_id in stream_id_list]): return self.err("stream {0} does not exists".format(stream_id)) - params = {"handler": self.handler, - "port_id": self.port_id, - "stream_id": stream_id} + batch = [] + for stream_id in stream_id_list: + params = {"handler": self.handler, + "port_id": self.port_id, + "stream_id": stream_id} - rc = self.transmit("remove_stream", params) - if rc.bad(): - return self.err(rc.err()) + cmd = RpcCmdData('remove_stream', params) + batch.append(cmd) - self.streams[stream_id] = None + del self.streams[stream_id] + + + rc = self.transmit_batch(batch) + if not rc: + return self.err(rc.err()) self.state = self.STATE_STREAMS if (len(self.streams) > 0) else self.STATE_IDLE return self.ok() + # remove all the streams def remove_all_streams (self): if not self.is_acquired(): return self.err("port is not owned") + if not self.is_port_writable(): + return self.err("Please stop port before attempting to remove streams") + params = {"handler": self.handler, "port_id": self.port_id} rc = self.transmit("remove_all_streams", params) - if rc.bad(): + if not rc: return self.err(rc.err()) self.streams = {} @@ -231,7 +248,6 @@ class Port(object): # start traffic def start (self, mul, duration, force): - if not self.is_acquired(): return self.err("port is not owned") diff --git a/scripts/automation/trex_control_plane/client/trex_stateless_client.py b/scripts/automation/trex_control_plane/client/trex_stateless_client.py index 3d4dbc93..4a2cc436 100755 --- a/scripts/automation/trex_control_plane/client/trex_stateless_client.py +++ b/scripts/automation/trex_control_plane/client/trex_stateless_client.py @@ -511,26 +511,14 @@ class STLClient(object): - def __add_stream_pack(self, stream_pack, port_id_list = None): + def __remove_streams(self, stream_id_list, port_id_list = None): port_id_list = self.__ports(port_id_list) rc = RC() for port_id in port_id_list: - rc.add(self.ports[port_id].add_streams(stream_pack)) - - return rc - - - - def __remove_stream(self, stream_id, port_id_list = None): - port_id_list = self.__ports(port_id_list) - - rc = RC() - - for port_id in port_id_list: - rc.add(self.ports[port_id].remove_stream(stream_id)) + rc.add(self.ports[port_id].remove_streams(stream_id_list)) return rc @@ -703,9 +691,9 @@ class STLClient(object): # disconenct from server - def __disconnect(self): + def __disconnect(self, release_ports = True): # release any previous acquired ports - if self.is_connected(): + if self.is_connected() and release_ports: self.__release(self.get_acquired_ports()) self.comm_link.disconnect() @@ -739,7 +727,7 @@ class STLClient(object): total = {} for port_id in port_id_list: port_stats = self.ports[port_id].get_stats() - stats["port {0}".format(port_id)] = port_stats + stats[port_id] = port_stats for k, v in port_stats.iteritems(): if not k in total: @@ -1017,11 +1005,12 @@ class STLClient(object): :parameters: stop_traffic : bool tries to stop traffic before disconnecting - + release_ports : bool + tries to release all the acquired ports """ @__api_check(False) - def disconnect (self, stop_traffic = True): + def disconnect (self, stop_traffic = True, release_ports = True): # try to stop ports but do nothing if not possible if stop_traffic: @@ -1030,9 +1019,10 @@ class STLClient(object): except STLError: pass + self.logger.pre_cmd("Disconnecting from server at '{0}':'{1}'".format(self.connection_info['server'], self.connection_info['sync_port'])) - rc = self.__disconnect() + rc = self.__disconnect(release_ports) self.logger.post_cmd(rc) @@ -1077,6 +1067,34 @@ class STLClient(object): raise STLError(rc) + """ + Release ports + + :parameters: + ports : list + ports to execute the command + + :raises: + + :exc:`STLError` + + """ + @__api_check(True) + def release (self, ports = None): + # by default use all acquired ports + if ports == None: + ports = self.get_acquired_ports() + + # verify ports + rc = self._validate_port_list(ports) + if not rc: + raise STLArgumentError('ports', ports, valid_values = self.get_all_ports()) + + self.logger.pre_cmd("Releasing ports {0}:".format(ports)) + rc = self.__release(ports) + self.logger.post_cmd(rc) + + if not rc: + raise STLError(rc) """ Pings the server @@ -1173,6 +1191,9 @@ class STLClient(object): streams: list streams to attach + :returns: + list of stream IDs in order of the stream list + :raises: + :exc:`STLError` @@ -1203,6 +1224,50 @@ class STLClient(object): if not rc: raise STLError(rc) + return [stream.get_id() for stream in streams] + + + """ + remove a list of streams from ports + + :parameters: + ports : list + ports to execute the command + stream_id_list: list + stream id list to remove + + + :raises: + + :exc:`STLError` + + """ + @__api_check(True) + def remove_streams (self, stream_id_list, ports = None): + # by default use all ports + if ports == None: + ports = self.get_acquired_ports() + + # verify valid port id list + rc = self._validate_port_list(ports) + if not rc: + raise STLArgumentError('ports', ports, valid_values = self.get_all_ports()) + + # transform single stream + if not isinstance(stream_id_list, list): + stream_id_list = [stream_id_list] + + # check streams + if not all([isinstance(stream_id, long) for stream_id in stream_id_list]): + raise STLArgumentError('stream_id_list', stream_id_list) + + # remove streams + self.logger.pre_cmd("Removing {0} streams from port(s) {1}:".format(len(stream_id_list), ports)) + rc = self.__remove_streams(stream_id_list, ports) + self.logger.post_cmd(rc) + + if not rc: + raise STLError(rc) + """ load a profile file to port(s) 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 69ad14b2..3d55bc3e 100755 --- a/scripts/automation/trex_control_plane/client_utils/general_utils.py +++ b/scripts/automation/trex_control_plane/client_utils/general_utils.py @@ -90,7 +90,12 @@ 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: + return int(input) + except: + return None if __name__ == "__main__": pass diff --git a/scripts/automation/trex_control_plane/common/trex_streams.py b/scripts/automation/trex_control_plane/common/trex_streams.py index 0d77b457..caeaa8cf 100755 --- a/scripts/automation/trex_control_plane/common/trex_streams.py +++ b/scripts/automation/trex_control_plane/common/trex_streams.py @@ -415,7 +415,8 @@ class STLStream(object): self_start = True, isg = 0.0, rx_stats = None, - next_stream_id = -1): + next_stream_id = -1, + stream_id = None): # type checking if not isinstance(mode, STLTXMode): @@ -437,7 +438,7 @@ class STLStream(object): raise STLError("continuous stream cannot have a next stream ID") # use a random 31 bit for ID - self.stream_id = random.getrandbits(31) + self.stream_id = stream_id if stream_id is not None else random.getrandbits(31) self.fields = {} diff --git a/scripts/automation/trex_control_plane/console/trex_console.py b/scripts/automation/trex_control_plane/console/trex_console.py index 6a4af350..c8624626 100755 --- a/scripts/automation/trex_control_plane/console/trex_console.py +++ b/scripts/automation/trex_control_plane/console/trex_console.py @@ -320,6 +320,10 @@ class TRexConsole(TRexGeneralCmd): def help_history (self): self.do_history("-h") + def do_shell (self, line): + return self.do_history(line) + + def do_history (self, line): '''Manage the command history\n''' @@ -346,7 +350,9 @@ class TRexConsole(TRexGeneralCmd): if cmd == None: return - self.onecmd(cmd) + print "Executing '{0}'".format(cmd) + + return self.onecmd(cmd) diff --git a/scripts/ko/3.19.0-25-generic/igb_uio.ko b/scripts/ko/3.19.0-25-generic/igb_uio.ko Binary files differnew file mode 100644 index 00000000..126dc2a2 --- /dev/null +++ b/scripts/ko/3.19.0-25-generic/igb_uio.ko |