From c89a4fdd88b0f8832b32af55f64e0d3a35c84388 Mon Sep 17 00:00:00 2001 From: sridhargaddam Date: Thu, 10 Sep 2015 16:14:13 +0000 Subject: [PATCH] Configure gw_iface for RAs only in Master HA Router For an HA Router which does not have any IPv6 subnets in the external network and when ipv6_gateway is not set, Neutron configures the gateway interface of the router to receive Router Advts for default route. In an HA router, only the Master instance has the IP addresses while the Backup instance does not have any addresses (including LLA). In Kernel version 3.10, when the last IPv6 address is removed from the interface, IPv6 proc entries corresponding to the iface are also deleted. This is however reverted in the later versions of kernel code. This patch addresses this issue by configuring the proc entry only for the Master HA Router instance instead of doing it un-conditionally. Closes-Bug: #1494336 Change-Id: Ibf8e0ff64cda00314f8fa649ef5019c95c2d6004 --- neutron/agent/l3/ha.py | 13 +++++++++++++ neutron/agent/l3/ha_router.py | 5 +---- neutron/agent/l3/router_info.py | 14 +++++++------- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/neutron/agent/l3/ha.py b/neutron/agent/l3/ha.py index 76363c9af..b66e1a37d 100644 --- a/neutron/agent/l3/ha.py +++ b/neutron/agent/l3/ha.py @@ -122,10 +122,23 @@ class AgentMixin(object): 'possibly deleted concurrently.'), router_id) return + self._configure_ipv6_ra_on_ext_gw_port_if_necessary(ri, state) self._update_metadata_proxy(ri, router_id, state) self._update_radvd_daemon(ri, state) self.state_change_notifier.queue_event((router_id, state)) + def _configure_ipv6_ra_on_ext_gw_port_if_necessary(self, ri, state): + # If ipv6 is enabled on the platform, ipv6_gateway config flag is + # not set and external_network associated to the router does not + # include any IPv6 subnet, enable the gateway interface to accept + # Router Advts from upstream router for default route. + ex_gw_port_id = ri.ex_gw_port and ri.ex_gw_port['id'] + if state == 'master' and ex_gw_port_id and ri.use_ipv6: + gateway_ips = ri._get_external_gw_ips(ri.ex_gw_port) + if not ri.is_v6_gateway_set(gateway_ips): + interface_name = ri.get_external_device_name(ex_gw_port_id) + ri.driver.configure_ipv6_ra(ri.ns_name, interface_name) + def _update_metadata_proxy(self, ri, router_id, state): if state == 'master': LOG.debug('Spawning metadata proxy for router %s', router_id) diff --git a/neutron/agent/l3/ha_router.py b/neutron/agent/l3/ha_router.py index 33d750d30..43e3447c7 100644 --- a/neutron/agent/l3/ha_router.py +++ b/neutron/agent/l3/ha_router.py @@ -187,7 +187,7 @@ class HaRouter(router.RouterInfo): def _add_default_gw_virtual_route(self, ex_gw_port, interface_name): default_gw_rts = [] - gateway_ips, enable_ra_on_gw = self._get_external_gw_ips(ex_gw_port) + gateway_ips = self._get_external_gw_ips(ex_gw_port) for gw_ip in gateway_ips: # TODO(Carl) This is repeated everywhere. A method would # be nice. @@ -197,9 +197,6 @@ class HaRouter(router.RouterInfo): default_gw, gw_ip, interface_name)) instance.virtual_routes.gateway_routes = default_gw_rts - if enable_ra_on_gw: - self.driver.configure_ipv6_ra(self.ns_name, interface_name) - def _add_extra_subnet_onlink_routes(self, ex_gw_port, interface_name): extra_subnets = ex_gw_port.get('extra_subnets', []) instance = self._get_keepalived_instance() diff --git a/neutron/agent/l3/router_info.py b/neutron/agent/l3/router_info.py index 4c2db3655..79f52bd55 100644 --- a/neutron/agent/l3/router_info.py +++ b/neutron/agent/l3/router_info.py @@ -475,7 +475,6 @@ class RouterInfo(object): def _get_external_gw_ips(self, ex_gw_port): gateway_ips = [] - enable_ra_on_gw = False if 'subnets' in ex_gw_port: gateway_ips = [subnet['gateway_ip'] for subnet in ex_gw_port['subnets'] @@ -485,11 +484,7 @@ class RouterInfo(object): if self.agent_conf.ipv6_gateway: # ipv6_gateway configured, use address for default route. gateway_ips.append(self.agent_conf.ipv6_gateway) - else: - # ipv6_gateway is also not configured. - # Use RA for default route. - enable_ra_on_gw = True - return gateway_ips, enable_ra_on_gw + return gateway_ips def _external_gateway_added(self, ex_gw_port, interface_name, ns_name, preserve_ips): @@ -501,7 +496,12 @@ class RouterInfo(object): # will be added to the interface. ip_cidrs = common_utils.fixed_ip_cidrs(ex_gw_port['fixed_ips']) - gateway_ips, enable_ra_on_gw = self._get_external_gw_ips(ex_gw_port) + gateway_ips = self._get_external_gw_ips(ex_gw_port) + enable_ra_on_gw = False + if self.use_ipv6 and not self.is_v6_gateway_set(gateway_ips): + # There is no IPv6 gw_ip, use RouterAdvt for default route. + enable_ra_on_gw = True + self.driver.init_router_port( interface_name, ip_cidrs, -- 2.45.2