diff --git a/neutron/agent/l3/ha.py b/neutron/agent/l3/ha.py index 9a55d25c256..aa77b729066 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 fd15e19b37e..92493578d84 100644 --- a/neutron/agent/l3/ha_router.py +++ b/neutron/agent/l3/ha_router.py @@ -192,7 +192,7 @@ class HaRouter(router.RouterInfo): self.routes = new_routes def _add_default_gw_virtual_route(self, ex_gw_port, interface_name): - 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. @@ -207,9 +207,6 @@ class HaRouter(router.RouterInfo): keepalived.KeepalivedVirtualRoute( default_gw, gw_ip, interface_name)) - if enable_ra_on_gw: - self.driver.configure_ipv6_ra(self.ns_name, interface_name) - 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 diff --git a/neutron/agent/l3/router_info.py b/neutron/agent/l3/router_info.py index 66d45dd4272..8f2b930bad3 100644 --- a/neutron/agent/l3/router_info.py +++ b/neutron/agent/l3/router_info.py @@ -434,7 +434,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'] @@ -444,11 +443,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): @@ -458,7 +453,11 @@ 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_l3(interface_name, ip_cidrs, namespace=ns_name,