X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=resources%2Flibraries%2Fpython%2FInterfaceUtil.py;h=b25e70bd6e2ca66413b1d369ca0526666094d120;hb=bab0b570345ceb6ffeaec9e47a50e62d7303387e;hp=1a97130a8e6c0d65ace81db21816672eaa2ab064;hpb=669d320bc64e41f879c047a39a66b8ec99bf4b1e;p=csit.git diff --git a/resources/libraries/python/InterfaceUtil.py b/resources/libraries/python/InterfaceUtil.py index 1a97130a8e..b25e70bd6e 100644 --- a/resources/libraries/python/InterfaceUtil.py +++ b/resources/libraries/python/InterfaceUtil.py @@ -30,20 +30,77 @@ from resources.libraries.python.topology import NodeType, Topology from resources.libraries.python.VPPUtil import VPPUtil -class LinkBondLoadBalance(IntEnum): - """Link bonding load balance.""" - L2 = 0 # pylint: disable=invalid-name - L34 = 1 - L23 = 2 +class InterfaceStatusFlags(IntEnum): + """Interface status flags.""" + IF_STATUS_API_FLAG_ADMIN_UP = 1 + IF_STATUS_API_FLAG_LINK_UP = 2 + + +class MtuProto(IntEnum): + """MTU protocol.""" + MTU_PROTO_API_L3 = 0 + MTU_PROTO_API_IP4 = 1 + MTU_PROTO_API_IP6 = 2 + MTU_PROTO_API_MPLS = 3 + MTU_PROTO_API_N = 4 + + +class LinkDuplex(IntEnum): + """Link duplex""" + LINK_DUPLEX_API_UNKNOWN = 0 + LINK_DUPLEX_API_HALF = 1 + LINK_DUPLEX_API_FULL = 2 + + +class SubInterfaceFlags(IntEnum): + """Sub-interface flags.""" + SUB_IF_API_FLAG_NO_TAGS = 1 + SUB_IF_API_FLAG_ONE_TAG = 2 + SUB_IF_API_FLAG_TWO_TAGS = 4 + SUB_IF_API_FLAG_DOT1AD = 8 + SUB_IF_API_FLAG_EXACT_MATCH = 16 + SUB_IF_API_FLAG_DEFAULT = 32 + SUB_IF_API_FLAG_OUTER_VLAN_ID_ANY = 64 + SUB_IF_API_FLAG_INNER_VLAN_ID_ANY = 128 + SUB_IF_API_FLAG_DOT1AH = 256 + + +class RxMode(IntEnum): + """RX mode""" + RX_MODE_API_UNKNOWN = 0 + RX_MODE_API_POLLING = 1 + RX_MODE_API_INTERRUPT = 2 + RX_MODE_API_ADAPTIVE = 3 + RX_MODE_API_DEFAULT = 4 + + +class IfType(IntEnum): + """Interface type""" + # A hw interface + IF_API_TYPE_HARDWARE = 0 + # A sub-interface + IF_API_TYPE_SUB = 1 + IF_API_TYPE_P2P = 2 + IF_API_TYPE_PIPE = 3 + + +class LinkBondLoadBalanceAlgo(IntEnum): + """Link bonding load balance algorithm.""" + BOND_API_LB_ALGO_L2 = 0 + BOND_API_LB_ALGO_L34 = 1 + BOND_API_LB_ALGO_L23 = 2 + BOND_API_LB_ALGO_RR = 3 + BOND_API_LB_ALGO_BC = 4 + BOND_API_LB_ALGO_AB = 5 class LinkBondMode(IntEnum): - """Link bonding load balance.""" - ROUND_ROBIN = 1 - ACTIVE_BACKUP = 2 - XOR = 3 - BROADCAST = 4 - LACP = 5 + """Link bonding mode.""" + BOND_API_MODE_ROUND_ROBIN = 1 + BOND_API_MODE_ACTIVE_BACKUP = 2 + BOND_API_MODE_XOR = 3 + BOND_API_MODE_BROADCAST = 4 + BOND_API_MODE_LACP = 5 class InterfaceUtil(object): @@ -126,17 +183,18 @@ class InterfaceUtil(object): if node['type'] == NodeType.DUT: if state == 'up': - admin_up_down = 1 + flags = InterfaceStatusFlags.IF_STATUS_API_FLAG_ADMIN_UP.value elif state == 'down': - admin_up_down = 0 + flags = 0 else: raise ValueError('Unexpected interface state: {state}'.format( state=state)) cmd = 'sw_interface_set_flags' err_msg = 'Failed to set interface state on host {host}'.format( host=node['host']) - args = dict(sw_if_index=sw_if_index, - admin_up_down=admin_up_down) + args = dict( + sw_if_index=sw_if_index, + flags=flags) with PapiSocketExecutor(node) as papi_exec: papi_exec.add(cmd, **args).get_reply(err_msg) elif node['type'] == NodeType.TG or node['type'] == NodeType.VM: @@ -258,13 +316,12 @@ class InterfaceUtil(object): not_ready = list() out = InterfaceUtil.vpp_get_interface_data(node) for interface in out: - if interface.get('admin_up_down') == 1: - if interface.get('link_up_down') != 1: - not_ready.append(interface.get('interface_name')) + if interface.get('flags') == 1: + not_ready.append(interface.get('interface_name')) if not not_ready: break else: - logger.debug('Interfaces still in link-down state:\n{ifs} ' + logger.debug('Interfaces still not in link-up state:\n{ifs} ' '\nWaiting...'.format(ifs=not_ready)) sleep(1) else: @@ -312,11 +369,16 @@ class InterfaceUtil(object): :returns: Processed interface dump. :rtype: dict """ - if_dump['interface_name'] = if_dump['interface_name'].rstrip('\x00') - if_dump['tag'] = if_dump['tag'].rstrip('\x00') - if_dump['l2_address'] = L2Util.bin_to_mac(if_dump['l2_address']) - if_dump['b_dmac'] = L2Util.bin_to_mac(if_dump['b_dmac']) - if_dump['b_smac'] = L2Util.bin_to_mac(if_dump['b_smac']) + if_dump['l2_address'] = str(if_dump['l2_address']) + if_dump['b_dmac'] = str(if_dump['b_dmac']) + if_dump['b_smac'] = str(if_dump['b_smac']) + if_dump['flags'] = if_dump['flags'].value + if_dump['type'] = if_dump['type'].value + if_dump['link_duplex'] = if_dump['link_duplex'].value + if_dump['sub_if_flags'] = if_dump['sub_if_flags'].value \ + if hasattr(if_dump['sub_if_flags'], 'value') \ + else int(if_dump['sub_if_flags']) + return if_dump if interface is not None: @@ -331,12 +393,15 @@ class InterfaceUtil(object): param = '' cmd = 'sw_interface_dump' - args = dict(name_filter_valid=0, - name_filter='') + args = dict( + name_filter_valid=False, + name_filter='' + ) err_msg = 'Failed to get interface dump on host {host}'.format( host=node['host']) with PapiSocketExecutor(node) as papi_exec: details = papi_exec.add(cmd, **args).get_details(err_msg) + logger.debug('Received data:\n{d!r}'.format(d=details)) data = list() if interface is None else dict() for dump in details: @@ -724,8 +789,10 @@ class InterfaceUtil(object): sw_if_index = InterfaceUtil.get_interface_index(node, interface) cmd = 'create_vlan_subif' - args = dict(sw_if_index=sw_if_index, - vlan_id=int(vlan)) + args = dict( + sw_if_index=sw_if_index, + vlan_id=int(vlan) + ) err_msg = 'Failed to create VLAN sub-interface on host {host}'.format( host=node['host']) with PapiSocketExecutor(node) as papi_exec: @@ -930,20 +997,31 @@ class InterfaceUtil(object): """ subif_types = type_subif.split() + flags = 0 + if 'no_tags' in subif_types: + flags = flags | SubInterfaceFlags.SUB_IF_API_FLAG_NO_TAGS + if 'one_tag' in subif_types: + flags = flags | SubInterfaceFlags.SUB_IF_API_FLAG_ONE_TAG + if 'two_tags' in subif_types: + flags = flags | SubInterfaceFlags.SUB_IF_API_FLAG_TWO_TAGS + if 'dot1ad' in subif_types: + flags = flags | SubInterfaceFlags.SUB_IF_API_FLAG_DOT1AD + if 'exact_match' in subif_types: + flags = flags | SubInterfaceFlags.SUB_IF_API_FLAG_EXACT_MATCH + if 'default_sub' in subif_types: + flags = flags | SubInterfaceFlags.SUB_IF_API_FLAG_DEFAULT + if type_subif == 'default_sub': + flags = flags | SubInterfaceFlags.SUB_IF_API_FLAG_INNER_VLAN_ID_ANY\ + | SubInterfaceFlags.SUB_IF_API_FLAG_OUTER_VLAN_ID_ANY + cmd = 'create_subif' args = dict( sw_if_index=InterfaceUtil.get_interface_index(node, interface), sub_id=int(sub_id), - no_tags=1 if 'no_tags' in subif_types else 0, - one_tag=1 if 'one_tag' in subif_types else 0, - two_tags=1 if 'two_tags' in subif_types else 0, - dot1ad=1 if 'dot1ad' in subif_types else 0, - exact_match=1 if 'exact_match' in subif_types else 0, - default_sub=1 if 'default_sub' in subif_types else 0, - outer_vlan_id_any=1 if type_subif == 'default_sub' else 0, - inner_vlan_id_any=1 if type_subif == 'default_sub' else 0, + sub_if_flags=flags.value if hasattr(flags, 'value') else int(flags), outer_vlan_id=int(outer_vlan_id) if outer_vlan_id else 0, - inner_vlan_id=int(inner_vlan_id) if inner_vlan_id else 0) + inner_vlan_id=int(inner_vlan_id) if inner_vlan_id else 0 + ) err_msg = 'Failed to create sub-interface on host {host}'.format( host=node['host']) with PapiSocketExecutor(node) as papi_exec: @@ -996,7 +1074,7 @@ class InterfaceUtil(object): """Create loopback interface on VPP node. :param node: Node to create loopback interface on. - :param mac: Optional MAC address for Loopback interface. + :param mac: Optional MAC address for loopback interface. :type node: dict :type mac: str :returns: SW interface index. @@ -1040,21 +1118,24 @@ class InterfaceUtil(object): the node. """ cmd = 'bond_create' - args = dict(id=int(Constants.BITWISE_NON_ZERO), - use_custom_mac=0 if mac is None else 1, - mac_address=0 if mac is None else L2Util.mac_to_bin(mac), - mode=getattr(LinkBondMode, '{md}'.format( - md=mode.replace('-', '_').upper())).value, - lb=0 if load_balance is None else getattr( - LinkBondLoadBalance, '{lb}'.format( - lb=load_balance.upper())).value) + args = dict( + id=int(Constants.BITWISE_NON_ZERO), + use_custom_mac=False if mac is None else True, + mac_address=L2Util.mac_to_bin(mac) if mac else None, + mode=getattr(LinkBondMode, 'BOND_API_MODE_{md}'.format( + md=mode.replace('-', '_').upper())).value, + lb=0 if load_balance is None else getattr( + LinkBondLoadBalanceAlgo, 'BOND_API_LB_ALGO_{lb}'.format( + lb=load_balance.upper())).value, + numa_only=False + ) err_msg = 'Failed to create bond interface on host {host}'.format( host=node['host']) with PapiSocketExecutor(node) as papi_exec: sw_if_index = papi_exec.add(cmd, **args).get_sw_if_index(err_msg) - InterfaceUtil.add_eth_interface(node, sw_if_index=sw_if_index, - ifc_pfx='eth_bond') + InterfaceUtil.add_eth_interface( + node, sw_if_index=sw_if_index, ifc_pfx='eth_bond') if_key = Topology.get_interface_by_sw_index(node, sw_if_index) return if_key @@ -1133,8 +1214,9 @@ class InterfaceUtil(object): args = dict( sw_if_index=Topology.get_interface_sw_index(node, interface), bond_sw_if_index=Topology.get_interface_sw_index(node, bond_if), - is_passive=0, - is_long_timeout=0) + is_passive=False, + is_long_timeout=False + ) err_msg = 'Failed to enslave physical interface {ifc} to bond ' \ 'interface {bond} on host {host}'.format(ifc=interface, bond=bond_if, @@ -1160,9 +1242,11 @@ class InterfaceUtil(object): details = papi_exec.add(cmd).get_details(err_msg) for bond in details: - data += ('{b}\n'.format(b=bond['interface_name'].rstrip('\x00'))) - data += (' mode: {m}\n'.format(m=bond['mode']).lower()) - data += (' load balance: {lb}\n'.format(lb=bond['lb']).lower()) + data += ('{b}\n'.format(b=bond['interface_name'])) + data += (' mode: {m}\n'.format( + m=bond['mode'].name.replace('BOND_API_MODE_', '').lower())) + data += (' load balance: {lb}\n'.format( + lb=bond['lb'].name.replace('BOND_API_LB_ALGO_', '').lower())) data += (' number of active slaves: {n}\n'.format( n=bond['active_slaves'])) if verbose: @@ -1191,18 +1275,6 @@ class InterfaceUtil(object): :returns: Bond slave interface data. :rtype: dict """ - def process_slave_dump(slave_dump): - """Process slave dump. - - :param slave_dump: Slave interface dump. - :type slave_dump: dict - :returns: Processed slave interface dump. - :rtype: dict - """ - slave_dump['interface_name'] = slave_dump['interface_name'].\ - rstrip('\x00') - return slave_dump - cmd = 'sw_interface_slave_dump' args = dict(sw_if_index=Topology.get_interface_sw_index( node, interface)) @@ -1212,10 +1284,6 @@ class InterfaceUtil(object): with PapiSocketExecutor(node) as papi_exec: details = papi_exec.add(cmd, **args).get_details(err_msg) - for dump in details: - # In-place edits. - process_slave_dump(dump) - logger.debug('Slave data:\n{slave_data}'.format(slave_data=details)) return details @@ -1378,7 +1446,7 @@ class InterfaceUtil(object): cmd = 'sw_interface_set_table' args = dict( sw_if_index=InterfaceUtil.get_interface_index(node, interface), - is_ipv6=1 if ipv6 else 0, + is_ipv6=ipv6, vrf_id=int(table_id)) err_msg = 'Failed to assign interface {ifc} to FIB table'.format( ifc=interface) @@ -1455,12 +1523,12 @@ class InterfaceUtil(object): @staticmethod def init_avf_interface(node, ifc_key, numvfs=1, osi_layer='L2'): - """Init PCI device by creating VFs and bind them to vfio-pci for AVF + """Init PCI device by creating VIFs and bind them to vfio-pci for AVF driver testing on DUT. :param node: DUT node. :param ifc_key: Interface key from topology file. - :param numvfs: Number of VFs to initialize, 0 - disable the VFs. + :param numvfs: Number of VIFs to initialize, 0 - disable the VIFs. :param osi_layer: OSI Layer type to initialize TG with. Default value "L2" sets linux interface spoof off. :type node: dict @@ -1518,7 +1586,7 @@ class InterfaceUtil(object): DUTSetup.pci_vf_driver_bind(node, pf_pci_addr, vf_id, uio_driver) # Add newly created ports into topology file - vf_ifc_name = '{pf_if_key}_vf'.format(pf_if_key=ifc_key) + vf_ifc_name = '{pf_if_key}_vif'.format(pf_if_key=ifc_key) vf_pci_addr = DUTSetup.get_virtfn_pci_addr(node, pf_pci_addr, vf_id) vf_ifc_key = Topology.add_new_port(node, vf_ifc_name) Topology.update_interface_name(node, vf_ifc_key, @@ -1567,8 +1635,12 @@ class InterfaceUtil(object): cmd = 'sw_interface_set_rx_placement' err_msg = "Failed to set interface RX placement to worker on host " \ "{host}!".format(host=node['host']) - args = dict(sw_if_index=sw_if_index, queue_id=queue_id, - worker_id=worker_id) + args = dict( + sw_if_index=sw_if_index, + queue_id=queue_id, + worker_id=worker_id, + is_main=False + ) with PapiSocketExecutor(node) as papi_exec: papi_exec.add(cmd, **args).get_reply(err_msg)