From b01e0c2aa98866df9c25e20a66c02fccccdc7885 Mon Sep 17 00:00:00 2001 From: Slawek Kaplonski Date: Wed, 27 Nov 2019 10:44:19 +0100 Subject: [PATCH] [OVS FW] Clean port rules if port not found in ovsdb During e.g. migration or shelve of VM it may happend that port update event will be send to the ovs agent and in the almost the same time, port will be removed from br-int. In such case during update_port_filter method openvswitch firewall driver will not find port in br-int, and it will do nothing with it. That will lead to leftover rules for this port in br-int. So this patch adds calling remove_port_filter() method if port was not found in br-int. Just to be sure that there is no any leftovers from the port in br-int anymore. Change-Id: I06036ce5fe15d91aa440dc340a70dd27ae078c53 Closes-Bug: #1850557 --- neutron/agent/linux/openvswitch_firewall/firewall.py | 3 +++ .../agent/linux/openvswitch_firewall/test_firewall.py | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/neutron/agent/linux/openvswitch_firewall/firewall.py b/neutron/agent/linux/openvswitch_firewall/firewall.py index 9977861a95f..e816cce0041 100644 --- a/neutron/agent/linux/openvswitch_firewall/firewall.py +++ b/neutron/agent/linux/openvswitch_firewall/firewall.py @@ -630,6 +630,9 @@ class OVSFirewallDriver(firewall.FirewallDriver): LOG.info("port %(port_id)s does not exist in ovsdb: %(err)s.", {'port_id': port['device'], 'err': not_found_error}) + # If port doesn't exist in ovsdb, lets ensure that there are no + # leftovers + self.remove_port_filter(port) except exceptions.OVSFWTagNotFound as tag_not_found: LOG.info("Tag was not found for port %(port_id)s: %(err)s.", {'port_id': port['device'], diff --git a/neutron/tests/unit/agent/linux/openvswitch_firewall/test_firewall.py b/neutron/tests/unit/agent/linux/openvswitch_firewall/test_firewall.py index 5b08b00b728..1542f51f35b 100644 --- a/neutron/tests/unit/agent/linux/openvswitch_firewall/test_firewall.py +++ b/neutron/tests/unit/agent/linux/openvswitch_firewall/test_firewall.py @@ -731,6 +731,16 @@ class TestOVSFirewallDriver(base.BaseTestCase): self.firewall.update_port_filter(port_dict) self.assertEqual(2, self.mock_bridge.apply_flows.call_count) + def test_update_port_filter_clean_when_port_not_found(self): + """Check flows are cleaned if port is not found in the bridge.""" + port_dict = {'device': 'port-id', + 'security_groups': [1]} + self._prepare_security_group() + self.firewall.prepare_port_filter(port_dict) + self.mock_bridge.br.get_vif_port_by_id.return_value = None + self.firewall.update_port_filter(port_dict) + self.assertTrue(self.mock_bridge.br.delete_flows.called) + def test_remove_port_filter(self): port_dict = {'device': 'port-id', 'security_groups': [1]}