Merge "Handle properly existing LLA address during l3 agent restart" into stable/ussuri
This commit is contained in:
commit
8d84963857
|
@ -27,6 +27,7 @@ from oslo_utils import netutils
|
|||
import six
|
||||
from stevedore import driver
|
||||
|
||||
from neutron.agent.linux import ip_lib
|
||||
from neutron.common import utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
@ -209,16 +210,20 @@ class PrefixDelegation(object):
|
|||
|
||||
def _add_lla(self, router, lla_with_mask):
|
||||
if router['gw_interface']:
|
||||
self.intf_driver.add_ipv6_addr(router['gw_interface'],
|
||||
lla_with_mask,
|
||||
router['ns_name'],
|
||||
'link')
|
||||
# There is a delay before the LLA becomes active.
|
||||
# This is because the kernel runs DAD to make sure LLA uniqueness
|
||||
# Spawn a thread to wait for the interface to be ready
|
||||
self._spawn_lla_thread(router['gw_interface'],
|
||||
router['ns_name'],
|
||||
lla_with_mask)
|
||||
try:
|
||||
self.intf_driver.add_ipv6_addr(router['gw_interface'],
|
||||
lla_with_mask,
|
||||
router['ns_name'],
|
||||
'link')
|
||||
# There is a delay before the LLA becomes active.
|
||||
# This is because the kernel runs DAD to make sure LLA
|
||||
# uniqueness
|
||||
# Spawn a thread to wait for the interface to be ready
|
||||
self._spawn_lla_thread(router['gw_interface'],
|
||||
router['ns_name'],
|
||||
lla_with_mask)
|
||||
except ip_lib.IpAddressAlreadyExists:
|
||||
pass
|
||||
|
||||
def _spawn_lla_thread(self, gw_ifname, ns_name, lla_with_mask):
|
||||
eventlet.spawn_n(self._ensure_lla_task,
|
||||
|
|
|
@ -3814,6 +3814,53 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
|
|||
self._pd_assert_dibbler_calls(expected_calls,
|
||||
self.external_process.mock_calls[-len(expected_calls):])
|
||||
|
||||
@mock.patch.object(pd.PrefixDelegation, 'update_subnet')
|
||||
@mock.patch.object(dibbler.PDDibbler, 'get_prefix', autospec=True)
|
||||
@mock.patch.object(dibbler.os, 'getpid', return_value=1234)
|
||||
@mock.patch.object(pd.PrefixDelegation, '_is_lla_active',
|
||||
return_value=True)
|
||||
@mock.patch.object(dibbler.os, 'chmod')
|
||||
@mock.patch.object(dibbler.shutil, 'rmtree')
|
||||
@mock.patch.object(pd.PrefixDelegation, '_get_sync_data')
|
||||
def test_pd_lla_already_exists(self, mock1, mock2, mock3, mock4,
|
||||
mock_getpid, mock_get_prefix,
|
||||
mock_pd_update_subnet):
|
||||
'''Test HA in the active router
|
||||
The intent is to test the PD code with HA. To avoid unnecessary
|
||||
complexities, use the regular router.
|
||||
'''
|
||||
# Initial setup
|
||||
agent, router, ri = self._pd_setup_agent_router(enable_ha=True)
|
||||
|
||||
agent.pd.intf_driver = mock.MagicMock()
|
||||
agent.pd.intf_driver.add_ipv6_addr.side_effect = (
|
||||
ip_lib.IpAddressAlreadyExists())
|
||||
|
||||
# Create one pd-enabled subnet and add router interface
|
||||
l3_test_common.router_append_pd_enabled_subnet(router)
|
||||
self._pd_add_gw_interface(agent, ri)
|
||||
ri.process()
|
||||
|
||||
# No client should be started since it's standby router
|
||||
agent.pd.process_prefix_update()
|
||||
self.assertFalse(self.external_process.called)
|
||||
self.assertFalse(mock_get_prefix.called)
|
||||
|
||||
update_router = copy.deepcopy(router)
|
||||
pd_intfs = l3_test_common.get_unassigned_pd_interfaces(update_router)
|
||||
|
||||
# Turn the router to be active
|
||||
agent.pd.process_ha_state(router['id'], True)
|
||||
|
||||
# Get prefixes
|
||||
self._pd_get_prefixes(agent, ri, [], pd_intfs, mock_get_prefix)
|
||||
|
||||
# Update the router with the new prefix
|
||||
ri.router = update_router
|
||||
ri.process()
|
||||
|
||||
self._pd_verify_update_results(ri, pd_intfs, mock_pd_update_subnet)
|
||||
|
||||
@mock.patch.object(dibbler.os, 'chmod')
|
||||
def test_pd_generate_dibbler_conf(self, mock_chmod):
|
||||
pddib = dibbler.PDDibbler("router_id", "subnet-id", "ifname")
|
||||
|
|
Loading…
Reference in New Issue