Ensure that MAC address of the device is set correctly
For unknown (for me at least) reason sometimes we observed e.g. in the CI jobs that interfaces created by e.g. L3 agent didn't had properly set MAC address to the one generated by Neutron. To avoid that this patch adds check if the requested MAC was actually set on the device before moving on to configure MTU and other attributes of the device. Co-Authored-By: Brian Haley <haleyb.dev@gmail.com> Closes-bug: #2000164 Change-Id: I23facc53795a9592ccb137c60fb1f356406a4e00
This commit is contained in:
parent
4e26901feb
commit
c362016620
@ -18,6 +18,7 @@ import time
|
||||
|
||||
import netaddr
|
||||
from neutron_lib.agent.linux import interface
|
||||
from neutron_lib.api import converters
|
||||
from neutron_lib import constants
|
||||
from neutron_lib import exceptions
|
||||
from neutron_lib.plugins.ml2 import ovs_constants as ovs_const
|
||||
@ -26,6 +27,7 @@ from oslo_utils import excutils
|
||||
from pyroute2.netlink import exceptions \
|
||||
as pyroute2_exc # pylint: disable=no-name-in-module
|
||||
|
||||
from neutron._i18n import _
|
||||
from neutron.agent.common import ovs_lib
|
||||
from neutron.agent.linux import ip_lib
|
||||
from neutron.common import utils
|
||||
@ -336,20 +338,29 @@ class OVSInterfaceDriver(LinuxInterfaceDriver):
|
||||
ovs.replace_port(device_name, *attrs)
|
||||
|
||||
def _set_device_address(self, device, mac_address):
|
||||
device.link.set_address(mac_address)
|
||||
current_mac = converters.convert_to_sanitized_mac_address(
|
||||
device.link.address)
|
||||
if current_mac != mac_address:
|
||||
msg = _("Failed to set mac address to: %s; "
|
||||
"Current mac: %s") % (mac_address, current_mac)
|
||||
raise RuntimeError(msg)
|
||||
|
||||
def _ensure_device_address(self, device, mac_address):
|
||||
mac_address = converters.convert_to_sanitized_mac_address(mac_address)
|
||||
for i in range(9):
|
||||
# workaround for the OVS shy port syndrome. ports sometimes
|
||||
# hide for a bit right after they are first created.
|
||||
# see bug/1618987
|
||||
try:
|
||||
device.link.set_address(mac_address)
|
||||
break
|
||||
self._set_device_address(device, mac_address)
|
||||
return
|
||||
except RuntimeError as e:
|
||||
LOG.warning("Got error trying to set mac, retrying: %s",
|
||||
str(e))
|
||||
time.sleep(1)
|
||||
else:
|
||||
# didn't break, we give it one last shot without catching
|
||||
device.link.set_address(mac_address)
|
||||
# didn't break, we give it one last shot without catching
|
||||
self._set_device_address(device, mac_address)
|
||||
|
||||
def _add_device_to_namespace(self, ip_wrapper, device, namespace):
|
||||
namespace_obj = ip_wrapper.ensure_namespace(namespace)
|
||||
@ -406,7 +417,7 @@ class OVSInterfaceDriver(LinuxInterfaceDriver):
|
||||
self._ovs_add_port(bridge, tap_name, port_id, mac_address,
|
||||
internal=internal)
|
||||
try:
|
||||
self._set_device_address(ns_dev, mac_address)
|
||||
self._ensure_device_address(ns_dev, mac_address)
|
||||
except Exception:
|
||||
LOG.warning("Failed to set mac for interface %s", ns_dev)
|
||||
with excutils.save_and_reraise_exception():
|
||||
|
@ -72,6 +72,8 @@ class TestBase(base.BaseTestCase):
|
||||
self.ip_dev = self.ip_dev_p.start()
|
||||
self.ip_p = mock.patch.object(ip_lib, 'IPWrapper')
|
||||
self.ip = self.ip_p.start()
|
||||
link = self.ip.return_value.device.return_value.link
|
||||
link.address = 'aa:bb:cc:dd:ee:ff'
|
||||
self.device_exists_p = mock.patch.object(ip_lib, 'device_exists')
|
||||
self.device_exists = self.device_exists_p.start()
|
||||
self.get_devices_with_ip_p = mock.patch.object(ip_lib,
|
||||
@ -492,12 +494,11 @@ class TestOVSInterfaceDriver(TestBase):
|
||||
reraise = mock.patch.object(
|
||||
excutils, 'save_and_reraise_exception')
|
||||
reraise.start()
|
||||
ip_wrapper = mock.Mock()
|
||||
for exception in (OSError(),
|
||||
pyroute2_exc.NetlinkError(22),
|
||||
RuntimeError()):
|
||||
ip_wrapper.ensure_namespace.side_effect = exception
|
||||
self.ip.return_value = ip_wrapper
|
||||
ip = self.ip.return_value
|
||||
ip.ensure_namespace.side_effect = exception
|
||||
delete_port.reset_mock()
|
||||
ovs.plug_new(
|
||||
'01234567-1234-1234-99',
|
||||
@ -568,6 +569,7 @@ class TestOVSInterfaceDriverWithVeth(TestOVSInterfaceDriver):
|
||||
|
||||
root_dev = mock.Mock()
|
||||
ns_dev = mock.Mock()
|
||||
ns_dev.link.address = 'aa:bb:cc:dd:ee:ff'
|
||||
self.ip().add_veth = mock.Mock(return_value=(root_dev, ns_dev))
|
||||
mock.patch.object(
|
||||
interface, '_get_veth',
|
||||
|
Loading…
x
Reference in New Issue
Block a user