From cf14d20b543662847e2be00af84633b5b3bfd9b5 Mon Sep 17 00:00:00 2001 From: Swaminathan Vasudevan Date: Fri, 23 Mar 2018 15:11:13 -0700 Subject: [PATCH] DVR: Restarting l3 agent loses centralized fip ip on qg-interface When l3 agent is restarted on a dvr_snat node that is configured for L3_HA and has a centralized FloatingIP configured to the qg-interface in the snat_namespace, that FloatingIP is not re-configured to the qg-interface when agent starts. The reason being, the cidr is not being retrieved from the keepalived instance and only retrieved from the centralized_fip_cidr_set. If 'L3_HA' is configured we need to retrieve it from the keepalived instance. This patch fixes the problem by retrieving the cidrs from the keepalived instance for the qg-interface. Change-Id: I848a20d06e2d344503a4cb1776dbe2617d91bc41 Closes-Bug: #1740450 (cherry picked from commit 64028a389ff904f15e471b44bd5b3979c5db2cd2) --- neutron/agent/l3/dvr_edge_ha_router.py | 5 +++ .../functional/agent/l3/test_dvr_router.py | 37 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/neutron/agent/l3/dvr_edge_ha_router.py b/neutron/agent/l3/dvr_edge_ha_router.py index 9fe5a25a86e..238e14699c2 100644 --- a/neutron/agent/l3/dvr_edge_ha_router.py +++ b/neutron/agent/l3/dvr_edge_ha_router.py @@ -71,6 +71,11 @@ class DvrEdgeHaRouter(dvr_edge_router.DvrEdgeRouter, super(DvrEdgeHaRouter, self).remove_centralized_floatingip( fip_cidr) + def _get_centralized_fip_cidr_set(self): + interface_name = self.get_snat_external_device_interface_name( + self.get_ex_gw_port()) + return set(self._get_cidrs_from_keepalived(interface_name)) + def external_gateway_added(self, ex_gw_port, interface_name): super(DvrEdgeHaRouter, self).external_gateway_added( ex_gw_port, interface_name) diff --git a/neutron/tests/functional/agent/l3/test_dvr_router.py b/neutron/tests/functional/agent/l3/test_dvr_router.py index 446a9fad623..1ba07fdd6a0 100644 --- a/neutron/tests/functional/agent/l3/test_dvr_router.py +++ b/neutron/tests/functional/agent/l3/test_dvr_router.py @@ -24,7 +24,10 @@ import six import testtools from neutron.agent.l3 import agent as neutron_l3_agent +from neutron.agent.l3 import dvr_edge_ha_router as dvr_ha_router +from neutron.agent.l3 import dvr_edge_router from neutron.agent.l3 import dvr_fip_ns +from neutron.agent.l3 import dvr_local_router from neutron.agent.l3 import dvr_snat_ns from neutron.agent.l3 import namespaces from neutron.agent.linux import ip_lib @@ -1276,6 +1279,40 @@ class TestDvrRouter(framework.L3AgentTestFramework): self._assert_no_ip_addresses_on_interface(namespace, ex_gw_port_name) + @mock.patch.object(dvr_local_router.DvrLocalRouter, 'connect_rtr_2_fip') + @mock.patch.object( + dvr_ha_router.DvrEdgeHaRouter, '_get_centralized_fip_cidr_set') + def test_dvr_ha_router_with_centralized_fip_calls_keepalived_cidr( + self, connect_rtr_2_fip_mock, fip_cidr_centralized_mock): + + self._setup_dvr_ha_agents() + self._setup_dvr_ha_bridges() + + router1 = self._create_dvr_ha_router( + self.agent, enable_gw=True, + enable_centralized_fip=True, + snat_bound_fip=True) + self.assertTrue(fip_cidr_centralized_mock.called) + restarted_agent = neutron_l3_agent.L3NATAgentWithStateReport( + self.agent.host, self.agent.conf) + self.manage_router(restarted_agent, router1.router) + self.assertTrue(fip_cidr_centralized_mock.called) + + @mock.patch.object(dvr_local_router.DvrLocalRouter, 'connect_rtr_2_fip') + @mock.patch.object( + dvr_edge_router.DvrEdgeRouter, '_get_centralized_fip_cidr_set') + def test_dvr_router_with_centralized_fip_calls_keepalived_cidr( + self, connect_rtr_2_fip_mock, fip_cidr_centralized_mock): + + router_info = self.generate_dvr_router_info( + enable_gw=True, enable_centralized_fip=True, snat_bound_fip=True) + router1 = self.manage_router(self.agent, router_info) + self.assertTrue(fip_cidr_centralized_mock.called) + restarted_agent = neutron_l3_agent.L3NATAgentWithStateReport( + self.agent.host, self.agent.conf) + self.manage_router(restarted_agent, router1.router) + self.assertTrue(fip_cidr_centralized_mock.called) + def _test_dvr_ha_router_failover_with_gw_and_fip(self, enable_gw, enable_centralized_fip, snat_bound_fip):