From 37430d4bd096a04a0b3e23165ac244ac1f47a774 Mon Sep 17 00:00:00 2001 From: Yi Zhao Date: Thu, 27 Aug 2015 15:24:21 +0800 Subject: [PATCH] Delete gateway conntrack state when remove external gateway This fixed the problem that a gateway ip conntrack state not cleared when user clears a router external gateway. Change-Id: I77f22d9504430259b01366e6296a99ba1cd6a046 Closes-Bug: #1488730 --- neutron/agent/l3/ha_router.py | 2 +- neutron/agent/l3/router_info.py | 9 +++++++++ neutron/agent/linux/ip_lib.py | 7 ++++--- neutron/tests/unit/agent/l3/test_legacy_router.py | 9 +++++++++ 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/neutron/agent/l3/ha_router.py b/neutron/agent/l3/ha_router.py index 33d750d30..7b94a8718 100644 --- a/neutron/agent/l3/ha_router.py +++ b/neutron/agent/l3/ha_router.py @@ -362,10 +362,10 @@ class HaRouter(router.RouterInfo): interface_name) def delete(self, agent): + super(HaRouter, self).delete(agent) self.destroy_state_change_monitor(self.process_monitor) self.ha_network_removed() self.disable_keepalived() - super(HaRouter, self).delete(agent) def process(self, agent): super(HaRouter, self).process(agent) diff --git a/neutron/agent/l3/router_info.py b/neutron/agent/l3/router_info.py index 4c2db3655..b4f917ce5 100644 --- a/neutron/agent/l3/router_info.py +++ b/neutron/agent/l3/router_info.py @@ -202,6 +202,9 @@ class RouterInfo(object): def remove_floating_ip(self, device, ip_cidr): device.delete_addr_and_conntrack_state(ip_cidr) + def remove_external_gateway_ip(self, device, ip_cidr): + device.delete_addr_and_conntrack_state(ip_cidr) + def get_router_cidrs(self, device): return set([addr['cidr'] for addr in device.addr.list()]) @@ -538,6 +541,12 @@ class RouterInfo(object): def external_gateway_removed(self, ex_gw_port, interface_name): LOG.debug("External gateway removed: port(%s), interface(%s)", ex_gw_port, interface_name) + device = ip_lib.IPDevice(interface_name, namespace=self.ns_name) + for ip_addr in ex_gw_port['fixed_ips']: + self.remove_external_gateway_ip(device, + common_utils.ip_to_cidr( + ip_addr['ip_address'], + ip_addr['prefixlen'])) self.driver.unplug(interface_name, bridge=self.agent_conf.external_network_bridge, namespace=self.ns_name, diff --git a/neutron/agent/linux/ip_lib.py b/neutron/agent/linux/ip_lib.py index dedf8d5b6..bdf4e0a08 100644 --- a/neutron/agent/linux/ip_lib.py +++ b/neutron/agent/linux/ip_lib.py @@ -231,9 +231,10 @@ class IPDevice(SubProcessBase): This terminates any active connections through an IP. - cidr: the IP address for which state should be removed. This can be - passed as a string with or without /NN. A netaddr.IPAddress or - netaddr.Network representing the IP address can also be passed. + :param cidr: the IP address for which state should be removed. + This can be passed as a string with or without /NN. + A netaddr.IPAddress or netaddr.Network representing the IP address + can also be passed. """ self.addr.delete(cidr) diff --git a/neutron/tests/unit/agent/l3/test_legacy_router.py b/neutron/tests/unit/agent/l3/test_legacy_router.py index b900d9a5e..95f6bccc9 100644 --- a/neutron/tests/unit/agent/l3/test_legacy_router.py +++ b/neutron/tests/unit/agent/l3/test_legacy_router.py @@ -48,6 +48,15 @@ class TestBasicRouterOperations(BasicRouterTestCaseFramework): device.delete_addr_and_conntrack_state.assert_called_once_with(cidr) + def test_remove_external_gateway_ip(self): + ri = self._create_router(mock.MagicMock()) + device = mock.Mock() + cidr = '172.16.0.0/24' + + ri.remove_external_gateway_ip(device, cidr) + + device.delete_addr_and_conntrack_state.assert_called_once_with(cidr) + @mock.patch.object(ip_lib, 'send_ip_addr_adv_notif') class TestAddFloatingIpWithMockGarp(BasicRouterTestCaseFramework): -- 2.45.2