From 234779fd32e747f4ac918f3c39e59618dde0f2d7 Mon Sep 17 00:00:00 2001 From: imarom Date: Thu, 3 Nov 2016 16:33:52 +0200 Subject: moved RX filter feature to port attr Signed-off-by: imarom --- .../stl/trex_stl_lib/trex_stl_client.py | 42 +++++++++++++-------- .../stl/trex_stl_lib/trex_stl_port.py | 43 ++++++++++++++-------- .../stl/trex_stl_lib/trex_stl_stats.py | 2 + .../stl/trex_stl_lib/trex_stl_types.py | 6 +++ .../stl/trex_stl_lib/utils/parsing_opts.py | 7 ++++ 5 files changed, 68 insertions(+), 32 deletions(-) (limited to 'scripts/automation/trex_control_plane/stl/trex_stl_lib') diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py index 2e3f681c..907e405a 100755 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py @@ -322,12 +322,16 @@ class EventsHandler(object): # port attr changed elif (event_type == 8): + port_id = int(data['port_id']) + if data['attr'] == self.client.ports[port_id].attr: return # false alarm - old_info = self.client.ports[port_id].get_info() + + old_info = self.client.ports[port_id].get_formatted_info() self.__async_event_port_attr_changed(port_id, data['attr']) - new_info = self.client.ports[port_id].get_info() + + new_info = self.client.ports[port_id].get_formatted_info() ev = "port {0} attributes changed".format(port_id) for key, old_val in old_info.items(): new_val = new_info[key] @@ -1739,10 +1743,6 @@ class STLClient(object): """ - rc = self.ports[0].set_rx_filter_mode("all") - if not rc: - raise STLError(rc) - self.logger.pre_cmd("Pinging the server on '{0}' port '{1}': ".format(self.connection_info['server'], self.connection_info['sync_port'])) rc = self._transmit("ping", api_class = None) @@ -2630,7 +2630,13 @@ class STLClient(object): @__api_check(True) - def set_port_attr (self, ports = None, promiscuous = None, link_up = None, led_on = None, flow_ctrl = None): + def set_port_attr (self, + ports = None, + promiscuous = None, + link_up = None, + led_on = None, + flow_ctrl = None, + rx_filter_mode = None): """ Set port attributes @@ -2639,7 +2645,7 @@ class STLClient(object): link_up - True or False led_on - True or False flow_ctrl - 0: disable all, 1: enable tx side, 2: enable rx side, 3: full enable - + rx_filter_mode - 'hw' for hardware rules matching packets only or 'all' all packets :raises: + :exe:'STLError' @@ -2653,6 +2659,7 @@ class STLClient(object): validate_type('link_up', link_up, (bool, type(None))) validate_type('led_on', led_on, (bool, type(None))) validate_type('flow_ctrl', flow_ctrl, (int, type(None))) + validate_choice('rx_filter_mode', rx_filter_mode, ['hw', 'all']) # build attributes attr_dict = {} @@ -2664,7 +2671,9 @@ class STLClient(object): attr_dict['led_status'] = {'on': led_on} if flow_ctrl is not None: attr_dict['flow_ctrl_mode'] = {'mode': flow_ctrl} - + if rx_filter_mode is not None: + attr_dict['rx_filter_mode'] = {'mode': rx_filter_mode} + # no attributes to set if not attr_dict: return @@ -3234,7 +3243,7 @@ class STLClient(object): '''Sets port attributes ''' parser = parsing_opts.gen_parser(self, - "port_attr", + "portattr", self.set_port_attr_line.__doc__, parsing_opts.PORT_LIST_WITH_ALL, parsing_opts.PROMISCUOUS, @@ -3242,19 +3251,20 @@ class STLClient(object): parsing_opts.LED_STATUS, parsing_opts.FLOW_CTRL, parsing_opts.SUPPORTED, + parsing_opts.RX_FILTER_MODE, ) opts = parser.parse_args(line.split(), default_ports = self.get_acquired_ports(), verify_acquired = True) if not opts: return opts - opts.prom = parsing_opts.ON_OFF_DICT.get(opts.prom) - opts.link = parsing_opts.UP_DOWN_DICT.get(opts.link) - opts.led = parsing_opts.ON_OFF_DICT.get(opts.led) - opts.flow_ctrl = parsing_opts.FLOW_CTRL_DICT.get(opts.flow_ctrl) + opts.prom = parsing_opts.ON_OFF_DICT.get(opts.prom) + opts.link = parsing_opts.UP_DOWN_DICT.get(opts.link) + opts.led = parsing_opts.ON_OFF_DICT.get(opts.led) + opts.flow_ctrl = parsing_opts.FLOW_CTRL_DICT.get(opts.flow_ctrl) # if no attributes - fall back to printing the status - if not filter(lambda x:x is not None, [opts.prom, opts.link, opts.led, opts.flow_ctrl, opts.supp]): + if not list(filter(lambda x:x is not None, [opts.prom, opts.link, opts.led, opts.flow_ctrl, opts.supp, opts.rx_filter_mode])): self.show_stats_line("--ps --port {0}".format(' '.join(str(port) for port in opts.ports))) return @@ -3268,7 +3278,7 @@ class STLClient(object): print(' Flow control: %s' % info['fc_supported']) print('') else: - return self.set_port_attr(opts.ports, opts.prom, opts.link, opts.led, opts.flow_ctrl) + return self.set_port_attr(opts.ports, opts.prom, opts.link, opts.led, opts.flow_ctrl, opts.rx_filter_mode) 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 bf0251b8..59793495 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 @@ -128,10 +128,10 @@ class Port(object): return RC_OK(data) def get_speed_bps (self): - return (self.info['speed'] * 1000 * 1000 * 1000) + return (self.attr['speed'] * 1000 * 1000 * 1000) def get_formatted_speed (self): - return "{0} Gbps".format(self.info['speed']) + return "%g Gb/s" % (self.attr['speed'] / 1000) def is_acquired(self): return (self.handler != None) @@ -252,9 +252,6 @@ class Port(object): # attributes self.attr = rc.data()['attr'] - if 'speed' in rc.data(): - self.info['speed'] = rc.data()['speed'] // 1000 - return self.ok() @@ -487,14 +484,19 @@ class Port(object): return self.ok() + # @writeable - def set_rx_filter_mode (self, filter_mode): - assert(filter_mode in ["hw", "all"]) + def start_rx_capture (self, pcap_filename, limit): + + prefix, suffix = pcap_filename.split('.') + filename = "{0}-{1}.{2}".format(prefix, self.port_id, suffix) - params = {"handler": self.handler, - "port_id": self.port_id, - "type": "filter_mode", - "filter_type": filter_mode} + params = {"handler": self.handler, + "port_id": self.port_id, + "type": "capture", + "enabled": True, + "pcap_filename": filename, + "limit": limit} rc = self.transmit("set_rx_feature", params) if rc.bad(): @@ -675,8 +677,8 @@ class Port(object): format_time(exp_time_factor_sec))) print("\n") - # generate port info - def get_info (self): + # generate formatted (console friendly) port info + def get_formatted_info (self): info = dict(self.info) info['status'] = self.get_port_state_name() @@ -719,6 +721,13 @@ class Port(object): else: info['is_virtual'] = 'N/A' + if 'speed' in self.attr: + info['speed'] = self.get_formatted_speed() + else: + info['speed'] = 'N/A' + + info['rx_filter_mode'] = self.attr.get('rx_filter_mode', 'N/A') + return info @@ -731,7 +740,7 @@ class Port(object): def generate_port_status(self): - info = self.get_info() + info = self.get_formatted_info() return {"driver": info['driver'], "description": info.get('description', 'N/A')[:18], @@ -742,11 +751,14 @@ class Port(object): "NUMA Node": info['numa'], "--": "", "---": "", - "link speed": "{speed} Gb/s".format(speed=info['speed']), + "----": "", + "link speed": info['speed'], "port status": info['status'], "link status": info['link'], "promiscuous" : info['prom'], "flow ctrl" : info['fc'], + + "RX Filter Mode": info['rx_filter_mode'], } def clear_stats(self): @@ -792,7 +804,6 @@ class Port(object): self.last_factor_type = None def async_event_port_attr_changed (self, attr): - self.info['speed'] = attr['speed'] // 1000 self.attr = attr # rest of the events are used for TUI / read only sessions diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py index 9f601484..7e47eb61 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py @@ -676,6 +676,8 @@ class CTRexInfoGenerator(object): ("---", []), ("PCI Address", []), ("NUMA Node", []), + ("----", []), + ("RX Filter Mode", []), ] ) diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_types.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_types.py index aa6c4218..81015ddc 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_types.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_types.py @@ -135,6 +135,12 @@ def validate_type(arg_name, arg, valid_types): else: raise STLError('validate_type: valid_types should be type or list or tuple of types') + +def validate_choice (arg_name, arg, choices): + if arg is not None and not arg in choices: + raise STLError("validate_choice: argument '{0}' can only be one of '{1}'".format(arg_name, choices)) + + # throws STLError if not exactly one argument is present def verify_exclusive_arg (args_list): if not (len(list(filter(lambda x: x is not None, args_list))) == 1): diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py index 7eda8635..0d316c9e 100755 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py @@ -43,6 +43,7 @@ CORE_MASK = 26 DUAL = 27 FLOW_CTRL = 28 SUPPORTED = 29 +RX_FILTER_MODE = 30 GLOBAL_STATS = 50 PORT_STATS = 51 @@ -303,6 +304,12 @@ OPTIONS_DB = {MULTIPLIER: ArgumentPack(['-m', '--multiplier'], 'dest': 'flow_ctrl', 'choices': FLOW_CTRL_DICT}), + RX_FILTER_MODE: ArgumentPack(['--rxf'], + {'help': 'Set RX filtering mode', + 'dest': 'rx_filter_mode', + 'choices': ['hw', 'all']}), + + SUPPORTED: ArgumentPack(['--supp'], {'help': 'Show which attributes are supported by current NICs', 'default': None, -- cgit 1.2.3-korg