From 51f0ef04375e4fa931e133b762e96c0cbfadd128 Mon Sep 17 00:00:00 2001 From: Nicolas Fort Date: Mon, 6 May 2024 14:58:56 +0000 Subject: [PATCH] T6265: firewall: allow only ethernet interfaces to flowtables. --- interface-definitions/firewall.xml.in | 7 ++- smoketest/scripts/cli/test_firewall.py | 4 +- src/migration-scripts/firewall/15-to-16 | 67 +++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 3 deletions(-) create mode 100755 src/migration-scripts/firewall/15-to-16 diff --git a/interface-definitions/firewall.xml.in b/interface-definitions/firewall.xml.in index 24e63c5ecc..32211ce3bf 100644 --- a/interface-definitions/firewall.xml.in +++ b/interface-definitions/firewall.xml.in @@ -20,8 +20,13 @@ Interfaces to use this flowtable - + interfaces ethernet + interfaces loopback + + ^(eth\d+|lo)$ + + Only ethernet and loopback interfaces are allowed in flowtables diff --git a/smoketest/scripts/cli/test_firewall.py b/smoketest/scripts/cli/test_firewall.py index c475627142..3f01e43ef2 100755 --- a/smoketest/scripts/cli/test_firewall.py +++ b/smoketest/scripts/cli/test_firewall.py @@ -802,7 +802,7 @@ def test_zone_basic(self): def test_flow_offload(self): self.cli_set(['interfaces', 'ethernet', 'eth0', 'vif', '10']) - self.cli_set(['firewall', 'flowtable', 'smoketest', 'interface', 'eth0.10']) + self.cli_set(['firewall', 'flowtable', 'smoketest', 'interface', 'eth0']) self.cli_set(['firewall', 'flowtable', 'smoketest', 'offload', 'hardware']) # QEMU virtual NIC does not support hw-tc-offload @@ -828,7 +828,7 @@ def test_flow_offload(self): nftables_search = [ ['flowtable VYOS_FLOWTABLE_smoketest'], ['hook ingress priority filter'], - ['devices = { eth0.10 }'], + ['devices = { eth0 }'], ['ct state { established, related }', 'meta l4proto { tcp, udp }', 'flow add @VYOS_FLOWTABLE_smoketest'], ] diff --git a/src/migration-scripts/firewall/15-to-16 b/src/migration-scripts/firewall/15-to-16 new file mode 100755 index 0000000000..ee4f2cb8ef --- /dev/null +++ b/src/migration-scripts/firewall/15-to-16 @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2022-2024 VyOS maintainers and contributors +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or later as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# T6265: allow only ethernet and loopback interface on firewall flowtables +# If non ethernet|lo interface found in flowtables, remove it +# If after removing flowtable is empty, add lo interface in order to keep it + +from sys import argv +from sys import exit + +from vyos.configtree import ConfigTree + +if len(argv) < 2: + print("Must specify file name!") + exit(1) + +file_name = argv[1] + +with open(file_name, 'r') as f: + config_file = f.read() + +config = ConfigTree(config_file) +base = ['firewall', 'flowtable'] + +if not config.exists(base): + # Nothing to do + exit(0) + +valid_str = ['eth','lo'] +invalid_arguments = ['.'] + +for ft in config.list_nodes(base): + interfaces = config.return_values(base + [ft, 'interface']) + # Remove all node, and only add what is allowed + config.delete(base + [ft, 'interface']) + for iface in interfaces: + for aux in valid_str: + if aux in iface: + ## We may need to re-add it + for inv_arg in invalid_arguments: + if inv_arg not in iface: + # We need to re-add it + config.set(base + [ft, 'interface'], value=iface, replace=False) + + # Now we need to check that >ft interface> is not empty + if 'interface' not in config.list_nodes(base + [ft]): + config.set(base + [ft, 'interface'], value='lo') + +try: + with open(file_name, 'w') as f: + f.write(config.to_string()) +except OSError as e: + print("Failed to save the modified config: {}".format(e)) + exit(1) \ No newline at end of file