From 1eb71e8e80a30c559932690470791cdf10ac5c76 Mon Sep 17 00:00:00 2001 From: Nicolas Fort Date: Wed, 7 Sep 2022 14:16:49 +0000 Subject: T1024: Firewall and Policy route: add option to match dscp value, both on firewall and in policy route --- interface-definitions/firewall.xml.in | 2 ++ interface-definitions/include/firewall/dscp.xml.i | 38 +++++++++++++++++++++++ interface-definitions/policy-route.xml.in | 2 ++ python/vyos/firewall.py | 7 +++++ smoketest/scripts/cli/test_firewall.py | 24 +++++++++----- smoketest/scripts/cli/test_policy_route.py | 12 +++++-- 6 files changed, 75 insertions(+), 10 deletions(-) create mode 100644 interface-definitions/include/firewall/dscp.xml.i diff --git a/interface-definitions/firewall.xml.in b/interface-definitions/firewall.xml.in index 0ab9d6a66..d1497d572 100644 --- a/interface-definitions/firewall.xml.in +++ b/interface-definitions/firewall.xml.in @@ -383,6 +383,7 @@ #include + #include #include #include @@ -530,6 +531,7 @@ #include + #include #include diff --git a/interface-definitions/include/firewall/dscp.xml.i b/interface-definitions/include/firewall/dscp.xml.i new file mode 100644 index 000000000..642212d7e --- /dev/null +++ b/interface-definitions/include/firewall/dscp.xml.i @@ -0,0 +1,38 @@ + + + + DSCP value + + u32:0-63 + DSCP value to match + + + <start-end> + DSCP range to match + + + + + + + + + + + DSCP value not to match + + u32:0-63 + DSCP value not to match + + + <start-end> + DSCP range not to match + + + + + + + + + \ No newline at end of file diff --git a/interface-definitions/policy-route.xml.in b/interface-definitions/policy-route.xml.in index ba1371fab..f480f3bd5 100644 --- a/interface-definitions/policy-route.xml.in +++ b/interface-definitions/policy-route.xml.in @@ -47,6 +47,7 @@ #include + #include #include #include @@ -98,6 +99,7 @@ #include + #include #include #include diff --git a/python/vyos/firewall.py b/python/vyos/firewall.py index 0bc5378db..2fbaef0e9 100644 --- a/python/vyos/firewall.py +++ b/python/vyos/firewall.py @@ -274,6 +274,13 @@ def parse_rule(rule_conf, fw_name, rule_id, ip_name): negated_lengths_str = ','.join(rule_conf['packet_length_exclude']) output.append(f'ip{def_suffix} length != {{{negated_lengths_str}}}') + if 'dscp' in rule_conf: + dscp_str = ','.join(rule_conf['dscp']) + output.append(f'ip{def_suffix} dscp {{{dscp_str}}}') + + if 'dscp_exclude' in rule_conf: + negated_dscp_str = ','.join(rule_conf['dscp_exclude']) + output.append(f'ip{def_suffix} dscp != {{{negated_dscp_str}}}') if 'ipsec' in rule_conf: if 'match_ipsec' in rule_conf['ipsec']: diff --git a/smoketest/scripts/cli/test_firewall.py b/smoketest/scripts/cli/test_firewall.py index 1517180de..49d4d6170 100755 --- a/smoketest/scripts/cli/test_firewall.py +++ b/smoketest/scripts/cli/test_firewall.py @@ -232,8 +232,8 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): self.verify_nftables(nftables_search, 'ip filter') - def test_ipv4_packet_length(self): - name = 'smoketest-plen' + def test_ipv4_advanced(self): + name = 'smoketest-adv' interface = 'eth0' self.cli_set(['firewall', 'name', name, 'default-action', 'drop']) @@ -243,10 +243,14 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): self.cli_set(['firewall', 'name', name, 'rule', '6', 'packet-length', '64']) self.cli_set(['firewall', 'name', name, 'rule', '6', 'packet-length', '512']) self.cli_set(['firewall', 'name', name, 'rule', '6', 'packet-length', '1024']) + self.cli_set(['firewall', 'name', name, 'rule', '6', 'dscp', '17']) + self.cli_set(['firewall', 'name', name, 'rule', '6', 'dscp', '52']) self.cli_set(['firewall', 'name', name, 'rule', '7', 'action', 'accept']) self.cli_set(['firewall', 'name', name, 'rule', '7', 'packet-length', '1-30000']) self.cli_set(['firewall', 'name', name, 'rule', '7', 'packet-length-exclude', '60000-65535']) + self.cli_set(['firewall', 'name', name, 'rule', '7', 'dscp', '3-11']) + self.cli_set(['firewall', 'name', name, 'rule', '7', 'dscp-exclude', '21-25']) self.cli_set(['interfaces', 'ethernet', interface, 'firewall', 'in', 'name', name]) @@ -254,8 +258,8 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): nftables_search = [ [f'iifname "{interface}"', f'jump NAME_{name}'], - ['ip length { 64, 512, 1024 }', 'return'], - ['ip length { 1-30000 }', 'ip length != { 60000-65535 }', 'return'], + ['ip length { 64, 512, 1024 }', 'ip dscp { 0x11, 0x34 }', 'return'], + ['ip length { 1-30000 }', 'ip length != { 60000-65535 }', 'ip dscp { 0x03-0x0b }', 'ip dscp != { 0x15-0x19 }', 'return'], [f'log prefix "[{name}-default-D]" drop'] ] @@ -291,8 +295,8 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): self.verify_nftables(nftables_search, 'ip6 filter') - def test_ipv6_packet_length(self): - name = 'v6-smoketest-plen' + def test_ipv6_advanced(self): + name = 'v6-smoketest-adv' interface = 'eth0' self.cli_set(['firewall', 'ipv6-name', name, 'default-action', 'drop']) @@ -302,10 +306,14 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): self.cli_set(['firewall', 'ipv6-name', name, 'rule', '3', 'packet-length', '65']) self.cli_set(['firewall', 'ipv6-name', name, 'rule', '3', 'packet-length', '513']) self.cli_set(['firewall', 'ipv6-name', name, 'rule', '3', 'packet-length', '1025']) + self.cli_set(['firewall', 'ipv6-name', name, 'rule', '3', 'dscp', '18']) + self.cli_set(['firewall', 'ipv6-name', name, 'rule', '3', 'dscp', '53']) self.cli_set(['firewall', 'ipv6-name', name, 'rule', '4', 'action', 'accept']) self.cli_set(['firewall', 'ipv6-name', name, 'rule', '4', 'packet-length', '1-1999']) self.cli_set(['firewall', 'ipv6-name', name, 'rule', '4', 'packet-length-exclude', '60000-65535']) + self.cli_set(['firewall', 'ipv6-name', name, 'rule', '4', 'dscp', '4-14']) + self.cli_set(['firewall', 'ipv6-name', name, 'rule', '4', 'dscp-exclude', '31-35']) self.cli_set(['interfaces', 'ethernet', interface, 'firewall', 'in', 'ipv6-name', name]) @@ -313,8 +321,8 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): nftables_search = [ [f'iifname "{interface}"', f'jump NAME6_{name}'], - ['ip6 length { 65, 513, 1025 }', 'return'], - ['ip6 length { 1-1999 }', 'ip6 length != { 60000-65535 }', 'return'], + ['ip6 length { 65, 513, 1025 }', 'ip6 dscp { af21, 0x35 }', 'return'], + ['ip6 length { 1-1999 }', 'ip6 length != { 60000-65535 }', 'ip6 dscp { 0x04-0x0e }', 'ip6 dscp != { 0x1f-0x23 }', 'return'], [f'log prefix "[{name}-default-D]"', 'drop'] ] diff --git a/smoketest/scripts/cli/test_policy_route.py b/smoketest/scripts/cli/test_policy_route.py index f8406bbe0..309fe908e 100755 --- a/smoketest/scripts/cli/test_policy_route.py +++ b/smoketest/scripts/cli/test_policy_route.py @@ -177,6 +177,9 @@ class TestPolicyRoute(VyOSUnitTestSHIM.TestCase): self.cli_set(['policy', 'route', 'smoketest', 'rule', '4', 'packet-length', '1024-2048']) self.cli_set(['policy', 'route', 'smoketest', 'rule', '4', 'log', 'enable']) self.cli_set(['policy', 'route', 'smoketest', 'rule', '4', 'set', 'table', table_id]) + self.cli_set(['policy', 'route', 'smoketest', 'rule', '5', 'dscp', '41']) + self.cli_set(['policy', 'route', 'smoketest', 'rule', '5', 'dscp', '57-59']) + self.cli_set(['policy', 'route', 'smoketest', 'rule', '5', 'set', 'table', table_id]) self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '1', 'protocol', 'udp']) self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '1', 'action', 'drop']) @@ -196,6 +199,9 @@ class TestPolicyRoute(VyOSUnitTestSHIM.TestCase): self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '4', 'packet-length-exclude', '1024-2048']) self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '4', 'log', 'enable']) self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '4', 'set', 'table', table_id]) + self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '5', 'dscp-exclude', '61']) + self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '5', 'dscp-exclude', '14-19']) + self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '5', 'set', 'table', table_id]) self.cli_set(['interfaces', 'ethernet', interface, 'policy', 'route', 'smoketest']) self.cli_set(['interfaces', 'ethernet', interface, 'policy', 'route6', 'smoketest6']) @@ -210,7 +216,8 @@ class TestPolicyRoute(VyOSUnitTestSHIM.TestCase): ['meta l4proto udp', 'drop'], ['tcp flags & (syn | ack) == syn', 'meta mark set ' + mark_hex], ['ct state { new }', 'tcp dport { 22 }', 'ip saddr 198.51.100.0/24', 'ip ttl > 2', 'meta mark set ' + mark_hex], - ['meta l4proto icmp', 'log prefix "[smoketest-4-A]"', 'icmp type echo-request', 'ip length { 128, 1024-2048 }', 'meta mark set ' + mark_hex] + ['meta l4proto icmp', 'log prefix "[smoketest-4-A]"', 'icmp type echo-request', 'ip length { 128, 1024-2048 }', 'meta mark set ' + mark_hex], + ['ip dscp { 0x29, 0x39-0x3b }', 'meta mark set ' + mark_hex] ] self.verify_nftables(nftables_search, 'ip mangle') @@ -221,7 +228,8 @@ class TestPolicyRoute(VyOSUnitTestSHIM.TestCase): ['meta l4proto udp', 'drop'], ['tcp flags & (syn | ack) == syn', 'meta mark set ' + mark_hex], ['ct state { new }', 'tcp dport { 22 }', 'ip6 saddr 2001:db8::/64', 'ip6 hoplimit > 2', 'meta mark set ' + mark_hex], - ['meta l4proto ipv6-icmp', 'log prefix "[smoketest6-4-A]"', 'icmpv6 type echo-request', 'ip6 length != { 128, 1024-2048 }', 'meta mark set ' + mark_hex] + ['meta l4proto ipv6-icmp', 'log prefix "[smoketest6-4-A]"', 'icmpv6 type echo-request', 'ip6 length != { 128, 1024-2048 }', 'meta mark set ' + mark_hex], + ['ip6 dscp != { 0x0e-0x13, 0x3d }', 'meta mark set ' + mark_hex] ] self.verify_nftables(nftables6_search, 'ip6 mangle') -- cgit v1.2.3