From ceb66d4552e6c4c0da60cb08fdf208fb90c34660 Mon Sep 17 00:00:00 2001 From: Chad Smith Date: Thu, 23 Mar 2023 06:08:12 -0600 Subject: macs: ignore duplicate MAC for devs with driver driver qmi_wwan (#2090) Another physical modem which has duplicate MAC addresses. Cloud-init needs to ignore the subordinate devices which are associated with the qmi_wwan driver. Fixes network rendering for the following modems: Quectel EG25 Quectel RM510Q-GLHA Sierra Wireless MC7455 LP: #2008888 --- cloudinit/net/__init__.py | 2 +- tests/unittests/test_net.py | 40 ++++++++++++++++++++++++++++------------ 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/cloudinit/net/__init__.py b/cloudinit/net/__init__.py index 65d45edf..46bce184 100644 --- a/cloudinit/net/__init__.py +++ b/cloudinit/net/__init__.py @@ -1044,7 +1044,7 @@ def get_interfaces_by_mac_on_linux(blacklist_drivers=None) -> dict: # cloud-init happens to enumerate network interfaces before drivers # have fully initialized the leader/subordinate relationships for # those devices or switches. - if driver == "mscc_felix" or driver == "fsl_enetc": + if driver in ("fsl_enetc", "mscc_felix", "qmi_wwan"): LOG.debug( "Ignoring duplicate macs from '%s' and '%s' due to " "driver '%s'.", diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py index 832d94fb..d7640d70 100644 --- a/tests/unittests/test_net.py +++ b/tests/unittests/test_net.py @@ -8223,23 +8223,39 @@ class TestGetInterfacesByMac(CiTestCase): } self.assertEqual(expected, result) - def test_duplicate_ignored_macs(self): - # LP: #199792 - self._data = copy.deepcopy(self._data) - self._data["macs"]["swp0"] = "9a:57:7d:78:47:c0" - self._data["macs"]["swp1"] = "9a:57:7d:78:47:c0" - self._data["own_macs"].append("swp0") - self._data["own_macs"].append("swp1") - self._data["drivers"]["swp0"] = "mscc_felix" - self._data["drivers"]["swp1"] = "mscc_felix" - self._mock_setup() + +@pytest.mark.parametrize("driver", ("mscc_felix", "fsl_enetc", "qmi_wwan")) +@mock.patch("cloudinit.net.get_sys_class_path") +@mock.patch("cloudinit.util.system_info", return_value={"variant": "ubuntu"}) +class TestDuplicateMac: + def test_duplicate_ignored_macs( + self, _get_system_info, get_sys_class_path, driver, tmpdir, caplog + ): + # Create sysfs representation of network devices and drivers in tmpdir + sys_net_path = tmpdir.join("class/net") + get_sys_class_path.return_value = sys_net_path.strpath + "/" + net_data = { + "swp0/address": "9a:57:7d:78:47:c0", + "swp0/addr_assign_type": "0", + "swp0/device/dev_id": "something", + "swp1/address": "9a:57:7d:78:47:c0", + "swp1/addr_assign_type": "0", + "swp1/device/dev_id": "something else", + } + populate_dir(sys_net_path.strpath, net_data) + # Symlink for device driver + driver_path = tmpdir.join(f"module/{driver}") + driver_path.ensure_dir() + sys_net_path.join("swp0/device/driver").mksymlinkto(driver_path) + sys_net_path.join("swp1/device/driver").mksymlinkto(driver_path) + with does_not_raise(): net.get_interfaces_by_mac() pattern = ( "Ignoring duplicate macs from 'swp[0-1]' and 'swp[0-1]' due to " - "driver 'mscc_felix'." + f"driver '{driver}'." ) - assert re.search(pattern, self.logs.getvalue()) + assert re.search(pattern, caplog.text) class TestInterfacesSorting(CiTestCase): -- cgit v1.2.1