diff options
Diffstat (limited to 'resources/libraries/python')
-rw-r--r-- | resources/libraries/python/CpuUtils.py | 6 | ||||
-rw-r--r-- | resources/libraries/python/DPDK/L3fwdTest.py | 22 | ||||
-rw-r--r-- | resources/libraries/python/DPDK/TestpmdTest.py | 20 | ||||
-rw-r--r-- | resources/libraries/python/HoststackUtil.py | 21 | ||||
-rw-r--r-- | resources/libraries/python/IPsecUtil.py | 79 | ||||
-rw-r--r-- | resources/libraries/python/KubernetesUtils.py | 2 | ||||
-rw-r--r-- | resources/libraries/python/QemuManager.py | 28 | ||||
-rw-r--r-- | resources/libraries/python/QemuUtils.py | 16 | ||||
-rw-r--r-- | resources/libraries/python/VppConfigGenerator.py | 65 | ||||
-rw-r--r-- | resources/libraries/python/autogen/Regenerator.py | 3 | ||||
-rw-r--r-- | resources/libraries/python/enum_util.py | 19 |
11 files changed, 197 insertions, 84 deletions
diff --git a/resources/libraries/python/CpuUtils.py b/resources/libraries/python/CpuUtils.py index c77d0f83b1..518469bd31 100644 --- a/resources/libraries/python/CpuUtils.py +++ b/resources/libraries/python/CpuUtils.py @@ -1,4 +1,4 @@ -# Copyright (c) 2023 Cisco and/or its affiliates. +# Copyright (c) 2024 Cisco and/or its affiliates. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: @@ -247,6 +247,9 @@ class CpuUtils: """Return list of DUT node related list of CPU numbers. The main computing unit is physical core count. + On SMT enabled DUTs, both sibling logical cores are used, + unless Robot variable \${smt_used} is set to False. + :param node: DUT node. :param cpu_node: Numa node number. :param nf_chains: Number of NF chains. @@ -278,6 +281,7 @@ class CpuUtils: raise RuntimeError(u"NodeID is out of range!") smt_used = CpuUtils.is_smt_enabled(node[u"cpuinfo"]) + smt_used = BuiltIn().get_variable_value("\${smt_used}", smt_used) cpu_list = CpuUtils.cpu_list_per_node(node, cpu_node, smt_used) # CPU thread sibling offset. sib = len(cpu_list) // CpuUtils.NR_OF_THREADS diff --git a/resources/libraries/python/DPDK/L3fwdTest.py b/resources/libraries/python/DPDK/L3fwdTest.py index 178c747da5..f7da7bdb3b 100644 --- a/resources/libraries/python/DPDK/L3fwdTest.py +++ b/resources/libraries/python/DPDK/L3fwdTest.py @@ -1,4 +1,4 @@ -# Copyright (c) 2023 Cisco and/or its affiliates. +# Copyright (c) 2024 Cisco and/or its affiliates. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: @@ -31,7 +31,7 @@ class L3fwdTest: @staticmethod def start_l3fwd_on_all_duts( - nodes, topology_info, phy_cores, rx_queues=None, jumbo_frames=False, + nodes, topology_info, phy_cores, rx_queues=None, jumbo=False, rxd=None, txd=None): """ Execute the l3fwd on all dut nodes. @@ -40,7 +40,7 @@ class L3fwdTest: :param topology_info: All the info from the topology file. :param phy_cores: Number of physical cores to use. :param rx_queues: Number of RX queues. - :param jumbo_frames: Jumbo frames on/off. + :param jumbo: Jumbo frames on/off. :param rxd: Number of RX descriptors. :param txd: Number of TX descriptors. @@ -48,7 +48,7 @@ class L3fwdTest: :type topology_info: dict :type phy_cores: int :type rx_queues: int - :type jumbo_frames: bool + :type jumbo: bool :type rxd: int :type txd: int :raises RuntimeError: If bash return code is not 0. @@ -76,7 +76,7 @@ class L3fwdTest: L3fwdTest.start_l3fwd( nodes, node, if1=if1, if2=if2, lcores_list=cpu_dp, nb_cores=dp_count_int, queue_nums=rxq_count_int, - jumbo_frames=jumbo_frames, tg_flip=tg_flip + jumbo=jumbo, tg_flip=tg_flip ) for node in nodes: if u"DUT" in node: @@ -88,7 +88,7 @@ class L3fwdTest: L3fwdTest.start_l3fwd( nodes, nodes[node], if1=if1, if2=if2, lcores_list=cpu_dp, nb_cores=dp_count_int, - queue_nums=rxq_count_int, jumbo_frames=jumbo_frames, + queue_nums=rxq_count_int, jumbo=jumbo, tg_flip=tg_flip ) else: @@ -98,7 +98,7 @@ class L3fwdTest: @staticmethod def start_l3fwd( nodes, node, if1, if2, lcores_list, nb_cores, queue_nums, - jumbo_frames, tg_flip): + jumbo, tg_flip): """ Execute the l3fwd on the dut_node. @@ -113,7 +113,7 @@ class L3fwdTest: :param lcores_list: The lcore list string for the l3fwd routing :param nb_cores: The cores number for the forwarding :param queue_nums: The queues number for the NIC - :param jumbo_frames: Indication if the jumbo frames are used (True) or + :param jumbo: Indication if the jumbo frames are used (True) or not (False). :param tg_flip: Whether TG ports are reordered. :type nodes: dict @@ -123,7 +123,7 @@ class L3fwdTest: :type lcores_list: str :type nb_cores: str :type queue_nums: str - :type jumbo_frames: bool + :type jumbo: bool :type tg_flip: bool """ if node[u"type"] == NodeType.DUT: @@ -144,7 +144,7 @@ class L3fwdTest: f"({port}, {queue}, {lcores[index % NB_PORTS]})," index += 1 - if jumbo_frames: + if jumbo: l3fwd_args = DpdkUtil.get_l3fwd_args( eal_corelist=f"1,{lcores_list}", eal_driver=False, @@ -155,7 +155,7 @@ class L3fwdTest: pmd_eth_dest_0=f"\\\"0,{adj_mac0}\\\"", pmd_eth_dest_1=f"\\\"1,{adj_mac1}\\\"", pmd_parse_ptype=True, - pmd_max_pkt_len=jumbo_frames + pmd_max_pkt_len=jumbo ) else: l3fwd_args = DpdkUtil.get_l3fwd_args( diff --git a/resources/libraries/python/DPDK/TestpmdTest.py b/resources/libraries/python/DPDK/TestpmdTest.py index 3baba30715..c141851bdc 100644 --- a/resources/libraries/python/DPDK/TestpmdTest.py +++ b/resources/libraries/python/DPDK/TestpmdTest.py @@ -1,4 +1,4 @@ -# Copyright (c) 2023 Cisco and/or its affiliates. +# Copyright (c) 2024 Cisco and/or its affiliates. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: @@ -30,7 +30,7 @@ class TestpmdTest: @staticmethod def start_testpmd_on_all_duts( - nodes, topology_info, phy_cores, rx_queues=None, jumbo_frames=False, + nodes, topology_info, phy_cores, rx_queues=None, jumbo=False, rxd=None, txd=None, nic_rxq_size=None, nic_txq_size=None): """ Start the testpmd with M worker threads and rxqueues N and jumbo @@ -40,7 +40,7 @@ class TestpmdTest: :param topology_info: All the info from the topology file. :param phy_cores: Number of physical cores to use. :param rx_queues: Number of RX queues. - :param jumbo_frames: Jumbo frames on/off. + :param jumbo: Jumbo frames on/off. :param rxd: Number of RX descriptors. :param txd: Number of TX descriptors. :param nic_rxq_size: RX queue size. @@ -50,7 +50,7 @@ class TestpmdTest: :type topology_info: dict :type phy_cores: int :type rx_queues: int - :type jumbo_frames: bool + :type jumbo: bool :type rxd: int :type txd: int :type nic_rxq_size: int @@ -80,7 +80,7 @@ class TestpmdTest: TestpmdTest.start_testpmd( node, if1=if1, if2=if2, lcores_list=cpu_dp, nb_cores=dp_count_int, queue_nums=rxq_count_int, - jumbo_frames=jumbo_frames, rxq_size=nic_rxq_size, + jumbo=jumbo, rxq_size=nic_rxq_size, txq_size=nic_txq_size ) for node in nodes: @@ -99,7 +99,7 @@ class TestpmdTest: nodes[node], if1=if1, if2=if2, lcores_list=cpu_dp, nb_cores=dp_count_int, queue_nums=rxq_count_int, - jumbo_frames=jumbo_frames, + jumbo=jumbo, rxq_size=nic_rxq_size, txq_size=nic_txq_size ) else: @@ -109,7 +109,7 @@ class TestpmdTest: @staticmethod def start_testpmd( node, if1, if2, lcores_list, nb_cores, queue_nums, - jumbo_frames, rxq_size=1024, txq_size=1024): + jumbo, rxq_size=1024, txq_size=1024): """ Execute the testpmd on the DUT node. @@ -119,7 +119,7 @@ class TestpmdTest: :param lcores_list: The DPDK run cores. :param nb_cores: The cores number for the forwarding. :param queue_nums: The queues number for the NIC. - :param jumbo_frames: Indication if the jumbo frames are used (True) or + :param jumbo: Indication if the jumbo frames are used (True) or not (False). :param rxq_size: RXQ size. Default=1024. :param txq_size: TXQ size. Default=1024. @@ -129,7 +129,7 @@ class TestpmdTest: :type lcores_list: str :type nb_cores: int :type queue_nums: str - :type jumbo_frames: bool + :type jumbo: bool :type rxq_size: int :type txq_size: int :raises RuntimeError: If the script "run_testpmd.sh" fails. @@ -138,7 +138,7 @@ class TestpmdTest: if_pci0 = Topology.get_interface_pci_addr(node, if1) if_pci1 = Topology.get_interface_pci_addr(node, if2) - pmd_max_pkt_len = u"9200" if jumbo_frames else u"1518" + pmd_max_pkt_len = u"9200" if jumbo else u"1518" testpmd_args = DpdkUtil.get_testpmd_args( eal_corelist=f"1,{lcores_list}", eal_driver=False, diff --git a/resources/libraries/python/HoststackUtil.py b/resources/libraries/python/HoststackUtil.py index 399395d41a..4ac73ff924 100644 --- a/resources/libraries/python/HoststackUtil.py +++ b/resources/libraries/python/HoststackUtil.py @@ -1,4 +1,4 @@ -# Copyright (c) 2023 Cisco and/or its affiliates. +# Copyright (c) 2024 Cisco and/or its affiliates. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: @@ -413,10 +413,6 @@ class HoststackUtil(): f"bits/sec, pkt-drop-rate {nsim_attr[u'packets_per_drop']} " \ f"pkts/drop\n" - test_results += \ - f"\n{role} VPP 'show errors' on host {node[u'host']}:\n" \ - f"{PapiSocketExecutor.run_cli_cmd(node, u'show error')}\n" - if u"error" in program_stderr.lower(): test_results += f"ERROR DETECTED:\n{program_stderr}" return (True, test_results) @@ -469,18 +465,3 @@ class HoststackUtil(): :rtype: bool """ return server_defer_fail and client_defer_fail - - @staticmethod - def log_vpp_hoststack_data(node): - """Retrieve and log VPP HostStack data. - - :param node: DUT node. - :type node: dict - :raises RuntimeError: If node subtype is not a DUT or startup failed. - """ - - if node[u"type"] != u"DUT": - raise RuntimeError(u"Node type is not a DUT!") - - PapiSocketExecutor.run_cli_cmd(node, u"show error") - PapiSocketExecutor.run_cli_cmd(node, u"show interface") diff --git a/resources/libraries/python/IPsecUtil.py b/resources/libraries/python/IPsecUtil.py index 59374ab73f..1abfee2cec 100644 --- a/resources/libraries/python/IPsecUtil.py +++ b/resources/libraries/python/IPsecUtil.py @@ -85,13 +85,35 @@ class IpsecSpdAction(Enum): class CryptoAlg(Enum): - """Encryption algorithms.""" + """Encryption algorithms. + + API names and numeric enums from ipsec_types.api (enum ipsec_crypto_alg). + + Lowercase names from ipsec_sa.h (foreach_ipsec_crypto_alg). + + Scapy names are from: + https://github.com/secdev/scapy/blob/master/scapy/layers/ipsec.py + + Key lengths from crypto.h + (foreach_crypto_cipher_alg and foreach_crypto_aead_alg). + """ NONE = ("none", 0, "none", 0) AES_CBC_128 = ("aes-cbc-128", 1, "AES-CBC", 16) + AES_CBC_192 = ("aes-cbc-192", 2, "AES-CBC", 24) AES_CBC_256 = ("aes-cbc-256", 3, "AES-CBC", 32) + AES_CTR_128 = ("aes-ctr-128", 4, "AES-CTR", 16) + AES_CTR_192 = ("aes-ctr-192", 5, "AES-CTR", 24) + AES_CTR_256 = ("aes-ctr-256", 6, "AES-CTR", 32) AES_GCM_128 = ("aes-gcm-128", 7, "AES-GCM", 16) + AES_GCM_192 = ("aes-gcm-192", 8, "AES-GCM", 24) AES_GCM_256 = ("aes-gcm-256", 9, "AES-GCM", 32) + DES_CBC = ("des-cbc", 10, "DES", 7) + _3DES_CBC = ("3des-cbc", 11, "3DES", 24) + CHACHA20_POLY1305 = ("chacha20-poly1305", 12, "CHACHA20-POLY1305", 32) + AES_NULL_GMAC_128 = ("aes-null-gmac-128", 13, "AES-NULL-GMAC", 16) + AES_NULL_GMAC_192 = ("aes-null-gmac-192", 14, "AES-NULL-GMAC", 24) + AES_NULL_GMAC_256 = ("aes-null-gmac-256", 15, "AES-NULL-GMAC", 32) def __init__( self, alg_name: str, alg_int_repr: int, scapy_name: str, key_len: int @@ -108,10 +130,30 @@ class CryptoAlg(Enum): class IntegAlg(Enum): - """Integrity algorithm.""" + """Integrity algorithms. + + API names and numeric enums from ipsec_types.api (enum ipsec_integ_alg). + + Lowercase names from ipsec_sa.h (foreach_ipsec_integ_alg). + + Scapy names are from: + https://github.com/secdev/scapy/blob/master/scapy/layers/ipsec.py + Among those, "AES-CMAC-96" may be a mismatch, + but there is no sha2-related item with "96" in it. + + Key lengths seem to be given double of digest length + from crypto.h (foreach_crypto_link_async_alg), + but data there is not complete + (e.g. it does not distinguish sha-256-96 from sha-256-128). + The missing values are chosen based on last number (e.g. 192 / 4 = 48). + """ NONE = ("none", 0, "none", 0) + MD5_96 = ("md5-96", 1, "HMAC-MD5-96", 24) + SHA1_96 = ("sha1-96", 2, "HMAC-SHA1-96", 24) + SHA_256_96 = ("sha-256-96", 3, "AES-CMAC-96", 24) SHA_256_128 = ("sha-256-128", 4, "SHA2-256-128", 32) + SHA_384_192 = ("sha-384-192", 5, "SHA2-384-192", 48) SHA_512_256 = ("sha-512-256", 6, "SHA2-512-256", 64) def __init__( @@ -1226,6 +1268,8 @@ class IPsecUtil: addr_incr: int, spi_d: dict, existing_tunnels: int = 0, + udp_encap: bool = False, + anti_replay: bool = False, ) -> Tuple[List[bytes], List[bytes]]: """Create multiple IPsec tunnel interfaces on DUT1 node using PAPI. @@ -1247,6 +1291,8 @@ class IPsecUtil: :param addr_incr: IP / IPv6 address incremental step. :param existing_tunnels: Number of tunnel interfaces before creation. Useful mainly for reconf tests. Default 0. + :param udp_encap: Whether to apply UDP_ENCAP flag. + :param anti_replay: Whether to apply USE_ANTI_REPLAY flag. :type nodes: dict :type tun_ips: dict :type if1_key: str @@ -1258,6 +1304,8 @@ class IPsecUtil: :type addr_incr: int :type spi_d: dict :type existing_tunnels: int + :type udp_encap: bool + :type anti_replay: bool :returns: Generated ckeys and ikeys. :rtype: List[bytes], List[bytes] """ @@ -1331,6 +1379,10 @@ class IPsecUtil: c_key = dict(length=0, data=None) i_key = dict(length=0, data=None) common_flags = IPsecSadFlags.IPSEC_API_SAD_FLAG_NONE + if udp_encap: + common_flags |= IPsecSadFlags.IPSEC_API_SAD_FLAG_UDP_ENCAP + if anti_replay: + common_flags |= IPsecSadFlags.IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY sad_entry = dict( sad_id=None, spi=None, @@ -1470,6 +1522,8 @@ class IPsecUtil: addr_incr: int, spi_d: dict, existing_tunnels: int = 0, + udp_encap: bool = False, + anti_replay: bool = False, ) -> None: """Create multiple IPsec tunnel interfaces on DUT2 node using PAPI. @@ -1493,6 +1547,8 @@ class IPsecUtil: :param addr_incr: IP / IPv6 address incremental step. :param existing_tunnels: Number of tunnel interfaces before creation. Useful mainly for reconf tests. Default 0. + :param udp_encap: Whether to apply UDP_ENCAP flag. + :param anti_replay: Whether to apply USE_ANTI_REPLAY flag. :type nodes: dict :type tun_ips: dict :type if2_key: str @@ -1505,6 +1561,8 @@ class IPsecUtil: :type addr_incr: int :type spi_d: dict :type existing_tunnels: int + :type udp_encap: bool + :type anti_replay: bool """ crypto_alg = get_enum_instance(CryptoAlg, crypto_alg) integ_alg = get_enum_instance(IntegAlg, integ_alg) @@ -1569,6 +1627,10 @@ class IPsecUtil: c_key = dict(length=0, data=None) i_key = dict(length=0, data=None) common_flags = IPsecSadFlags.IPSEC_API_SAD_FLAG_NONE + if udp_encap: + common_flags |= IPsecSadFlags.IPSEC_API_SAD_FLAG_UDP_ENCAP + if anti_replay: + common_flags |= IPsecSadFlags.IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY sad_entry = dict( sad_id=None, spi=None, @@ -1718,6 +1780,8 @@ class IPsecUtil: raddr_ip2: str, raddr_range: int, existing_tunnels: int = 0, + udp_encap: bool = False, + anti_replay: bool = False, return_keys: bool = False, ) -> Optional[Tuple[List[bytes], List[bytes], int, int]]: """Create multiple IPsec tunnel interfaces between two VPP nodes. @@ -1747,6 +1811,8 @@ class IPsecUtil: :param existing_tunnels: Number of tunnel interfaces before creation. Useful mainly for reconf tests. Default 0. :param return_keys: Whether generated keys should be returned. + :param udp_encap: Whether to apply UDP_ENCAP flag. + :param anti_replay: Whether to apply USE_ANTI_REPLAY flag. :type nodes: dict :type tun_if1_ip_addr: str :type tun_if2_ip_addr: str @@ -1760,6 +1826,8 @@ class IPsecUtil: :type raddr_range: int :type existing_tunnels: int :type return_keys: bool + :type udp_encap: bool + :type anti_replay: bool :returns: Ckeys, ikeys, spi_1, spi_2. :rtype: Optional[Tuple[List[bytes], List[bytes], int, int]] """ @@ -1791,6 +1859,8 @@ class IPsecUtil: addr_incr, spi_d, existing_tunnels, + udp_encap, + anti_replay, ) if "DUT2" in nodes.keys(): IPsecUtil._ipsec_create_tunnel_interfaces_dut2_papi( @@ -1806,6 +1876,8 @@ class IPsecUtil: addr_incr, spi_d, existing_tunnels, + udp_encap, + anti_replay, ) if return_keys: @@ -2150,7 +2222,8 @@ class IPsecUtil: # The proto argument does not correspond to IPsecProto. # The allowed values come from src/vnet/ip/protocols.def # and we do not have a good enum for that yet. - # FlowUti. and FlowUtil. are close but not exactly the same. + # FlowUtil.FlowType and FlowUtil.FlowProto are close, + # but not exactly the same. # TODO: to be fixed to use full PAPI when it is ready in VPP cmd = ( diff --git a/resources/libraries/python/KubernetesUtils.py b/resources/libraries/python/KubernetesUtils.py index 9ded0e8b9e..a58c337a18 100644 --- a/resources/libraries/python/KubernetesUtils.py +++ b/resources/libraries/python/KubernetesUtils.py @@ -1,4 +1,4 @@ -# Copyright (c) 2021 Cisco and/or its affiliates. +# Copyright (c) 2024 Cisco and/or its affiliates. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: diff --git a/resources/libraries/python/QemuManager.py b/resources/libraries/python/QemuManager.py index 259b4c6981..78c88ddf3c 100644 --- a/resources/libraries/python/QemuManager.py +++ b/resources/libraries/python/QemuManager.py @@ -1,4 +1,4 @@ -# Copyright (c) 2021 Cisco and/or its affiliates. +# Copyright (c) 2024 Cisco and/or its affiliates. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: @@ -165,18 +165,18 @@ class QemuManager: vif1_mac=kwargs[u"vif1_mac"], vif2_mac=kwargs[u"vif2_mac"], queues=kwargs[u"queues"], - jumbo_frames=kwargs[u"jumbo"] + jumbo=kwargs[u"jumbo"] ) self.machines[name].add_vhost_user_if( f"/run/vpp/sock-{qemu_id}-1", - jumbo_frames=kwargs[u"jumbo"], + jumbo=kwargs[u"jumbo"], queues=kwargs[u"queues"], queue_size=kwargs[u"perf_qemu_qsz"], virtio_feature_mask=virtio_feature_mask ) self.machines[name].add_vhost_user_if( f"/run/vpp/sock-{qemu_id}-2", - jumbo_frames=kwargs[u"jumbo"], + jumbo=kwargs[u"jumbo"], queues=kwargs[u"queues"], queue_size=kwargs[u"perf_qemu_qsz"], virtio_feature_mask=virtio_feature_mask @@ -215,7 +215,7 @@ class QemuManager: arpip1=u"1.1.1.1", arpif1=u"avf-0/0/7/0", queues=kwargs[u"queues"], - jumbo_frames=kwargs[u"jumbo"] + jumbo=kwargs[u"jumbo"] ) else: self.machines[name].configure_kernelvm_vnf( @@ -231,7 +231,7 @@ class QemuManager: arpip1=u"3.3.3.1", arpif1=u"avf-0/0/6/0", queues=kwargs[u"queues"], - jumbo_frames=kwargs[u"jumbo"] + jumbo=kwargs[u"jumbo"] ) self.machines[name].add_vfio_pci_if( pci=Topology.get_interface_pci_addr( @@ -275,7 +275,7 @@ class QemuManager: arpip1=u"1.1.1.1", arpif1=u"avf-0/0/7/0", queues=kwargs[u"queues"], - jumbo_frames=kwargs[u"jumbo"] + jumbo=kwargs[u"jumbo"] ) else: self.machines[name].configure_kernelvm_vnf( @@ -291,7 +291,7 @@ class QemuManager: arpip1=u"3.3.3.1", arpif1=u"avf-0/0/6/0", queues=kwargs[u"queues"], - jumbo_frames=kwargs[u"jumbo"] + jumbo=kwargs[u"jumbo"] ) self.machines[name].add_vfio_pci_if( pci=Topology.get_interface_pci_addr( @@ -335,7 +335,7 @@ class QemuManager: arpip1=u"1.1.1.1", arpif1=u"avf-0/0/7/0", queues=kwargs[u"queues"], - jumbo_frames=kwargs[u"jumbo"] + jumbo=kwargs[u"jumbo"] ) else: self.machines[name].configure_kernelvm_vnf( @@ -351,7 +351,7 @@ class QemuManager: arpip1=u"3.3.3.1", arpif1=u"avf-0/0/6/0", queues=kwargs[u"queues"], - jumbo_frames=kwargs[u"jumbo"] + jumbo=kwargs[u"jumbo"] ) self.machines[name].add_vfio_pci_if( pci=Topology.get_interface_pci_addr( @@ -395,7 +395,7 @@ class QemuManager: arpip1=u"1.1.1.1", arpif1=u"avf-0/0/7/0", queues=kwargs[u"queues"], - jumbo_frames=kwargs[u"jumbo"] + jumbo=kwargs[u"jumbo"] ) else: self.machines[name].configure_kernelvm_vnf( @@ -411,7 +411,7 @@ class QemuManager: arpip1=u"3.3.3.1", arpif1=u"avf-0/0/6/0", queues=kwargs[u"queues"], - jumbo_frames=kwargs[u"jumbo"] + jumbo=kwargs[u"jumbo"] ) self.machines[name].add_vfio_pci_if( pci=Topology.get_interface_pci_addr( @@ -445,13 +445,13 @@ class QemuManager: self.machines[name].add_kernelvm_params() self.machines[name].configure_kernelvm_vnf( queues=kwargs[u"queues"], - jumbo_frames=kwargs[u"jumbo"] + jumbo=kwargs[u"jumbo"] ) self.machines[name].add_net_user() self.machines[name].add_vhost_user_if( f"/run/vpp/sock-{qemu_id}-1", server=False, - jumbo_frames=kwargs[u"jumbo"], + jumbo=kwargs[u"jumbo"], queues=kwargs[u"queues"], queue_size=kwargs[u"perf_qemu_qsz"], virtio_feature_mask=virtio_feature_mask diff --git a/resources/libraries/python/QemuUtils.py b/resources/libraries/python/QemuUtils.py index 2df89ee87c..8dac06001c 100644 --- a/resources/libraries/python/QemuUtils.py +++ b/resources/libraries/python/QemuUtils.py @@ -1,4 +1,4 @@ -# Copyright (c) 2022-2023 Cisco and/or its affiliates. +# Copyright (c) 2024-2024 Cisco and/or its affiliates. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: @@ -236,25 +236,25 @@ class QemuUtils: ) def add_vhost_user_if( - self, socket, server=True, jumbo_frames=False, queue_size=None, + self, socket, server=True, jumbo=False, queue_size=None, queues=1, virtio_feature_mask=None): """Add Vhost-user interface. :param socket: Path of the unix socket. :param server: If True the socket shall be a listening socket. - :param jumbo_frames: Set True if jumbo frames are used in the test. + :param jumbo: Set True if jumbo frames are used in the test. :param queue_size: Vring queue size. :param queues: Number of queues. :param virtio_feature_mask: Mask of virtio features to be enabled. :type socket: str :type server: bool - :type jumbo_frames: bool + :type jumbo: bool :type queue_size: int :type queues: int :type virtio_feature_mask: int """ self._nic_id += 1 - if jumbo_frames: + if jumbo: logger.debug(u"Jumbo frames temporarily disabled!") self._params.add_with_value( u"chardev", f"socket,id=char{self._nic_id}," @@ -342,7 +342,7 @@ class QemuUtils: vpp_config.add_dpdk_dev(u"0000:00:06.0", u"0000:00:07.0") vpp_config.add_dpdk_dev_default_rxq(kwargs[u"queues"]) vpp_config.add_dpdk_log_level(u"debug") - if not kwargs[u"jumbo_frames"]: + if not kwargs[u"jumbo"]: vpp_config.add_dpdk_no_multi_seg() vpp_config.add_dpdk_no_tx_checksum_offload() if "ipsec" in self._opt.get(u'vnf'): @@ -371,7 +371,7 @@ class QemuUtils: :param kwargs: Key-value pairs to construct command line parameters. :type kwargs: dict """ - pmd_max_pkt_len = u"9200" if kwargs[u"jumbo_frames"] else u"1518" + pmd_max_pkt_len = u"9200" if kwargs[u"jumbo"] else u"1518" testpmd_cmd = DpdkUtil.get_testpmd_cmdline( eal_corelist=f"0-{self._opt.get(u'smp') - 1}", eal_driver=False, @@ -398,7 +398,7 @@ class QemuUtils: :param kwargs: Key-value pairs to construct command line parameters. :type kwargs: dict """ - pmd_max_pkt_len = u"9200" if kwargs[u"jumbo_frames"] else u"1518" + pmd_max_pkt_len = u"9200" if kwargs[u"jumbo"] else u"1518" testpmd_cmd = DpdkUtil.get_testpmd_cmdline( eal_corelist=f"0-{self._opt.get(u'smp') - 1}", eal_driver=False, diff --git a/resources/libraries/python/VppConfigGenerator.py b/resources/libraries/python/VppConfigGenerator.py index 4191c0eed2..fb3df2fc16 100644 --- a/resources/libraries/python/VppConfigGenerator.py +++ b/resources/libraries/python/VppConfigGenerator.py @@ -296,6 +296,15 @@ class VppConfigGenerator: path = ["dpdk", cryptodev_config] self.add_config_item(self._nodeconfig, "", path) + def add_dpdk_dev_default_devargs(self, value): + """Add DPDK dev default devargs configuration. + + :param value: DPDK devargs to pass to interface. + :type value: str + """ + path = ["dpdk", "dev default", "devargs"] + self.add_config_item(self._nodeconfig, value, path) + def add_dpdk_dev_default_rxq(self, value): """Add DPDK dev default rxq configuration. @@ -334,7 +343,7 @@ class VppConfigGenerator: def add_dpdk_dev_default_tso(self): """Add DPDK dev default tso configuration.""" - path = [u"dpdk", u"dev default", u"tso"] + path = ["dpdk", "dev default", "tso"] self.add_config_item(self._nodeconfig, "on", path) def add_dpdk_log_level(self, value): @@ -382,7 +391,7 @@ class VppConfigGenerator: def add_dpdk_enable_tcp_udp_checksum(self): """Add DPDK enable-tcp-udp-checksum configuration.""" - path = [u"dpdk", u"enable-tcp-udp-checksum"] + path = ["dpdk", "enable-tcp-udp-checksum"] self.add_config_item(self._nodeconfig, u"", path) def add_cpu_main_core(self, value): @@ -477,7 +486,7 @@ class VppConfigGenerator: :param value: "on" to enable spd fast path. :type value: str """ - path = [u"ipsec", u"ipv4-inbound-spd-fast-path"] + path = ["ipsec", "ipv4-inbound-spd-fast-path"] self.add_config_item(self._nodeconfig, value, path) def add_ipsec_spd_fast_path_ipv4_outbound(self, value): @@ -542,6 +551,11 @@ class VppConfigGenerator: path = ["dpdk", "no-multi-seg"] self.add_config_item(self._nodeconfig, "", path) + def add_dpdk_enable_tcp_udp_checksum(self): + """Add DPDK enable-tcp-udp-checksum configuration.""" + path = ["dpdk", "enable-tcp-udp-checksum"] + self.add_config_item(self._nodeconfig, "", path) + def add_dpdk_no_tx_checksum_offload(self): """Add DPDK no-tx-checksum-offload configuration.""" path = ["dpdk", "no-tx-checksum-offload"] @@ -599,8 +613,8 @@ class VppConfigGenerator: def add_tcp_tso(self): """Add TCP tso configuration.""" - path = [u"tcp", u"tso"] - self.add_config_item(self._nodeconfig, u"", path) + path = ["tcp", "tso"] + self.add_config_item(self._nodeconfig, "", path) def add_session_enable(self): """Add session enable.""" @@ -794,3 +808,44 @@ class VppInitConfig: vpp_config.add_ip6_hash_buckets(2000000) vpp_config.add_ip6_heap_size("4G") vpp_config.apply_config() + + @staticmethod + def create_vpp_startup_configuration_container(node, cpuset_cpus=None): + """Create base startup configuration of VPP on container. + + :param node: Node in the topology. + :param cpuset_cpus: List of CPU cores to allocate. + :type node: dict + :type cpuset_cpus: list. + :returns: Base VPP startup configuration for container. + :rtype: VppConfigGenerator + """ + huge_size = Constants.DEFAULT_HUGEPAGE_SIZE + + vpp_config = VppConfigGenerator() + vpp_config.set_node(node) + vpp_config.add_unix_log() + vpp_config.add_unix_cli_listen() + vpp_config.add_unix_cli_no_pager() + vpp_config.add_unix_exec("/tmp/running.exec") + vpp_config.add_socksvr(socket=Constants.SOCKSVR_PATH) + if cpuset_cpus: + # We will pop the first core from the list to be a main core + vpp_config.add_cpu_main_core(str(cpuset_cpus.pop(0))) + # If more cores in the list, the rest will be used as workers. + corelist_workers = ",".join(str(cpu) for cpu in cpuset_cpus) + vpp_config.add_cpu_corelist_workers(corelist_workers) + vpp_config.add_buffers_per_numa(215040) + vpp_config.add_plugin("disable", "default") + vpp_config.add_plugin("enable", "memif_plugin.so") + vpp_config.add_plugin("enable", "perfmon_plugin.so") + vpp_config.add_main_heap_size("2G") + vpp_config.add_main_heap_page_size(huge_size) + vpp_config.add_default_hugepage_size(huge_size) + vpp_config.add_statseg_size("2G") + vpp_config.add_statseg_page_size(huge_size) + vpp_config.add_statseg_per_node_counters("on") + vpp_config.add_ip6_hash_buckets(2000000) + vpp_config.add_ip6_heap_size("4G") + + return vpp_config diff --git a/resources/libraries/python/autogen/Regenerator.py b/resources/libraries/python/autogen/Regenerator.py index 8d593fecca..ce8f21d4b6 100644 --- a/resources/libraries/python/autogen/Regenerator.py +++ b/resources/libraries/python/autogen/Regenerator.py @@ -178,9 +178,6 @@ def add_default_testcases( if u"reassembly" in suite_id: if kwargs[u"frame_size"] != 1518: emit = False - else: - if kwargs[u"frame_size"] not in MIN_FRAME_SIZE_VALUES: - emit = False kwargs.update({'phy_cores': kwas['phy_cores']*core_scale}) diff --git a/resources/libraries/python/enum_util.py b/resources/libraries/python/enum_util.py index 41dfd8a459..f721936ee4 100644 --- a/resources/libraries/python/enum_util.py +++ b/resources/libraries/python/enum_util.py @@ -31,13 +31,15 @@ def get_enum_instance( to convert string into the corresponding Enum instance. Aliases are also recognized. - As an added benefit, support various Robot-like niceties, - like lower case, or dash or space instead of underscore. - As a common shortcut, value is returned it it already is an instance. Another convenience: None or empty string is processed as "NONE". + As an added benefit, support various Robot-like niceties, + like lower case, or dash or space instead of underscore. + Also strip the identifiers, this is mostly due to "3DES". + Enum instance cannot start with a number, so "_3DES" + strip is needed. + If the class is a subclass of IntEnum, int values and (string) values convertable to int are also accepted as input. @@ -59,9 +61,10 @@ def get_enum_instance( return value if not value: value = "NONE" - normalized_name = str(value).upper().replace("-", "_").replace(" ", "_") + normalized_name = str(value).upper().replace("-", " ").replace("_", " ") members = enum_class.__members__ # Includes aliases, useful for NONE. - if normalized_name not in members: - msg = f"Enum class {enum_class} does not have value {normalized_name!r}" - raise ValueError(msg) - return members[normalized_name] + for member_name in members: + if normalized_name.strip() == member_name.replace("_", " ").strip(): + return members[member_name] + msg = f"Enum class {enum_class} does not have value {normalized_name!r}" + raise ValueError(msg) |