For every router interface added to a router
with a default gateway there will be an internal
SNAT port generated and will be required by the
L3 Agent to process the SNAT rules.
This bug was introduced by the change ID below
Icc099c1a97e3e68eeaf4690bc83167ba30d8099a.
When the gateway is removed these ports have to
be removed from the namespace. These ports are
cached in the router_info and should be provided
to the get_snat_port_for_internal_port function
when called from external_gateway_removed or when
called from _dvr_internal_network_removed.
This patch fixes this problem.
Closes-Bug: #
1496578
Change-Id: Id5af4774ba246e24f343f5623af5ea9143bd5f6b
self.get_external_device_interface_name(ex_gw_port))
self.process_floating_ip_addresses(to_fip_interface_name)
for p in self.internal_ports:
- gateway = self.get_snat_port_for_internal_port(p)
+ # NOTE: When removing the gateway port, pass in the snat_port
+ # cache along with the current ports.
+ gateway = self.get_snat_port_for_internal_port(p, self.snat_ports)
internal_interface = self.get_internal_device_name(p['id'])
self._snat_redirect_remove(gateway, p, internal_interface)
snat_ports = self.get_snat_interfaces()
fixed_ip = int_port['fixed_ips'][0]
subnet_id = fixed_ip['subnet_id']
- match_port = [p for p in snat_ports
- if p['fixed_ips'][0]['subnet_id'] == subnet_id]
- if match_port:
- return match_port[0]
- else:
- LOG.error(_LE('DVR: SNAT port not found in the list '
- '%(snat_list)s for the given router '
- ' internal port %(int_p)s'), {
- 'snat_list': snat_ports,
- 'int_p': int_port})
+ if snat_ports:
+ match_port = [p for p in snat_ports
+ if p['fixed_ips'][0]['subnet_id'] == subnet_id]
+ if match_port:
+ return match_port[0]
+ else:
+ LOG.error(_LE('DVR: SNAT port not found in the list '
+ '%(snat_list)s for the given router '
+ ' internal port %(int_p)s'), {
+ 'snat_list': snat_ports,
+ 'int_p': int_port})
**self.ri_kwargs)
ri._create_dvr_gateway = mock.Mock()
ri.get_snat_interfaces = mock.Mock(return_value=self.snat_ports)
+ ri.snat_ports = self.snat_ports
ri._create_snat_namespace()
ri.fip_ns = agent.get_fip_ns(ex_net_id)
ri.internal_ports = self.snat_ports
ri._snat_redirect_remove.assert_called_with(
sn_port, sn_port,
ri.get_internal_device_name(sn_port['id']))
+ ri.get_snat_port_for_internal_port.assert_called_with(
+ mock.ANY, ri.snat_ports)
else:
raise Exception("Invalid action %s" % action)