From fe9aa8247d2329b28538e98d17c2d4172a94b9d5 Mon Sep 17 00:00:00 2001 From: Alessandro Pilotti Date: Fri, 24 Aug 2018 00:46:22 +0300 Subject: [PATCH] Use the interface name when setting the MTU When using bonds and VLANs, multiple NICs can have the same MAC address. This patch replaces the MAC address with the name as a unique network adapter identifier. Partially-Implements: blueprint json-network-config Change-Id: Id1a32e8dfa4322edbc579e96e76a23965f19345b --- cloudbaseinit/osutils/base.py | 3 ++ cloudbaseinit/osutils/windows.py | 19 ++++++------ cloudbaseinit/plugins/common/mtu.py | 4 +-- cloudbaseinit/tests/osutils/test_windows.py | 29 ++++++++++--------- .../tests/plugins/common/test_mtu.py | 4 +-- 5 files changed, 32 insertions(+), 27 deletions(-) diff --git a/cloudbaseinit/osutils/base.py b/cloudbaseinit/osutils/base.py index f22ae972..8af0656f 100644 --- a/cloudbaseinit/osutils/base.py +++ b/cloudbaseinit/osutils/base.py @@ -78,6 +78,9 @@ class BaseOSUtils(object): def get_network_adapters(self): raise NotImplementedError() + def set_network_adapter_mtu(self, name, mtu): + raise NotImplementedError() + def rename_network_adapter(self, old_name, new_name): raise NotImplementedError() diff --git a/cloudbaseinit/osutils/windows.py b/cloudbaseinit/osutils/windows.py index f66163cf..fcbd8050 100644 --- a/cloudbaseinit/osutils/windows.py +++ b/cloudbaseinit/osutils/windows.py @@ -728,7 +728,7 @@ class WindowsUtils(base.BaseOSUtils): 'w32tm failed to configure NTP.\nOutput: %(out)s\nError:' ' %(err)s' % {'out': out, 'err': err}) - def set_network_adapter_mtu(self, mac_address, mtu): + def set_network_adapter_mtu(self, name, mtu): if not self.check_os_version(6, 0): raise exception.CloudbaseInitException( 'Setting the MTU is currently not supported on Windows XP ' @@ -737,18 +737,18 @@ class WindowsUtils(base.BaseOSUtils): iface_index_list = [ net_addr["interface_index"] for net_addr in network.get_adapter_addresses() - if net_addr["mac_address"] == mac_address] + if net_addr["friendly_name"] == name] if not iface_index_list: - raise exception.CloudbaseInitException( - 'Network interface with MAC address "%s" not found' % - mac_address) + raise exception.ItemNotFoundException( + 'Network interface with name "%s" not found' % + name) else: iface_index = iface_index_list[0] - LOG.debug('Setting MTU for interface "%(mac_address)s" with ' + LOG.debug('Setting MTU for interface "%(name)s" with ' 'value "%(mtu)s"', - {'mac_address': mac_address, 'mtu': mtu}) + {'name': name, 'mtu': mtu}) base_dir = self._get_system_dir() netsh_path = os.path.join(base_dir, 'netsh.exe') @@ -759,9 +759,8 @@ class WindowsUtils(base.BaseOSUtils): (out, err, ret_val) = self.execute_process(args, shell=False) if ret_val: raise exception.CloudbaseInitException( - 'Setting MTU for interface "%(mac_address)s" with ' - 'value "%(mtu)s" failed' % {'mac_address': mac_address, - 'mtu': mtu}) + 'Setting MTU for interface "%(name)s" with ' + 'value "%(mtu)s" failed' % {'name': name, 'mtu': mtu}) def rename_network_adapter(self, old_name, new_name): base_dir = self._get_system_dir() diff --git a/cloudbaseinit/plugins/common/mtu.py b/cloudbaseinit/plugins/common/mtu.py index 9a41ceeb..a5b922bd 100644 --- a/cloudbaseinit/plugins/common/mtu.py +++ b/cloudbaseinit/plugins/common/mtu.py @@ -33,14 +33,14 @@ class MTUPlugin(base.BasePlugin): osutils = osutils_factory.get_os_utils() dhcp_hosts = osutils.get_dhcp_hosts_in_use() - for (_, mac_address, dhcp_host) in dhcp_hosts: + for (adapter_name, mac_address, dhcp_host) in dhcp_hosts: options_data = dhcp.get_dhcp_options(dhcp_host, [dhcp.OPTION_MTU]) if options_data: mtu_option_data = options_data.get(dhcp.OPTION_MTU) if mtu_option_data: mtu = struct.unpack('!H', mtu_option_data)[0] - osutils.set_network_adapter_mtu(mac_address, mtu) + osutils.set_network_adapter_mtu(adapter_name, mtu) else: LOG.debug('Could not obtain the MTU configuration ' 'via DHCP for interface "%s"' % mac_address) diff --git a/cloudbaseinit/tests/osutils/test_windows.py b/cloudbaseinit/tests/osutils/test_windows.py index 73f71e7a..f740528b 100644 --- a/cloudbaseinit/tests/osutils/test_windows.py +++ b/cloudbaseinit/tests/osutils/test_windows.py @@ -1987,34 +1987,37 @@ class TestWindowsUtils(testutils.CloudbaseInitTestBase): mock_get_system_dir, mock_execute_process, fail=False, os_version_ret=True, - mac_address_match=True, + name_match=True, execute_process_val=0): - mac_address = "fake mac" + name = "fake name" + index = 1 mtu = "fake mtu" base_dir = "fake path" mock_check_os_version.return_value = os_version_ret mock_get_adapter_addresses.return_value = [mock.MagicMock() for _ in range(3)] - if mac_address_match: - # Same as `iface_index` under the "interface_index" key. - mock_get_adapter_addresses.return_value[1].\ - __getitem__.return_value = mac_address + if name_match: + mock_get_adapter_addresses.return_value = [ + {"friendly_name": name, "interface_index": index}] + else: + mock_get_adapter_addresses.return_value = [] + mock_get_system_dir.return_value = base_dir mock_execute_process.return_value = [None, None, execute_process_val] if fail: with self.assertRaises(exception.CloudbaseInitException): - self._winutils.set_network_adapter_mtu(mac_address, mtu) + self._winutils.set_network_adapter_mtu(name, mtu) return with self.snatcher: - self._winutils.set_network_adapter_mtu(mac_address, mtu) - expected_log = ['Setting MTU for interface "%(mac_address)s" with ' + self._winutils.set_network_adapter_mtu(name, mtu) + expected_log = ['Setting MTU for interface "%(name)s" with ' 'value "%(mtu)s"' % - {'mac_address': mac_address, 'mtu': mtu}] + {'name': name, 'mtu': mtu}] args = [os.path.join(base_dir, "netsh.exe"), "interface", "ipv4", "set", "subinterface", - mac_address, "mtu=%s" % mtu, "store=persistent"] + str(index), "mtu=%s" % mtu, "store=persistent"] self.assertEqual(expected_log, self.snatcher.output) mock_check_os_version.assert_called_once_with(6, 0) mock_get_adapter_addresses.assert_called_once_with() @@ -2024,9 +2027,9 @@ class TestWindowsUtils(testutils.CloudbaseInitTestBase): def test_set_network_adapter_mtu_not_supported(self): self._test_set_network_adapter_mtu(fail=True, os_version_ret=False) - def test_set_network_adapter_mtu_no_mac_match(self): + def test_set_network_adapter_mtu_no_name_match(self): self._test_set_network_adapter_mtu(fail=True, - mac_address_match=False) + name_match=False) def test_set_network_adapter_mtu_execute_fail(self): self._test_set_network_adapter_mtu(fail=True, diff --git a/cloudbaseinit/tests/plugins/common/test_mtu.py b/cloudbaseinit/tests/plugins/common/test_mtu.py index b7a650db..2df40c40 100644 --- a/cloudbaseinit/tests/plugins/common/test_mtu.py +++ b/cloudbaseinit/tests/plugins/common/test_mtu.py @@ -86,8 +86,8 @@ class MTUPluginTests(unittest.TestCase): mock_osutils = mock_get_os_utils() mocked_calls = [ - mock.call(mock.sentinel.mac_address1, 4), - mock.call(mock.sentinel.mac_address2, 4), + mock.call(mock.sentinel.adapter_name1, 4), + mock.call(mock.sentinel.adapter_name2, 4), ] self.assertEqual( mocked_calls,