diff options
| -rw-r--r-- | interface-definitions/firewall.xml.in | 2 | ||||
| -rw-r--r-- | interface-definitions/include/firewall/dscp.xml.i | 38 | ||||
| -rw-r--r-- | interface-definitions/policy-route.xml.in | 2 | ||||
| -rw-r--r-- | python/vyos/firewall.py | 7 | ||||
| -rwxr-xr-x | smoketest/scripts/cli/test_firewall.py | 24 | ||||
| -rwxr-xr-x | smoketest/scripts/cli/test_policy_route.py | 12 | 
6 files changed, 75 insertions, 10 deletions
| 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 @@                  </children>                </node>                #include <include/firewall/common-rule.xml.i> +              #include <include/firewall/dscp.xml.i>                #include <include/firewall/packet-length.xml.i>                #include <include/firewall/hop-limit.xml.i>                <node name="icmpv6"> @@ -530,6 +531,7 @@                  </children>                </node>                #include <include/firewall/common-rule.xml.i> +              #include <include/firewall/dscp.xml.i>                #include <include/firewall/packet-length.xml.i>                <node name="icmp">                  <properties> 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 @@ +<!-- include start from firewall/dscp.xml.i --> +<leafNode name="dscp"> +  <properties> +    <help>DSCP value</help> +    <valueHelp> +      <format>u32:0-63</format> +      <description>DSCP value to match</description> +    </valueHelp> +    <valueHelp> +      <format><start-end></format> +      <description>DSCP range to match</description> +    </valueHelp> +    <constraint> +      <validator name="numeric" argument="--range 0-63"/> +      <validator name="range" argument="--min=0 --max=63"/> +    </constraint> +    <multi/> +  </properties> +</leafNode> +<leafNode name="dscp-exclude"> +  <properties> +    <help>DSCP value not to match</help> +    <valueHelp> +      <format>u32:0-63</format> +      <description>DSCP value not to match</description> +    </valueHelp> +    <valueHelp> +      <format><start-end></format> +      <description>DSCP range not to match</description> +    </valueHelp> +    <constraint> +      <validator name="numeric" argument="--range 0-63"/> +      <validator name="range" argument="--min=0 --max=63"/> +    </constraint> +    <multi/> +  </properties> +</leafNode> +<!-- include end -->
\ 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 @@                  </children>                </node>                #include <include/policy/route-common-rule-ipv6.xml.i> +              #include <include/firewall/dscp.xml.i>                #include <include/firewall/packet-length.xml.i>                #include <include/firewall/hop-limit.xml.i>              </children> @@ -98,6 +99,7 @@                  </children>                </node>                #include <include/policy/route-common-rule.xml.i> +              #include <include/firewall/dscp.xml.i>                #include <include/firewall/packet-length.xml.i>                #include <include/firewall/ttl.xml.i>              </children> 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') | 
