diff --git a/neutron/agent/l3/dvr_local_router.py b/neutron/agent/l3/dvr_local_router.py index f1a40126148..d75a01f073f 100644 --- a/neutron/agent/l3/dvr_local_router.py +++ b/neutron/agent/l3/dvr_local_router.py @@ -100,6 +100,16 @@ class DvrLocalRouter(dvr_router_base.DvrRouterBase): if floating_ip_status == lib_constants.FLOATINGIP_STATUS_ACTIVE: self.centralized_floatingips_set.add(fip_cidr) return floating_ip_status + if not self._check_if_floatingip_bound_to_host(fip): + # TODO(Swami): Need to figure out what status + # should be returned when the floating IP is + # not destined for this agent and if the floating + # IP is configured in a different compute host. + # This should not happen once we fix the server + # side code, but still a check to make sure if + # the floating IP is intended for this host should + # be done. + return floating_ip = fip['floating_ip_address'] fixed_ip = fip['fixed_ip_address'] self._add_floating_ip_rule(floating_ip, fixed_ip) @@ -440,9 +450,6 @@ 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) @@ -544,10 +551,9 @@ 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 [fip for fip in floating_ips - if self.host in (fip.get('host'), fip.get('dest_host'))] + def _check_if_floatingip_bound_to_host(self, fip): + """Check if the floating IP is bound to this host.""" + return self.host in (fip.get('host'), fip.get('dest_host')) def process_external(self): if self.agent_conf.agent_mode != ( diff --git a/neutron/tests/unit/agent/l3/test_agent.py b/neutron/tests/unit/agent/l3/test_agent.py index 03042de4de6..48bddbfd769 100644 --- a/neutron/tests/unit/agent/l3/test_agent.py +++ b/neutron/tests/unit/agent/l3/test_agent.py @@ -1191,8 +1191,6 @@ 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], @@ -1211,6 +1209,64 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework): create_fip.assert_called_once_with() self.assertEqual(1, ri.fip_ns.create_rtr_2_fip_link.call_count) + @mock.patch.object(lla.LinkLocalAllocator, '_write') + def test_floating_ip_not_configured_if_no_host_or_dest_host( + self, lla_write): + fake_network_id = _uuid() + subnet_id = _uuid() + fake_floatingips = {'floatingips': [ + {'id': _uuid(), + 'floating_ip_address': '20.0.0.3', + 'fixed_ip_address': '192.168.0.1', + 'floating_network_id': _uuid(), + 'port_id': _uuid()}]} + agent_gateway_port = ( + [{'fixed_ips': [ + {'ip_address': '20.0.0.30', + 'prefixlen': 24, + 'subnet_id': subnet_id}], + 'subnets': [ + {'id': subnet_id, + 'cidr': '20.0.0.0/24', + 'gateway_ip': '20.0.0.1'}], + 'id': _uuid(), + 'network_id': fake_network_id, + 'mac_address': 'ca:fe:de:ad:be:ef'}] + ) + + router = l3_test_common.prepare_router_data(enable_snat=True) + router[lib_constants.FLOATINGIP_KEY] = fake_floatingips['floatingips'] + router[n_const.FLOATINGIP_AGENT_INTF_KEY] = agent_gateway_port + router['distributed'] = True + agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) + self._set_ri_kwargs(agent, router['id'], router) + ri = dvr_router.DvrEdgeRouter(HOSTNAME, **self.ri_kwargs) + ext_gw_port = ri.router.get('gw_port') + ri.fip_ns = agent.get_fip_ns(ext_gw_port['network_id']) + agent.process_router_add = mock.Mock() + ri.fip_ns.create_rtr_2_fip_link = mock.Mock() + with mock.patch.object(ri, 'get_floating_ips') as fips, \ + mock.patch.object(ri, 'get_floating_agent_gw_interface' + ) as fip_gw_port, \ + mock.patch.object(ri, + '_add_floating_ip_rule') as add_rule, \ + mock.patch.object(ri.fip_ns, + 'create') as create_fip: + fips.return_value = fake_floatingips + fip_gw_port.return_value = agent_gateway_port[0] + ri.create_dvr_external_gateway_on_agent(ext_gw_port) + ri.connect_rtr_2_fip() + self.assertTrue(fip_gw_port.called) + self.assertTrue(create_fip.called) + self.assertEqual(agent_gateway_port[0], + ri.fip_ns.agent_gateway_port) + self.assertTrue(ri.rtr_fip_connect) + # Now let us associate the fip to the router + status = ri.floating_ip_added_dist(fips, "192.168.0.1/32") + self.assertIsNone(status) + self.assertEqual(0, self.send_adv_notif.call_count) + self.assertFalse(add_rule.called) + @mock.patch.object(lla.LinkLocalAllocator, '_write') def test_floating_ip_centralized(self, lla_write): fake_network_id = _uuid() @@ -1370,8 +1426,6 @@ 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) @@ -1421,8 +1475,6 @@ 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 02605d56906..1e148a5e620 100644 --- a/neutron/tests/unit/agent/l3/test_dvr_local_router.py +++ b/neutron/tests/unit/agent/l3/test_dvr_local_router.py @@ -179,7 +179,6 @@ 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)