Clean port forwarding cache when router is DOWN

Port forwarding L3 agent extension needs to clean cache when
router is DOWN, otherwise the port forwarding extension will
skip all objects processing when router is UP again, because
the cache is hitting.

This patch addresses this issue.

Change-Id: Idd65f1eda020ada9a76c39904efa8d55680d9e6b
Closes-bug: #1917393
(cherry picked from commit 0582146708)
This commit is contained in:
LIU Yulong 2021-03-02 11:26:34 +08:00 committed by liuyulong
parent 19b42a3186
commit 64abee5aa2
2 changed files with 41 additions and 1 deletions

View File

@ -100,6 +100,14 @@ class RouterFipPortForwardingMapping(object):
old_pf = self.managed_port_forwardings.get(new_pf.id)
return old_pf != new_pf
@lockutils.synchronized('port-forwarding-cache')
def clean_port_forwardings_by_router_id(self, router_id):
router_fips = self.router_fip_mapping.pop(router_id, [])
for fip_id in router_fips:
pf_ids = self.fip_port_forwarding.pop(fip_id, [])
for pf_id in pf_ids:
self.managed_port_forwardings.pop(pf_id, None)
class PortForwardingAgentExtension(l3_extension.L3AgentExtension):
SUPPORTED_RESOURCE_TYPES = [resources.PORTFORWARDING]
@ -458,7 +466,7 @@ class PortForwardingAgentExtension(l3_extension.L3AgentExtension):
:param context: RPC context.
:param data: Router data.
"""
pass
self.mapping.clean_port_forwardings_by_router_id(data['id'])
def ha_state_change(self, context, data):
pass

View File

@ -282,6 +282,38 @@ class FipPortForwardingExtensionTestCase(PortForwardingExtensionBaseTestCase):
lib_const.FLOATINGIP_STATUS_DOWN}
mock_send_fip_status.assert_called_once_with(mock.ANY, fip_status)
@mock.patch.object(pf.PortForwardingAgentExtension,
'_sending_port_forwarding_fip_status')
@mock.patch.object(iptables_manager.IptablesTable, 'add_rule')
@mock.patch.object(iptables_manager.IptablesTable, 'add_chain')
@mock.patch.object(l3router.RouterInfo, 'add_floating_ip')
def test_add_delete_router(self, mock_add_fip,
mock_add_chain, mock_add_rule,
mock_send_fip_status):
# simulate the router add and already there is a port forwarding
# resource association.
mock_add_fip.return_value = lib_const.FLOATINGIP_STATUS_ACTIVE
self.fip_pf_ext.add_router(self.context, self.router)
self._assert_called_iptables_process(
mock_add_chain, mock_add_rule, mock_add_fip, mock_send_fip_status,
target_obj=self.portforwarding1)
router_fip_ids = self.fip_pf_ext.mapping.router_fip_mapping.get(
self.router['id'])
self.assertIsNotNone(router_fip_ids)
for fip_id in router_fip_ids:
pf_ids = self.fip_pf_ext.mapping.fip_port_forwarding.get(fip_id)
self.assertIsNotNone(pf_ids)
for pf_id in pf_ids:
pf = self.fip_pf_ext.mapping.managed_port_forwardings.get(
pf_id)
self.assertIsNotNone(pf)
self.fip_pf_ext.delete_router(self.context, self.router)
self.assertIsNone(
self.fip_pf_ext.mapping.router_fip_mapping.get(self.router['id']))
def test_check_if_need_process_no_snat_ns(self):
ex_gw_port = {'id': _uuid()}
router_id = _uuid()