def vpp_show_errors_verbose(node): """Run "show errors verbose" debug CLI command. :param node: Node to run command on. :type node: dict """ PapiExecutor.run_cli_cmd(node, 'show errors verbose')
def set_nat44_interfaces(node, int_in, int_out): """Set inside and outside interfaces for NAT44. :param node: DUT node. :param int_in: Inside interface. :param int_out: Outside interface. :type node: dict :type int_in: str :type int_out: str """ cmd = 'nat44_interface_add_del_feature' int_in_idx = InterfaceUtil.get_sw_if_index(node, int_in) err_msg = 'Failed to set inside interface {int} for NAT44 on host ' \ '{host}'.format(int=int_in, host=node['host']) args_in = dict(sw_if_index=int_in_idx, is_add=1, flags=getattr(NATConfigFlags, "NAT_IS_INSIDE").value) with PapiExecutor(node) as papi_exec: papi_exec.add(cmd, **args_in).get_reply(err_msg) int_out_idx = InterfaceUtil.get_sw_if_index(node, int_out) err_msg = 'Failed to set outside interface {int} for NAT44 on host ' \ '{host}'.format(int=int_out, host=node['host']) args_in = dict(sw_if_index=int_out_idx, is_add=1, flags=getattr(NATConfigFlags, "NAT_IS_OUTSIDE").value) with PapiExecutor(node) as papi_exec: papi_exec.add(cmd, **args_in).get_reply(err_msg)
def show_event_logger_on_dut(node): """Show event logger on the DUT node. :param node: DUT node to show traces on. :type node: dict """ PapiExecutor.run_cli_cmd(node, "show event-logger")
def show_nat(node): """Show the NAT configuration and data. Used data sources: nat_show_config nat_worker_dump nat44_interface_addr_dump nat44_address_dump nat44_static_mapping_dump nat44_user_dump nat44_interface_dump nat44_user_session_dump nat_det_map_dump :param node: DUT node. :type node: dict """ cmd = 'nat_show_config' err_msg = 'Failed to get NAT configuration on host {host}'.\ format(host=node['host']) with PapiExecutor(node) as papi_exec: reply = papi_exec.add(cmd).get_reply(err_msg) logger.debug( "NAT Configuration:\n{reply}".format(reply=pformat(reply))) cmds = [ "nat_worker_dump", "nat44_interface_addr_dump", "nat44_address_dump", "nat44_static_mapping_dump", "nat44_user_dump", "nat44_interface_dump", "nat44_user_session_dump", "nat_det_map_dump" ] PapiExecutor.dump_and_log(node, cmds)
def vpp_show_hardware_detail(node): """Run "show hardware-interfaces detail" debug CLI command. :param node: Node to run command on. :type node: dict """ PapiExecutor.run_cli_cmd(node, 'show hardware detail')
def vpp_enable_elog_traces_on_dut(node): """Enable API/CLI/Barrier traces on the DUT node. :param node: DUT node to set up. :type node: dict """ PapiExecutor.run_cli_cmd(node, "elog trace api cli barrier")
def clear_packet_trace_on_all_duts(nodes): """Clear VPP packet trace. :param nodes: Nodes where the packet trace will be cleared. :type nodes: dict """ for node in nodes.values(): if node['type'] == NodeType.DUT: PapiExecutor.run_cli_cmd(node, cmd="clear trace")
def vpp_log_macip_acl_settings(node): """Retrieve configured MACIP settings from the ACL plugin and write to robot log. :param node: VPP node. :type node: dict """ PapiExecutor.dump_and_log(node, [ "macip_acl_dump", ])
def vpp_log_plugin_acl_interface_assignment(node): """Retrieve interface assignment from the ACL plugin and write to robot log. :param node: VPP node. :type node: dict """ PapiExecutor.dump_and_log(node, [ "acl_interface_list_dump", ])
def vpp_get_ip_tables_prefix(node, address): """Get dump of all IP FIB tables on a VPP node. :param node: VPP node. :type node: dict """ addr = ip_address(unicode(address)) PapiExecutor.run_cli_cmd( node, 'show {ip_ver} fib {addr}/{addr_len}'.format( ip_ver='ip6' if addr.version == 6 else 'ip', addr=addr, addr_len=addr.max_prefixlen))
def show_packet_trace_on_all_duts(nodes, maximum=None): """Show VPP packet trace. :param nodes: Nodes from which the packet trace will be displayed. :param maximum: Maximum number of packet traces to be displayed. :type nodes: dict :type maximum: int """ maximum = "max {count}".format(count=maximum) if maximum is not None\ else "" for node in nodes.values(): if node['type'] == NodeType.DUT: PapiExecutor.run_cli_cmd(node, cmd="show trace {max}". format(max=maximum))
def vpp_add_ip_neighbor(node, iface_key, ip_addr, mac_address): """Add IP neighbor on DUT node. :param node: VPP node. :param iface_key: Interface key. :param ip_addr: IP address of the interface. :param mac_address: MAC address of the interface. :type node: dict :type iface_key: str :type ip_addr: str :type mac_address: str """ dst_ip = ip_address(unicode(ip_addr)) neighbor = dict(sw_if_index=Topology.get_interface_sw_index( node, iface_key), flags=0, mac_address=str(mac_address), ip_address=str(dst_ip)) cmd = 'ip_neighbor_add_del' args = dict(is_add=1, neighbor=neighbor) err_msg = 'Failed to add IP neighbor on interface {ifc}'.format( ifc=iface_key) with PapiExecutor(node) as papi_exec: papi_exec.add(cmd, **args).get_reply(err_msg)
def vpp_interface_set_ip_address(node, interface, address, prefix_length=None): """Set IP address to VPP interface. :param node: VPP node. :param interface: Interface name. :param address: IP address. :param prefix_length: Prefix length. :type node: dict :type interface: str :type address: str :type prefix_length: int """ ip_addr = ip_address(unicode(address)) cmd = 'sw_interface_add_del_address' args = dict(sw_if_index=InterfaceUtil.get_interface_index( node, interface), is_add=1, is_ipv6=1 if ip_addr.version == 6 else 0, del_all=0, address_length=int(prefix_length) if prefix_length else 128 if ip_addr.version == 6 else 32, address=ip_addr.packed) err_msg = 'Failed to add IP address on interface {ifc}'.format( ifc=interface) with PapiExecutor(node) as papi_exec: papi_exec.add(cmd, **args).get_reply(err_msg)
def _memif_create(node, mid, sid, rxq=1, txq=1, role=1): """Create Memif interface on the given node, return its sw_if_index. :param node: Given node to create Memif interface on. :param mid: Memif interface ID. :param sid: Socket ID. :param rxq: Number of RX queues; 0 means do not set. :param txq: Number of TX queues; 0 means do not set. :param role: Memif interface role [master=0|slave=1]. Default is slave. :type node: dict :type mid: str :type sid: str :type rxq: int :type txq: int :type role: int :returns: sw_if_index :rtype: int """ cmd = 'memif_create' err_msg = 'Failed to create memif interface on host {host}'.format( host=node['host']) args = dict(role=role, rx_queues=int(rxq), tx_queues=int(txq), socket_id=int(sid), id=int(mid)) with PapiExecutor(node) as papi_exec: return papi_exec.add(cmd, **args).get_sw_if_index(err_msg)
def vpp_show_interfaces(node): """Run "show interface" CLI command. :param node: Node to run command on. :type node: dict """ cmd = 'sw_interface_dump' cmd_reply = 'sw_interface_details' args = dict(name_filter_valid=0, name_filter='') err_msg = 'Failed to get interface dump on host {host}'.format( host=node['host']) with PapiExecutor(node) as papi_exec: papi_resp = papi_exec.add(cmd, **args).get_replies(err_msg) papi_if_dump = papi_resp.reply[0]['api_reply'] if_data = list() for item in papi_if_dump: data = item[cmd_reply] data['interface_name'] = data['interface_name'].rstrip('\x00') data['tag'] = data['tag'].rstrip('\x00') data['l2_address'] = str(':'.join( binascii.hexlify(data['l2_address'])[i:i + 2] for i in range(0, 12, 2)).decode('ascii')) if_data.append(data) # TODO: return only base data logger.trace('Interface data of host {host}:\n{if_data}'.format( host=node['host'], if_data=if_data))
def _run_cli_cmd(node, cmd, log=True): """Run a CLI command. :param node: Node to run command on. :param cmd: The CLI command to be run on the node. :param log: If True, the response is logged. :type node: dict :type cmd: str :type log: bool :returns: Verified data from PAPI response. :rtype: dict """ cli = 'cli_inband' args = dict(cmd=cmd) err_msg = "Failed to run 'cli_inband {cmd}' PAPI command on host " \ "{host}".format(host=node['host'], cmd=cmd) with PapiExecutor(node) as papi_exec: data = papi_exec.add(cli, **args).get_replies(err_msg). \ verify_reply(err_msg=err_msg) if log: logger.info("{cmd}:\n{data}".format(cmd=cmd, data=data["reply"])) return data
def vpp_create_vhost_user_interface(node, socket): """Create Vhost-user interface on VPP node. :param node: Node to create Vhost-user interface on. :param socket: Vhost-user interface socket path. :type node: dict :type socket: str :returns: SW interface index. :rtype: int """ cmd = 'create_vhost_user_if' err_msg = 'Failed to create Vhost-user interface on host {host}'.format( host=node['host']) args = dict(sock_filename=str(socket)) with PapiExecutor(node) as papi_exec: sw_if_index = papi_exec.add(cmd, **args).get_sw_if_index(err_msg) # Update the Topology: if_key = Topology.add_new_port(node, 'vhost') Topology.update_interface_sw_if_index(node, if_key, sw_if_index) ifc_name = InterfaceUtil.vpp_get_interface_name(node, sw_if_index) Topology.update_interface_name(node, if_key, ifc_name) ifc_mac = InterfaceUtil.vpp_get_interface_mac(node, sw_if_index) Topology.update_interface_mac_address(node, if_key, ifc_mac) Topology.update_interface_vhost_socket(node, if_key, socket) return sw_if_index
def vpp_ipsec_select_backend(node, protocol, index=1): """Select IPsec backend. :param node: VPP node to select IPsec backend on. :param protocol: IPsec protocol. :param index: Backend index. :type node: dict :type protocol: IPsecProto :type index: int :raises RuntimeError: If failed to select IPsec backend or if no API reply received. """ cmd = 'ipsec_select_backend' cmd_reply = 'ipsec_select_backend_reply' err_msg = 'Failed to select IPsec backend on host {host}'.format( host=node['host']) args = dict(protocol=protocol, index=index) with PapiExecutor(node) as papi_exec: papi_resp = papi_exec.add(cmd, **args).execute_should_pass(err_msg) data = papi_resp.reply[0]['api_reply'][cmd_reply] if data['retval'] != 0: raise RuntimeError( 'Failed to select IPsec backend on host {host}'.format( host=node['host']))
def _acl_interface_set_acl_list(node, sw_if_index, acl_type, acls): """Set ACL list for interface. :param node: VPP node to set ACL list for interface. :param sw_if_index: sw_if_index of the used interface. :param acl_type: Type of ACL(s) - input or output. :param acls: List of ACLs. :type node: dict :type sw_if_index: int :type acl_type: str :type acls: list """ cmd = "acl_interface_set_acl_list" n_input = len(acls) if acl_type == "input" else 0 args = dict(sw_if_index=sw_if_index, acls=acls, n_input=n_input, count=len(acls)) err_msg = "Failed to set acl list for interface {idx} on host {host}".\ format(idx=sw_if_index, host=node['host']) with PapiExecutor(node) as papi_exec: papi_exec.add(cmd, **args).get_replies(err_msg). \ verify_reply(err_msg=err_msg)
def get_interface_vrf_table(node, interface, ip_version='ipv4'): """Get vrf ID for the given interface. :param node: VPP node. :param interface: Name or sw_if_index of a specific interface. :type node: dict :param ip_version: IP protocol version (ipv4 or ipv6). :type interface: str or int :type ip_version: str :returns: vrf ID of the specified interface. :rtype: int """ sw_if_index = InterfaceUtil.get_interface_index(node, interface) is_ipv6 = 1 if ip_version == 'ipv6' else 0 cmd = 'sw_interface_get_table' args = dict(sw_if_index=sw_if_index, is_ipv6=is_ipv6) err_msg = 'Failed to get VRF id assigned to interface {ifc}'.format( ifc=interface) with PapiExecutor(node) as papi_exec: reply = papi_exec.add(cmd, **args).get_reply(err_msg) return reply['vrf_id']
def get_l2_fib_table(node, bd_id): """Retrieves the L2 FIB table. :param node: VPP node. :param bd_id: Index of the bridge domain. :type node: dict :type bd_id: int :returns: L2 FIB table. :rtype: list """ cmd = 'l2_fib_table_dump' cmd_reply = 'l2_fib_table_details' args = dict(bd_id=int(bd_id)) err_msg = 'Failed to get L2FIB dump on host {host}'.format( host=node['host']) with PapiExecutor(node) as papi_exec: papi_resp = papi_exec.add(cmd, **args).get_dump(err_msg) data = papi_resp.reply[0]['api_reply'] fib_data = list() for fib in data: fib_item = fib[cmd_reply] fib_item['mac'] = L2Util.bin_to_mac(fib_item['mac']) fib_data.append(fib_item) return fib_data
def vpp_get_bridge_domain_data(node, bd_id=0xffffffff): """Get all bridge domain data from a VPP node. If a domain ID number is provided, return only data for the matching bridge domain. :param node: VPP node to get bridge domain data from. :param bd_id: Numeric ID of a specific bridge domain. :type node: dict :type bd_id: int :returns: List of dictionaries containing data for each bridge domain, or a single dictionary for the specified bridge domain. :rtype: list or dict """ cmd = 'bridge_domain_dump' cmd_reply = 'bridge_domain_details' args = dict(bd_id=int(bd_id)) err_msg = 'Failed to get L2FIB dump on host {host}'.format( host=node['host']) with PapiExecutor(node) as papi_exec: papi_resp = papi_exec.add(cmd, **args).get_dump(err_msg) data = papi_resp.reply[0]['api_reply'] bd_data = list() if bd_id == Constants.BITWISE_NON_ZERO else dict() for bridge_domain in data: if bd_id == Constants.BITWISE_NON_ZERO: bd_data.append(bridge_domain[cmd_reply]) else: if bridge_domain[cmd_reply]['bd_id'] == bd_id: return bridge_domain[cmd_reply] return bd_data
def _memif_socket_filename_add_del(node, is_add, filename, sid): """Create Memif socket on the given node. :param node: Given node to create Memif socket on. :param is_add: If True, socket is added, otherwise deleted. :param filename: Memif interface socket filename. :param sid: Socket ID. :type node: dict :type is_add: bool :type filename: str :type sid: str :returns: Verified data from PAPI response. In this case, the response includes only retval. :rtype: dict """ cmd = 'memif_socket_filename_add_del' err_msg = 'Failed to create memif socket on host {host}'.format( host=node['host']) args = dict(is_add=int(is_add), socket_id=int(sid), socket_filename=str('/tmp/' + filename)) with PapiExecutor(node) as papi_exec: data = papi_exec.add(cmd, **args).get_replies(err_msg).\ verify_reply(err_msg=err_msg) return data
def add_interface_to_l2_bd(node, interface, bd_id, shg=0, port_type=0): """Add an interface to the L2 bridge domain. Get SW IF ID and add it to the bridge domain. :param node: Node where we want to execute the command that does this. :param interface: Interface name. :param bd_id: Bridge domain index. :param shg: Split-horizon group index. (Default value = 0) :param port_type: Port mode: 0 - normal, 1 - BVI, 2 - UU_FWD. (Default value = 0) :type node: dict :type interface: str :type bd_id: int or str :type shg: int or str :type port_type: int or str """ sw_if_index = Topology.get_interface_sw_index(node, interface) cmd = 'sw_interface_set_l2_bridge' err_msg = 'Failed to add interface {ifc} to L2 bridge domain on host ' \ '{host}'.format(ifc=interface, host=node['host']) args = dict(rx_sw_if_index=sw_if_index, bd_id=int(bd_id), shg=int(shg), port_type=int(port_type), enable=1) with PapiExecutor(node) as papi_exec: papi_exec.add(cmd, **args).get_replies(err_msg).\ verify_reply(err_msg=err_msg)
def vpp_setup_bidirectional_l2_patch(node, interface1, interface2): """Create bidirectional l2 patch between 2 interfaces on vpp node. :param node: Node to add bidirectional l2 patch. :param interface1: First interface name or sw_if_index. :param interface2: Second interface name or sw_if_index. :type node: dict :type interface1: str or int :type interface2: str or int """ if isinstance(interface1, basestring): sw_iface1 = Topology().get_interface_sw_index(node, interface1) else: sw_iface1 = interface1 if isinstance(interface2, basestring): sw_iface2 = Topology().get_interface_sw_index(node, interface2) else: sw_iface2 = interface2 cmd = 'l2_patch_add_del' args1 = dict(rx_sw_if_index=sw_iface1, tx_sw_if_index=sw_iface2, is_add=1) args2 = dict(rx_sw_if_index=sw_iface2, tx_sw_if_index=sw_iface1, is_add=1) err_msg = 'Failed to add L2 patch between two interfaces on' \ ' host {host}'.format(host=node['host']) with PapiExecutor(node) as papi_exec: papi_exec.add(cmd, **args1).add(cmd, **args2).get_replies(err_msg).\ verify_replies(err_msg=err_msg)
def set_nat44_deterministic(node, ip_in, subnet_in, ip_out, subnet_out): """Set deterministic behaviour of NAT44. :param node: DUT node. :param ip_in: Inside IP. :param subnet_in: Inside IP subnet. :param ip_out: Outside IP. :param subnet_out: Outside IP subnet. :type node: dict :type ip_in: str :type subnet_in: str or int :type ip_out: str :type subnet_out: str or int """ cmd = 'nat_det_add_del_map' err_msg = 'Failed to set deterministic behaviour of NAT on host ' \ '{host}'.format(host=node['host']) args_in = dict(is_add=True, in_addr=inet_pton(AF_INET, str(ip_in)), in_plen=int(subnet_in), out_addr=inet_pton(AF_INET, str(ip_out)), out_plen=int(subnet_out)) with PapiExecutor(node) as papi_exec: papi_exec.add(cmd, **args_in).get_reply(err_msg)
def add_del_macip_acl_interface(node, interface, action, acl_idx): """Apply/un-apply the MACIP ACL to/from a given interface. :param node: VPP node to set MACIP ACL on. :param interface: Interface name or sw_if_index. :param action: Required action - add or del. :param acl_idx: ACL index to be applied on the interface. :type node: dict :type interface: str or int :type action: str :type acl_idx: str or int :raises RuntimeError: If unable to set MACIP ACL for the interface. """ if isinstance(interface, basestring): sw_if_index = Topology.get_interface_sw_index(node, interface) else: sw_if_index = interface is_add = 1 if action == "add" else 0 cmd = 'macip_acl_interface_add_del' err_msg = "Failed to get 'macip_acl_interface' on host {host}".format( host=node['host']) args = dict(is_add=is_add, sw_if_index=int(sw_if_index), acl_index=int(acl_idx)) with PapiExecutor(node) as papi_exec: papi_exec.add(cmd, **args).get_replies(err_msg).\ verify_reply(err_msg=err_msg)
def vpp_clear_errors_counters(node): """Run "clear errors" CLI command. :param node: Node to run command on. :type node: dict :returns: Verified data from PAPI response. :rtype: dict """ return PapiExecutor.run_cli_cmd(node, 'clear errors', log=False)
def show_log(node): """Show log on the specified topology node. :param node: Topology node. :type node: dict :returns: VPP log data. :rtype: list """ return PapiExecutor.run_cli_cmd(node, "show log")
def vpp_get_ip_tables(node): """Get dump of all IP FIB tables on a VPP node. :param node: VPP node. :type node: dict """ PapiExecutor.run_cli_cmd(node, 'show ip fib') PapiExecutor.run_cli_cmd(node, 'show ip fib summary') PapiExecutor.run_cli_cmd(node, 'show ip6 fib') PapiExecutor.run_cli_cmd(node, 'show ip6 fib summary')