DVR: Cleanup the stale snat redirect rules in router namespace
After the stale snat namespace is deleted the snat redirect rules
in router namespace should be cleaned.
Here we are basically reading the ip rule from the router namespace
and just cleaning up all the snat redirect rules leaving the default
ones untouched.
Closes-Bug: #1599287
(cherry picked from commit 34e51cad42
)
Conflicts:
neutron/tests/functional/agent/l3/test_dvr_router.py
Change-Id: Ic505a46e56d9e950bd36a1596d3f1adfb5ef5577
This commit is contained in:
parent
9cd2dfceae
commit
bce58c6410
|
@ -292,6 +292,32 @@ class DvrLocalRouter(dvr_router_base.DvrRouterBase):
|
|||
except exceptions.DeviceNotFoundError:
|
||||
pass
|
||||
|
||||
def _stale_ip_rule_cleanup(self, ns_ipr, ns_ipd, ip_version):
|
||||
ip_rules_list = ns_ipr.rule.list_rules(ip_version)
|
||||
snat_table_list = []
|
||||
for ip_rule in ip_rules_list:
|
||||
snat_table = ip_rule['table']
|
||||
priority = ip_rule['priority']
|
||||
if snat_table in ['local', 'default', 'main']:
|
||||
continue
|
||||
if (ip_version == l3_constants.IP_VERSION_4 and
|
||||
snat_table in range(dvr_fip_ns.FIP_PR_START,
|
||||
dvr_fip_ns.FIP_PR_END)):
|
||||
continue
|
||||
gateway_cidr = ip_rule['from']
|
||||
ns_ipr.rule.delete(ip=gateway_cidr,
|
||||
table=snat_table,
|
||||
priority=priority)
|
||||
snat_table_list.append(snat_table)
|
||||
for tb in snat_table_list:
|
||||
ns_ipd.route.flush(ip_version, table=tb)
|
||||
|
||||
def gateway_redirect_cleanup(self, rtr_interface):
|
||||
ns_ipr = ip_lib.IPRule(namespace=self.ns_name)
|
||||
ns_ipd = ip_lib.IPDevice(rtr_interface, namespace=self.ns_name)
|
||||
self._stale_ip_rule_cleanup(ns_ipr, ns_ipd, l3_constants.IP_VERSION_4)
|
||||
self._stale_ip_rule_cleanup(ns_ipr, ns_ipd, l3_constants.IP_VERSION_6)
|
||||
|
||||
def _snat_redirect_modify(self, gateway, sn_port, sn_int, is_add):
|
||||
"""Adds or removes rules and routes for SNAT redirection."""
|
||||
try:
|
||||
|
|
|
@ -197,6 +197,9 @@ class RouterInfo(object):
|
|||
def add_floating_ip(self, fip, interface_name, device):
|
||||
raise NotImplementedError()
|
||||
|
||||
def gateway_redirect_cleanup(self, rtr_interface):
|
||||
pass
|
||||
|
||||
def remove_floating_ip(self, device, ip_cidr):
|
||||
device.delete_addr_and_conntrack_state(ip_cidr)
|
||||
|
||||
|
@ -599,6 +602,10 @@ class RouterInfo(object):
|
|||
elif not ex_gw_port and self.ex_gw_port:
|
||||
self.external_gateway_removed(self.ex_gw_port, interface_name)
|
||||
pd.remove_gw_interface(self.router['id'])
|
||||
elif not ex_gw_port and not self.ex_gw_port:
|
||||
for p in self.internal_ports:
|
||||
interface_name = self.get_internal_device_name(p['id'])
|
||||
self.gateway_redirect_cleanup(interface_name)
|
||||
|
||||
existing_devices = self._get_existing_devices()
|
||||
stale_devs = [dev for dev in existing_devices
|
||||
|
|
|
@ -1700,6 +1700,33 @@ class TestDvrRouter(L3AgentTestFramework):
|
|||
self.assertFalse(sg_device)
|
||||
self.assertTrue(qg_device)
|
||||
|
||||
def test_dvr_router_gateway_redirect_cleanup_on_agent_restart(self):
|
||||
"""Test to validate the router namespace gateway redirect rule cleanup.
|
||||
|
||||
This test checks for the non existence of the gateway redirect
|
||||
rules in the router namespace after the agent restarts while the
|
||||
gateway is removed for the router.
|
||||
"""
|
||||
self.agent.conf.agent_mode = 'dvr_snat'
|
||||
router_info = self.generate_dvr_router_info()
|
||||
router1 = self.manage_router(self.agent, router_info)
|
||||
self._assert_snat_namespace_exists(router1)
|
||||
self.assertTrue(self._namespace_exists(router1.ns_name))
|
||||
restarted_agent = neutron_l3_agent.L3NATAgentWithStateReport(
|
||||
self.agent.host, self.agent.conf)
|
||||
router1.router['gw_port'] = ""
|
||||
router1.router['gw_port_host'] = ""
|
||||
router1.router['external_gateway_info'] = ""
|
||||
restarted_router = self.manage_router(restarted_agent, router1.router)
|
||||
self.assertTrue(self._namespace_exists(restarted_router.ns_name))
|
||||
ns_ipr = ip_lib.IPRule(namespace=router1.ns_name)
|
||||
ip4_rules_list = ns_ipr.rule.list_rules(l3_constants.IP_VERSION_4)
|
||||
ip6_rules_list = ns_ipr.rule.list_rules(l3_constants.IP_VERSION_6)
|
||||
# Just make sure the basic set of rules are there in the router
|
||||
# namespace
|
||||
self.assertEqual(3, len(ip4_rules_list))
|
||||
self.assertEqual(2, len(ip6_rules_list))
|
||||
|
||||
def _assert_fip_namespace_deleted(self, ext_gateway_port):
|
||||
ext_net_id = ext_gateway_port['network_id']
|
||||
self.agent.fipnamespace_delete_on_ext_net(
|
||||
|
|
Loading…
Reference in New Issue