Merge "Fix - os-vif fails to get the correct UpLink Representor"
This commit is contained in:
commit
cb21c4ed8d
10
releasenotes/notes/bug-1892132-812e6d5ce0588ebb.yaml
Normal file
10
releasenotes/notes/bug-1892132-812e6d5ce0588ebb.yaml
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
Linux kernel 5.8 changed the sysfs interface that is used to
|
||||
discover the interfaces used for OVS offloads for certain NIC
|
||||
models. This results in network plugging failure, as described
|
||||
in `bug #1892132`_. This release fixes the plugging issue by
|
||||
properly handling the new sysfs structure.
|
||||
|
||||
.. _bug #1892132: https://bugs.launchpad.net/os-vif/+bug/1892132
|
@ -45,6 +45,8 @@ VF_RE = re.compile(r"vf(\d+)", re.IGNORECASE)
|
||||
PF_RE = re.compile(r"pf(\d+)", re.IGNORECASE)
|
||||
# bus_info (bdf) contains <bus>:<dev>.<func>
|
||||
PF_FUNC_RE = re.compile(r"\.(\d+)", 0)
|
||||
# phys_port_name contains p##
|
||||
UPLINK_PORT_RE = re.compile(r"p(\d+)", re.IGNORECASE)
|
||||
|
||||
_SRIOV_TOTALVFS = "sriov_totalvfs"
|
||||
NIC_NAME_LEN = 14
|
||||
@ -328,12 +330,28 @@ def get_ifname_by_pci_address(pci_addr, pf_interface=False, switchdev=False):
|
||||
itself based on the argument of pf_interface.
|
||||
"""
|
||||
dev_path = _get_sysfs_netdev_path(pci_addr, pf_interface)
|
||||
# make the if statement later more readable
|
||||
ignore_switchdev = not switchdev
|
||||
try:
|
||||
for netdev in os.listdir(dev_path):
|
||||
if ignore_switchdev or _is_switchdev(netdev):
|
||||
return netdev
|
||||
devices = os.listdir(dev_path)
|
||||
|
||||
# Return the first netdev in case of switchdev=False
|
||||
if not switchdev:
|
||||
return devices[0]
|
||||
elif pf_interface:
|
||||
fallback_netdev = None
|
||||
for netdev in devices:
|
||||
# Return the uplink representor in case of switchdev=True
|
||||
if _is_switchdev(netdev):
|
||||
fallback_netdev = netdev if fallback_netdev is None \
|
||||
else fallback_netdev
|
||||
phys_port_name = _get_phys_port_name(netdev)
|
||||
if phys_port_name is not None and \
|
||||
UPLINK_PORT_RE.search(phys_port_name):
|
||||
return netdev
|
||||
|
||||
# Fallback to first switchdev netdev in case of switchdev=True
|
||||
if fallback_netdev is not None:
|
||||
return fallback_netdev
|
||||
|
||||
except Exception:
|
||||
raise exception.PciDeviceNotFoundById(id=pci_addr)
|
||||
raise exception.PciDeviceNotFoundById(id=pci_addr)
|
||||
|
@ -261,26 +261,64 @@ class LinuxNetTest(testtools.TestCase):
|
||||
|
||||
@mock.patch.object(os, 'listdir')
|
||||
@mock.patch.object(linux_net, '_get_phys_switch_id')
|
||||
@mock.patch.object(linux_net, "_get_phys_port_name")
|
||||
def test_physical_function_interface_name(
|
||||
self, mock__get_phys_switch_id, mock_listdir):
|
||||
self, mock__get_phys_port_name, mock__get_phys_switch_id,
|
||||
mock_listdir):
|
||||
mock_listdir.return_value = ['foo', 'bar']
|
||||
mock__get_phys_switch_id.side_effect = (
|
||||
['', 'valid_switch'])
|
||||
mock__get_phys_port_name.side_effect = (["p1"])
|
||||
ifname = linux_net.get_ifname_by_pci_address(
|
||||
'0000:00:00.1', pf_interface=True, switchdev=False)
|
||||
self.assertEqual(ifname, 'foo')
|
||||
|
||||
@mock.patch.object(os, 'listdir')
|
||||
@mock.patch.object(linux_net, '_get_phys_switch_id')
|
||||
@mock.patch.object(linux_net, "_get_phys_switch_id")
|
||||
@mock.patch.object(linux_net, "_get_phys_port_name")
|
||||
def test_physical_function_interface_name_with_switchdev(
|
||||
self, mock__get_phys_switch_id, mock_listdir):
|
||||
self, mock__get_phys_port_name, mock__get_phys_switch_id,
|
||||
mock_listdir):
|
||||
mock_listdir.return_value = ['foo', 'bar']
|
||||
mock__get_phys_switch_id.side_effect = (
|
||||
['', 'valid_switch'])
|
||||
mock__get_phys_port_name.side_effect = (["p1s0"])
|
||||
ifname = linux_net.get_ifname_by_pci_address(
|
||||
'0000:00:00.1', pf_interface=True, switchdev=True)
|
||||
self.assertEqual(ifname, 'bar')
|
||||
|
||||
@mock.patch.object(os, 'listdir')
|
||||
@mock.patch.object(linux_net, "_get_phys_switch_id")
|
||||
@mock.patch.object(linux_net, "_get_phys_port_name")
|
||||
def test_physical_function_interface_name_with_representors(
|
||||
self, mock__get_phys_port_name, mock__get_phys_switch_id,
|
||||
mock_listdir):
|
||||
# Get the PF that matches the phys_port_name regex
|
||||
mock_listdir.return_value = ['enp2s0f0_0', 'enp2s0f0_1', 'enp2s0f0']
|
||||
mock__get_phys_switch_id.side_effect = (
|
||||
['valid_switch', 'valid_switch', 'valid_switch'])
|
||||
mock__get_phys_port_name.side_effect = (["pf0vf0", "pf0vf1", "p0"])
|
||||
ifname = linux_net.get_ifname_by_pci_address(
|
||||
'0000:00:00.1', pf_interface=True, switchdev=True)
|
||||
self.assertEqual(ifname, 'enp2s0f0')
|
||||
|
||||
@mock.patch.object(os, 'listdir')
|
||||
@mock.patch.object(linux_net, "_get_phys_switch_id")
|
||||
@mock.patch.object(linux_net, "_get_phys_port_name")
|
||||
def test_physical_function_interface_name_with_fallback_To_first_netdev(
|
||||
self, mock__get_phys_port_name, mock__get_phys_switch_id,
|
||||
mock_listdir):
|
||||
# Try with switchdev mode to get PF but fail because there is no match
|
||||
# for the phys_port_name then fallback to first interface found
|
||||
mock_listdir.return_value = ['enp2s0f0_0', 'enp2s0f0_1', 'enp2s0f0']
|
||||
mock__get_phys_switch_id.side_effect = (['valid_switch',
|
||||
'valid_switch',
|
||||
'valid_switch'])
|
||||
mock__get_phys_port_name.side_effect = (["pf0vf0", "pf0vf1", "pf0vf2"])
|
||||
ifname = linux_net.get_ifname_by_pci_address(
|
||||
'0000:00:00.1', pf_interface=True, switchdev=True)
|
||||
self.assertEqual(ifname, 'enp2s0f0_0')
|
||||
|
||||
@mock.patch.object(os, 'listdir')
|
||||
def test_get_ifname_by_pci_address_exception(self, mock_listdir):
|
||||
mock_listdir.side_effect = OSError('No such file or directory')
|
||||
|
Loading…
x
Reference in New Issue
Block a user