summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/templates/firewall/nftables-defines.j221
-rw-r--r--interface-definitions/firewall.xml.in29
-rw-r--r--interface-definitions/include/firewall/add-dynamic-address-groups.xml.i34
-rw-r--r--interface-definitions/include/firewall/add-dynamic-ipv6-address-groups.xml.i34
-rw-r--r--interface-definitions/include/firewall/common-rule-ipv4.xml.i25
-rw-r--r--interface-definitions/include/firewall/common-rule-ipv6.xml.i25
-rw-r--r--interface-definitions/include/firewall/source-destination-dynamic-group-ipv6.xml.i17
-rw-r--r--interface-definitions/include/firewall/source-destination-dynamic-group.xml.i17
-rw-r--r--python/vyos/firewall.py20
-rwxr-xr-xsmoketest/scripts/cli/test_firewall.py81
-rwxr-xr-xsrc/conf_mode/nat.py4
-rwxr-xr-xsrc/conf_mode/policy_route.py4
-rwxr-xr-xsrc/op_mode/firewall.py57
13 files changed, 350 insertions, 18 deletions
diff --git a/data/templates/firewall/nftables-defines.j2 b/data/templates/firewall/nftables-defines.j2
index a20c399ae..8a75ab2d6 100644
--- a/data/templates/firewall/nftables-defines.j2
+++ b/data/templates/firewall/nftables-defines.j2
@@ -98,5 +98,26 @@
}
{% endfor %}
{% endif %}
+
+{% if group.dynamic_group is vyos_defined %}
+{% if group.dynamic_group.address_group is vyos_defined and not is_ipv6 and is_l3 %}
+{% for group_name, group_conf in group.dynamic_group.address_group.items() %}
+ set DA_{{ group_name }} {
+ type {{ ip_type }}
+ flags dynamic, timeout
+ }
+{% endfor %}
+{% endif %}
+
+{% if group.dynamic_group.ipv6_address_group is vyos_defined and is_ipv6 and is_l3 %}
+{% for group_name, group_conf in group.dynamic_group.ipv6_address_group.items() %}
+ set DA6_{{ group_name }} {
+ type {{ ip_type }}
+ flags dynamic, timeout
+ }
+{% endfor %}
+{% endif %}
+{% endif %}
+
{% endif %}
{% endmacro %}
diff --git a/interface-definitions/firewall.xml.in b/interface-definitions/firewall.xml.in
index a4023058f..662ba24ab 100644
--- a/interface-definitions/firewall.xml.in
+++ b/interface-definitions/firewall.xml.in
@@ -115,6 +115,35 @@
#include <include/generic-description.xml.i>
</children>
</tagNode>
+ <node name="dynamic-group">
+ <properties>
+ <help>Firewall dynamic group</help>
+ </properties>
+ <children>
+ <tagNode name="address-group">
+ <properties>
+ <help>Firewall dynamic address group</help>
+ <constraint>
+ <regex>[a-zA-Z0-9][\w\-\.]*</regex>
+ </constraint>
+ </properties>
+ <children>
+ #include <include/generic-description.xml.i>
+ </children>
+ </tagNode>
+ <tagNode name="ipv6-address-group">
+ <properties>
+ <help>Firewall dynamic IPv6 address group</help>
+ <constraint>
+ <regex>[a-zA-Z0-9][\w\-\.]*</regex>
+ </constraint>
+ </properties>
+ <children>
+ #include <include/generic-description.xml.i>
+ </children>
+ </tagNode>
+ </children>
+ </node>
<tagNode name="interface-group">
<properties>
<help>Firewall interface-group</help>
diff --git a/interface-definitions/include/firewall/add-dynamic-address-groups.xml.i b/interface-definitions/include/firewall/add-dynamic-address-groups.xml.i
new file mode 100644
index 000000000..769761cb6
--- /dev/null
+++ b/interface-definitions/include/firewall/add-dynamic-address-groups.xml.i
@@ -0,0 +1,34 @@
+<!-- include start from firewall/add-dynamic-address-groups.xml.i -->
+<leafNode name="address-group">
+ <properties>
+ <help>Dynamic address-group</help>
+ <completionHelp>
+ <path>firewall group dynamic-group address-group</path>
+ </completionHelp>
+ </properties>
+</leafNode>
+<leafNode name="timeout">
+ <properties>
+ <help>Set timeout</help>
+ <valueHelp>
+ <format>&lt;number&gt;s</format>
+ <description>Timeout value in seconds</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;m</format>
+ <description>Timeout value in minutes</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;h</format>
+ <description>Timeout value in hours</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;d</format>
+ <description>Timeout value in days</description>
+ </valueHelp>
+ <constraint>
+ <regex>\d+(s|m|h|d)</regex>
+ </constraint>
+ </properties>
+</leafNode>
+<!-- include end --> \ No newline at end of file
diff --git a/interface-definitions/include/firewall/add-dynamic-ipv6-address-groups.xml.i b/interface-definitions/include/firewall/add-dynamic-ipv6-address-groups.xml.i
new file mode 100644
index 000000000..7bd91c58a
--- /dev/null
+++ b/interface-definitions/include/firewall/add-dynamic-ipv6-address-groups.xml.i
@@ -0,0 +1,34 @@
+<!-- include start from firewall/add-dynamic-ipv6-address-groups.xml.i -->
+<leafNode name="address-group">
+ <properties>
+ <help>Dynamic ipv6-address-group</help>
+ <completionHelp>
+ <path>firewall group dynamic-group ipv6-address-group</path>
+ </completionHelp>
+ </properties>
+</leafNode>
+<leafNode name="timeout">
+ <properties>
+ <help>Set timeout</help>
+ <valueHelp>
+ <format>&lt;number&gt;s</format>
+ <description>Timeout value in seconds</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;m</format>
+ <description>Timeout value in minutes</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;h</format>
+ <description>Timeout value in hours</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;d</format>
+ <description>Timeout value in days</description>
+ </valueHelp>
+ <constraint>
+ <regex>\d+(s|m|h|d)</regex>
+ </constraint>
+ </properties>
+</leafNode>
+<!-- include end --> \ No newline at end of file
diff --git a/interface-definitions/include/firewall/common-rule-ipv4.xml.i b/interface-definitions/include/firewall/common-rule-ipv4.xml.i
index 4ed179ae7..158c7a662 100644
--- a/interface-definitions/include/firewall/common-rule-ipv4.xml.i
+++ b/interface-definitions/include/firewall/common-rule-ipv4.xml.i
@@ -1,6 +1,29 @@
<!-- include start from firewall/common-rule-ipv4.xml.i -->
#include <include/firewall/common-rule-inet.xml.i>
#include <include/firewall/ttl.xml.i>
+<node name="add-address-to-group">
+ <properties>
+ <help>Add ip address to dynamic address-group</help>
+ </properties>
+ <children>
+ <node name="source-address">
+ <properties>
+ <help>Add source ip addresses to dynamic address-group</help>
+ </properties>
+ <children>
+ #include <include/firewall/add-dynamic-address-groups.xml.i>
+ </children>
+ </node>
+ <node name="destination-address">
+ <properties>
+ <help>Add destination ip addresses to dynamic address-group</help>
+ </properties>
+ <children>
+ #include <include/firewall/add-dynamic-address-groups.xml.i>
+ </children>
+ </node>
+ </children>
+</node>
<node name="destination">
<properties>
<help>Destination parameters</help>
@@ -13,6 +36,7 @@
#include <include/firewall/mac-address.xml.i>
#include <include/firewall/port.xml.i>
#include <include/firewall/source-destination-group.xml.i>
+ #include <include/firewall/source-destination-dynamic-group.xml.i>
</children>
</node>
<node name="icmp">
@@ -67,6 +91,7 @@
#include <include/firewall/mac-address.xml.i>
#include <include/firewall/port.xml.i>
#include <include/firewall/source-destination-group.xml.i>
+ #include <include/firewall/source-destination-dynamic-group.xml.i>
</children>
</node>
<!-- include end --> \ No newline at end of file
diff --git a/interface-definitions/include/firewall/common-rule-ipv6.xml.i b/interface-definitions/include/firewall/common-rule-ipv6.xml.i
index 6219557db..78eeb361e 100644
--- a/interface-definitions/include/firewall/common-rule-ipv6.xml.i
+++ b/interface-definitions/include/firewall/common-rule-ipv6.xml.i
@@ -1,6 +1,29 @@
<!-- include start from firewall/common-rule-ipv6.xml.i -->
#include <include/firewall/common-rule-inet.xml.i>
#include <include/firewall/hop-limit.xml.i>
+<node name="add-address-to-group">
+ <properties>
+ <help>Add ipv6 address to dynamic ipv6-address-group</help>
+ </properties>
+ <children>
+ <node name="source-address">
+ <properties>
+ <help>Add source ipv6 addresses to dynamic ipv6-address-group</help>
+ </properties>
+ <children>
+ #include <include/firewall/add-dynamic-ipv6-address-groups.xml.i>
+ </children>
+ </node>
+ <node name="destination-address">
+ <properties>
+ <help>Add destination ipv6 addresses to dynamic ipv6-address-group</help>
+ </properties>
+ <children>
+ #include <include/firewall/add-dynamic-ipv6-address-groups.xml.i>
+ </children>
+ </node>
+ </children>
+</node>
<node name="destination">
<properties>
<help>Destination parameters</help>
@@ -13,6 +36,7 @@
#include <include/firewall/mac-address.xml.i>
#include <include/firewall/port.xml.i>
#include <include/firewall/source-destination-group-ipv6.xml.i>
+ #include <include/firewall/source-destination-dynamic-group-ipv6.xml.i>
</children>
</node>
<node name="icmpv6">
@@ -67,6 +91,7 @@
#include <include/firewall/mac-address.xml.i>
#include <include/firewall/port.xml.i>
#include <include/firewall/source-destination-group-ipv6.xml.i>
+ #include <include/firewall/source-destination-dynamic-group-ipv6.xml.i>
</children>
</node>
<!-- include end --> \ No newline at end of file
diff --git a/interface-definitions/include/firewall/source-destination-dynamic-group-ipv6.xml.i b/interface-definitions/include/firewall/source-destination-dynamic-group-ipv6.xml.i
new file mode 100644
index 000000000..845f8fe7c
--- /dev/null
+++ b/interface-definitions/include/firewall/source-destination-dynamic-group-ipv6.xml.i
@@ -0,0 +1,17 @@
+<!-- include start from firewall/source-destination-dynamic-group-ipv6.xml.i -->
+<node name="group">
+ <properties>
+ <help>Group</help>
+ </properties>
+ <children>
+ <leafNode name="dynamic-address-group">
+ <properties>
+ <help>Group of dynamic ipv6 addresses</help>
+ <completionHelp>
+ <path>firewall group dynamic-group ipv6-address-group</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ </children>
+</node>
+<!-- include end -->
diff --git a/interface-definitions/include/firewall/source-destination-dynamic-group.xml.i b/interface-definitions/include/firewall/source-destination-dynamic-group.xml.i
new file mode 100644
index 000000000..29ab98c68
--- /dev/null
+++ b/interface-definitions/include/firewall/source-destination-dynamic-group.xml.i
@@ -0,0 +1,17 @@
+<!-- include start from firewall/source-destination-dynamic-group.xml.i -->
+<node name="group">
+ <properties>
+ <help>Group</help>
+ </properties>
+ <children>
+ <leafNode name="dynamic-address-group">
+ <properties>
+ <help>Group of dynamic addresses</help>
+ <completionHelp>
+ <path>firewall group dynamic-group address-group</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ </children>
+</node>
+<!-- include end -->
diff --git a/python/vyos/firewall.py b/python/vyos/firewall.py
index 28ebf282c..eee11bd2d 100644
--- a/python/vyos/firewall.py
+++ b/python/vyos/firewall.py
@@ -226,6 +226,14 @@ def parse_rule(rule_conf, hook, fw_name, rule_id, ip_name):
operator = '!=' if exclude else '=='
operator = f'& {address_mask} {operator}'
output.append(f'{ip_name} {prefix}addr {operator} @A{def_suffix}_{group_name}')
+ elif 'dynamic_address_group' in group:
+ group_name = group['dynamic_address_group']
+ operator = ''
+ exclude = group_name[0] == "!"
+ if exclude:
+ operator = '!='
+ group_name = group_name[1:]
+ output.append(f'{ip_name} {prefix}addr {operator} @DA{def_suffix}_{group_name}')
# Generate firewall group domain-group
elif 'domain_group' in group:
group_name = group['domain_group']
@@ -419,6 +427,18 @@ def parse_rule(rule_conf, hook, fw_name, rule_id, ip_name):
output.append('counter')
+ if 'add_address_to_group' in rule_conf:
+ for side in ['destination_address', 'source_address']:
+ if side in rule_conf['add_address_to_group']:
+ prefix = side[0]
+ side_conf = rule_conf['add_address_to_group'][side]
+ dyn_group = side_conf['address_group']
+ if 'timeout' in side_conf:
+ timeout_value = side_conf['timeout']
+ output.append(f'set update ip{def_suffix} {prefix}addr timeout {timeout_value} @DA{def_suffix}_{dyn_group}')
+ else:
+ output.append(f'set update ip{def_suffix} saddr @DA{def_suffix}_{dyn_group}')
+
if 'set' in rule_conf:
output.append(parse_policy_set(rule_conf['set'], def_suffix))
diff --git a/smoketest/scripts/cli/test_firewall.py b/smoketest/scripts/cli/test_firewall.py
index 72fbdb37d..a7dd11145 100755
--- a/smoketest/scripts/cli/test_firewall.py
+++ b/smoketest/scripts/cli/test_firewall.py
@@ -403,6 +403,46 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
self.verify_nftables(nftables_search, 'ip vyos_filter')
+ def test_ipv4_dynamic_groups(self):
+ group01 = 'knock01'
+ group02 = 'allowed'
+
+ self.cli_set(['firewall', 'group', 'dynamic-group', 'address-group', group01])
+ self.cli_set(['firewall', 'group', 'dynamic-group', 'address-group', group02])
+
+ self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '10', 'action', 'drop'])
+ self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '10', 'protocol', 'tcp'])
+ self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '10', 'destination', 'port', '5151'])
+ self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '10', 'add-address-to-group', 'source-address', 'address-group', group01])
+ self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '10', 'add-address-to-group', 'source-address', 'timeout', '30s'])
+
+ self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '20', 'action', 'drop'])
+ self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '20', 'protocol', 'tcp'])
+ self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '20', 'destination', 'port', '7272'])
+ self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '20', 'source', 'group', 'dynamic-address-group', group01])
+ self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '20', 'add-address-to-group', 'source-address', 'address-group', group02])
+ self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '20', 'add-address-to-group', 'source-address', 'timeout', '5m'])
+
+ self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '30', 'action', 'accept'])
+ self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '30', 'protocol', 'tcp'])
+ self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '30', 'destination', 'port', '22'])
+ self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '30', 'source', 'group', 'dynamic-address-group', group02])
+
+ self.cli_commit()
+
+ nftables_search = [
+ [f'DA_{group01}'],
+ [f'DA_{group02}'],
+ ['type ipv4_addr'],
+ ['flags dynamic,timeout'],
+ ['chain VYOS_INPUT_filter {'],
+ ['type filter hook input priority filter', 'policy accept'],
+ ['tcp dport 5151', f'update @DA_{group01}', '{ ip saddr timeout 30s }', 'drop'],
+ ['tcp dport 7272', f'ip saddr @DA_{group01}', f'update @DA_{group02}', '{ ip saddr timeout 5m }', 'drop'],
+ ['tcp dport 22', f'ip saddr @DA_{group02}', 'accept']
+ ]
+
+ self.verify_nftables(nftables_search, 'ip vyos_filter')
def test_ipv6_basic_rules(self):
name = 'v6-smoketest'
@@ -540,6 +580,47 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
self.verify_nftables(nftables_search, 'ip6 vyos_filter')
+ def test_ipv6_dynamic_groups(self):
+ group01 = 'knock01'
+ group02 = 'allowed'
+
+ self.cli_set(['firewall', 'group', 'dynamic-group', 'ipv6-address-group', group01])
+ self.cli_set(['firewall', 'group', 'dynamic-group', 'ipv6-address-group', group02])
+
+ self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '10', 'action', 'drop'])
+ self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '10', 'protocol', 'tcp'])
+ self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '10', 'destination', 'port', '5151'])
+ self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '10', 'add-address-to-group', 'source-address', 'address-group', group01])
+ self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '10', 'add-address-to-group', 'source-address', 'timeout', '30s'])
+
+ self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '20', 'action', 'drop'])
+ self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '20', 'protocol', 'tcp'])
+ self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '20', 'destination', 'port', '7272'])
+ self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '20', 'source', 'group', 'dynamic-address-group', group01])
+ self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '20', 'add-address-to-group', 'source-address', 'address-group', group02])
+ self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '20', 'add-address-to-group', 'source-address', 'timeout', '5m'])
+
+ self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '30', 'action', 'accept'])
+ self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '30', 'protocol', 'tcp'])
+ self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '30', 'destination', 'port', '22'])
+ self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '30', 'source', 'group', 'dynamic-address-group', group02])
+
+ self.cli_commit()
+
+ nftables_search = [
+ [f'DA6_{group01}'],
+ [f'DA6_{group02}'],
+ ['type ipv6_addr'],
+ ['flags dynamic,timeout'],
+ ['chain VYOS_IPV6_INPUT_filter {'],
+ ['type filter hook input priority filter', 'policy accept'],
+ ['tcp dport 5151', f'update @DA6_{group01}', '{ ip6 saddr timeout 30s }', 'drop'],
+ ['tcp dport 7272', f'ip6 saddr @DA6_{group01}', f'update @DA6_{group02}', '{ ip6 saddr timeout 5m }', 'drop'],
+ ['tcp dport 22', f'ip6 saddr @DA6_{group02}', 'accept']
+ ]
+
+ self.verify_nftables(nftables_search, 'ip6 vyos_filter')
+
def test_ipv4_state_and_status_rules(self):
name = 'smoketest-state'
interface = 'eth0'
diff --git a/src/conf_mode/nat.py b/src/conf_mode/nat.py
index bd9b5162c..26822b755 100755
--- a/src/conf_mode/nat.py
+++ b/src/conf_mode/nat.py
@@ -69,6 +69,10 @@ def get_config(config=None):
nat['firewall_group'] = conf.get_config_dict(['firewall', 'group'], key_mangling=('-', '_'), get_first_key=True,
no_tag_node_value_mangle=True)
+ # Remove dynamic firewall groups if present:
+ if 'dynamic_group' in nat['firewall_group']:
+ del nat['firewall_group']['dynamic_group']
+
return nat
def verify_rule(config, err_msg, groups_dict):
diff --git a/src/conf_mode/policy_route.py b/src/conf_mode/policy_route.py
index adad012de..6d7a06714 100755
--- a/src/conf_mode/policy_route.py
+++ b/src/conf_mode/policy_route.py
@@ -53,6 +53,10 @@ def get_config(config=None):
policy['firewall_group'] = conf.get_config_dict(['firewall', 'group'], key_mangling=('-', '_'), get_first_key=True,
no_tag_node_value_mangle=True)
+ # Remove dynamic firewall groups if present:
+ if 'dynamic_group' in policy['firewall_group']:
+ del policy['firewall_group']['dynamic_group']
+
return policy
def verify_rule(policy, name, rule_conf, ipv6, rule_id):
diff --git a/src/op_mode/firewall.py b/src/op_mode/firewall.py
index 36bb013fe..4dcffc412 100755
--- a/src/op_mode/firewall.py
+++ b/src/op_mode/firewall.py
@@ -327,6 +327,8 @@ def show_firewall_group(name=None):
dest_group = dict_search_args(rule_conf, 'destination', 'group', group_type)
in_interface = dict_search_args(rule_conf, 'inbound_interface', 'group')
out_interface = dict_search_args(rule_conf, 'outbound_interface', 'group')
+ dyn_group_source = dict_search_args(rule_conf, 'add_address_to_group', 'source_address', group_type)
+ dyn_group_dst = dict_search_args(rule_conf, 'add_address_to_group', 'destination_address', group_type)
if source_group:
if source_group[0] == "!":
source_group = source_group[1:]
@@ -348,6 +350,14 @@ def show_firewall_group(name=None):
if group_name == out_interface:
out.append(f'{item}-{name_type}-{priority}-{rule_id}')
+ if dyn_group_source:
+ if group_name == dyn_group_source:
+ out.append(f'{item}-{name_type}-{priority}-{rule_id}')
+ if dyn_group_dst:
+ if group_name == dyn_group_dst:
+ out.append(f'{item}-{name_type}-{priority}-{rule_id}')
+
+
# Look references in route | route6
for name_type in ['route', 'route6']:
if name_type not in policy:
@@ -423,26 +433,37 @@ def show_firewall_group(name=None):
rows = []
for group_type, group_type_conf in firewall['group'].items():
- for group_name, group_conf in group_type_conf.items():
- if name and name != group_name:
- continue
+ ##
+ if group_type != 'dynamic_group':
- references = find_references(group_type, group_name)
- row = [group_name, group_type, '\n'.join(references) or 'N/D']
- if 'address' in group_conf:
- row.append("\n".join(sorted(group_conf['address'])))
- elif 'network' in group_conf:
- row.append("\n".join(sorted(group_conf['network'], key=ipaddress.ip_network)))
- elif 'mac_address' in group_conf:
- row.append("\n".join(sorted(group_conf['mac_address'])))
- elif 'port' in group_conf:
- row.append("\n".join(sorted(group_conf['port'])))
- elif 'interface' in group_conf:
- row.append("\n".join(sorted(group_conf['interface'])))
- else:
- row.append('N/D')
- rows.append(row)
+ for group_name, group_conf in group_type_conf.items():
+ if name and name != group_name:
+ continue
+ references = find_references(group_type, group_name)
+ row = [group_name, group_type, '\n'.join(references) or 'N/D']
+ if 'address' in group_conf:
+ row.append("\n".join(sorted(group_conf['address'])))
+ elif 'network' in group_conf:
+ row.append("\n".join(sorted(group_conf['network'], key=ipaddress.ip_network)))
+ elif 'mac_address' in group_conf:
+ row.append("\n".join(sorted(group_conf['mac_address'])))
+ elif 'port' in group_conf:
+ row.append("\n".join(sorted(group_conf['port'])))
+ elif 'interface' in group_conf:
+ row.append("\n".join(sorted(group_conf['interface'])))
+ else:
+ row.append('N/D')
+ rows.append(row)
+
+ else:
+ for dynamic_type in ['address_group', 'ipv6_address_group']:
+ if dynamic_type in firewall['group']['dynamic_group']:
+ for dynamic_name, dynamic_conf in firewall['group']['dynamic_group'][dynamic_type].items():
+ references = find_references(dynamic_type, dynamic_name)
+ row = [dynamic_name, dynamic_type + '(dynamic)', '\n'.join(references) or 'N/D']
+ row.append('N/D')
+ rows.append(row)
if rows:
print('Firewall Groups\n')