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
'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)
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.
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()
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']
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):
# 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,