From 081fc4466f200bf358fdd78b755a8732518f7df4 Mon Sep 17 00:00:00 2001
From: sarthurdev <965089+sarthurdev@users.noreply.github.com>
Date: Tue, 18 Jan 2022 12:16:23 +0100
Subject: firewall: policy: T1292: Clean up any rules required to delete a
chain
---
src/conf_mode/firewall.py | 12 ++++++++++++
src/conf_mode/policy-route.py | 12 ++++++++++++
2 files changed, 24 insertions(+)
diff --git a/src/conf_mode/firewall.py b/src/conf_mode/firewall.py
index 906d477b0..ae46801c6 100755
--- a/src/conf_mode/firewall.py
+++ b/src/conf_mode/firewall.py
@@ -15,6 +15,7 @@
# along with this program. If not, see .
import os
+import re
from glob import glob
from json import loads
@@ -212,6 +213,16 @@ def verify(firewall):
return None
+def cleanup_rule(table, jump_chain):
+ commands = []
+ results = cmd(f'nft -a list table {table}').split("\n")
+ for line in results:
+ if f'jump {jump_chain}' in line:
+ handle_search = re.search('handle (\d+)', line)
+ if handle_search:
+ commands.append(f'delete rule {table} {chain} handle {handle_search[1]}')
+ return commands
+
def cleanup_commands(firewall):
commands = []
for table in ['ip filter', 'ip6 filter']:
@@ -234,6 +245,7 @@ def cleanup_commands(firewall):
elif table == 'ip6 filter' and dict_search_args(firewall, 'ipv6_name', chain):
commands.append(f'flush chain {table} {chain}')
else:
+ commands += cleanup_rule(table, chain)
commands.append(f'delete chain {table} {chain}')
elif 'rule' in item:
rule = item['rule']
diff --git a/src/conf_mode/policy-route.py b/src/conf_mode/policy-route.py
index eb13788dd..ee5197af0 100755
--- a/src/conf_mode/policy-route.py
+++ b/src/conf_mode/policy-route.py
@@ -15,6 +15,7 @@
# along with this program. If not, see .
import os
+import re
from json import loads
from sys import exit
@@ -160,6 +161,16 @@ def verify(policy):
return None
+def cleanup_rule(table, jump_chain):
+ commands = []
+ results = cmd(f'nft -a list table {table}').split("\n")
+ for line in results:
+ if f'jump {jump_chain}' in line:
+ handle_search = re.search('handle (\d+)', line)
+ if handle_search:
+ commands.append(f'delete rule {table} {chain} handle {handle_search[1]}')
+ return commands
+
def cleanup_commands(policy):
commands = []
for table in ['ip mangle', 'ip6 mangle']:
@@ -178,6 +189,7 @@ def cleanup_commands(policy):
elif table == 'ip6 mangle' and dict_search_args(policy, 'route6', chain.replace("VYOS_PBR6_", "", 1)):
commands.append(f'flush chain {table} {chain}')
else:
+ commands += cleanup_rule(table, chain)
commands.append(f'delete chain {table} {chain}')
return commands
--
cgit v1.2.3
From f96a4fcd5d0cc4e43dd8163a81dd7ca66355c6b4 Mon Sep 17 00:00:00 2001
From: sarthurdev <965089+sarthurdev@users.noreply.github.com>
Date: Tue, 18 Jan 2022 12:30:34 +0100
Subject: firewall: T2199: Raise ConfigError if deleted node is used in
zone-policy
---
src/conf_mode/firewall.py | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/src/conf_mode/firewall.py b/src/conf_mode/firewall.py
index ae46801c6..82223d60b 100755
--- a/src/conf_mode/firewall.py
+++ b/src/conf_mode/firewall.py
@@ -102,6 +102,35 @@ def get_firewall_interfaces(conf):
out.update(find_interfaces(iftype_conf))
return out
+def get_firewall_zones(conf):
+ used_v4 = []
+ used_v6 = []
+ zone_policy = conf.get_config_dict(['zone-policy'], key_mangling=('-', '_'), get_first_key=True,
+ no_tag_node_value_mangle=True)
+
+ if 'zone' in zone_policy:
+ for zone, zone_conf in zone_policy['zone'].items():
+ if 'from' in zone_conf:
+ for from_zone, from_conf in zone_conf['from'].items():
+ name = dict_search_args(from_conf, 'firewall', 'name')
+ if name:
+ used_v4.append(name)
+
+ ipv6_name = dict_search_args(from_conf, 'firewall', 'ipv6_name')
+ if ipv6_name:
+ used_v6.append(ipv6_name)
+
+ if 'intra_zone_filtering' in zone_conf:
+ name = dict_search_args(zone_conf, 'intra_zone_filtering', 'firewall', 'name')
+ if name:
+ used_v4.append(name)
+
+ ipv6_name = dict_search_args(zone_conf, 'intra_zone_filtering', 'firewall', 'ipv6_name')
+ if ipv6_name:
+ used_v6.append(ipv6_name)
+
+ return {'name': used_v4, 'ipv6_name': used_v6}
+
def get_config(config=None):
if config:
conf = config
@@ -117,6 +146,7 @@ def get_config(config=None):
firewall['policy_resync'] = bool('group' in firewall or node_changed(conf, base + ['group']))
firewall['interfaces'] = get_firewall_interfaces(conf)
+ firewall['zone_policy'] = get_firewall_zones(conf)
if 'config_trap' in firewall and firewall['config_trap'] == 'enable':
diff = get_config_diff(conf)
@@ -211,6 +241,11 @@ def verify(firewall):
if ipv6_name and not dict_search_args(firewall, 'ipv6_name', ipv6_name):
raise ConfigError(f'Firewall ipv6-name "{ipv6_name}" is still referenced on interface {ifname}')
+ for fw_name, used_names in firewall['zone_policy'].items():
+ for name in used_names:
+ if not dict_search_args(firewall, fw_name, name):
+ raise ConfigError(f'Firewall {fw_name.replace("_", "-")} "{name}" is still referenced in zone-policy')
+
return None
def cleanup_rule(table, jump_chain):
--
cgit v1.2.3