From 64668771d5f14fc4b68fff382d166238c164bdde Mon Sep 17 00:00:00 2001
From: sarthurdev <965089+sarthurdev@users.noreply.github.com>
Date: Sat, 15 Jan 2022 12:48:48 +0100
Subject: firewall: policy: T4178: Migrate and refactor tcp flags
* Add support for ECN and CWR flags
---
smoketest/scripts/cli/test_firewall.py | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
(limited to 'smoketest/scripts/cli/test_firewall.py')
diff --git a/smoketest/scripts/cli/test_firewall.py b/smoketest/scripts/cli/test_firewall.py
index 2b3b354ba..c70743a9f 100755
--- a/smoketest/scripts/cli/test_firewall.py
+++ b/smoketest/scripts/cli/test_firewall.py
@@ -53,7 +53,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'source', 'group', 'network-group', 'smoketest_network'])
self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'destination', 'address', '172.16.10.10'])
self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'destination', 'group', 'port-group', 'smoketest_port'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'protocol', 'tcp'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'protocol', 'tcp_udp'])
self.cli_set(['interfaces', 'ethernet', 'eth0', 'firewall', 'in', 'name', 'smoketest'])
@@ -61,7 +61,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
nftables_search = [
['iifname "eth0"', 'jump smoketest'],
- ['ip saddr { 172.16.99.0/24 }', 'ip daddr 172.16.10.10', 'tcp dport { 53, 123 }', 'return'],
+ ['ip saddr { 172.16.99.0/24 }', 'ip daddr 172.16.10.10', 'th dport { 53, 123 }', 'return'],
]
nftables_output = cmd('sudo nft list table ip filter')
@@ -72,7 +72,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
if all(item in line for item in search):
matched = True
break
- self.assertTrue(matched)
+ self.assertTrue(matched, msg=search)
def test_basic_rules(self):
self.cli_set(['firewall', 'name', 'smoketest', 'default-action', 'drop'])
@@ -80,8 +80,10 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'source', 'address', '172.16.20.10'])
self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'destination', 'address', '172.16.10.10'])
self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'action', 'reject'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'protocol', 'tcp_udp'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'protocol', 'tcp'])
self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'destination', 'port', '8888'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'tcp', 'flags', 'syn'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'tcp', 'flags', 'not', 'ack'])
self.cli_set(['interfaces', 'ethernet', 'eth0', 'firewall', 'in', 'name', 'smoketest'])
@@ -90,7 +92,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
nftables_search = [
['iifname "eth0"', 'jump smoketest'],
['saddr 172.16.20.10', 'daddr 172.16.10.10', 'return'],
- ['meta l4proto { tcp, udp }', 'th dport { 8888 }', 'reject'],
+ ['tcp flags & (syn | ack) == syn', 'tcp dport { 8888 }', 'reject'],
['smoketest default-action', 'drop']
]
@@ -102,7 +104,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
if all(item in line for item in search):
matched = True
break
- self.assertTrue(matched)
+ self.assertTrue(matched, msg=search)
def test_basic_rules_ipv6(self):
self.cli_set(['firewall', 'ipv6-name', 'v6-smoketest', 'default-action', 'drop'])
@@ -132,7 +134,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
if all(item in line for item in search):
matched = True
break
- self.assertTrue(matched)
+ self.assertTrue(matched, msg=search)
def test_state_policy(self):
self.cli_set(['firewall', 'state-policy', 'established', 'action', 'accept'])
--
cgit v1.2.3
From 0a5a78621b2b28f06af1f40c10ee8bb880f860a0 Mon Sep 17 00:00:00 2001
From: sarthurdev <965089+sarthurdev@users.noreply.github.com>
Date: Tue, 18 Jan 2022 15:29:03 +0100
Subject: firewall: T3560: Add support for MAC address groups
---
data/templates/firewall/nftables-defines.tmpl | 5 ++++
interface-definitions/firewall.xml.in | 21 +++++++++++++++++
.../include/firewall/common-rule.xml.i | 3 +++
.../include/firewall/mac-group.xml.i | 10 ++++++++
.../firewall/source-destination-group-ipv6.xml.i | 1 +
.../firewall/source-destination-group.xml.i | 1 +
.../include/policy/route-common-rule-ipv6.xml.i | 3 +++
.../include/policy/route-common-rule.xml.i | 3 +++
python/vyos/firewall.py | 3 +++
smoketest/scripts/cli/test_firewall.py | 4 ++++
src/op_mode/firewall.py | 2 ++
src/validators/mac-address-firewall | 27 ++++++++++++++++++++++
12 files changed, 83 insertions(+)
create mode 100644 interface-definitions/include/firewall/mac-group.xml.i
create mode 100755 src/validators/mac-address-firewall
(limited to 'smoketest/scripts/cli/test_firewall.py')
diff --git a/data/templates/firewall/nftables-defines.tmpl b/data/templates/firewall/nftables-defines.tmpl
index 3578a9dc5..d9eb7c199 100644
--- a/data/templates/firewall/nftables-defines.tmpl
+++ b/data/templates/firewall/nftables-defines.tmpl
@@ -9,6 +9,11 @@ define A_{{ group_name }} = { {{ group_conf.address | join(",") }} }
define A6_{{ group_name }} = { {{ group_conf.address | join(",") }} }
{% endfor %}
{% endif %}
+{% if group.mac_group is defined %}
+{% for group_name, group_conf in group.mac_group.items() %}
+define M_{{ group_name }} = { {{ group_conf.mac_address | join(",") }} }
+{% endfor %}
+{% endif %}
{% if group.network_group is defined %}
{% for group_name, group_conf in group.network_group.items() %}
define N_{{ group_name }} = { {{ group_conf.network | join(",") }} }
diff --git a/interface-definitions/firewall.xml.in b/interface-definitions/firewall.xml.in
index fd98ae138..987ccaca6 100644
--- a/interface-definitions/firewall.xml.in
+++ b/interface-definitions/firewall.xml.in
@@ -144,6 +144,27 @@
+
+
+ Firewall mac-group
+
+
+ #include
+
+
+ Mac-group member
+
+ <MAC address>
+ MAC address to match
+
+
+
+
+
+
+
+
+
Firewall network-group
diff --git a/interface-definitions/include/firewall/common-rule.xml.i b/interface-definitions/include/firewall/common-rule.xml.i
index 5ffbd639c..521fe54f2 100644
--- a/interface-definitions/include/firewall/common-rule.xml.i
+++ b/interface-definitions/include/firewall/common-rule.xml.i
@@ -176,6 +176,9 @@
!<MAC address>
Match everything except the specified MAC address
+
+
+
#include
diff --git a/interface-definitions/include/firewall/mac-group.xml.i b/interface-definitions/include/firewall/mac-group.xml.i
new file mode 100644
index 000000000..dbce3fc88
--- /dev/null
+++ b/interface-definitions/include/firewall/mac-group.xml.i
@@ -0,0 +1,10 @@
+
+
+
+ Group of MAC addresses
+
+ firewall group mac-group
+
+
+
+
\ No newline at end of file
diff --git a/interface-definitions/include/firewall/source-destination-group-ipv6.xml.i b/interface-definitions/include/firewall/source-destination-group-ipv6.xml.i
index 7815b78d4..c2cc7edb3 100644
--- a/interface-definitions/include/firewall/source-destination-group-ipv6.xml.i
+++ b/interface-definitions/include/firewall/source-destination-group-ipv6.xml.i
@@ -12,6 +12,7 @@
+ #include
Group of networks
diff --git a/interface-definitions/include/firewall/source-destination-group.xml.i b/interface-definitions/include/firewall/source-destination-group.xml.i
index 9a9bed0fe..ab11e89e9 100644
--- a/interface-definitions/include/firewall/source-destination-group.xml.i
+++ b/interface-definitions/include/firewall/source-destination-group.xml.i
@@ -12,6 +12,7 @@
+ #include
Group of networks
diff --git a/interface-definitions/include/policy/route-common-rule-ipv6.xml.i b/interface-definitions/include/policy/route-common-rule-ipv6.xml.i
index 735edbd48..406125e55 100644
--- a/interface-definitions/include/policy/route-common-rule-ipv6.xml.i
+++ b/interface-definitions/include/policy/route-common-rule-ipv6.xml.i
@@ -232,6 +232,9 @@
!<MAC address>
Match everything except the specified MAC address
+
+
+
#include
diff --git a/interface-definitions/include/policy/route-common-rule.xml.i b/interface-definitions/include/policy/route-common-rule.xml.i
index 4452f78fc..33c4ba77c 100644
--- a/interface-definitions/include/policy/route-common-rule.xml.i
+++ b/interface-definitions/include/policy/route-common-rule.xml.i
@@ -232,6 +232,9 @@
!<MAC address>
Match everything except the specified MAC address
+
+
+
#include
diff --git a/python/vyos/firewall.py b/python/vyos/firewall.py
index ad84393df..2ab78ff18 100644
--- a/python/vyos/firewall.py
+++ b/python/vyos/firewall.py
@@ -108,6 +108,9 @@ def parse_rule(rule_conf, fw_name, rule_id, ip_name):
elif 'network_group' in group:
group_name = group['network_group']
output.append(f'{ip_name} {prefix}addr $N{def_suffix}_{group_name}')
+ if 'mac_group' in group:
+ group_name = group['mac_group']
+ output.append(f'ether {prefix}addr $M_{group_name}')
if 'port_group' in group:
proto = rule_conf['protocol']
group_name = group['port_group']
diff --git a/smoketest/scripts/cli/test_firewall.py b/smoketest/scripts/cli/test_firewall.py
index c70743a9f..6b74e6c92 100755
--- a/smoketest/scripts/cli/test_firewall.py
+++ b/smoketest/scripts/cli/test_firewall.py
@@ -46,6 +46,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
def test_groups(self):
+ self.cli_set(['firewall', 'group', 'mac-group', 'smoketest_mac', 'mac-address', '00:01:02:03:04:05'])
self.cli_set(['firewall', 'group', 'network-group', 'smoketest_network', 'network', '172.16.99.0/24'])
self.cli_set(['firewall', 'group', 'port-group', 'smoketest_port', 'port', '53'])
self.cli_set(['firewall', 'group', 'port-group', 'smoketest_port', 'port', '123'])
@@ -54,6 +55,8 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'destination', 'address', '172.16.10.10'])
self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'destination', 'group', 'port-group', 'smoketest_port'])
self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'protocol', 'tcp_udp'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'action', 'accept'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'source', 'group', 'mac-group', 'smoketest_mac'])
self.cli_set(['interfaces', 'ethernet', 'eth0', 'firewall', 'in', 'name', 'smoketest'])
@@ -62,6 +65,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
nftables_search = [
['iifname "eth0"', 'jump smoketest'],
['ip saddr { 172.16.99.0/24 }', 'ip daddr 172.16.10.10', 'th dport { 53, 123 }', 'return'],
+ ['ether saddr { 00:01:02:03:04:05 }', 'return']
]
nftables_output = cmd('sudo nft list table ip filter')
diff --git a/src/op_mode/firewall.py b/src/op_mode/firewall.py
index 030a9b19a..b6bb5b802 100755
--- a/src/op_mode/firewall.py
+++ b/src/op_mode/firewall.py
@@ -272,6 +272,8 @@ def show_firewall_group(name=None):
row.append("\n".join(sorted(group_conf['address'], key=ipaddress.ip_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'])))
else:
diff --git a/src/validators/mac-address-firewall b/src/validators/mac-address-firewall
new file mode 100755
index 000000000..70551f86d
--- /dev/null
+++ b/src/validators/mac-address-firewall
@@ -0,0 +1,27 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2018-2022 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 .
+
+import re
+import sys
+
+pattern = "^!?([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$"
+
+if __name__ == '__main__':
+ if len(sys.argv) != 2:
+ sys.exit(1)
+ if not re.match(pattern, sys.argv[1]):
+ sys.exit(1)
+ sys.exit(0)
--
cgit v1.2.3
From ed67750b94e8bc779ec0e2cf6d568a3f7292de13 Mon Sep 17 00:00:00 2001
From: sarthurdev <965089+sarthurdev@users.noreply.github.com>
Date: Sat, 29 Jan 2022 13:18:28 +0100
Subject: firewall: T4218: Adds a prefix to all user defined chains
---
data/templates/firewall/nftables.tmpl | 4 ++--
data/templates/zone_policy/nftables.tmpl | 12 ++++++------
python/vyos/template.py | 3 ++-
smoketest/scripts/cli/test_firewall.py | 6 +++---
smoketest/scripts/cli/test_zone_policy.py | 4 ++--
src/conf_mode/firewall-interface.py | 11 +++++++----
src/conf_mode/firewall.py | 7 +++++--
src/op_mode/firewall.py | 3 ++-
8 files changed, 29 insertions(+), 21 deletions(-)
(limited to 'smoketest/scripts/cli/test_firewall.py')
diff --git a/data/templates/firewall/nftables.tmpl b/data/templates/firewall/nftables.tmpl
index 33c821e84..468a5a32f 100644
--- a/data/templates/firewall/nftables.tmpl
+++ b/data/templates/firewall/nftables.tmpl
@@ -32,7 +32,7 @@ table ip filter {
{% endif %}
{% if name is defined %}
{% for name_text, conf in name.items() %}
- chain {{ name_text }} {
+ chain NAME_{{ name_text }} {
{% if conf.rule is defined %}
{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not defined %}
{{ rule_conf | nft_rule(name_text, rule_id) }}
@@ -82,7 +82,7 @@ table ip6 filter {
{% endif %}
{% if ipv6_name is defined %}
{% for name_text, conf in ipv6_name.items() %}
- chain {{ name_text }} {
+ chain NAME6_{{ name_text }} {
{% if conf.rule is defined %}
{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not defined %}
{{ rule_conf | nft_rule(name_text, rule_id, 'ip6') }}
diff --git a/data/templates/zone_policy/nftables.tmpl b/data/templates/zone_policy/nftables.tmpl
index e59208a0d..093da6bd8 100644
--- a/data/templates/zone_policy/nftables.tmpl
+++ b/data/templates/zone_policy/nftables.tmpl
@@ -13,7 +13,7 @@ table ip filter {
chain VZONE_{{ zone_name }}_IN {
iifname lo counter return
{% for from_zone, from_conf in zone_conf.from.items() if from_conf.firewall.name is defined %}
- iifname { {{ zone[from_zone].interface | join(",") }} } counter jump {{ from_conf.firewall.name }}
+ iifname { {{ zone[from_zone].interface | join(",") }} } counter jump NAME_{{ from_conf.firewall.name }}
iifname { {{ zone[from_zone].interface | join(",") }} } counter return
{% endfor %}
counter {{ zone_conf.default_action if zone_conf.default_action is defined else 'drop' }}
@@ -21,7 +21,7 @@ table ip filter {
chain VZONE_{{ zone_name }}_OUT {
oifname lo counter return
{% for from_zone, from_conf in zone_conf.from_local.items() if from_conf.firewall.name is defined %}
- oifname { {{ zone[from_zone].interface | join(",") }} } counter jump {{ from_conf.firewall.name }}
+ oifname { {{ zone[from_zone].interface | join(",") }} } counter jump NAME_{{ from_conf.firewall.name }}
oifname { {{ zone[from_zone].interface | join(",") }} } counter return
{% endfor %}
counter {{ zone_conf.default_action if zone_conf.default_action is defined else 'drop' }}
@@ -34,7 +34,7 @@ table ip filter {
{% endif %}
{% for from_zone, from_conf in zone_conf.from.items() if from_conf.firewall.name is defined %}
{% if zone[from_zone].local_zone is not defined %}
- iifname { {{ zone[from_zone].interface | join(",") }} } counter jump {{ from_conf.firewall.name }}
+ iifname { {{ zone[from_zone].interface | join(",") }} } counter jump NAME_{{ from_conf.firewall.name }}
iifname { {{ zone[from_zone].interface | join(",") }} } counter return
{% endif %}
{% endfor %}
@@ -50,7 +50,7 @@ table ip6 filter {
chain VZONE6_{{ zone_name }}_IN {
iifname lo counter return
{% for from_zone, from_conf in zone_conf.from.items() if from_conf.firewall.ipv6_name is defined %}
- iifname { {{ zone[from_zone].interface | join(",") }} } counter jump {{ from_conf.firewall.ipv6_name }}
+ iifname { {{ zone[from_zone].interface | join(",") }} } counter jump NAME6_{{ from_conf.firewall.ipv6_name }}
iifname { {{ zone[from_zone].interface | join(",") }} } counter return
{% endfor %}
counter {{ zone_conf.default_action if zone_conf.default_action is defined else 'drop' }}
@@ -58,7 +58,7 @@ table ip6 filter {
chain VZONE6_{{ zone_name }}_OUT {
oifname lo counter return
{% for from_zone, from_conf in zone_conf.from_local.items() if from_conf.firewall.ipv6_name is defined %}
- oifname { {{ zone[from_zone].interface | join(",") }} } counter jump {{ from_conf.firewall.ipv6_name }}
+ oifname { {{ zone[from_zone].interface | join(",") }} } counter jump NAME6_{{ from_conf.firewall.ipv6_name }}
oifname { {{ zone[from_zone].interface | join(",") }} } counter return
{% endfor %}
counter {{ zone_conf.default_action if zone_conf.default_action is defined else 'drop' }}
@@ -71,7 +71,7 @@ table ip6 filter {
{% endif %}
{% for from_zone, from_conf in zone_conf.from.items() if from_conf.firewall.ipv6_name is defined %}
{% if zone[from_zone].local_zone is not defined %}
- iifname { {{ zone[from_zone].interface | join(",") }} } counter jump {{ from_conf.firewall.ipv6_name }}
+ iifname { {{ zone[from_zone].interface | join(",") }} } counter jump NAME6_{{ from_conf.firewall.ipv6_name }}
iifname { {{ zone[from_zone].interface | join(",") }} } counter return
{% endif %}
{% endfor %}
diff --git a/python/vyos/template.py b/python/vyos/template.py
index 633b28ade..3675aef5d 100644
--- a/python/vyos/template.py
+++ b/python/vyos/template.py
@@ -548,6 +548,7 @@ def nft_intra_zone_action(zone_conf, ipv6=False):
if 'intra_zone_filtering' in zone_conf:
intra_zone = zone_conf['intra_zone_filtering']
fw_name = 'ipv6_name' if ipv6 else 'name'
+ name_prefix = 'NAME6_' if ipv6 else 'NAME_'
if 'action' in intra_zone:
if intra_zone['action'] == 'accept':
@@ -555,5 +556,5 @@ def nft_intra_zone_action(zone_conf, ipv6=False):
return intra_zone['action']
elif dict_search_args(intra_zone, 'firewall', fw_name):
name = dict_search_args(intra_zone, 'firewall', fw_name)
- return f'jump {name}'
+ return f'jump {name_prefix}{name}'
return 'return'
diff --git a/smoketest/scripts/cli/test_firewall.py b/smoketest/scripts/cli/test_firewall.py
index 6b74e6c92..ecc0c29a0 100755
--- a/smoketest/scripts/cli/test_firewall.py
+++ b/smoketest/scripts/cli/test_firewall.py
@@ -63,7 +63,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
nftables_search = [
- ['iifname "eth0"', 'jump smoketest'],
+ ['iifname "eth0"', 'jump NAME_smoketest'],
['ip saddr { 172.16.99.0/24 }', 'ip daddr 172.16.10.10', 'th dport { 53, 123 }', 'return'],
['ether saddr { 00:01:02:03:04:05 }', 'return']
]
@@ -94,7 +94,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
nftables_search = [
- ['iifname "eth0"', 'jump smoketest'],
+ ['iifname "eth0"', 'jump NAME_smoketest'],
['saddr 172.16.20.10', 'daddr 172.16.10.10', 'return'],
['tcp flags & (syn | ack) == syn', 'tcp dport { 8888 }', 'reject'],
['smoketest default-action', 'drop']
@@ -124,7 +124,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
nftables_search = [
- ['iifname "eth0"', 'jump v6-smoketest'],
+ ['iifname "eth0"', 'jump NAME6_v6-smoketest'],
['saddr 2002::1', 'daddr 2002::1:1', 'return'],
['meta l4proto { tcp, udp }', 'th dport { 8888 }', 'reject'],
['smoketest default-action', 'drop']
diff --git a/smoketest/scripts/cli/test_zone_policy.py b/smoketest/scripts/cli/test_zone_policy.py
index c0af6164b..00dfe0182 100755
--- a/smoketest/scripts/cli/test_zone_policy.py
+++ b/smoketest/scripts/cli/test_zone_policy.py
@@ -44,8 +44,8 @@ class TestZonePolicy(VyOSUnitTestSHIM.TestCase):
['oifname { "eth0" }', 'jump VZONE_smoketest-eth0'],
['jump VZONE_smoketest-local_IN'],
['jump VZONE_smoketest-local_OUT'],
- ['iifname { "eth0" }', 'jump smoketest'],
- ['oifname { "eth0" }', 'jump smoketest']
+ ['iifname { "eth0" }', 'jump NAME_smoketest'],
+ ['oifname { "eth0" }', 'jump NAME_smoketest']
]
nftables_output = cmd('sudo nft list table ip filter')
diff --git a/src/conf_mode/firewall-interface.py b/src/conf_mode/firewall-interface.py
index a7442ecbd..9a5d278e9 100755
--- a/src/conf_mode/firewall-interface.py
+++ b/src/conf_mode/firewall-interface.py
@@ -31,6 +31,9 @@ from vyos import ConfigError
from vyos import airbag
airbag.enable()
+NAME_PREFIX = 'NAME_'
+NAME6_PREFIX = 'NAME6_'
+
NFT_CHAINS = {
'in': 'VYOS_FW_FORWARD',
'out': 'VYOS_FW_FORWARD',
@@ -127,7 +130,7 @@ def apply(if_firewall):
name = dict_search_args(if_firewall, direction, 'name')
if name:
- rule_exists = cleanup_rule('ip filter', chain, if_prefix, ifname, name)
+ rule_exists = cleanup_rule('ip filter', chain, if_prefix, ifname, f'{NAME_PREFIX}{name}')
if not rule_exists:
rule_action = 'insert'
@@ -138,13 +141,13 @@ def apply(if_firewall):
rule_action = 'add'
rule_prefix = f'position {handle}'
- run(f'nft {rule_action} rule ip filter {chain} {rule_prefix} {if_prefix}ifname {ifname} counter jump {name}')
+ run(f'nft {rule_action} rule ip filter {chain} {rule_prefix} {if_prefix}ifname {ifname} counter jump {NAME_PREFIX}{name}')
else:
cleanup_rule('ip filter', chain, if_prefix, ifname)
ipv6_name = dict_search_args(if_firewall, direction, 'ipv6_name')
if ipv6_name:
- rule_exists = cleanup_rule('ip6 filter', ipv6_chain, if_prefix, ifname, ipv6_name)
+ rule_exists = cleanup_rule('ip6 filter', ipv6_chain, if_prefix, ifname, f'{NAME6_PREFIX}{ipv6_name}')
if not rule_exists:
rule_action = 'insert'
@@ -155,7 +158,7 @@ def apply(if_firewall):
rule_action = 'add'
rule_prefix = f'position {handle}'
- run(f'nft {rule_action} rule ip6 filter {ipv6_chain} {rule_prefix} {if_prefix}ifname {ifname} counter jump {ipv6_name}')
+ run(f'nft {rule_action} rule ip6 filter {ipv6_chain} {rule_prefix} {if_prefix}ifname {ifname} counter jump {NAME6_PREFIX}{ipv6_name}')
else:
cleanup_rule('ip6 filter', ipv6_chain, if_prefix, ifname)
diff --git a/src/conf_mode/firewall.py b/src/conf_mode/firewall.py
index 358b938e3..5b6c57d04 100755
--- a/src/conf_mode/firewall.py
+++ b/src/conf_mode/firewall.py
@@ -54,6 +54,9 @@ sysfs_config = {
'twa_hazards_protection': {'sysfs': '/proc/sys/net/ipv4/tcp_rfc1337'}
}
+NAME_PREFIX = 'NAME_'
+NAME6_PREFIX = 'NAME6_'
+
preserve_chains = [
'INPUT',
'FORWARD',
@@ -281,9 +284,9 @@ def cleanup_commands(firewall):
else:
commands.append(f'flush chain {table} {chain}')
elif chain not in preserve_chains and not chain.startswith("VZONE"):
- if table == 'ip filter' and dict_search_args(firewall, 'name', chain):
+ if table == 'ip filter' and dict_search_args(firewall, 'name', chain.replace(NAME_PREFIX, "", 1)):
commands.append(f'flush chain {table} {chain}')
- elif table == 'ip6 filter' and dict_search_args(firewall, 'ipv6_name', chain):
+ elif table == 'ip6 filter' and dict_search_args(firewall, 'ipv6_name', chain.replace(NAME6_PREFIX, "", 1)):
commands.append(f'flush chain {table} {chain}')
else:
commands += cleanup_rule(table, chain)
diff --git a/src/op_mode/firewall.py b/src/op_mode/firewall.py
index b6bb5b802..3146fc357 100755
--- a/src/op_mode/firewall.py
+++ b/src/op_mode/firewall.py
@@ -88,7 +88,8 @@ def get_config_firewall(conf, name=None, ipv6=False, interfaces=True):
def get_nftables_details(name, ipv6=False):
suffix = '6' if ipv6 else ''
- command = f'sudo nft list chain ip{suffix} filter {name}'
+ name_prefix = 'NAME6_' if ipv6 else 'NAME_'
+ command = f'sudo nft list chain ip{suffix} filter {name_prefix}{name}'
try:
results = cmd(command)
except:
--
cgit v1.2.3
From c514cea0ad94a00838530cd07f87723be372ea8f Mon Sep 17 00:00:00 2001
From: sarthurdev <965089+sarthurdev@users.noreply.github.com>
Date: Tue, 5 Apr 2022 20:40:45 +0200
Subject: firewall: T4345: Fix incorrect rule limit rate syntax
---
interface-definitions/include/firewall/common-rule.xml.i | 6 +++---
python/vyos/firewall.py | 2 +-
smoketest/configs/dialup-router-complex | 3 +++
smoketest/scripts/cli/test_firewall.py | 5 +++++
src/conf_mode/firewall.py | 6 ++++++
5 files changed, 18 insertions(+), 4 deletions(-)
(limited to 'smoketest/scripts/cli/test_firewall.py')
diff --git a/interface-definitions/include/firewall/common-rule.xml.i b/interface-definitions/include/firewall/common-rule.xml.i
index 353804990..cd80b7e28 100644
--- a/interface-definitions/include/firewall/common-rule.xml.i
+++ b/interface-definitions/include/firewall/common-rule.xml.i
@@ -66,11 +66,11 @@
Maximum average matching rate
- u32:0-4294967295
- Maximum average matching rate
+ txt
+ integer/unit (Example: 5/minute)
-
+ ^\d+/(second|minute|hour|day)$
diff --git a/python/vyos/firewall.py b/python/vyos/firewall.py
index 55ce318e7..ff8623592 100644
--- a/python/vyos/firewall.py
+++ b/python/vyos/firewall.py
@@ -174,7 +174,7 @@ def parse_rule(rule_conf, fw_name, rule_id, ip_name):
if 'limit' in rule_conf:
if 'rate' in rule_conf['limit']:
- output.append(f'limit rate {rule_conf["limit"]["rate"]}/second')
+ output.append(f'limit rate {rule_conf["limit"]["rate"]}')
if 'burst' in rule_conf['limit']:
output.append(f'burst {rule_conf["limit"]["burst"]} packets')
diff --git a/smoketest/configs/dialup-router-complex b/smoketest/configs/dialup-router-complex
index 1b62deb5c..ac5ff5e99 100644
--- a/smoketest/configs/dialup-router-complex
+++ b/smoketest/configs/dialup-router-complex
@@ -498,6 +498,9 @@ firewall {
destination {
port 110,995
}
+ limit {
+ rate "10/minute"
+ }
protocol tcp
}
rule 123 {
diff --git a/smoketest/scripts/cli/test_firewall.py b/smoketest/scripts/cli/test_firewall.py
index ecc0c29a0..16b020e07 100755
--- a/smoketest/scripts/cli/test_firewall.py
+++ b/smoketest/scripts/cli/test_firewall.py
@@ -88,6 +88,10 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'destination', 'port', '8888'])
self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'tcp', 'flags', 'syn'])
self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'tcp', 'flags', 'not', 'ack'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '3', 'action', 'accept'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '3', 'protocol', 'tcp'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '3', 'destination', 'port', '22'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '3', 'limit', 'rate', '5/minute'])
self.cli_set(['interfaces', 'ethernet', 'eth0', 'firewall', 'in', 'name', 'smoketest'])
@@ -97,6 +101,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
['iifname "eth0"', 'jump NAME_smoketest'],
['saddr 172.16.20.10', 'daddr 172.16.10.10', 'return'],
['tcp flags & (syn | ack) == syn', 'tcp dport { 8888 }', 'reject'],
+ ['tcp dport { 22 }', 'limit rate 5/minute', 'return'],
['smoketest default-action', 'drop']
]
diff --git a/src/conf_mode/firewall.py b/src/conf_mode/firewall.py
index 41df1b84a..f33198a49 100755
--- a/src/conf_mode/firewall.py
+++ b/src/conf_mode/firewall.py
@@ -171,6 +171,12 @@ def verify_rule(firewall, rule_conf, ipv6):
if {'match_frag', 'match_non_frag'} <= set(rule_conf['fragment']):
raise ConfigError('Cannot specify both "match-frag" and "match-non-frag"')
+ if 'limit' in rule_conf:
+ if 'rate' in rule_conf['limit']:
+ rate_int = re.sub(r'\D', '', rule_conf['limit']['rate'])
+ if int(rate_int) < 1:
+ raise ConfigError('Limit rate integer cannot be less than 1')
+
if 'ipsec' in rule_conf:
if {'match_ipsec', 'match_non_ipsec'} <= set(rule_conf['ipsec']):
raise ConfigError('Cannot specify both "match-ipsec" and "match-non-ipsec"')
--
cgit v1.2.3