X-Git-Url: https://gerrit.fd.io/r/gitweb?p=csit.git;a=blobdiff_plain;f=resources%2Flibraries%2Fpython%2FInterfaceUtil.py;h=2b985bf4341e30ceb6a1354ef5b05240f67dcf9d;hp=a84d5957673f7c40e6fdf829ab71fbce608422bd;hb=7c3e0cc41f55327d6eeb04fe757c6e80064ab28a;hpb=e8c787b699661f00e8358cc711bb20b8993dc87a diff --git a/resources/libraries/python/InterfaceUtil.py b/resources/libraries/python/InterfaceUtil.py index a84d595767..2b985bf434 100644 --- a/resources/libraries/python/InterfaceUtil.py +++ b/resources/libraries/python/InterfaceUtil.py @@ -32,19 +32,36 @@ class InterfaceUtil(object): __UDEV_IF_RULES_FILE = '/etc/udev/rules.d/10-network.rules' @staticmethod - def set_interface_state(node, interface, state): + def set_interface_state(node, interface, state, if_type="key"): """Set interface state on a node. Function can be used for DUTs as well as for TGs. :param node: Node where the interface is. - :param interface: Interface name or sw_if_index. + :param interface: Interface key or sw_if_index or name. :param state: One of 'up' or 'down'. + :param if_type: Interface type :type node: dict :type interface: str or int :type state: str + :type if_type: str :return: nothing """ + + if if_type == "key": + if isinstance(interface, basestring): + sw_if_index = Topology.get_interface_sw_index(node, interface) + iface_name = Topology.get_interface_name(node, interface) + else: + sw_if_index = interface + elif if_type == "name": + iface_key = Topology.get_interface_by_name(node, interface) + if iface_key is not None: + sw_if_index = Topology.get_interface_sw_index(node, iface_key) + iface_name = interface + else: + raise ValueError("if_type unknown: {}".format(if_type)) + if node['type'] == NodeType.DUT: if state == 'up': state = 'admin-up' @@ -52,33 +69,26 @@ class InterfaceUtil(object): state = 'admin-down' else: raise ValueError('Unexpected interface state: {}'.format(state)) - - if isinstance(interface, basestring): - sw_if_index = Topology.get_interface_sw_index(node, interface) - else: - sw_if_index = interface - VatExecutor.cmd_from_template(node, 'set_if_state.vat', sw_if_index=sw_if_index, state=state) - elif node['type'] == NodeType.TG or node['type'] == NodeType.VM: - cmd = 'ip link set {} {}'.format(interface, state) + cmd = 'ip link set {} {}'.format(iface_name, state) exec_cmd_no_error(node, cmd, sudo=True) else: raise Exception('Node {} has unknown NodeType: "{}"'. format(node['host'], node['type'])) @staticmethod - def set_interface_ethernet_mtu(node, interface, mtu): + def set_interface_ethernet_mtu(node, iface_key, mtu): """Set Ethernet MTU for specified interface. Function can be used only for TGs. :param node: Node where the interface is. - :param interface: Interface name. + :param interface: Interface key from topology file. :param mtu: MTU to set. :type node: dict - :type interface: str + :type iface_key: str :type mtu: int :return: nothing """ @@ -86,7 +96,8 @@ class InterfaceUtil(object): ValueError('Node {}: Setting Ethernet MTU for interface ' 'on DUT nodes not supported', node['host']) elif node['type'] == NodeType.TG: - cmd = 'ip link set {} mtu {}'.format(interface, mtu) + iface_name = Topology.get_interface_name(node, iface_key) + cmd = 'ip link set {} mtu {}'.format(iface_name, mtu) exec_cmd_no_error(node, cmd, sudo=True) else: raise ValueError('Node {} has unknown NodeType: "{}"'. @@ -102,8 +113,8 @@ class InterfaceUtil(object): :type node: dict :return: nothing """ - for ifc in node['interfaces'].values(): - InterfaceUtil.set_interface_ethernet_mtu(node, ifc['name'], 1500) + for ifc in node['interfaces']: + InterfaceUtil.set_interface_ethernet_mtu(node, ifc, 1500) @staticmethod def vpp_node_interfaces_ready_wait(node, timeout=10): @@ -216,7 +227,7 @@ class InterfaceUtil(object): Note: A single interface may have multiple IP addresses assigned. :rtype: list """ - sw_if_index = Topology.get_interface_sw_index(node, interface) + sw_if_index = InterfaceUtil.get_sw_if_index(node, interface) with VatTerminal(node) as vat: response = vat.vat_terminal_exec_cmd_from_template( @@ -444,7 +455,8 @@ class InterfaceUtil(object): :return: Name and index of created subinterface. :rtype: tuple """ - sw_if_index = Topology.get_interface_sw_index(node, interface) + iface_key = Topology.get_interface_by_name(node, interface) + sw_if_index = Topology.get_interface_sw_index(node, iface_key) output = VatExecutor.cmd_from_template(node, "create_vlan_subif.vat", sw_if_index=sw_if_index, @@ -568,28 +580,41 @@ class InterfaceUtil(object): return {} @staticmethod - def create_subinterface(node, interface, sub_id, outer_vlan_id, - inner_vlan_id, type_subif): - """Create sub-interface on node. + def create_subinterface(node, interface, sub_id, outer_vlan_id=None, + inner_vlan_id=None, type_subif=None): + """Create sub-interface on node. It is possible to set required + sub-interface type and VLAN tag(s). :param node: Node to add sub-interface. :param interface: Interface name on which create sub-interface. :param sub_id: ID of the sub-interface to be created. - :param outer_vlan_id: Outer VLAN ID. - :param inner_vlan_id: Inner VLAN ID. - :param type_subif: Type of sub-interface. + :param outer_vlan_id: Optional outer VLAN ID. + :param inner_vlan_id: Optional inner VLAN ID. + :param type_subif: Optional type of sub-interface. Values supported by + VPP: [no_tags] [one_tag] [two_tags] [dot1ad] [exact_match] [default_sub] :type node: dict :type interface: str or int :type sub_id: int :type outer_vlan_id: int :type inner_vlan_id: int :type type_subif: str - :return: name and index of created sub-interface + :return: Name and index of created sub-interface. :rtype: tuple + :raises RuntimeError: If it is not possible to create sub-interface. """ + outer_vlan_id = 'outer_vlan_id {0}'.format(outer_vlan_id)\ + if outer_vlan_id else '' + + inner_vlan_id = 'inner_vlan_id {0}'.format(inner_vlan_id)\ + if inner_vlan_id else '' + + if type_subif is None: + type_subif = '' + if isinstance(interface, basestring): - sw_if_index = Topology.get_interface_sw_index(node, interface) + iface_key = Topology.get_interface_by_name(node, interface) + sw_if_index = Topology.get_interface_sw_index(node, iface_key) else: sw_if_index = interface @@ -605,10 +630,10 @@ class InterfaceUtil(object): logger.trace('Created subinterface with index {}' .format(sw_subif_index)) else: - raise RuntimeError('Unable to create subinterface on node {}' + raise RuntimeError('Unable to create sub-interface on node {}' .format(node['host'])) - with VatTerminal(node) as vat: + with VatTerminal(node, json_param=False) as vat: vat.vat_terminal_exec_cmd('exec show interfaces') name = '{}.{}'.format(interface, sub_id) @@ -687,6 +712,29 @@ class InterfaceUtil(object): ip_version=ip_version, table_index=table_index) + @staticmethod + def get_interface_classify_table(node, interface): + """Get name of classify table for the given interface. + + :param node: VPP node to get data from. + :param interface: Name or sw_if_index of a specific interface. + :type node: dict + :type interface: str or int + :return: Classify table name. + :rtype: str + """ + if isinstance(interface, basestring): + sw_if_index = InterfaceUtil.get_sw_if_index(node, interface) + else: + sw_if_index = interface + + with VatTerminal(node) as vat: + data = vat.vat_terminal_exec_cmd_from_template( + "classify_interface_table.vat", + sw_if_index=sw_if_index + ) + return data[0] + @staticmethod def get_sw_if_index(node, interface_name): """Get sw_if_index for the given interface from actual interface dump. @@ -736,3 +784,76 @@ class InterfaceUtil(object): return {} return vxlan_gpe_data[0] + + @staticmethod + def vpp_proxy_arp_interface_enable(node, interface): + """Enable proxy ARP on interface. + + :param node: VPP node to enable proxy ARP on interface. + :param interface: Interface to enable proxy ARP. + :type node: dict + :type interface: str or int + """ + if isinstance(interface, basestring): + sw_if_index = InterfaceUtil.get_sw_if_index(node, interface) + else: + sw_if_index = interface + + with VatTerminal(node) as vat: + vat.vat_terminal_exec_cmd_from_template( + "proxy_arp_intfc_enable.vat", + sw_if_index=sw_if_index) + + @staticmethod + def vpp_ip_source_check_setup(node, interface): + """Setup Reverse Path Forwarding source check on interface. + + :param node: Node to setup RPF source check. + :param interface: Interface name to setup RPF source check. + :type node: dict + :type interface: str + """ + with VatTerminal(node) as vat: + vat.vat_terminal_exec_cmd_from_template("ip_source_check.vat", + interface_name=interface) + + @staticmethod + def assign_interface_to_fib_table(node, interface, table_id): + """Assign VPP interface to specific VRF/FIB table. + + :param node: VPP node where the FIB and interface are located. + :param interface: Interface to be assigned to FIB. + :param table_id: VRF table ID. + :type node: dict + :type interface: str or int + :type table_id: int + """ + if isinstance(interface, basestring): + sw_if_index = Topology.get_interface_sw_index(node, interface) + else: + sw_if_index = interface + + with VatTerminal(node) as vat: + vat.vat_terminal_exec_cmd_from_template("set_fib_to_interface.vat", + sw_index=sw_if_index, + vrf=table_id) + + @staticmethod + def set_linux_interface_mac(node, interface, mac, namespace=None): + """Set MAC address for interface in linux. + + :param node: Node where to execute command. + :param interface: Interface in namespace. + :param mac: MAC to be assigned to interface. + :param namespace: Execute command in namespace. Optional + :type node: dict + :type interface: str + :type mac: str + :type namespace: str + """ + if namespace is not None: + cmd = 'ip netns exec {} ip link set {} address {}'.format( + namespace, interface, mac) + else: + cmd = 'ip link set {} address {}'.format(interface, mac) + exec_cmd_no_error(node, cmd, sudo=True)