diff options
| author | Christian Poessinger <christian@poessinger.com> | 2022-12-19 19:32:45 +0100 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-12-19 19:32:45 +0100 | 
| commit | 71d2c583e3b8331e877bbb2f364b6da5c0a587a0 (patch) | |
| tree | 41069c9cf16f53091ee13812aed97cf3f2194ff0 | |
| parent | c4097097487467300a0a63c8a75f670dc0429f7c (diff) | |
| parent | d9c9092dcdc430b26a326345934c4513534bff9b (diff) | |
| download | vyos-1x-71d2c583e3b8331e877bbb2f364b6da5c0a587a0.tar.gz vyos-1x-71d2c583e3b8331e877bbb2f364b6da5c0a587a0.zip | |
Merge pull request #1718 from nicolas-fort/T4886_conn_mark
T4886: Firewall and route policy: Add connection-mark feature to vyos.
| -rw-r--r-- | interface-definitions/firewall.xml.in | 2 | ||||
| -rw-r--r-- | interface-definitions/include/firewall/connection-mark.xml.i | 15 | ||||
| -rw-r--r-- | interface-definitions/include/policy/route-common.xml.i | 12 | ||||
| -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 | 6 | ||||
| -rwxr-xr-x | smoketest/scripts/cli/test_policy_route.py | 21 | 
7 files changed, 64 insertions, 1 deletions
| diff --git a/interface-definitions/firewall.xml.in b/interface-definitions/firewall.xml.in index c964abb41..7d7e0a38f 100644 --- a/interface-definitions/firewall.xml.in +++ b/interface-definitions/firewall.xml.in @@ -461,6 +461,7 @@                #include <include/firewall/dscp.xml.i>                #include <include/firewall/packet-length.xml.i>                #include <include/firewall/hop-limit.xml.i> +              #include <include/firewall/connection-mark.xml.i>                <node name="icmpv6">                  <properties>                    <help>ICMPv6 type and code information</help> @@ -628,6 +629,7 @@                #include <include/firewall/common-rule.xml.i>                #include <include/firewall/dscp.xml.i>                #include <include/firewall/packet-length.xml.i> +              #include <include/firewall/connection-mark.xml.i>                <node name="icmp">                  <properties>                    <help>ICMP type and code information</help> diff --git a/interface-definitions/include/firewall/connection-mark.xml.i b/interface-definitions/include/firewall/connection-mark.xml.i new file mode 100644 index 000000000..2cb826635 --- /dev/null +++ b/interface-definitions/include/firewall/connection-mark.xml.i @@ -0,0 +1,15 @@ +<!-- include start from firewall/connection-mark.xml.i --> +<leafNode name="connection-mark"> +  <properties> +    <help>Connection mark</help> +    <valueHelp> +      <format>u32:1-2147483647</format> +      <description>Connection-mark to match</description> +    </valueHelp> +    <constraint> +      <validator name="numeric" argument="--range 1-2147483647"/> +    </constraint> +    <multi/> +  </properties> +</leafNode> +<!-- include end --> diff --git a/interface-definitions/include/policy/route-common.xml.i b/interface-definitions/include/policy/route-common.xml.i index 8b959c2a4..6973d7a8f 100644 --- a/interface-definitions/include/policy/route-common.xml.i +++ b/interface-definitions/include/policy/route-common.xml.i @@ -159,6 +159,18 @@      <help>Packet modifications</help>
    </properties>
    <children>
 +    <leafNode name="connection-mark">
 +      <properties>
 +        <help>Connection marking</help>
 +        <valueHelp>
 +          <format>u32:1-2147483647</format>
 +          <description>Connection marking</description>
 +        </valueHelp>
 +        <constraint>
 +          <validator name="numeric" argument="--range 1-2147483647"/>
 +        </constraint>
 +      </properties>
 +    </leafNode>
      <leafNode name="dscp">
        <properties>
          <help>Packet Differentiated Services Codepoint (DSCP)</help>
 diff --git a/interface-definitions/policy-route.xml.in b/interface-definitions/policy-route.xml.in index 48a5bf7d1..d7b159839 100644 --- a/interface-definitions/policy-route.xml.in +++ b/interface-definitions/policy-route.xml.in @@ -52,6 +52,7 @@                #include <include/firewall/dscp.xml.i>                #include <include/firewall/packet-length.xml.i>                #include <include/firewall/hop-limit.xml.i> +              #include <include/firewall/connection-mark.xml.i>              </children>            </tagNode>          </children> @@ -106,6 +107,7 @@                #include <include/firewall/dscp.xml.i>                #include <include/firewall/packet-length.xml.i>                #include <include/firewall/ttl.xml.i> +              #include <include/firewall/connection-mark.xml.i>              </children>            </tagNode>          </children> diff --git a/python/vyos/firewall.py b/python/vyos/firewall.py index 429c44802..b4b9e67bb 100644 --- a/python/vyos/firewall.py +++ b/python/vyos/firewall.py @@ -322,6 +322,10 @@ def parse_rule(rule_conf, fw_name, rule_id, ip_name):      if tcp_mss:          output.append(f'tcp option maxseg size {tcp_mss}') +    if 'connection_mark' in rule_conf: +        conn_mark_str = ','.join(rule_conf['connection_mark']) +        output.append(f'ct mark {{{conn_mark_str}}}') +      output.append('counter')      if 'set' in rule_conf: @@ -368,6 +372,9 @@ def parse_time(time):  def parse_policy_set(set_conf, def_suffix):      out = [] +    if 'connection_mark' in set_conf: +        conn_mark = set_conf['connection_mark'] +        out.append(f'ct mark set {conn_mark}')      if 'dscp' in set_conf:          dscp = set_conf['dscp']          out.append(f'ip{def_suffix} dscp set {dscp}') diff --git a/smoketest/scripts/cli/test_firewall.py b/smoketest/scripts/cli/test_firewall.py index 9b28eb81b..f1c18d761 100755 --- a/smoketest/scripts/cli/test_firewall.py +++ b/smoketest/scripts/cli/test_firewall.py @@ -199,6 +199,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):          name = 'smoketest'          interface = 'eth0'          mss_range = '501-1460' +        conn_mark = '555'          self.cli_set(['firewall', 'name', name, 'default-action', 'drop'])          self.cli_set(['firewall', 'name', name, 'enable-default-log']) @@ -234,11 +235,14 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):          self.cli_set(['firewall', 'name', name, 'rule', '6', 'action', 'return'])          self.cli_set(['firewall', 'name', name, 'rule', '6', 'protocol', 'gre'])          self.cli_set(['firewall', 'name', name, 'rule', '6', 'outbound-interface', 'interface-name', interface]) +        self.cli_set(['firewall', 'name', name, 'rule', '6', 'connection-mark', conn_mark])          self.cli_set(['firewall', 'interface', interface, 'in', 'name', name])          self.cli_commit() +        mark_hex = "{0:#010x}".format(int(conn_mark)) +          nftables_search = [              [f'iifname "{interface}"', f'jump NAME_{name}'],              ['saddr 172.16.20.10', 'daddr 172.16.10.10', 'log prefix "[smoketest-1-A]" level debug', 'ip ttl 15', 'return'], @@ -247,7 +251,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):              ['log prefix "[smoketest-default-D]"','smoketest default-action', 'drop'],              ['tcp dport 22', 'add @RECENT_smoketest_4 { ip saddr limit rate over 10/minute burst 10 packets }', 'drop'],              ['tcp flags & syn == syn', f'tcp option maxseg size {mss_range}', f'iifname "{interface}"'], -            ['meta l4proto gre', f'oifname "{interface}"', 'return'] +            ['meta l4proto gre', f'oifname "{interface}"', f'ct mark {mark_hex}', 'return']          ]          self.verify_nftables(nftables_search, 'ip vyos_filter') diff --git a/smoketest/scripts/cli/test_policy_route.py b/smoketest/scripts/cli/test_policy_route.py index 11b3c678e..cb48a84ff 100755 --- a/smoketest/scripts/cli/test_policy_route.py +++ b/smoketest/scripts/cli/test_policy_route.py @@ -21,6 +21,8 @@ from base_vyostest_shim import VyOSUnitTestSHIM  from vyos.util import cmd  mark = '100' +conn_mark = '555' +conn_mark_set = '111'  table_mark_offset = 0x7fffffff  table_id = '101'  interface = 'eth0' @@ -122,6 +124,25 @@ class TestPolicyRoute(VyOSUnitTestSHIM.TestCase):          self.verify_nftables(nftables_search, 'ip vyos_mangle') +    def test_pbr_mark_connection(self): +        self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'source', 'address', '172.16.20.10']) +        self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'destination', 'address', '172.16.10.10']) +        self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'connection-mark', conn_mark]) +        self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'set', 'connection-mark', conn_mark_set]) +        self.cli_set(['policy', 'route', 'smoketest', 'interface', interface]) + +        self.cli_commit() + +        mark_hex = "{0:#010x}".format(int(conn_mark)) +        mark_hex_set = "{0:#010x}".format(int(conn_mark_set)) + +        nftables_search = [ +            [f'iifname "{interface}"','jump VYOS_PBR_smoketest'], +            ['ip daddr 172.16.10.10', 'ip saddr 172.16.20.10', 'ct mark ' + mark_hex, 'ct mark set ' + mark_hex_set], +        ] + +        self.verify_nftables(nftables_search, 'ip vyos_mangle') +      def test_pbr_table(self):          self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'protocol', 'tcp'])          self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'destination', 'port', '8888']) | 
