diff --git a/scripts/caclmgrd b/scripts/caclmgrd index 90aff6a0..30b166e7 100755 --- a/scripts/caclmgrd +++ b/scripts/caclmgrd @@ -581,6 +581,7 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): iptables_cmds.append(self.iptables_cmd_ns_prefix[namespace] + ['ip6tables', '-P', 'OUTPUT', 'ACCEPT']) iptables_cmds.append(self.iptables_cmd_ns_prefix[namespace] + ['ip6tables', '-F']) iptables_cmds.append(self.iptables_cmd_ns_prefix[namespace] + ['ip6tables', '-X']) + iptables_cmds.append(self.iptables_cmd_ns_prefix[namespace] + ['ip6tables', '-t', 'raw', '-F']) # Add iptables/ip6tables commands to allow all traffic from localhost iptables_cmds.append(self.iptables_cmd_ns_prefix[namespace] + ['iptables', '-A', 'INPUT', '-s', '127.0.0.1', '-i', 'lo', '-j', 'ACCEPT']) @@ -643,6 +644,10 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): iptables_cmds.append(self.iptables_cmd_ns_prefix[namespace] + ['iptables', '-A', 'INPUT', '-p', 'tcp', '--dport', '179', '-j', 'ACCEPT']) iptables_cmds.append(self.iptables_cmd_ns_prefix[namespace] + ['ip6tables', '-A', 'INPUT', '-p', 'tcp', '--dport', '179', '-j', 'ACCEPT']) + # Add ip6tables commands to disable connection tracking for icmpv6 traffic + iptables_cmds.append(self.iptables_cmd_ns_prefix[namespace] + ['ip6tables', '-t', 'raw', '-A', 'PREROUTING', '-p', 'ipv6-icmp', '-j', 'NOTRACK']) + iptables_cmds.append(self.iptables_cmd_ns_prefix[namespace] + ['ip6tables', '-t', 'raw', '-A', 'OUTPUT', '-p', 'ipv6-icmp', '-j', 'NOTRACK']) + # Get current ACL tables and rules from Config DB self._tables_db_info = config_db_connector.get_table(self.ACL_TABLE) diff --git a/setup.py b/setup.py index 397cf25a..9cb0ff39 100644 --- a/setup.py +++ b/setup.py @@ -48,6 +48,7 @@ 'systemd-python', 'Jinja2>=2.10', 'PyGObject', + 'pycairo==1.26.1', 'psutil' ] + sonic_dependencies, setup_requires = [ diff --git a/tests/caclmgrd/caclmgrd_conntrack_test.py b/tests/caclmgrd/caclmgrd_conntrack_test.py new file mode 100644 index 00000000..2ada47de --- /dev/null +++ b/tests/caclmgrd/caclmgrd_conntrack_test.py @@ -0,0 +1,48 @@ +import os +import sys + +from swsscommon import swsscommon +from parameterized import parameterized +from unittest import TestCase, mock +from pyfakefs.fake_filesystem_unittest import patchfs +from sonic_py_common.general import load_module_from_source + +from .test_icmpv6_ct_rule_vectors import CACLMGRD_ICMPV6_CT_RULE_TEST_VECTOR +from tests.common.mock_configdb import MockConfigDb + +DBCONFIG_PATH = '/var/run/redis/sonic-db/database_config.json' + + +class TestCaclmgrdConntrack(TestCase): + """ + Test to verify that ip6tables rules to not track icmpv6 packets exist + """ + def setUp(self): + swsscommon.ConfigDBConnector = MockConfigDb + test_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + modules_path = os.path.dirname(test_path) + scripts_path = os.path.join(modules_path, "scripts") + sys.path.insert(0, modules_path) + caclmgrd_path = os.path.join(scripts_path, 'caclmgrd') + self.caclmgrd = load_module_from_source('caclmgrd', caclmgrd_path) + self.icmpv6_ct_prerouting_rule = ('ip6tables', '-t', 'raw', '-A', 'PREROUTING', '-p', 'ipv6-icmp', '-j', 'NOTRACK') + self.icmpv6_ct_output_rule = ('ip6tables', '-t', 'raw', '-A', 'OUTPUT', '-p', 'ipv6-icmp', '-j', 'NOTRACK') + + @parameterized.expand(CACLMGRD_ICMPV6_CT_RULE_TEST_VECTOR) + @patchfs + def test_caclmgrd_icmpv6_ct_rules(self, test_name, test_data, fs): + if not os.path.exists(DBCONFIG_PATH): + fs.create_file(DBCONFIG_PATH) # fake database_config.json + + MockConfigDb.set_config_db(test_data["config_db"]) + self.caclmgrd.ControlPlaneAclManager.get_namespace_mgmt_ip = mock.MagicMock() + self.caclmgrd.ControlPlaneAclManager.get_namespace_mgmt_ipv6 = mock.MagicMock() + self.caclmgrd.ControlPlaneAclManager.generate_block_ip2me_traffic_iptables_commands = mock.MagicMock(return_value=[]) + self.caclmgrd.ControlPlaneAclManager.get_chain_list = mock.MagicMock(return_value=["INPUT", "FORWARD", "OUTPUT"]) + self.caclmgrd.ControlPlaneAclManager.get_chassis_midplane_interface_ip = mock.MagicMock(return_value='') + caclmgrd_daemon = self.caclmgrd.ControlPlaneAclManager("caclmgrd") + + ip6tables_rules_ret, _ = caclmgrd_daemon.get_acl_rules_and_translate_to_iptables_commands('', MockConfigDb()) + ip6tables_rules_ret = [tuple(i) for i in ip6tables_rules_ret] + self.assertIn(self.icmpv6_ct_prerouting_rule, ip6tables_rules_ret) + self.assertIn(self.icmpv6_ct_output_rule, ip6tables_rules_ret) diff --git a/tests/caclmgrd/test_icmpv6_ct_rule_vectors.py b/tests/caclmgrd/test_icmpv6_ct_rule_vectors.py new file mode 100644 index 00000000..011a8b88 --- /dev/null +++ b/tests/caclmgrd/test_icmpv6_ct_rule_vectors.py @@ -0,0 +1,24 @@ +from unittest.mock import call +import subprocess + +""" + caclmgrd icmpv6 conntrack rules test vector +""" +CACLMGRD_ICMPV6_CT_RULE_TEST_VECTOR = [ + [ + "ICMPv6 conntrack rules test", + { + "config_db": { + "DEVICE_METADATA": { + "localhost": { + "subtype": "DualToR", + "type": "ToRRouter", + } + }, + "FEATURE": {}, + }, + "return": [ + ], + } + ] +]