Browse Source

Fix deletion of rfp interfaces when router is re-enabled

1. When dvr router is disabled and enabled back, the rfp
interfaces are deleted on the nodes without snat-* namespace.
This is due to creation of snat namespace during router
initialization stage on all the nodes. At later stages, since
the gw_port_host is not bounded on this node, external gateway
is removed which triggers removal of rfp interfaces and snat
namespace.
Create snat namespace only on the nodes where gw_port_host is
bounded.

2. In case of DVR SNAT, when the l3 agent is rescheduled to
another node, the rfp interfaces on qrouter-* namespace are
removed. Instead of calling external_gateway_removed() which
further deletes the rfp interfaces, the qg-, sg- interfaces
need to be unplugged and snat namespace need to be deleted.

Closes-Bug: #1894843
Change-Id: Ic35c2f9bceacec8eeba67a2b1ea0cd0b0ffc72fe
(cherry picked from commit 393d484e07)
changes/17/777317/1
Hemanth Nakkina 6 months ago
committed by Hemanth N
parent
commit
4360603d8b
  1. 10
      neutron/agent/l3/dvr_edge_router.py
  2. 48
      neutron/tests/functional/agent/l3/test_dvr_router.py

10
neutron/agent/l3/dvr_edge_router.py

@ -71,8 +71,10 @@ class DvrEdgeRouter(dvr_local_router.DvrLocalRouter):
if self.snat_namespace.exists():
LOG.debug("SNAT was rescheduled to host %s. Clearing snat "
"namespace.", self.router.get('gw_port_host'))
return self.external_gateway_removed(
ex_gw_port, interface_name)
self.driver.unplug(interface_name,
namespace=self.snat_namespace.name,
prefix=router.EXTERNAL_DEV_PREFIX)
self.snat_namespace.delete()
return
if not self.snat_namespace.exists():
@ -178,8 +180,8 @@ class DvrEdgeRouter(dvr_local_router.DvrLocalRouter):
# TODO(mlavalle): in the near future, this method should contain the
# code in the L3 agent that creates a gateway for a dvr. The first step
# is to move the creation of the snat namespace here
self.snat_namespace.create()
return self.snat_namespace
if self._is_this_snat_host():
self.snat_namespace.create()
def _get_snat_int_device_name(self, port_id):
long_name = lib_constants.SNAT_INT_DEV_PREFIX + port_id

48
neutron/tests/functional/agent/l3/test_dvr_router.py

@ -782,6 +782,54 @@ class TestDvrRouter(DvrRouterTestFramework, framework.L3AgentTestFramework):
self._assert_iptables_rules_exist(
iptables_mgr, 'nat', expected_rules)
def test_dvr_router_fip_associations_exist_when_router_reenabled(self):
"""Test to validate the fip associations when router is re-enabled.
This test validates the fip associations when the router is disabled
and enabled back again. This test is specifically for the host where
snat namespace is not created or gateway port is binded on other host.
"""
self.agent.conf.agent_mode = 'dvr_snat'
router_info = self.generate_dvr_router_info(enable_snat=True)
# Ensure agent does not create snat namespace by changing gw_port_host
router_info['gw_port_host'] = 'agent2'
router_info_copy = copy.deepcopy(router_info)
router1 = self.manage_router(self.agent, router_info)
fip_ns_name = router1.fip_ns.name
self.assertTrue(self._namespace_exists(router1.fip_ns.name))
# Simulate disable router
self.agent._safe_router_removed(router1.router['id'])
self.assertFalse(self._namespace_exists(router1.ns_name))
self.assertTrue(self._namespace_exists(fip_ns_name))
# Simulated enable router
router_updated = self.manage_router(self.agent, router_info_copy)
self._assert_dvr_floating_ips(router_updated)
def test_dvr_router_fip_associations_exist_when_snat_removed(self):
"""Test to validate the fip associations when snat is removed.
This test validates the fip associations when the snat is removed from
the agent. The fip associations should exist when the snat is moved to
another l3 agent.
"""
self.agent.conf.agent_mode = 'dvr_snat'
router_info = self.generate_dvr_router_info(enable_snat=True)
router_info_copy = copy.deepcopy(router_info)
router1 = self.manage_router(self.agent, router_info)
# Remove gateway port host and the binding host_id to simulate
# removal of snat from l3 agent
router_info_copy['gw_port_host'] = ''
router_info_copy['gw_port']['binding:host_id'] = ''
router_info_copy['gw_port']['binding:vif_type'] = 'unbound'
router_info_copy['gw_port']['binding:vif_details'] = {}
self.agent._process_updated_router(router_info_copy)
router_updated = self.agent.router_info[router1.router['id']]
self._assert_dvr_floating_ips(router_updated)
def test_dvr_router_with_ha_for_fip_disassociation(self):
"""Test to validate the fip rules are deleted in dvr_snat_ha router.

Loading…
Cancel
Save