ovs-fw: Handle only known trusted ports
Similarly to filtered ports this patch caches so called trusted ports to avoid processing in case of unknown port is passed down to firewall driver. The cached ofport is used for removal as the cache reflects currently installed flows. The patch also catches exception caused by inconsistency coming from ovsdb. Closes-bug: #1707339 Change-Id: I15cdb28072835fcb8c37ae4b56fc8754375a807c
This commit is contained in:
parent
927edca4fd
commit
1d80c960f6
|
@ -145,6 +145,8 @@ class SGPortMap(object):
|
|||
def __init__(self):
|
||||
self.ports = {}
|
||||
self.sec_groups = {}
|
||||
# Maps port_id to ofport number
|
||||
self.unfiltered = {}
|
||||
|
||||
def get_sg(self, sg_id):
|
||||
return self.sec_groups.get(sg_id, None)
|
||||
|
@ -615,12 +617,19 @@ class OVSFirewallDriver(firewall.FirewallDriver):
|
|||
)
|
||||
|
||||
def _initialize_egress_no_port_security(self, port_id):
|
||||
ovs_port = self.get_ovs_port(port_id)
|
||||
try:
|
||||
ovs_port = self.get_ovs_port(port_id)
|
||||
vlan_tag = self._get_port_vlan_tag(ovs_port.port_name)
|
||||
except exceptions.OVSFWTagNotFound:
|
||||
# It's a patch port, don't set anything
|
||||
return
|
||||
except exceptions.OVSFWPortNotFound as not_found_e:
|
||||
LOG.error("Initializing unfiltered port %(port_id)s that does not "
|
||||
"exist in ovsdb: %(err)s.",
|
||||
{'port_id': port_id,
|
||||
'err': not_found_e})
|
||||
return
|
||||
self.sg_port_map.unfiltered[port_id] = ovs_port.ofport
|
||||
self._add_flow(
|
||||
table=ovs_consts.TRANSIENT_TABLE,
|
||||
priority=100,
|
||||
|
@ -642,21 +651,20 @@ class OVSFirewallDriver(firewall.FirewallDriver):
|
|||
)
|
||||
|
||||
def _remove_egress_no_port_security(self, port_id):
|
||||
ovs_port = self.get_ovs_port(port_id)
|
||||
try:
|
||||
# Test if it's a patch port
|
||||
self._get_port_vlan_tag(ovs_port.port_name)
|
||||
except exceptions.OVSFWTagNotFound:
|
||||
# It's a patch port, don't do anything
|
||||
ofport = self.sg_port_map.unfiltered[port_id]
|
||||
except KeyError:
|
||||
LOG.debug("Port %s is not handled by the firewall.", port_id)
|
||||
return
|
||||
self._delete_flows(
|
||||
table=ovs_consts.TRANSIENT_TABLE,
|
||||
in_port=ovs_port.ofport
|
||||
in_port=ofport
|
||||
)
|
||||
self._delete_flows(
|
||||
table=ovs_consts.ACCEPT_OR_INGRESS_TABLE,
|
||||
reg_port=ovs_port.ofport
|
||||
reg_port=ofport
|
||||
)
|
||||
del self.sg_port_map.unfiltered[port_id]
|
||||
|
||||
def _initialize_egress(self, port):
|
||||
"""Identify egress traffic and send it to egress base"""
|
||||
|
|
|
@ -639,6 +639,7 @@ class TestOVSFirewallDriver(base.BaseTestCase):
|
|||
|
||||
def test__remove_egress_no_port_security_deletes_flow(self):
|
||||
self.mock_bridge.br.db_get_val.return_value = {'tag': TESTING_VLAN_TAG}
|
||||
self.firewall.sg_port_map.unfiltered['port_id'] = 1
|
||||
self.firewall._remove_egress_no_port_security('port_id')
|
||||
expected_call = mock.call(
|
||||
table=ovs_consts.TRANSIENT_TABLE,
|
||||
|
@ -651,3 +652,23 @@ class TestOVSFirewallDriver(base.BaseTestCase):
|
|||
self.mock_bridge.br.db_get_val.return_value = {}
|
||||
self.firewall._remove_egress_no_port_security('port_id')
|
||||
self.assertFalse(self.mock_bridge.br.delete_flows.called)
|
||||
|
||||
def test_process_trusted_ports_caches_port_id(self):
|
||||
self.firewall.process_trusted_ports(['port_id'])
|
||||
self.assertIn('port_id', self.firewall.sg_port_map.unfiltered)
|
||||
|
||||
def test_process_trusted_ports_port_not_found(self):
|
||||
"""Check that exception is not propagated outside."""
|
||||
self.mock_bridge.br.get_vif_port_by_id.return_value = None
|
||||
self.firewall.process_trusted_ports(['port_id'])
|
||||
# Processing should have failed so port is not cached
|
||||
self.assertNotIn('port_id', self.firewall.sg_port_map.unfiltered)
|
||||
|
||||
def test_remove_trusted_ports_clears_cached_port_id(self):
|
||||
self.firewall.sg_port_map.unfiltered['port_id'] = 1
|
||||
self.firewall.remove_trusted_ports(['port_id'])
|
||||
self.assertNotIn('port_id', self.firewall.sg_port_map.unfiltered)
|
||||
|
||||
def test_remove_trusted_ports_not_managed_port(self):
|
||||
"""Check that exception is not propagated outside."""
|
||||
self.firewall.remove_trusted_ports(['port_id'])
|
||||
|
|
Loading…
Reference in New Issue