diff --git a/neutron/agent/l3/dvr_local_router.py b/neutron/agent/l3/dvr_local_router.py index c1f11989ab6..ae46c86dd4d 100644 --- a/neutron/agent/l3/dvr_local_router.py +++ b/neutron/agent/l3/dvr_local_router.py @@ -440,6 +440,9 @@ class DvrLocalRouter(dvr_router_base.DvrRouterBase): pass def get_external_device_interface_name(self, ex_gw_port): + floating_ips = self.get_floating_ips() + if not self._get_floatingips_bound_to_host(floating_ips): + return self.get_snat_external_device_interface_name(ex_gw_port) fip_int = self.fip_ns.get_int_device_name(self.router_id) if ip_lib.device_exists(fip_int, namespace=self.fip_ns.get_name()): return self.fip_ns.get_rtr_ext_device_name(self.router_id) @@ -541,6 +544,12 @@ class DvrLocalRouter(dvr_router_base.DvrRouterBase): ext_scope_mark) return ports_scopemark + def _get_floatingips_bound_to_host(self, floating_ips): + """Filter Floating IPs to be hosted on this agent.""" + return [i for i in floating_ips + if (i['host'] == self.host or + i.get('dest_host') == self.host)] + def process_external(self): if self.agent_conf.agent_mode != ( n_const.L3_AGENT_MODE_DVR_NO_EXTERNAL): diff --git a/neutron/tests/functional/agent/l3/test_dvr_router.py b/neutron/tests/functional/agent/l3/test_dvr_router.py index 3480f4ce5b9..1e598541d62 100644 --- a/neutron/tests/functional/agent/l3/test_dvr_router.py +++ b/neutron/tests/functional/agent/l3/test_dvr_router.py @@ -1040,17 +1040,6 @@ class TestDvrRouter(framework.L3AgentTestFramework): self.assertFalse(self._assert_iptables_rules_exist( router1.iptables_manager, 'nat', expected_rules)) - def test_floating_ip_create_does_not_raise_keyerror_on_missing_host(self): - """Test to check floating ips configure does not raise Keyerror.""" - self.agent.conf.agent_mode = 'dvr' - router_info = self.generate_dvr_router_info( - enable_floating_ip=True) - del router_info[lib_constants.FLOATINGIP_KEY][0]['host'] - centralized_floatingips = router_info[lib_constants.FLOATINGIP_KEY][0] - self.assertIsNone(centralized_floatingips.get('host')) - # No Keyerror should be raised when calling manage_router - self.manage_router(self.agent, router_info) - def test_dvr_router_snat_namespace_with_interface_remove(self): """Test to validate the snat namespace with interface remove. diff --git a/neutron/tests/unit/agent/l3/test_agent.py b/neutron/tests/unit/agent/l3/test_agent.py index 9d4ec5ef8f9..03042de4de6 100644 --- a/neutron/tests/unit/agent/l3/test_agent.py +++ b/neutron/tests/unit/agent/l3/test_agent.py @@ -1191,6 +1191,8 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework): fip_gw_port.return_value = agent_gateway_port[0] ri.create_dvr_external_gateway_on_agent(ext_gw_port) ri.connect_rtr_2_fip() + ri._get_floatingips_bound_to_host = mock.Mock( + return_value=True) self.assertTrue(fip_gw_port.called) self.assertTrue(create_fip.called) self.assertEqual(agent_gateway_port[0], @@ -1368,6 +1370,8 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework): fip_gw_port.return_value = agent_gateway_port[0] ri.create_dvr_external_gateway_on_agent(ext_gw_port) ri.connect_rtr_2_fip() + ri._get_floatingips_bound_to_host = mock.Mock( + return_value=True) self.assertTrue(fip_gw_port.called) self.assertEqual(agent_gateway_port[0], ri.fip_ns.agent_gateway_port) @@ -1417,6 +1421,8 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework): fip_gw_port.return_value = agent_gateway_port[0] ri.create_dvr_external_gateway_on_agent(ext_gw_port) ri.connect_rtr_2_fip() + ri._get_floatingips_bound_to_host = mock.Mock( + return_value=True) self.assertTrue(fip_gw_port.called) self.assertEqual(agent_gateway_port[0], ri.fip_ns.agent_gateway_port) diff --git a/neutron/tests/unit/agent/l3/test_dvr_local_router.py b/neutron/tests/unit/agent/l3/test_dvr_local_router.py index 1e148a5e620..02605d56906 100644 --- a/neutron/tests/unit/agent/l3/test_dvr_local_router.py +++ b/neutron/tests/unit/agent/l3/test_dvr_local_router.py @@ -179,6 +179,7 @@ class TestDvrRouterOperations(base.BaseTestCase): ri.rtr_fip_connect = True ex_gw_port = {'network_id': 'fake_net_id'} ri.create_dvr_external_gateway_on_agent(ex_gw_port) + ri._get_floatingips_bound_to_host = mock.Mock(return_value=True) ri.fip_ns.create_or_update_gateway_port.assert_called_once_with( fip_agent_port)