diff options
author | imarom <imarom@cisco.com> | 2016-12-12 19:26:24 +0200 |
---|---|---|
committer | imarom <imarom@cisco.com> | 2016-12-12 19:26:24 +0200 |
commit | 0c45815234abbb79b147b8093eb19e274ee65f52 (patch) | |
tree | a604b3865f201e1fe841bca3a10e8f86e3248186 /scripts/automation/trex_control_plane/stl | |
parent | af9f439b2bf768f9168cecac2488b4c718ab783f (diff) |
grat ARP
Signed-off-by: imarom <imarom@cisco.com>
Diffstat (limited to 'scripts/automation/trex_control_plane/stl')
4 files changed, 171 insertions, 79 deletions
diff --git a/scripts/automation/trex_control_plane/stl/console/trex_console.py b/scripts/automation/trex_control_plane/stl/console/trex_console.py index eb8a0443..1a97ad0c 100755 --- a/scripts/automation/trex_control_plane/stl/console/trex_console.py +++ b/scripts/automation/trex_control_plane/stl/console/trex_console.py @@ -330,6 +330,25 @@ class TRexConsole(TRexGeneralCmd): self.do_portattr("-h") @verify_connected + def do_source (self, line): + '''Configure source address for port(s)\n''' + self.stateless_client.set_source_addr_line(line) + + def help_source (self): + self.do_source("-h") + + + @verify_connected + def do_dest (self, line): + '''Configure destination address for port(s)\n''' + self.stateless_client.set_dest_addr_line(line) + + def help_dest (self): + self.do_dest("-h") + + + + @verify_connected def do_set_rx_sniffer (self, line): '''Sets a port sniffer on RX channel as PCAP recorder''' self.stateless_client.set_rx_sniffer_line(line) 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 fe691fb0..80daadd2 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 @@ -1843,6 +1843,74 @@ class STLClient(object): raise STLError(rc) + + @__api_check(True) + def set_source_addr (self, port, addr): + """ + Configures a port with a source address + + :parameters: + port - the port to set the source address + addr - source address. currently only IPv4 is supported + :raises: + + :exc:`STLError` + """ + + validate_type('port', port, int) + if port not in self.get_all_ports(): + raise STLError("port {0} is not a valid port id".format(port)) + + if not is_valid_ipv4(addr): + raise STLError("addr is not a valid IPv4 address: '{0}'".format(addr)) + + self.logger.pre_cmd("Setting port {0} source address as '{1}': ".format(port, addr)) + rc = self.ports[port].set_source_addr(addr) + self.logger.post_cmd(rc) + + if not rc: + raise STLError(rc) + + # for MAC dest - no resolve + if not self.ports[port].get_dst_addr()['ipv4']: + return rc + + # resolve the address + return self.resolve(ports = port, verbose = False) + + + @__api_check(True) + def set_dest_addr (self, port, addr): + """ + Configures a port with a destination address + + :parameters: + port - the port to set the destination address + addr - destination address. can be either MAC or IPv4 + :raises: + + :exc:`STLError` + """ + + validate_type('port', port, int) + if port not in self.get_all_ports(): + raise STLError("port {0} is not a valid port id".format(port)) + + if not is_valid_ipv4(addr) and not is_valid_mac(addr): + raise STLError("addr is not a valid IPv4 address or a MAC address: '{0}'".format(addr)) + + if is_valid_ipv4(addr) and not self.ports[port].get_src_addr()['ipv4']: + raise STLError("cannot configure destination as IPv4 address without IPv4 source address") + + self.logger.pre_cmd("Setting port {0} destination address as '{1}': ".format(port, addr)) + rc = self.ports[port].set_dest_addr(addr) + self.logger.post_cmd(rc) + + if not rc: + raise STLError(rc) + + # resolve the address + return self.resolve(ports = port, verbose = False) + + @__api_check(True) def ping_ip (self, src_port, dst_ipv4, pkt_size = 64, count = 5): """ @@ -2010,8 +2078,8 @@ class STLClient(object): self.clear_stats(ports) self.set_port_attr(ports, promiscuous = False, - link_up = True if restart else None, - rxf = 'hw') + link_up = True if restart else None) + self.set_service_mode(ports, False) self.remove_rx_sniffer(ports) self.remove_rx_queue(ports) @@ -2813,9 +2881,6 @@ class STLClient(object): link_up = None, led_on = None, flow_ctrl = None, - rxf = None, - ipv4 = None, - dest = None, resolve = True): """ Set port attributes @@ -2825,9 +2890,6 @@ 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 - rxf - 'hw' for hardware rules matching packets only or 'all' all packets - ipv4 - configure IPv4 address for port(s). for multiple ports should be a list of IPv4 addresses in the same length of the ports array - dest - configure destination address for port(s) in either IPv4 or MAC format. for multiple ports should be a list in the same length of the ports array resolve - if true, in case a destination address is configured as IPv4 try to resolve it :raises: + :exe:'STLError' @@ -2842,7 +2904,6 @@ 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('rxf', rxf, ['hw', 'all']) # common attributes for all ports cmn_attr_dict = {} @@ -2851,34 +2912,10 @@ class STLClient(object): cmn_attr_dict['link_status'] = link_up cmn_attr_dict['led_status'] = led_on cmn_attr_dict['flow_ctrl_mode'] = flow_ctrl - cmn_attr_dict['rx_filter_mode'] = rxf # each port starts with a set of the common attributes attr_dict = [dict(cmn_attr_dict) for _ in ports] - # default value for IPv4 / dest is none for all ports - if ipv4 is None: - ipv4 = [None] * len(ports) - if dest is None: - dest = [None] * len(ports) - - ipv4 = listify(ipv4) - if len(ipv4) != len(ports): - raise STLError("'ipv4' must be a list in the same length of ports - 'ports': {0}, 'ip': {1}".format(ports, ipv4)) - - dest = listify(dest) - if len(dest) != len(ports): - raise STLError("'dest' must be a list in the same length of ports - 'ports': {0}, 'dest': {1}".format(ports, dest)) - - # update each port attribute with ipv4 - for addr, port_attr in zip(ipv4, attr_dict): - port_attr['ipv4'] = addr - - # update each port attribute with dest - for addr, port_attr in zip(dest, attr_dict): - port_attr['dest'] = addr - - self.logger.pre_cmd("Applying attributes on port(s) {0}:".format(ports)) rc = self.__set_port_attr(ports, attr_dict) self.logger.post_cmd(rc) @@ -2886,15 +2923,7 @@ class STLClient(object): if not rc: raise STLError(rc) - - # automatic resolve - if resolve: - # find any port with a dest configured as IPv4 - resolve_ports = [port_id for port_id, port_dest in zip(ports, dest) if is_valid_ipv4(port_dest)] - - if resolve_ports: - self.resolve(ports = resolve_ports) - + @__api_check(True) @@ -2927,13 +2956,14 @@ class STLClient(object): @__api_check(True) - def resolve (self, ports = None, retries = 0): + def resolve (self, ports = None, retries = 0, verbose = True): """ Resolves ports (ARP resolution) :parameters: ports - for which ports to apply a unique sniffer (each port gets a unique file) retires - how many times to retry on each port (intervals of 100 milliseconds) + verbose - log for each request the response :raises: + :exe:'STLError' @@ -2957,8 +2987,9 @@ class STLClient(object): raise STLError(rc) # print the ARP transaction - self.logger.log(rc) - self.logger.log('') + if verbose: + self.logger.log(rc) + self.logger.log('') @@ -3122,7 +3153,7 @@ class STLClient(object): try: rc = f(*args) except STLError as e: - client.logger.log("Action has failed with the following error:\n" + format_text(e.brief() + "\n", 'bold')) + client.logger.log("\nAction has failed with the following error:\n" + format_text(e.brief() + "\n", 'bold')) return RC_ERR(e.brief()) # if got true - print time @@ -3156,7 +3187,8 @@ class STLClient(object): return opts # IP ping - self.ping_ip(opts.source_port, opts.ping_ipv4, opts.pkt_size, opts.count) + # source ports maps to ports as a single port + self.ping_ip(opts.ports[0], opts.ping_ipv4, opts.pkt_size, opts.count) @__console @@ -3691,9 +3723,6 @@ class STLClient(object): parsing_opts.LED_STATUS, parsing_opts.FLOW_CTRL, parsing_opts.SUPPORTED, - parsing_opts.RX_FILTER_MODE, - parsing_opts.IPV4, - parsing_opts.DEST ) opts = parser.parse_args(line.split(), default_ports = self.get_acquired_ports(), verify_acquired = True) @@ -3706,7 +3735,7 @@ class STLClient(object): opts.flow_ctrl = parsing_opts.FLOW_CTRL_DICT.get(opts.flow_ctrl) # if no attributes - fall back to printing the status - 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, opts.ipv4, opts.dest])): + if not list(filter(lambda x:x is not None, [opts.prom, opts.link, opts.led, opts.flow_ctrl, opts.supp])): self.show_stats_line("--ps --port {0}".format(' '.join(str(port) for port in opts.ports))) return @@ -3724,10 +3753,7 @@ class STLClient(object): opts.prom, opts.link, opts.led, - opts.flow_ctrl, - opts.rx_filter_mode, - opts.ipv4, - opts.dest) + opts.flow_ctrl) @@ -3782,6 +3808,46 @@ class STLClient(object): @__console + def set_source_addr_line (self, line): + '''Configures source address for port(s)''' + + parser = parsing_opts.gen_parser(self, + "source", + self.set_source_addr_line.__doc__, + parsing_opts.SOURCE_PORT, + parsing_opts.IPV4) + + opts = parser.parse_args(line.split()) + if not opts: + return opts + + # source ports maps to ports as a single port + self.set_source_addr(opts.ports[0], opts.ipv4) + + return RC_OK() + + + @__console + def set_dest_addr_line (self, line): + '''Configures destination address for port(s)''' + + parser = parsing_opts.gen_parser(self, + "dest", + self.set_dest_addr_line.__doc__, + parsing_opts.SOURCE_PORT, + parsing_opts.DEST) + + opts = parser.parse_args(line.split()) + if not opts: + return opts + + # source ports maps to ports as a single port + self.set_dest_addr(opts.ports[0], opts.dest) + + return RC_OK() + + + @__console def show_profile_line (self, line): '''Shows profile information''' 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 9309ad0c..5ec1f852 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 @@ -519,7 +519,23 @@ class Port(object): return self.ok() - + + @owned + def set_source_addr (self, addr): + if not self.is_service_mode_on(): + return self.err('port service mode must be enabled for configuring source address. Please enable service mode') + + return self.set_attr(ipv4 = addr) + + + @owned + def set_dest_addr (self, addr): + if not self.is_service_mode_on(): + return self.err('port service mode must be enabled for configuring destination address. Please enable service mode') + + return self.set_attr(dest = addr) + + @owned def set_arp_resolution (self, ipv4, mac): 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 66a17a03..c5f53d68 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 @@ -46,7 +46,6 @@ SUPPORTED = 29 FILE_PATH_NO_CHECK = 30 OUTPUT_FILENAME = 31 -ALL_FILES = 32 LIMIT = 33 PORT_RESTART = 34 @@ -54,7 +53,6 @@ IPV4 = 35 DEST = 36 RETRIES = 37 -RX_FILTER_MODE = 38 SOURCE_PORT = 39 PING_IPV4 = 40 PING_COUNT = 41 @@ -343,24 +341,17 @@ 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']}), - - IPV4: ArgumentPack(['--ipv4'], {'help': 'IPv4 address(s) for the port(s)', 'dest': 'ipv4', - 'nargs': '+', - 'default': None, + 'required': True, 'type': check_ipv4_addr}), - DEST: ArgumentPack(['--dest'], + DEST: ArgumentPack(['--addr'], {'help': 'Destination address(s) for the port(s) in either IPv4 or MAC format', + 'metavar': 'addr', 'dest': 'dest', - 'nargs': '+', - 'default': None, + 'required' : True, 'type': check_dest_addr}), RETRIES: ArgumentPack(['-r', '--retries'], @@ -384,14 +375,6 @@ OPTIONS_DB = {MULTIPLIER: ArgumentPack(['-m', '--multiplier'], 'default': False, 'action': 'store_true'}), - - ALL_FILES: ArgumentPack(['--all'], - {'help': 'change RX port filter to fetch all packets', - 'dest': 'all', - 'default': False, - 'action': "store_true"}), - - LIMIT: ArgumentPack(['-l', '--limit'], {'help': 'Limit the packet count to be written to the file', 'dest': 'limit', @@ -423,8 +406,9 @@ OPTIONS_DB = {MULTIPLIER: ArgumentPack(['-m', '--multiplier'], SOURCE_PORT: ArgumentPack(['--port', '-p'], - {'dest':'source_port', + {'dest':'ports', 'type': int, + 'metavar': 'PORT', 'help': 'source port for the action', 'required': True}), @@ -652,6 +636,8 @@ class CCmdArgParser(argparse.ArgumentParser): if not self.has_ports_cfg(opts): return opts + opts.ports = listify(opts.ports) + # if all ports are marked or if (getattr(opts, "all_ports", None) == True) or (getattr(opts, "ports", None) == []): if default_ports is None: @@ -664,7 +650,12 @@ class CCmdArgParser(argparse.ArgumentParser): # so maybe we have ports configured invalid_ports = list_difference(opts.ports, self.stateless_client.get_all_ports()) if invalid_ports: - msg = "{0}: port(s) {1} are not valid port IDs".format(self.cmd_name, invalid_ports) + + if len(invalid_ports) > 1: + msg = "{0}: port(s) {1} are not valid port IDs".format(self.cmd_name, invalid_ports) + else: + msg = "{0}: port {1} is not a valid port ID".format(self.cmd_name, invalid_ports[0]) + self.stateless_client.logger.log(format_text(msg, 'bold')) return RC_ERR(msg) |