From 64028a389ff904f15e471b44bd5b3979c5db2cd2 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 --- 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 e64f7d485af..d231c6010eb 100644 --- a/neutron/agent/l3/dvr_edge_ha_router.py +++ b/neutron/agent/l3/dvr_edge_ha_router.py @@ -73,6 +73,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 47123b36b5f..b64314a6f22 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 @@ -1277,6 +1280,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):