diff options
| -rw-r--r-- | data/config-mode-dependencies/vyos-1x.json | 21 | ||||
| -rw-r--r-- | interface-definitions/include/firewall/common-rule-inet.xml.i | 1 | ||||
| -rw-r--r-- | interface-definitions/include/firewall/firewall-mark.xml.i | 26 | ||||
| -rw-r--r-- | interface-definitions/include/policy/route-common.xml.i | 1 | ||||
| -rw-r--r-- | python/vyos/firewall.py | 8 | ||||
| -rwxr-xr-x | smoketest/scripts/cli/test_firewall.py | 11 | ||||
| -rwxr-xr-x | smoketest/scripts/cli/test_policy_route.py | 12 | ||||
| -rwxr-xr-x | src/conf_mode/conntrack.py | 7 | ||||
| -rw-r--r-- | src/validators/numeric-exclude | 8 | 
9 files changed, 82 insertions, 13 deletions
| diff --git a/data/config-mode-dependencies/vyos-1x.json b/data/config-mode-dependencies/vyos-1x.json index 72a3d1153..6c86642c7 100644 --- a/data/config-mode-dependencies/vyos-1x.json +++ b/data/config-mode-dependencies/vyos-1x.json @@ -1,10 +1,23 @@  {    "conntrack": {"conntrack_sync": ["conntrack_sync"]}, -  "firewall": {"conntrack": ["conntrack"], "group_resync": ["conntrack", "nat", "policy-route"]}, +  "firewall": { +                "conntrack": ["conntrack"], +                "conntrack_sync": ["conntrack_sync"], +                "group_resync": ["conntrack", "nat", "policy-route"] +              },    "http_api": {"https": ["https"]}, -  "load_balancing_wan": {"conntrack": ["conntrack"]}, -  "nat": {"conntrack": ["conntrack"]}, -  "nat66": {"conntrack": ["conntrack"]}, +  "load_balancing_wan": { +                          "conntrack": ["conntrack"], +                          "conntrack_sync": ["conntrack_sync"] +                        }, +  "nat": { +           "conntrack": ["conntrack"], +           "conntrack_sync": ["conntrack_sync"] +         }, +  "nat66": { +             "conntrack": ["conntrack"], +             "conntrack_sync": ["conntrack_sync"] +           },    "pki": {             "ethernet": ["interfaces-ethernet"],             "openvpn": ["interfaces-openvpn"], diff --git a/interface-definitions/include/firewall/common-rule-inet.xml.i b/interface-definitions/include/firewall/common-rule-inet.xml.i index 872abe6cc..a55a1a551 100644 --- a/interface-definitions/include/firewall/common-rule-inet.xml.i +++ b/interface-definitions/include/firewall/common-rule-inet.xml.i @@ -3,6 +3,7 @@  #include <include/generic-description.xml.i>  #include <include/firewall/dscp.xml.i>  #include <include/firewall/packet-options.xml.i> +#include <include/firewall/firewall-mark.xml.i>  #include <include/firewall/connection-mark.xml.i>  #include <include/firewall/conntrack-helper.xml.i>  #include <include/firewall/nft-queue.xml.i> diff --git a/interface-definitions/include/firewall/firewall-mark.xml.i b/interface-definitions/include/firewall/firewall-mark.xml.i new file mode 100644 index 000000000..36a939ba3 --- /dev/null +++ b/interface-definitions/include/firewall/firewall-mark.xml.i @@ -0,0 +1,26 @@ +<!-- include start from firewall/firewall-mark.xml.i --> +<leafNode name="mark"> +  <properties> +    <help>Firewall mark</help> +    <valueHelp> +      <format>u32:0-2147483647</format> +      <description>Firewall mark to match</description> +    </valueHelp> +    <valueHelp> +      <format>!u32:0-2147483647</format> +      <description>Inverted Firewall mark to match</description> +    </valueHelp> +    <valueHelp> +      <format><start-end></format> +      <description>Firewall mark range to match</description> +    </valueHelp> +    <valueHelp> +      <format>!<start-end></format> +      <description>Firewall mark inverted range to match</description> +    </valueHelp> +    <constraint> +      <validator name="numeric-exclude" argument="--allow-range --range 0-2147483647"/> +    </constraint> +  </properties> +</leafNode> +<!-- include end -->
\ No newline at end of file diff --git a/interface-definitions/include/policy/route-common.xml.i b/interface-definitions/include/policy/route-common.xml.i index 6551d23ab..8eab04d4a 100644 --- a/interface-definitions/include/policy/route-common.xml.i +++ b/interface-definitions/include/policy/route-common.xml.i @@ -1,6 +1,7 @@  <!-- include start from policy/route-common.xml.i -->
  #include <include/policy/route-rule-action.xml.i>
  #include <include/generic-description.xml.i>
 +#include <include/firewall/firewall-mark.xml.i>
  <leafNode name="disable">
    <properties>
      <help>Option to disable firewall rule</help>
 diff --git a/python/vyos/firewall.py b/python/vyos/firewall.py index 9122e264e..c07ed1adf 100644 --- a/python/vyos/firewall.py +++ b/python/vyos/firewall.py @@ -381,6 +381,14 @@ def parse_rule(rule_conf, hook, fw_name, rule_id, ip_name):          conn_mark_str = ','.join(rule_conf['connection_mark'])          output.append(f'ct mark {{{conn_mark_str}}}') +    if 'mark' in rule_conf: +        mark = rule_conf['mark'] +        operator = '' +        if mark[0] == '!': +            operator = '!=' +            mark = mark[1:] +        output.append(f'meta mark {operator} {{{mark}}}') +      if 'vlan' in rule_conf:          if 'id' in rule_conf['vlan']:              output.append(f'vlan id {rule_conf["vlan"]["id"]}') diff --git a/smoketest/scripts/cli/test_firewall.py b/smoketest/scripts/cli/test_firewall.py index 67e949f95..7b4ba11d0 100755 --- a/smoketest/scripts/cli/test_firewall.py +++ b/smoketest/scripts/cli/test_firewall.py @@ -308,10 +308,12 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):          self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'default-action', 'drop'])          self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '1', 'source', 'address', '198.51.100.1']) +        self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '1', 'mark', '1010'])          self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '1', 'action', 'jump'])          self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '1', 'jump-target', name])          self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '2', 'protocol', 'tcp']) +        self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '2', 'mark', '!98765'])          self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '2', 'action', 'queue'])          self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '2', 'queue', '3'])          self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '3', 'protocol', 'udp']) @@ -325,11 +327,11 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):          nftables_search = [              ['chain VYOS_FORWARD_filter'],              ['type filter hook forward priority filter; policy drop;'], -            ['ip saddr 198.51.100.1', f'jump NAME_{name}'], +            ['ip saddr 198.51.100.1', 'meta mark 0x000003f2', f'jump NAME_{name}'],              ['chain VYOS_INPUT_filter'],              ['type filter hook input priority filter; policy accept;'], -            [f'meta l4proto tcp','queue to 3'], -            [f'meta l4proto udp','queue flags bypass,fanout to 0-15'], +            ['meta mark != 0x000181cd', 'meta l4proto tcp','queue to 3'], +            ['meta l4proto udp','queue flags bypass,fanout to 0-15'],              [f'chain NAME_{name}'],              ['ip length { 64, 512, 1024 }', 'ip dscp { 0x11, 0x34 }', f'log prefix "[ipv4-NAM-{name}-6-A]" log group 66 snaplen 6666 queue-threshold 32000', 'accept'],              ['ip length 1-30000', 'ip length != 60000-65535', 'ip dscp 0x03-0x0b', 'ip dscp != 0x15-0x19', 'accept'], @@ -466,6 +468,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):          self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'default-action', 'accept'])          self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '1', 'source', 'address', '2001:db8::/64']) +        self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '1', 'mark', '!6655-7766'])          self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '1', 'action', 'jump'])          self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '1', 'jump-target', name]) @@ -477,7 +480,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):              ['ip6 length 1-1999', 'ip6 length != 60000-65535', 'ip6 dscp 0x04-0x0e', 'ip6 dscp != 0x1f-0x23', 'accept'],              ['chain VYOS_IPV6_INPUT_filter'],              ['type filter hook input priority filter; policy accept;'], -            ['ip6 saddr 2001:db8::/64', f'jump NAME6_{name}'], +            ['ip6 saddr 2001:db8::/64', 'meta mark != 0x000019ff-0x00001e56', f'jump NAME6_{name}'],              [f'chain NAME6_{name}'],              ['ip6 length { 65, 513, 1025 }', 'ip6 dscp { af21, 0x35 }', 'accept'],              [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 c7ddf873e..72192fb98 100755 --- a/smoketest/scripts/cli/test_policy_route.py +++ b/smoketest/scripts/cli/test_policy_route.py @@ -191,15 +191,18 @@ class TestPolicyRoute(VyOSUnitTestSHIM.TestCase):      def test_pbr_matching_criteria(self):          self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'protocol', 'udp'])          self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'action', 'drop']) +        self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'mark', '2020'])          self.cli_set(['policy', 'route', 'smoketest', 'rule', '2', 'protocol', 'tcp'])          self.cli_set(['policy', 'route', 'smoketest', 'rule', '2', 'tcp', 'flags', 'syn'])          self.cli_set(['policy', 'route', 'smoketest', 'rule', '2', 'tcp', 'flags', 'not', 'ack']) +        self.cli_set(['policy', 'route', 'smoketest', 'rule', '2', 'mark', '2-3000'])          self.cli_set(['policy', 'route', 'smoketest', 'rule', '2', 'set', 'table', table_id])          self.cli_set(['policy', 'route', 'smoketest', 'rule', '3', 'source', 'address', '198.51.100.0/24'])          self.cli_set(['policy', 'route', 'smoketest', 'rule', '3', 'protocol', 'tcp'])          self.cli_set(['policy', 'route', 'smoketest', 'rule', '3', 'destination', 'port', '22'])          self.cli_set(['policy', 'route', 'smoketest', 'rule', '3', 'state', 'new', 'enable'])          self.cli_set(['policy', 'route', 'smoketest', 'rule', '3', 'ttl', 'gt', '2']) +        self.cli_set(['policy', 'route', 'smoketest', 'rule', '3', 'mark', '!456'])          self.cli_set(['policy', 'route', 'smoketest', 'rule', '3', 'set', 'table', table_id])          self.cli_set(['policy', 'route', 'smoketest', 'rule', '4', 'protocol', 'icmp'])          self.cli_set(['policy', 'route', 'smoketest', 'rule', '4', 'icmp', 'type-name', 'echo-request']) @@ -210,6 +213,7 @@ class TestPolicyRoute(VyOSUnitTestSHIM.TestCase):          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', 'mark', '!456-500'])          self.cli_set(['policy', 'route', 'smoketest', 'rule', '5', 'set', 'table', table_id])          self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '1', 'protocol', 'udp']) @@ -247,11 +251,11 @@ class TestPolicyRoute(VyOSUnitTestSHIM.TestCase):          # IPv4          nftables_search = [              ['iifname { "' + interface + '", "' + interface_wc + '" }', 'jump VYOS_PBR_UD_smoketest'], -            ['meta l4proto udp', 'drop'], -            ['tcp flags syn / syn,ack', '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 udp', 'meta mark 0x000007e4', 'drop'], +            ['tcp flags syn / syn,ack', 'meta mark 0x00000002-0x00000bb8', 'meta mark set ' + mark_hex], +            ['ct state new', 'tcp dport 22', 'ip saddr 198.51.100.0/24', 'ip ttl > 2', 'meta mark != 0x000001c8', 'meta mark set ' + mark_hex],              ['log prefix "[ipv4-route-smoketest-4-A]"', 'icmp type echo-request', 'ip length { 128, 1024-2048 }', 'meta pkttype other', 'meta mark set ' + mark_hex], -            ['ip dscp { 0x29, 0x39-0x3b }', 'meta mark set ' + mark_hex] +            ['ip dscp { 0x29, 0x39-0x3b }', 'meta mark != 0x000001c8-0x000001f4', 'meta mark set ' + mark_hex]          ]          self.verify_nftables(nftables_search, 'ip vyos_mangle') diff --git a/src/conf_mode/conntrack.py b/src/conf_mode/conntrack.py index 2c5fa335e..4cece6921 100755 --- a/src/conf_mode/conntrack.py +++ b/src/conf_mode/conntrack.py @@ -212,7 +212,12 @@ def apply(conntrack):          module_str = ' '.join(rm_modules)          cmd(f'rmmod {module_str}') -    call_dependents() +    try: +        call_dependents() +    except ConfigError: +        # Ignore config errors on dependent due to being called too early. Example: +        # ConfigError("ConfigError('Interface ethN requires an IP address!')") +        pass      # We silently ignore all errors      # See: https://bugzilla.redhat.com/show_bug.cgi?id=1264080 diff --git a/src/validators/numeric-exclude b/src/validators/numeric-exclude new file mode 100644 index 000000000..676a240b6 --- /dev/null +++ b/src/validators/numeric-exclude @@ -0,0 +1,8 @@ +#!/bin/sh +path=$(dirname "$0") +num="${@: -1}" +if [ "${num:0:1}" != "!" ]; then +   ${path}/numeric $@ +else +    ${path}/numeric ${@:1:$#-1} ${num:1} +fi | 
