summaryrefslogtreecommitdiffstats
path: root/src/plugins
AgeCommit message (Collapse)AuthorFilesLines
2020-08-20tcp: track reorder with sacksFlorin Coras1-1/+5
Type: feature Change-Id: I041bff2e8d589c171661de286fa1503531dff891 Signed-off-by: Florin Coras <fcoras@cisco.com>
2020-08-20nat: fixed cli nat summary and nat limitFilip Varga3-50/+109
Type: fix Change-Id: I78017b02015116f93b579c7381119f618351c98d Signed-off-by: Filip Varga <fivarga@cisco.com>
2020-08-19nat: session cli command fixFilip Varga1-3/+11
Type: fix Change-Id: I57ae649d1b26d5bea2df89c209f257372e565b49 Signed-off-by: Filip Varga <fivarga@cisco.com>
2020-08-17nat: det: replace speculative buffer enqueue modelKlement Sekera2-948/+897
Replace speculative buffer enqueue coding model with vlib_get_buffers(...)/vlib_buffer_enqueue_to_next(...). Type: improvement Signed-off-by: Klement Sekera <ksekera@cisco.com> Change-Id: Ib5a32d60592fb17ed0ba1ac074047e39780f74be
2020-08-17nat: sessions get expired when fib table removedFilip Varga7-9/+348
fib table removal would leave lingering sessions in vpp this patch is aimed at solving this issue by grouping sessions by source and destionation fib. if one of the fibs gets removed this grouping is tagged as expired and session won't be passed to non existing fib table Ticket: VPPSUPP-93 Type: improvement Change-Id: I45b1205a8b58d91f174e6feb862554ec2f6cffad Signed-off-by: Filip Varga <fivarga@cisco.com>
2020-08-13nat: move deterministic nat to det44 sub featureFilip Varga27-3108/+4484
Type: refactor Change-Id: I0bb203102a0e13dd7448e2125925ab356bbd7937 Signed-off-by: Filip Varga <fivarga@cisco.com>
2020-08-13nat: remove non-error error countersKlement Sekera16-507/+585
Some statistics counters were implemented as error counters. Move them to stat segment, where they belong. Type: improvement Change-Id: I5600bec1b4e0496282297374ec1e79d909cdaf8a Signed-off-by: Klement Sekera <ksekera@cisco.com>
2020-08-13acl: use the global heap when allocating the lookup contextAndrew Yourtchenko1-0/+3
The "ACL as a service" lookup infra is shared, so a global heap must be used. Type: fix Signed-off-by: Andrew Yourtchenko <ayourtch@gmail.com> Change-Id: I86894254b737392c1968b6a581b5a37590376428
2020-08-13stats: remove offsets on vpp sideOle Troan1-16/+14
Represent pointers directly in shared memory and require clients to adjust for shared memory segment being mapped at different base address. Deprecated: stat_segment_pointer() / stat_segment_offset() Added: stat_segment_adjust() Bumped the stat segment version to 2. Type: refactor Signed-off-by: Ole Troan <ot@cisco.com> Change-Id: I33e756187b8903b45dcd353e6c1a101b7a4acb79
2020-08-07vrrp: change init of vrrp key in VR lookupMatthew Smith1-5/+7
Type: fix A struct that is used as a hash key was being initialized in its declaration. On CentOS 8 this caused some hash lookups to fail. This seems to be caused by uninitialized padding. Use clib_memset() to initialize the key with 0's to avoid the issue. Change-Id: I00555c201a1ab34133971313ba14f20f4e867a30 Signed-off-by: Matthew Smith <mgsmith@netgate.com>
2020-08-06memif: wrong interface counter is incrementedSteven Luong1-2/+2
vlib_increment_combined_counter takes sw_if_index, not hw_if_index. Type: fix Signed-off-by: Steven Luong <sluong@cisco.com> Change-Id: Iecde2697ed490940f0eff796d28d15381405b895
2020-08-06misc: harmonize namesDave Barach15-150/+157
Type: fix Signed-off-by: Dave Barach <dave@barachs.net> Change-Id: Ibad744788e200ce012ad88ff59c2c34920742454
2020-08-03unittest: add clib_count_equal_u8/16/32/64 testsBenoît Ganne1-4/+100
Type: test Change-Id: I490c1b1a2fa49badda038e6be014c77b9bee6c56 Signed-off-by: Benoît Ganne <bganne@cisco.com>
2020-07-31nsim: limit tx burst size and refactor input nodeFlorin Coras2-64/+30
Type: improvement Signed-off-by: Florin Coras <fcoras@cisco.com> Change-Id: Ic93a598051d437a5801d794b678edf6e73d42a47
2020-07-31nsim: basic reorder supportFlorin Coras5-388/+416
Reorder delayed packets, i.e., flush instead of delay, with a configured rate. Type: feature Change-Id: Ib1294f5f1c9b6e98a12b1bb0be655e54facfed3a Signed-off-by: Florin Coras <fcoras@cisco.com>
2020-07-29hsa: fix handling active connection failures in the proxyIvan Shvedunov1-9/+16
Type: fix Signed-off-by: Ivan Shvedunov <ivan4th@gmail.com> Change-Id: I9c62bb6524247e2cd25de198263c16f3d9db0da9
2020-07-28http_static: fix session cleanupFlorin Coras1-41/+30
Type: fix Signed-off-by: Florin Coras <fcoras@cisco.com> Change-Id: Ibb380eecca76ed9c00ed14c167dfcf576f943db0
2020-07-28hsa: fix http server session cleanupFlorin Coras1-36/+31
Type: fix Signed-off-by: Florin Coras <fcoras@cisco.com> Change-Id: I6832e3f24a56e043415a32eb4072d0bfb7697251
2020-07-28bonding lacp: replace slave string with memberSteven Luong16-630/+631
- Replace textual string slave with member except APIs. - For APIs, mark the existing APIs as deprecated and introduce new APIs - While introducing sw_bond_interface_dump, add the optional filter by sw_if_index and enhance the testcases to make use of it. Type: improvement Signed-off-by: Steven Luong <sluong@cisco.com> Change-Id: Ib6626c514e45350308aeeda0decb70f3aba2f63e
2020-07-28ikev2: fix session re-initiate after SA expiresFilip Tehlar2-1/+3
Type: fix Change-Id: Ie3d24b3df02d08fbb74d97f4e5ab0d79c35b0c0d Signed-off-by: Filip Tehlar <ftehlar@cisco.com>
2020-07-28nat: limit resource consumption when out of portsKlement Sekera1-2/+7
Type: improvement Signed-off-by: Klement Sekera <ksekera@cisco.com> Change-Id: I83f44711264376389989152666f3c71216146bdd
2020-07-24lacp: fix vector overflowBenoît Ganne1-2/+2
Type: fix Change-Id: I8f776ce10ee8c29689db5ceef70df42dfb6b747c Signed-off-by: Benoît Ganne <bganne@cisco.com>
2020-07-24ikev2: add SA dump APIjan_cavojsky5-6/+907
Type: feature Ticket: VPP-1897 Change-Id: I0245aceeb344efd29b1f9217c35889a8bbe1f744 Signed-off-by: jan_cavojsky <Jan.Cavojsky@pantheon.tech> Signed-off-by: Filip Tehlar <ftehlar@cisco.com>
2020-07-23dpdk: device_id sorted order for cryptodevVladimir Ratnikov1-0/+16
By default, VPP automatically assignes for each tunnel next available QAT device by order dev_id-que-pair. In most cases we have more than one device and it can greatly increase ipsec perfomance without any actions with configuration from user if we use all the devices first and first que-pairs Type: feature Signed-off-by: Vladimir Ratnikov <vratnikov@netgate.com> Change-Id: Iac9fe74768775459e22f69bb3706b542090a9375
2020-07-23acl: correct acl vat help messageLijian.Zhang1-2/+2
"ipv4"/"ipv6" option is not supported in acl_add_replace and macip_acl_add_replace vat api. Update its help message per actual api usage. Type: fix Change-Id: I8d34fac5f98bd78a46a5e98df05cd35182988dd8 Signed-off-by: Lijian Zhang <Lijian.Zhang@arm.com> Reviewed-by: Jieqiang Wang <Jieqiang.Wang@arm.com> Reviewed-by: Govindarajan Mohandoss <Govindarajan.Mohandoss@arm.com>
2020-07-23hsa: proxy session cleanup fixesFlorin Coras2-95/+188
Type: fix Signed-off-by: Florin Coras <fcoras@cisco.com> Change-Id: I96673c984077876e69b18b4126b55e70dc07b50f
2020-07-23nat: fix port number selectionElias Rudberg2-6/+6
Change the port number selection for new NAT sessions so that it matches how the thread index is calculated from the port number for out2in packets. Before this change there was a problem when the largest port number in the range was used, that resulted in the wrong thread index being selected when out2in packets arrive for that session. Type: fix Signed-off-by: Elias Rudberg <elias.rudberg@bahnhof.net> Change-Id: I936c389eb0d5df6168e18e5e44754de1cdad6ad1 Signed-off-by: Klement Sekera <ksekera@cisco.com>
2020-07-23ikev2: add global message length checkBenoît Ganne1-96/+89
Type: fix Change-Id: I3eb51ea4f6c29005b0315cf488fcabb8543dfcd1 Signed-off-by: Benoît Ganne <bganne@cisco.com>
2020-07-21crypto: bails out early for unsupported key typeBenoît Ganne2-8/+8
Do not access data structures based on uninitialized key->alg. Type: fix Fixes: f539578bac8b64886b57c460c9d74273e6613f8b Change-Id: I6bfb7e7a51af2c131b8bdf3bca6a38fcf1094760 Signed-off-by: Benoît Ganne <bganne@cisco.com>
2020-07-20ikev2: refactor and test profile dump APIFilip Tehlar9-129/+340
Type: refactor Change-Id: I6b8dc68e5d4a452776fbaf5a69fbd7f53a8abb75 Signed-off-by: Filip Tehlar <ftehlar@cisco.com>
2020-07-19api: call api reaper callbacks for socket clientsDave Barach2-0/+51
Add a callback to clear the per-client packet trace buffer cache. Save the packet trace dump pg setup script. Type: improvement Signed-off-by: Dave Barach <dave@barachs.net> Change-Id: I252be911b5f937ece0da5dca152263ece3d52963
2020-07-19unittest: keep ASAN happy for non-terminated string testsBenoît Ganne1-0/+2
Type: fix Change-Id: Iae9e84d4297acd54c909d3a8a39adafcd86b0a91 Signed-off-by: Benoît Ganne <bganne@cisco.com>
2020-07-17abf: mark API as in-progressAndrew Yourtchenko1-0/+8
As requested by Neale, mark the ABF API as in-progress Change-Id: I109a32fa54b1f2a882695d9fd71b235fa46bc6f3 Type: fix Signed-off-by: Andrew Yourtchenko <ayourtch@gmail.com>
2020-07-17gbp: mark APIs as in-progressAndrew Yourtchenko1-0/+35
As per request from Neale, mark the GBP plugin APIs as in-progress. Type: fix Change-Id: I679943edcfff0742ee32c45cd8f97f482c353b9f Signed-off-by: Andrew Yourtchenko <ayourtch@gmail.com>
2020-07-17l2e: mark API as in-progressAndrew Yourtchenko1-0/+1
As requested by Neale, mark the API as in-progress. Change-Id: Id92cad65c66435e179583507f077816e09e4205b Type: fix Signed-off-by: Andrew Yourtchenko <ayourtch@gmail.com>
2020-07-17pppoe: fix uninitialized memory bugTimotheeChauvin3-1/+7
In pppoe_cp_node.c, node->errors[error0] was accessed without node->errors being initialized. Found with AFL + ASAN. Type: fix Signed-off-by: TimotheeChauvin <timchauv@cisco.com> Change-Id: Ide8a60021b2d47b5e2fce7062d8f12c7f4d225f7
2020-07-16misc: add callback hooks and refactor pmcTom Seidenberg9-164/+326
Callbacks for monitoring and performance measurement: - Add new callback list type, with context - Add callbacks for API, CLI, and barrier sync - Modify node dispatch callback to pass plugin-specific context - Modify perfmon plugin to keep PMC samples local to the plugin - Include process nodes in dispatch callback - Pass dispatch function return value to callback Type: refactor Signed-off-by: Tom Seidenberg <tseidenb@cisco.com> Change-Id: I28b06c58490611e08d76ff5b01b2347ba2109b22
2020-07-16dpdk: fix coverity warning in the flow codeChenmin Sun1-1/+1
CID 211153 Type: fix Signed-off-by: Chenmin Sun <chenmin.sun@intel.com> Change-Id: Ic4d518d047c3ff36d9a7b72477c3efcb554d05bb
2020-07-16crypto: fix coverity issue for cryptodevFan Zhang1-65/+103
- Fixes coverity issue #210160. - Fixes the possible issue in cryptodev when input node does not update mbuf, such as avf-input. - Fixes GCM ESN packet incorrect tag. - Code clean up to reduce binary size. Type: fix Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com> Signed-off-by: Dariusz Kazimierski <dariuszx.kazimierski@intel.com> Signed-off-by: Piotr Kleski <piotrx.kleski@intel.com> Change-Id: Ic05ae29855ac1f7a62e4af5831a4ed9faa8f561a
2020-07-16vppinfra: fix format_c_identifier vector overflowBenoît Ganne1-4/+2
In case of vector, we must check length before trying to access element. Also fix wrong DPDK plugin workaround. Type: fix Change-Id: I2ecef1c88ebef2362f48cab0d462699aa43cd4b9 Signed-off-by: Benoît Ganne <bganne@cisco.com>
2020-07-16misc: add tracedump API pluginDave Barach5-0/+571
Type: feature Signed-off-by: Dave Barach <dave@barachs.net> Change-Id: I586547508003b95eaa74e18e4a5ac6f72986822c
2020-07-16adl: move allow/deny list function to pluginDave Barach13-2/+2044
Provide binary API compatibility support for the "cop" APIs until vpp 21.01. Change the deprecation date in map.api to vpp 21.01. Type: refactor Signed-off-by: Dave Barach <dave@barachs.net> Change-Id: I0e60d96de4ae9ae4448f134cf257934126f3b760
2020-07-16ikev2: fix race condition in child_sa updateBenoît Ganne1-0/+3
Type: fix Change-Id: I864d49a641b45337c0a45a0af7d996cad75f6629 Signed-off-by: Benoît Ganne <bganne@cisco.com> Signed-off-by: Filip Tehlar <ftehlar@cisco.com>
2020-07-15nat: add prefetching to in2out_ed/out2in_edKlement Sekera2-2/+27
This saves about 20 clocks/packet in both code paths. Type: improvement Signed-off-by: Klement Sekera <ksekera@cisco.com> Change-Id: Ib559c74bf8168e3ddd764d51b7e5bcd2a557f591
2020-07-15ikev2: add support for AES-GCM cipher in IKEFilip Tehlar6-120/+345
Type: feature Ticket: VPP-1920 Change-Id: I6e30f3594cb30553f3ca5a35e0a4f679325aacec Signed-off-by: Filip Tehlar <ftehlar@cisco.com>
2020-07-14ikev2: API downgrade due to lack of ikev2 testsFilip Tehlar1-19/+17
Type: refactor Change-Id: Ic7ddad20088e069887f81721cceb21f4902e8907 Signed-off-by: Filip Tehlar <ftehlar@cisco.com>
2020-07-13hsa: set connected mode for echo_server app in udp mode.jiangxiaoming1-7/+20
Type: fix Signed-off-by: jiangxiaoming <jiangxiaoming@outlook.com> Change-Id: I85a53ee049a9af371d929364400fe166cf71d53f
2020-07-13session: reduce verbosity on fifo alloc failureFlorin Coras1-3/+14
Also fix session test app name registrations Type: improvement Signed-off-by: Florin Coras <fcoras@cisco.com> Change-Id: I7d365154ab9af83b17b026762ab4f0aea85ce486
2020-07-09dpdk: add txq struct and fix dpdk tx lockBenoît Ganne4-19/+23
This introduces a txq structure mirroring the rxq structure. This fixes the case when #txq > #rxq, because lock must be per txq. Type: fix Fixes: dfb19cabe20ccf1cbd1aa714f493ccd322839b91 Change-Id: Ic1bce64d2b08b9a98c8242a1ba1bfcdbda322bec Signed-off-by: Benoît Ganne <bganne@cisco.com>
2020-07-07ikev2: per thread usage of openssl contextFilip Tehlar3-77/+47
Type: refactor Change-Id: I04af90b4d86c00092ce1732aeb3c0517af1808e0 Signed-off-by: Filip Tehlar <ftehlar@cisco.com>
except AssertionError: raise RuntimeError('Failed to get VPP version on host: {name}'. format(name=node['host'])) @staticmethod def show_vpp_version_on_all_duts(nodes): """Show VPP version verbose on all DUTs. :param nodes: VPP nodes :type nodes: dict """ for node in nodes.values(): if node['type'] == NodeType.DUT: DUTSetup.vpp_show_version_verbose(node) @staticmethod def vpp_show_interfaces(node): """Run "show interface" CLI command. :param node: Node to run command on. :type node: dict """ vat = VatExecutor() vat.execute_script("show_interface.vat", node, json_out=False) try: vat.script_should_have_passed() except AssertionError: raise RuntimeError('Failed to get VPP interfaces on host: {name}'. format(name=node['host'])) @staticmethod def vpp_api_trace_save(node): """Run "api trace save" CLI command. :param node: Node to run command on. :type node: dict """ vat = VatExecutor() vat.execute_script("api_trace_save.vat", node, json_out=False) @staticmethod def vpp_api_trace_dump(node): """Run "api trace custom-dump" CLI command. :param node: Node to run command on. :type node: dict """ vat = VatExecutor() vat.execute_script("api_trace_dump.vat", node, json_out=False) @staticmethod def setup_all_duts(nodes): """Prepare all DUTs in given topology for test execution.""" for node in nodes.values(): if node['type'] == NodeType.DUT: DUTSetup.setup_dut(node) @staticmethod def setup_dut(node): """Run script over SSH to setup the DUT node. :param node: DUT node to set up. :type node: dict :raises Exception: If the DUT setup fails. """ ssh = SSH() ssh.connect(node) ret_code, _, _ = \ ssh.exec_command('sudo -Sn bash {0}/{1}/dut_setup.sh'. format(Constants.REMOTE_FW_DIR, Constants.RESOURCES_LIB_SH), timeout=120) if int(ret_code) != 0: raise RuntimeError('DUT test setup script failed at node {name}'. format(name=node['host'])) @staticmethod def get_vpp_pid(node): """Get PID of running VPP process. :param node: DUT node. :type node: dict :returns: PID :rtype: int :raises RuntimeError: If it is not possible to get the PID. """ ssh = SSH() ssh.connect(node) for i in range(3): logger.trace('Try {}: Get VPP PID'.format(i)) ret_code, stdout, stderr = ssh.exec_command('pidof vpp') if int(ret_code) != 0: raise RuntimeError('Not possible to get PID of VPP process ' 'on node: {0}\n {1}'. format(node['host'], stdout + stderr)) if len(stdout.splitlines()) == 1: return int(stdout) elif len(stdout.splitlines()) == 0: logger.debug("No VPP PID found on node {0}". format(node['host'])) continue else: logger.debug("More then one VPP PID found on node {0}". format(node['host'])) ret_list = list() for line in stdout.splitlines(): ret_list.append(int(line)) return ret_list return None @staticmethod def get_vpp_pids(nodes): """Get PID of running VPP process on all DUTs. :param nodes: DUT nodes. :type nodes: dict :returns: PIDs :rtype: dict """ pids = dict() for node in nodes.values(): if node['type'] == NodeType.DUT: pids[node['host']] = DUTSetup.get_vpp_pid(node) return pids @staticmethod def vpp_show_crypto_device_mapping(node): """Run "show crypto device mapping" CLI command. :param node: Node to run command on. :type node: dict """ vat = VatExecutor() vat.execute_script("show_crypto_device_mapping.vat", node, json_out=False) @staticmethod def crypto_device_verify(node, force_init=False, numvfs=32): """Verify if Crypto QAT device virtual functions are initialized on all DUTs. If parameter force initialization is set to True, then try to initialize or disable QAT. :param node: DUT node. :param force_init: If True then try to initialize to specific value. :param numvfs: Number of VFs to initialize, 0 - disable the VFs. :type node: dict :type force_init: bool :type numvfs: int :returns: nothing :raises RuntimeError: If QAT is not initialized or failed to initialize. """ ssh = SSH() ssh.connect(node) cryptodev = Topology.get_cryptodev(node) cmd = 'cat /sys/bus/pci/devices/{0}/sriov_numvfs'.\ format(cryptodev.replace(':', r'\:')) # Try to read number of VFs from PCI address of QAT device for _ in range(3): ret_code, stdout, _ = ssh.exec_command(cmd) if int(ret_code) == 0: try: sriov_numvfs = int(stdout) except ValueError: logger.trace('Reading sriov_numvfs info failed on {0}'. format(node['host'])) else: if sriov_numvfs != numvfs: if force_init: # QAT is not initialized and we want to initialize # with numvfs DUTSetup.crypto_device_init(node, numvfs) else: raise RuntimeError('QAT device {0} is not ' 'initialized to {1} on host {2}' .format(cryptodev, numvfs, node['host'])) break @staticmethod def crypto_device_init(node, numvfs): """Init Crypto QAT device virtual functions on DUT. :param node: DUT node. :param numvfs: Number of VFs to initialize, 0 - disable the VFs. :type node: dict :type numvfs: int :returns: nothing :raises RuntimeError: If failed to stop VPP or QAT failed to initialize. """ cryptodev = Topology.get_cryptodev(node) # QAT device must be re-bound to kernel driver before initialization driver = 'dh895xcc' kernel_module = 'qat_dh895xcc' current_driver = DUTSetup.get_pci_dev_driver( node, cryptodev.replace(':', r'\:')) DUTSetup.kernel_module_verify(node, kernel_module, force_load=True) VPPUtil.stop_vpp_service(node) if current_driver is not None: DUTSetup.pci_driver_unbind(node, cryptodev) DUTSetup.pci_driver_bind(node, cryptodev, driver) ssh = SSH() ssh.connect(node) # Initialize QAT VFs if numvfs > 0: cmd = 'echo "{0}" | tee /sys/bus/pci/devices/{1}/sriov_numvfs'.\ format(numvfs, cryptodev.replace(':', r'\:'), timeout=180) ret_code, _, _ = ssh.exec_command_sudo("sh -c '{0}'".format(cmd)) if int(ret_code) != 0: raise RuntimeError('Failed to initialize {0} VFs on QAT device ' ' on host {1}'.format(numvfs, node['host'])) @staticmethod def pci_driver_unbind(node, pci_addr): """Unbind PCI device from current driver on node. :param node: DUT node. :param pci_addr: PCI device address. :type node: dict :type pci_addr: str :returns: nothing :raises RuntimeError: If PCI device unbind failed. """ ssh = SSH() ssh.connect(node) ret_code, _, _ = ssh.exec_command_sudo( "sh -c 'echo {0} | tee /sys/bus/pci/devices/{1}/driver/unbind'" .format(pci_addr, pci_addr.replace(':', r'\:')), timeout=180) if int(ret_code) != 0: raise RuntimeError('Failed to unbind PCI device {0} from driver on ' 'host {1}'.format(pci_addr, node['host'])) @staticmethod def pci_driver_bind(node, pci_addr, driver): """Bind PCI device to driver on node. :param node: DUT node. :param pci_addr: PCI device address. :param driver: Driver to bind. :type node: dict :type pci_addr: str :type driver: str :returns: nothing :raises RuntimeError: If PCI device bind failed. """ ssh = SSH() ssh.connect(node) ret_code, _, _ = ssh.exec_command_sudo( "sh -c 'echo {0} | tee /sys/bus/pci/drivers/{1}/bind'".format( pci_addr, driver), timeout=180) if int(ret_code) != 0: raise RuntimeError('Failed to bind PCI device {0} to {1} driver on ' 'host {2}'.format(pci_addr, driver, node['host'])) @staticmethod def get_pci_dev_driver(node, pci_addr): """Get current PCI device driver on node. .. note:: # lspci -vmmks 0000:00:05.0 Slot: 00:05.0 Class: Ethernet controller Vendor: Red Hat, Inc Device: Virtio network device SVendor: Red Hat, Inc SDevice: Device 0001 PhySlot: 5 Driver: virtio-pci :param node: DUT node. :param pci_addr: PCI device address. :type node: dict :type pci_addr: str :returns: Driver or None :raises RuntimeError: If PCI rescan or lspci command execution failed. :raises RuntimeError: If it is not possible to get the interface driver information from the node. """ ssh = SSH() ssh.connect(node) for i in range(3): logger.trace('Try number {0}: Get PCI device driver'.format(i)) cmd = 'lspci -vmmks {0}'.format(pci_addr) ret_code, stdout, _ = ssh.exec_command(cmd) if int(ret_code) != 0: raise RuntimeError("'{0}' failed on '{1}'" .format(cmd, node['host'])) for line in stdout.splitlines(): if len(line) == 0: continue name = None value = None try: name, value = line.split("\t", 1) except ValueError: if name == "Driver:": return None if name == 'Driver:': return value if i < 2: logger.trace('Driver for PCI device {} not found, executing ' 'pci rescan and retrying'.format(pci_addr)) cmd = 'sh -c "echo 1 > /sys/bus/pci/rescan"' ret_code, _, _ = ssh.exec_command_sudo(cmd) if int(ret_code) != 0: raise RuntimeError("'{0}' failed on '{1}'" .format(cmd, node['host'])) return None @staticmethod def kernel_module_verify(node, module, force_load=False): """Verify if kernel module is loaded on all DUTs. If parameter force load is set to True, then try to load the modules. :param node: DUT node. :param module: Module to verify. :param force_load: If True then try to load module. :type node: dict :type module: str :type force_load: bool :returns: nothing :raises RuntimeError: If module is not loaded or failed to load. """ ssh = SSH() ssh.connect(node) cmd = 'grep -w {0} /proc/modules'.format(module) ret_code, _, _ = ssh.exec_command(cmd) if int(ret_code) != 0: if force_load: # Module is not loaded and we want to load it DUTSetup.kernel_module_load(node, module) else: raise RuntimeError('Kernel module {0} is not loaded on host ' '{1}'.format(module, node['host'])) @staticmethod def kernel_module_load(node, module): """Load kernel module on node. :param node: DUT node. :param module: Module to load. :type node: dict :type module: str :returns: nothing :raises RuntimeError: If loading failed. """ ssh = SSH() ssh.connect(node) ret_code, _, _ = ssh.exec_command_sudo("modprobe {0}".format(module)) if int(ret_code) != 0: raise RuntimeError('Failed to load {0} kernel module on host {1}'. format(module, node['host'])) @staticmethod def vpp_enable_traces_on_all_duts(nodes): """Enable vpp packet traces on all DUTs in the given topology. :param nodes: Nodes in the topology. :type nodes: dict """ for node in nodes.values(): if node['type'] == NodeType.DUT: DUTSetup.vpp_enable_traces_on_dut(node) @staticmethod def vpp_enable_traces_on_dut(node): """Enable vpp packet traces on the DUT node. :param node: DUT node to set up. :type node: dict """ vat = VatExecutor() vat.execute_script("enable_dpdk_traces.vat", node, json_out=False) vat.execute_script("enable_vhost_user_traces.vat", node, json_out=False) vat.execute_script("enable_memif_traces.vat", node, json_out=False) @staticmethod def install_vpp_on_all_duts(nodes, vpp_pkg_dir, vpp_rpm_pkgs, vpp_deb_pkgs): """Install VPP on all DUT nodes. :param nodes: Nodes in the topology. :param vpp_pkg_dir: Path to directory where VPP packages are stored. :param vpp_rpm_pkgs: List of VPP rpm packages to be installed. :param vpp_deb_pkgs: List of VPP deb packages to be installed. :type nodes: dict :type vpp_pkg_dir: str :type vpp_rpm_pkgs: list :type vpp_deb_pkgs: list :raises RuntimeError: If failed to remove or install VPP. """ logger.debug("Installing VPP") for node in nodes.values(): if node['type'] == NodeType.DUT: logger.debug("Installing VPP on node {0}".format(node['host'])) ssh = SSH() ssh.connect(node) cmd = "[[ -f /etc/redhat-release ]]" return_code, _, _ = ssh.exec_command(cmd) if int(return_code) == 0: # workaroud - uninstall existing vpp installation until # start-testcase script is updated on all virl servers rpm_pkgs_remove = "vpp*" cmd_u = 'yum -y remove "{0}"'.format(rpm_pkgs_remove) r_rcode, _, r_err = ssh.exec_command_sudo(cmd_u, timeout=90) if int(r_rcode) != 0: raise RuntimeError('Failed to remove previous VPP' 'installation on host {0}:\n{1}' .format(node['host'], r_err)) rpm_pkgs = "*.rpm ".join(str(vpp_pkg_dir + pkg) for pkg in vpp_rpm_pkgs) + "*.rpm" cmd_i = "rpm -ivh {0}".format(rpm_pkgs) ret_code, _, err = ssh.exec_command_sudo(cmd_i, timeout=90) if int(ret_code) != 0: raise RuntimeError('Failed to install VPP on host {0}:' '\n{1}'.format(node['host'], err)) else: ssh.exec_command_sudo("rpm -qai vpp*") logger.info("VPP installed on node {0}". format(node['host'])) else: # workaroud - uninstall existing vpp installation until # start-testcase script is updated on all virl servers deb_pkgs_remove = "vpp*" cmd_u = 'apt-get purge -y "{0}"'.format(deb_pkgs_remove) r_rcode, _, r_err = ssh.exec_command_sudo(cmd_u, timeout=90) if int(r_rcode) != 0: raise RuntimeError('Failed to remove previous VPP' 'installation on host {0}:\n{1}' .format(node['host'], r_err)) deb_pkgs = "*.deb ".join(str(vpp_pkg_dir + pkg) for pkg in vpp_deb_pkgs) + "*.deb" cmd_i = "dpkg -i --force-all {0}".format(deb_pkgs) ret_code, _, err = ssh.exec_command_sudo(cmd_i, timeout=90) if int(ret_code) != 0: raise RuntimeError('Failed to install VPP on host {0}:' '\n{1}'.format(node['host'], err)) else: ssh.exec_command_sudo("dpkg -l | grep vpp") logger.info("VPP installed on node {0}". format(node['host'])) ssh.disconnect(node) @staticmethod def verify_vpp_on_all_duts(nodes): """Verify that VPP is installed on all DUT nodes. :param nodes: Nodes in the topology. :type nodes: dict """ logger.debug("Verify VPP on all DUTs") DUTSetup.start_vpp_service_on_all_duts(nodes) for node in nodes.values(): if node['type'] == NodeType.DUT: DUTSetup.verify_vpp_on_dut(node) @staticmethod def verify_vpp_on_dut(node): """Verify that VPP is installed on DUT node. :param node: DUT node. :type node: dict :raises RuntimeError: If failed to restart VPP, get VPP version or get VPP interfaces. """ logger.debug("Verify VPP on node {0}".format(node['host'])) DUTSetup.vpp_show_version_verbose(node) DUTSetup.vpp_show_interfaces(node)