Merge "Spawn RADVD only in the master HA router"

This commit is contained in:
Jenkins 2015-04-24 21:24:04 +00:00 committed by Gerrit Code Review
commit c5188d8bf8
4 changed files with 64 additions and 10 deletions

View File

@ -113,10 +113,7 @@ class AgentMixin(object):
LOG.info(_LI('Router %(router_id)s transitioned to %(state)s'),
{'router_id': router_id,
'state': state})
self._update_metadata_proxy(router_id, state)
self.state_change_notifier.queue_event((router_id, state))
def _update_metadata_proxy(self, router_id, state):
try:
ri = self.router_info[router_id]
except AttributeError:
@ -124,6 +121,11 @@ class AgentMixin(object):
'possibly deleted concurrently.'), router_id)
return
self._update_metadata_proxy(ri, router_id, state)
self._update_radvd_daemon(ri, state)
self.state_change_notifier.queue_event((router_id, state))
def _update_metadata_proxy(self, ri, router_id, state):
if state == 'master':
LOG.debug('Spawning metadata proxy for router %s', router_id)
self.metadata_driver.spawn_monitored_metadata_proxy(
@ -134,6 +136,14 @@ class AgentMixin(object):
self.metadata_driver.destroy_monitored_metadata_proxy(
self.process_monitor, ri.router_id, ri.ns_name, self.conf)
def _update_radvd_daemon(self, ri, state):
# Radvd has to be spawned only on the Master HA Router. If there are
# any state transitions, we enable/disable radvd accordingly.
if state == 'master':
ri.enable_radvd()
else:
ri.disable_radvd()
def notify_server(self, batched_events):
translation_map = {'master': 'active',
'backup': 'standby',

View File

@ -204,14 +204,17 @@ class HaRouter(router.RouterInfo):
def _should_delete_ipv6_lladdr(self, ipv6_lladdr):
"""Only the master should have any IP addresses configured.
Let keepalived manage IPv6 link local addresses, the same way we let
it manage IPv4 addresses. In order to do that, we must delete
the address first as it is autoconfigured by the kernel.
it manage IPv4 addresses. If the router is not in the master state,
we must delete the address first as it is autoconfigured by the kernel.
"""
manager = self.keepalived_manager
if manager.get_process().active:
conf = manager.get_conf_on_disk()
managed_by_keepalived = conf and ipv6_lladdr in conf
if managed_by_keepalived:
if self.ha_state != 'master':
conf = manager.get_conf_on_disk()
managed_by_keepalived = conf and ipv6_lladdr in conf
if managed_by_keepalived:
return False
else:
return False
return True
@ -345,3 +348,8 @@ class HaRouter(router.RouterInfo):
if self.ha_port:
self.enable_keepalived()
def enable_radvd(self, internal_ports=None):
if (self.keepalived_manager.get_process().active and
self.ha_state == 'master'):
super(HaRouter, self).enable_radvd(internal_ports)

View File

@ -274,7 +274,7 @@ class RouterInfo(object):
self.router[l3_constants.INTERFACE_KEY] = []
self.router[l3_constants.FLOATINGIP_KEY] = []
self.process(agent)
self.radvd.disable()
self.disable_radvd()
if self.router_namespace:
self.router_namespace.delete()
@ -342,6 +342,17 @@ class RouterInfo(object):
if netaddr.IPNetwork(subnet['cidr']).version == 6:
return True
def enable_radvd(self, internal_ports=None):
LOG.debug('Spawning radvd daemon in router device: %s', self.router_id)
if not internal_ports:
internal_ports = self.internal_ports
self.radvd.enable(internal_ports)
def disable_radvd(self):
LOG.debug('Terminating radvd daemon in router device: %s',
self.router_id)
self.radvd.disable()
def _process_internal_ports(self):
existing_port_ids = set(p['id'] for p in self.internal_ports)
@ -380,7 +391,7 @@ class RouterInfo(object):
# Enable RA
if enable_ra:
self.radvd.enable(internal_ports)
self.enable_radvd(internal_ports)
existing_devices = self._get_existing_devices()
current_internal_devs = set(n for n in existing_devices

View File

@ -740,6 +740,31 @@ class L3HATestFramework(L3AgentTestFramework):
utils.wait_until_true(lambda: router2.ha_state == 'master')
utils.wait_until_true(lambda: router1.ha_state == 'backup')
def test_ha_router_ipv6_radvd_status(self):
router_info = self.generate_router_info(ip_version=6, enable_ha=True)
router1 = self.manage_router(self.agent, router_info)
utils.wait_until_true(lambda: router1.ha_state == 'master')
utils.wait_until_true(lambda: router1.radvd.enabled)
def _check_lla_status(router, expected):
internal_devices = router.router[l3_constants.INTERFACE_KEY]
for device in internal_devices:
lladdr = ip_lib.get_ipv6_lladdr(device['mac_address'])
exists = ip_lib.device_exists_with_ips_and_mac(
router.get_internal_device_name(device['id']), [lladdr],
device['mac_address'], router.ns_name)
self.assertEqual(expected, exists)
_check_lla_status(router1, True)
device_name = router1.get_ha_device_name()
ha_device = ip_lib.IPDevice(device_name, namespace=router1.ns_name)
ha_device.link.set_down()
utils.wait_until_true(lambda: router1.ha_state == 'backup')
utils.wait_until_true(lambda: not router1.radvd.enabled, timeout=10)
_check_lla_status(router1, False)
class MetadataFakeProxyHandler(object):