Prevent configuring the Dell Minerva NIC VFs

Since the Dell Operator will be responsible for VF configuration, the
configuration of this NIC using sysinv is being blocked to prevent user
mistakes. This is valid for the Dell Minerva NICs using Marvell CNF105xx
family devices.

The CNF105xx device IDs were found in the octeon_ep driver source code:
https://github.com/MarvellEmbeddedProcessors/pcie_ep_octeon_host
/drivers/octeon_ep/octep_main.h

Test Plan:
PASS: host-if-modify class from none to pci-passthrough: allowed
PASS: host-if-modify class from pci-passthrough to none: allowed
PASS: host-if-modify class from none to pci-sriov w/ VFs: blocked
PASS: host-if-modify class from none to pci-sriov w/ VFs for other
      devices: allowed

Story: 2010047
Task: 49650

Signed-off-by: Caio Bruchert <caio.bruchert@windriver.com>
Change-Id: Ib6a20952060331ac230b01813be28116fbceef36
This commit is contained in:
Caio Bruchert 2024-02-29 13:41:00 -03:00
parent ae29b180c2
commit 46fc50f419
3 changed files with 53 additions and 1 deletions

View File

@ -1455,6 +1455,11 @@ def _check_interface_data(op, interface, ihost, existing_interface,
return interface
def _is_port_sriov_restricted(port):
return port.pvendor in constants.SRIOV_RESTRICTED_NET_DEVICES and \
port.pdevice in constants.SRIOV_RESTRICTED_NET_DEVICES[port.pvendor]
def _check_ports(op, interface, ihost, ports):
port_list = []
@ -1474,10 +1479,17 @@ def _check_ports(op, interface, ihost, ports):
raise wsme.exc.ClientSideError(_(
"For Ethernet, select a single port."))
# Make sure that no other interface is currently using these ports
# Make sure that the port is not in the SR-IOV restricted list and
# that no other interface is currently using these ports
host_ports = pecan.request.dbapi.ethernet_port_get_all(hostid=ihost['id'])
for p in host_ports:
if p.name in port_list or p.uuid in port_list:
if (interface['ifclass'] == constants.INTERFACE_CLASS_PCI_SRIOV and
_is_port_sriov_restricted(p)):
pif = pecan.request.dbapi.iinterface_get(p.interface_id)
msg = _("Cannot use port. PCI vendor '%s' and device '%s' is not allowed."
% (p.pvendor, p.pdevice))
raise wsme.exc.ClientSideError(msg)
if p.interface_id and p.interface_id != this_interface_id:
pif = pecan.request.dbapi.iinterface_get(p.interface_id)
msg = _("Another interface %s is already using this port"

View File

@ -2256,6 +2256,14 @@ DRIVERS_UP_BEFORE_SRIOV = [DRIVER_BNXT_EN]
# become operational
DRIVERS_NOT_IMMEDIATELY_OPERATIONAL = [DRIVER_BNXT_EN]
# SR-IOV restricted network devices (cannot be used to create VFs)
# Marvell (Cavium) CNF105xx family (CNF10KA and CNF10KB):
PVENDOR_CAVIUM = 'Cavium, Inc. [177d]'
PDEVICE_CAVIUM_BA00 = 'Device [ba00]'
PDEVICE_CAVIUM_BC00 = 'Device [bc00]'
SRIOV_RESTRICTED_NET_DEVICES = {PVENDOR_CAVIUM: (PDEVICE_CAVIUM_BA00,
PDEVICE_CAVIUM_BC00)}
# Traffic control
TRAFFIC_CONTROL_SCRIPT = '/usr/local/bin/tc_setup.sh'

View File

@ -1938,6 +1938,38 @@ class TestPostMixin(object):
self.assertEqual(http_client.OK, patch_result.status_code)
self.assertEqual(0, patch_result.json['max_tx_rate'])
def test_modify_sriov_restricted_port(self):
pvendor = constants.PVENDOR_CAVIUM
pdevice = constants.PDEVICE_CAVIUM_BA00
interface = dbutils.create_test_interface(forihostid=self.worker.id,
datanetworks='group0-data0')
dbutils.create_test_ethernet_port(
id=1, name='enp81s0f0', host_id=self.worker.id,
interface_id=interface.id,
pciaddr='0000:51:00.0', dev_id=0, sriov_totalvfs=32, sriov_numvfs=0,
driver='octeon_ep',
pvendor=pvendor,
pdevice=pdevice)
# ifclass to pci-passthrough is allowed
patch_result = self.patch_dict_json(
'%s' % self._get_path(interface['uuid']),
ifname='sriov0',
ifclass=constants.INTERFACE_CLASS_PCI_PASSTHROUGH,
expect_errors=True)
self.assertEqual('application/json', patch_result.content_type)
self.assertEqual(http_client.OK, patch_result.status_code)
# ifclass to pci-sriov is not allowed
patch_result = self.patch_dict_json(
'%s' % self._get_path(interface['uuid']),
ifclass=constants.INTERFACE_CLASS_PCI_SRIOV,
sriov_numvfs=8,
expect_errors=True)
self.assertEqual(http_client.BAD_REQUEST, patch_result.status_int)
self.assertTrue(patch_result.json['error_message'])
self.assertIn(f"Cannot use port. PCI vendor '{pvendor}' and "
f"device '{pdevice}' is not allowed.",
patch_result.json['error_message'])
class TestAIOPost(InterfaceTestCase):
def setUp(self):