]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Fixes SNAT port not found for internal port
authorSwaminathan Vasudevan <swaminathan.vasudevan@hp.com>
Wed, 16 Sep 2015 18:13:46 +0000 (11:13 -0700)
committerSwaminathan Vasudevan <swaminathan.vasudevan@hp.com>
Fri, 18 Sep 2015 18:21:35 +0000 (11:21 -0700)
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

neutron/agent/l3/dvr_local_router.py
neutron/agent/l3/dvr_router_base.py
neutron/tests/unit/agent/l3/test_agent.py

index 7819438d28f03dfc946668083e74880213d6b9d1..1ecc79fc47736712cff7ba51e1f364cfefad9918 100644 (file)
@@ -368,7 +368,9 @@ class DvrLocalRouter(dvr_router_base.DvrRouterBase):
                 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)
 
index 2fd1735e3a2f6bd6557bc3a6c955306fc5999f11..704be6ce6e0d16f1ce4ef4e8abdfa409943932c2 100644 (file)
@@ -40,13 +40,14 @@ class DvrRouterBase(router.RouterInfo):
             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})
index e2a5eb6b079f05716c369d76cca21791879daae8..3be71f5c07ede8bd44fe030bed39b460aec75c59 100644 (file)
@@ -453,6 +453,7 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
                                           **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
@@ -535,6 +536,8 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
                 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)