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
This commit is contained in:
Alessandro Pilotti 2018-08-24 00:46:22 +03:00
parent 705daeb7d0
commit fe9aa8247d
5 changed files with 32 additions and 27 deletions

View File

@ -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()

View File

@ -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()

View File

@ -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)

View File

@ -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,

View File

@ -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,