Fix for shared N3000 NIC with VF upper interfaces

Previous commit ec8ff34 (Fix for shared NIC with the N3000 FPGA)
enabled the restarting of any upper interfaces of an N3000 network
interface after the FPGA is reset.  This was needed to restore any
IP configuration and routes on the upper interfaces such as in the
case of a shared NIC scenario with mgmt and oam being vlan interfaces
ontop of a shared lower interface.

An issue can occur with this in the configuration scenario of the
lower N3000 device being of class PCI-SRIOV, with type 'VF' upper
interfaces. The 'VF' upper interfaces are virtual and do not have
a corresponding kernel interface.  This means an error will occur
when puppet attempts to ifdown/ifup them after the N3000 device is
reset.

This commit fixes the issue by restricting the upper interfaces in
puppet's interface fpga config resource to be only of type vlan.

Closes-Bug: #1931461
Change-Id: I280148883b33c4aef4cfd4a53dff53ca8c3f824e
Signed-off-by: Steven Webster <steven.webster@windriver.com>
This commit is contained in:
Steven Webster 2021-06-22 21:52:33 -04:00
parent d1186f36a5
commit ab38c47ad0
2 changed files with 53 additions and 2 deletions

View File

@ -1152,10 +1152,16 @@ def get_n3000_config(context, iface):
if not device_id:
return {}
vlans = []
for ifname in iface.get('used_by', []):
upper = context['interfaces'][ifname]
if upper['iftype'] == constants.INTERFACE_TYPE_VLAN:
vlans.append(get_interface_os_ifname(context, upper))
config = {
'ifname': port['name'],
'device_id': device_id,
'used_by': iface['used_by'] or []
'used_by': vlans
}
return config

View File

@ -167,7 +167,8 @@ class InterfaceTestCaseMixin(base.PuppetTestCaseMixin):
'mac': interface['imac'],
'driver': kwargs.get('driver', 'ixgbe'),
'dpdksupport': kwargs.get('dpdksupport', True),
'pdevice': "Ethernet Controller X710 for 10GbE SFP+ [1572]",
'pdevice': kwargs.get('pdevice',
"Ethernet Controller X710 for 10GbE SFP+ [1572]"),
'pciaddr': kwargs.get('pciaddr',
'0000:00:00.' + str(port_id + 1)),
'dev_id': kwargs.get('dev_id', 0),
@ -1138,6 +1139,15 @@ class InterfaceTestCase(InterfaceTestCaseMixin, dbbase.BaseHostTestCase):
return config
def _get_fpga_config(self, portname='eth1', device_id='0d58', vlans=None):
config = {
'ifname': portname,
'device_id': device_id,
'used_by': vlans
}
return config
def _get_loopback_config(self):
network_config = self._get_network_config(
ifname=interface.LOOPBACK_IFNAME, method=interface.LOOPBACK_METHOD)
@ -1651,6 +1661,41 @@ class InterfaceTestCase(InterfaceTestCaseMixin, dbbase.BaseHostTestCase):
vf_config=expected_vf_config)
self.assertEqual(expected, config)
def test_get_fpga_config(self):
port, iface = self._create_ethernet_test(
'n3000', constants.INTERFACE_CLASS_PCI_SRIOV,
constants.NETWORK_TYPE_PCI_SRIOV, sriov_numvfs=4,
iface_sriov_vf_driver=None,
port_sriov_vf_driver="iavf",
sriov_vfs_pci_address="0000:b1:02.0,0000:b1:02.1,0000:b1:02.2,0000:b1:02.3",
pdevice="Ethernet Controller [0d58]")
self._create_vf_test("vf1", 2, 'vfio', lower_iface=iface)
self._create_vlan_test('oam', constants.INTERFACE_CLASS_PLATFORM,
constants.NETWORK_TYPE_OAM, 1, lower_iface=iface)
self._update_context()
config = interface.get_fpga_config(self.context, iface)
# Since the interface's fpga config is used to determine whether
# any upper vlan interfaces need to be brought up after an
# n3000 device is reset, we ensure that no virtual (VF)
# type interfaces are in the dict.
# Note: the operating system name of a vlan will be
# vlan<VID> regardless of the logical name.
expected = self._get_fpga_config(
portname='eth1', device_id='0d58', vlans=["vlan1"])
self.assertEqual(expected, config)
def test_is_an_n3000_i40_device_false(self):
self.assertFalse(
interface.is_an_n3000_i40_device(self.context, self.iface))
def test_is_an_n3000_i40_device_true(self):
self.port['pdevice'] = "Ethernet Controller [0d58]"
self._update_context()
self.assertTrue(
interface.is_an_n3000_i40_device(self.context, self.iface))
def test_is_a_mellanox_cx3_device_false(self):
self.assertFalse(
interface.is_a_mellanox_cx3_device(self.context, self.iface))