]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
evaluate: reset statement length context only for set mappings
authorPablo Neira Ayuso <pablo@netfilter.org>
Sun, 5 Nov 2023 17:33:14 +0000 (18:33 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 6 Nov 2023 11:16:07 +0000 (12:16 +0100)
map expression (which is used a key to look up for the mapping) needs to
consider the statement length context, otherwise incorrect bytecode is
generated when {ct,meta} statement is generated.

 # nft -f - <<EOF
 add table ip6 t
 add chain ip6 t c
 add map ip6 t mapv6 { typeof ip6 dscp : meta mark; }
 EOF

 # nft -d netlink add rule ip6 t c meta mark set ip6 dscp map @mapv6
 ip6 t c
   [ payload load 2b @ network header + 0 => reg 1 ]
   [ bitwise reg 1 = ( reg 1 & 0x0000c00f ) ^ 0x00000000 ]
   ... missing byteorder conversion here before shift ...
   [ bitwise reg 1 = ( reg 1 >> 0x00000006 ) ]
   [ lookup reg 1 set mapv6 dreg 1 ]
   [ meta set mark with reg 1 ]

Reset statement length context only for the mapping side for the
elements in the set.

Fixes: edecd58755a8 ("evaluate: support shifts larger than the width of the left operand")
Reported-by: Brian Davidson <davidson.brian@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
src/evaluate.c
tests/py/ip6/ip6.t
tests/py/ip6/ip6.t.json
tests/py/ip6/ip6.t.payload.inet
tests/py/ip6/ip6.t.payload.ip6

index 894987df7895928356a5555185165b1314b33813..65e4cef9c14720551cfc2e73b74c752050ac2ccc 100644 (file)
@@ -1918,13 +1918,13 @@ static int expr_evaluate_map(struct eval_ctx *ctx, struct expr **expr)
        }
 
        expr_set_context(&ctx->ectx, NULL, 0);
-       ctx->stmt_len = 0;
        if (expr_evaluate(ctx, &map->map) < 0)
                return -1;
        if (expr_is_constant(map->map))
                return expr_error(ctx->msgs, map->map,
                                  "Map expression can not be constant");
 
+       ctx->stmt_len = 0;
        mappings = map->mappings;
        mappings->set_flags |= NFT_SET_MAP;
 
index 2ffe318e1e6df0c085a99a7ca4b1a7a2fb747629..60ea22333057a1c6cd1d7cd29a1f90a7b412356a 100644 (file)
@@ -17,6 +17,11 @@ ip6 dscp != 0x20;ok;ip6 dscp != cs4
 ip6 dscp {cs0, cs1, cs2, cs3, cs4, cs5, cs6, cs7, af11, af12, af13, af21, af22, af23, af31, af32, af33, af41, af42, af43, ef};ok
 ip6 dscp vmap { 0x04 : accept, 0x3f : continue } counter;ok
 
+!map1 type dscp : mark;ok
+meta mark set ip6 dscp map @map1;ok
+!map2 type dscp . ipv6_addr : mark;ok
+meta mark set ip6 dscp . ip6 daddr map @map2;ok
+
 ip6 flowlabel 22;ok
 ip6 flowlabel != 233;ok
 - ip6 flowlabel 33-45;ok
index cf802175b792685db25328d74a41c450db9821d0..5411190d6bb3741e4afbf67a7d5d6bd0c93e7564 100644 (file)
     }
 ]
 
+# meta mark set ip6 dscp map @map1
+[
+    {
+        "mangle": {
+            "key": {
+                "meta": {
+                    "key": "mark"
+                }
+            },
+            "value": {
+                "map": {
+                    "data": "@map1",
+                    "key": {
+                        "payload": {
+                            "field": "dscp",
+                            "protocol": "ip6"
+                        }
+                    }
+                }
+            }
+        }
+    }
+]
+
+# meta mark set ip6 dscp . ip6 daddr map @map2
+[
+    {
+        "mangle": {
+            "key": {
+                "meta": {
+                    "key": "mark"
+                }
+            },
+            "value": {
+                "map": {
+                    "data": "@map2",
+                    "key": {
+                        "concat": [
+                            {
+                                "payload": {
+                                    "field": "dscp",
+                                    "protocol": "ip6"
+                                }
+                            },
+                            {
+                                "payload": {
+                                    "field": "daddr",
+                                    "protocol": "ip6"
+                                }
+                            }
+                        ]
+                    }
+                }
+            }
+        }
+    }
+]
+
 # ip6 flowlabel 22
 [
     {
index 20dfe5497367633c295fb4819640c5ebf9d84dea..214a0ed9f90f2fb1632c42477d8256f78a7e368c 100644 (file)
@@ -53,6 +53,29 @@ ip6 test-ip6 input
   [ lookup reg 1 set __map%d dreg 0 ]
   [ counter pkts 0 bytes 0 ]
 
+# meta mark set ip6 dscp map @map1
+inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
+  [ payload load 2b @ network header + 0 => reg 1 ]
+  [ bitwise reg 1 = ( reg 1 & 0x0000c00f ) ^ 0x00000000 ]
+  [ byteorder reg 1 = ntoh(reg 1, 2, 2) ]
+  [ bitwise reg 1 = ( reg 1 >> 0x00000006 ) ]
+  [ lookup reg 1 set map1 dreg 1 ]
+  [ meta set mark with reg 1 ]
+
+# meta mark set ip6 dscp . ip6 daddr map @map2
+inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
+  [ payload load 2b @ network header + 0 => reg 1 ]
+  [ bitwise reg 1 = ( reg 1 & 0x0000c00f ) ^ 0x00000000 ]
+  [ byteorder reg 1 = ntoh(reg 1, 2, 2) ]
+  [ bitwise reg 1 = ( reg 1 >> 0x00000006 ) ]
+  [ payload load 16b @ network header + 24 => reg 9 ]
+  [ lookup reg 1 set map2 dreg 1 ]
+  [ meta set mark with reg 1 ]
+
 # ip6 flowlabel 22
 inet test-inet input
   [ meta load nfproto => reg 1 ]
index f8e3ca3cb62277a4585be7e148b024a865158474..428b8ea412785b6da971eaec58dcbbe25366ddfd 100644 (file)
@@ -41,6 +41,25 @@ ip6 test-ip6 input
   [ lookup reg 1 set __map%d dreg 0 ]
   [ counter pkts 0 bytes 0 ]
 
+# meta mark set ip6 dscp map @map1
+ip6 test-ip6 input
+  [ payload load 2b @ network header + 0 => reg 1 ]
+  [ bitwise reg 1 = ( reg 1 & 0x0000c00f ) ^ 0x00000000 ]
+  [ byteorder reg 1 = ntoh(reg 1, 2, 2) ]
+  [ bitwise reg 1 = ( reg 1 >> 0x00000006 ) ]
+  [ lookup reg 1 set map1 dreg 1 ]
+  [ meta set mark with reg 1 ]
+
+# meta mark set ip6 dscp . ip6 daddr map @map2
+ip6 test-ip6 input
+  [ payload load 2b @ network header + 0 => reg 1 ]
+  [ bitwise reg 1 = ( reg 1 & 0x0000c00f ) ^ 0x00000000 ]
+  [ byteorder reg 1 = ntoh(reg 1, 2, 2) ]
+  [ bitwise reg 1 = ( reg 1 >> 0x00000006 ) ]
+  [ payload load 16b @ network header + 24 => reg 9 ]
+  [ lookup reg 1 set map2 dreg 1 ]
+  [ meta set mark with reg 1 ]
+
 # ip6 flowlabel 22
 ip6 test-ip6 input
   [ payload load 3b @ network header + 1 => reg 1 ]