From 77f84fa9353dbf1d4c248c97ba59e857facefdb2 Mon Sep 17 00:00:00 2001 From: Hong Hui Xiao Date: Tue, 19 Jan 2016 22:17:20 -0500 Subject: [PATCH] Remove floatingip address only when the address has been configured For HA router, adding a floatingip will add a vip to keepalived, then keepalived will add the ip address to port. So there is a time window that the qg device in qrouter namespace will not have the address of floatingip. If user delete the floatingip at the time window, ip command will fail, because it tries to remove an ip address that doesn't exist on the qg device. The fix here is to check if the ip address is on the qg device, before removing the ip address. A functional test is added to address the issue. Change-Id: I72996d9a77f5f17b4d7a19d5be20b3f97f90dcba Closes-bug: #1533904 --- neutron/agent/l3/ha_router.py | 4 +++- .../tests/functional/agent/l3/test_ha_router.py | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/neutron/agent/l3/ha_router.py b/neutron/agent/l3/ha_router.py index 3e4389bf946..6c90d35d701 100644 --- a/neutron/agent/l3/ha_router.py +++ b/neutron/agent/l3/ha_router.py @@ -255,7 +255,9 @@ class HaRouter(router.RouterInfo): def remove_floating_ip(self, device, ip_cidr): self._remove_vip(ip_cidr) - if self.ha_state == 'master' and device.addr.list(): + if self.ha_state == 'master' and device.addr.list(to=ip_cidr): + # Delete the floatingip address from external port only after + # the ip address has been configured to the device super(HaRouter, self).remove_floating_ip(device, ip_cidr) def internal_network_updated(self, interface_name, ip_cidrs): diff --git a/neutron/tests/functional/agent/l3/test_ha_router.py b/neutron/tests/functional/agent/l3/test_ha_router.py index 1bdffa6e2c7..b7f4c038cba 100644 --- a/neutron/tests/functional/agent/l3/test_ha_router.py +++ b/neutron/tests/functional/agent/l3/test_ha_router.py @@ -238,6 +238,20 @@ class L3HATestCase(framework.L3AgentTestFramework): interface_name = router.get_external_device_name(port['id']) router.external_gateway_removed(port, interface_name) + def test_removing_floatingip_immediately(self): + router_info = self.generate_router_info(enable_ha=True) + router = self.manage_router(self.agent, router_info) + ex_gw_port = router.get_ex_gw_port() + interface_name = router.get_external_device_interface_name(ex_gw_port) + utils.wait_until_true(lambda: router.ha_state == 'master') + self._add_fip(router, '172.168.1.20', fixed_address='10.0.0.3') + router.process(self.agent) + router.router[l3_constants.FLOATINGIP_KEY] = [] + # The purpose of the test is to simply make sure no exception is raised + # Because router.process will consume the FloatingIpSetupException, + # call the configure_fip_addresses directly here + router.configure_fip_addresses(interface_name) + class L3HATestFailover(framework.L3AgentTestFramework):