[OVN] Allow logging all traffic related to an ACL

Before this patch, we would only get logged the client to server side of
the communication. The OVN allow-related ACL option was implemented [0]
so as to be able to log also the packets that are going from server to
client. This patch implements the addition of that feature in Neutron
and needs OVN version 22.03 or updated 21.12.

[0] https://patchwork.ozlabs.org/project/ovn/patch/20220201141118.1846390-1-mmichels@redhat.com/

Closes-Bug: #2003706
Change-Id: I72d061c333f53e07f6feedec032e2c0b06a61248
Signed-off-by: Elvira García <egarciar@redhat.com>
This commit is contained in:
Elvira García 2023-01-19 14:48:23 +01:00
parent f50dbac487
commit f7e31b4c05
4 changed files with 48 additions and 13 deletions

View File

@ -11,6 +11,7 @@
# under the License.
from collections import namedtuple
import random
from neutron_lib.api.definitions import portbindings
from neutron_lib.callbacks import resources
@ -38,6 +39,7 @@ DRIVER = None
log_cfg.register_log_driver_opts()
MAX_INT_LABEL = 2**32
SUPPORTED_LOGGING_TYPES = [log_const.SECURITY_GROUP]
@ -169,13 +171,20 @@ class OVNDriver(base.DriverBase):
if log_name:
if acl.name and acl.name[0] != log_name:
continue
columns = {
'log': False,
'meter': [],
'name': [],
'severity': []
}
# TODO(egarciar): There wont be a need to check if label exists
# once minimum version for OVN is >= 22.03
if hasattr(acl, 'label'):
columns['label'] = 0
ovn_txn.add(self.ovn_nb.db_remove(
"ACL", acl_uuid, 'options', 'log-related'))
ovn_txn.add(self.ovn_nb.db_set(
"ACL", acl_uuid,
("log", False),
("meter", []),
("name", []),
("severity", [])
))
"ACL", acl_uuid, *columns.items()))
acl_changes += 1
msg = "Cleared %d, Not found %d (out of %d visited) ACLs"
if log_name:
@ -191,13 +200,20 @@ class OVNDriver(base.DriverBase):
# skip acls used by a different network log
if acl.name and acl.name[0] != log_name:
continue
columns = {
'log': acl.action in actions_enabled,
'meter': self.meter_name,
'name': log_name,
'severity': "info"
}
# TODO(egarciar): There wont be a need to check if label exists
# once minimum version for OVN is >= 22.03
if hasattr(acl, "label"):
# Label needs to be an unsigned 32 bit number and not 0.
columns["label"] = random.randrange(1, MAX_INT_LABEL)
columns["options"] = {'log-related': "true"}
ovn_txn.add(self.ovn_nb.db_set(
"ACL", acl_uuid,
("log", acl.action in actions_enabled),
("meter", self.meter_name),
("name", log_name),
("severity", "info")
))
"ACL", acl_uuid, *columns.items()))
acl_changes += 1
LOG.info("Set %d (out of %d visited) ACLs for network log %s",
acl_changes, acl_visits, log_name)

View File

@ -151,6 +151,16 @@ class LogApiTestCaseComplex(LogApiTestCaseBase):
acl = self._find_security_group_rule_row_by_id(sgr)
self.assertIsNotNone(acl)
self.assertEqual(is_enabled, acl.log)
if hasattr(acl, "label"):
# Here we compare if there is a name because the log can be
# disabled but disabling a log would not take out the properties
# attached to it.
if acl.name:
self.assertNotEqual(0, acl.label)
self.assertEqual("true", acl.options.get("log-related"))
else:
self.assertEqual(0, acl.label)
self.assertIsNone(acl.options.get("log-related"))
return acl
def _check_acl_log_drop(self, is_enabled=True):

View File

@ -278,7 +278,10 @@ class TestOVNDriver(base.BaseTestCase):
self.assertEqual(len(pg_dict["acls"]), info_args[1])
self.assertEqual(len(pg_dict["acls"]) - 2, info_args[2])
self.assertEqual(len(pg_dict["acls"]), info_args[3])
self.assertEqual(len(pg_dict["acls"]), self._nb_ovn.db_set.call_count)
self.assertEqual(len(pg_dict["acls"]),
self._nb_ovn.db_set.call_count)
self.assertEqual(len(pg_dict["acls"]),
self._nb_ovn.db_remove.call_count)
@mock.patch.object(ovn_driver.LOG, 'info')
def test__remove_acls_log_missing_acls(self, m_info):

View File

@ -0,0 +1,6 @@
---
fixes:
- |
Neutron can record full connection using log-related feature introduced in
OVN 21.12.
For more info see `bug LP#<https://bugs.launchpad.net/neutron/+bug/2003706>`