ruleset: emit AF specific rules for DSCP matches
authorJo-Philipp Wich <jo@mein.io>
Wed, 26 Jan 2022 10:00:44 +0000 (11:00 +0100)
committerJo-Philipp Wich <jo@mein.io>
Wed, 26 Jan 2022 10:13:03 +0000 (11:13 +0100)
Since nftables `dscp` matches are IP family specific we must emit
separate IPv4 and IPv6 rules in case DSCP matches are present.

Ref: https://bugs.openwrt.org/index.php?do=details&task_id=4240
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
root/usr/share/firewall4/templates/rule.uc
root/usr/share/ucode/fw4.uc
tests/03_rules/03_constraints

index 5f1b696c9cf9fde63c35c1096c3609af31f39615..c8bab595a6ee9973bae5577601553acb89a8e444 100644 (file)
@@ -56,7 +56,7 @@
 {%+ if (rule.mark && rule.mark.mask == 0xFFFFFFFF): -%}
        meta mark{% if (rule.mark.invert): %} !={% endif %} {{ fw4.hex(rule.mark.mark) }} {%+ endif -%}
 {%+ if (rule.dscp): -%}
-       dscp{% if (rule.dscp.invert): %} !={% endif %} {{ fw4.hex(rule.dscp.dscp) }} {%+ endif -%}
+       {{ fw4.ipproto(rule.family) }} dscp{% if (rule.dscp.invert): %} !={% endif %} {{ fw4.hex(rule.dscp.dscp) }} {%+ endif -%}
 {%+ if (rule.ipset): -%}
        {{ fw4.concat(rule.ipset.fields) }}{{
                rule.ipset.invert ? ' !=' : ''
index 113e4f551214de11e6419c512c19d54e1d6d8bc6..0d1ece0cbb34f23abf5a5b192a6e63bd69dd2088 100644 (file)
@@ -2239,8 +2239,8 @@ return {
                        sip = subnets_split_af(rule.src_ip);
                        dip = subnets_split_af(rule.dest_ip);
 
-                       let has_ipv4_specifics = (length(sip[0]) || length(dip[0]) || length(itypes4));
-                       let has_ipv6_specifics = (length(sip[1]) || length(dip[1]) || length(itypes6));
+                       let has_ipv4_specifics = (length(sip[0]) || length(dip[0]) || length(itypes4) || rule.dscp !== null);
+                       let has_ipv6_specifics = (length(sip[1]) || length(dip[1]) || length(itypes6) || rule.dscp !== null);
 
                        /* if no family was configured, infer target family from IP addresses */
                        if (family === null) {
index a8e3f66cccfc446dc6b48e2912362758046c846f..db6cb88034e33fa7f656d3d3a22786a516e4cfa7 100644 (file)
@@ -47,12 +47,19 @@ Testing various option constraints.
                },
 
                {
-                       ".description": "DSCP rules require a set_dscp option",
+                       ".description": "DSCP target rules require a set_dscp option",
                        "proto": "any",
-                       "name": "DSCP rule #1",
+                       "name": "DSCP target rule #1",
                        "target": "dscp"
                },
 
+               {
+                       ".description": "DSCP matches enforce AF specific rules due to required ip/ip6 prefix",
+                       "proto": "any",
+                       "name": "DSCP match rule #1",
+                       "dscp": "0x0"
+               },
+
                {
                        ".description": "Mark rules require a set_xmark or set_mark option",
                        "proto": "any",
@@ -67,8 +74,8 @@ Testing various option constraints.
 [!] Section @rule[0] (Helper rule #1) must specify a source zone for target 'helper'
 [!] Section @rule[1] (Helper rule #2) must specify option 'set_helper' for target 'helper'
 [!] Section @rule[2] (Notrack rule) must specify a source zone for target 'notrack'
-[!] Section @rule[3] (DSCP rule #1) must specify option 'set_dscp' for target 'dscp'
-[!] Section @rule[4] (Mark rule #1) must specify option 'set_mark' or 'set_xmark' for target 'mark'
+[!] Section @rule[3] (DSCP target rule #1) must specify option 'set_dscp' for target 'dscp'
+[!] Section @rule[5] (Mark rule #1) must specify option 'set_mark' or 'set_xmark' for target 'mark'
 -- End --
 
 -- Expect stdout --
@@ -117,6 +124,8 @@ table inet fw4 {
                oifname "lo" accept comment "!fw4: Accept traffic towards loopback"
 
                ct state established,related accept comment "!fw4: Allow outbound established and related flows"
+               meta nfproto ipv4 ip dscp 0x0 counter comment "!fw4: DSCP match rule #1"
+               meta nfproto ipv6 ip6 dscp 0x0 counter comment "!fw4: DSCP match rule #1"
        }
 
        chain handle_reject {