]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
evaluate: skip byteorder conversion for selector smaller than 2 bytes
authorPablo Neira Ayuso <pablo@netfilter.org>
Wed, 7 Feb 2024 22:53:32 +0000 (23:53 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Fri, 9 Feb 2024 15:56:04 +0000 (16:56 +0100)
Add unary expression to trigger byteorder conversion for host byteorder
selectors only if selectors length is larger or equal than 2 bytes.

 # cat test.nft
 table ip x {
        set test {
                type ipv4_addr . ether_addr . inet_proto
                flags interval
        }

        chain y {
                ip saddr . ether saddr . meta l4proto @test counter
        }
 }

 # nft -f test.nft
 ip x y
  [ meta load iiftype => reg 1 ]
  [ cmp eq reg 1 0x00000001 ]
  [ payload load 4b @ network header + 12 => reg 1 ]
  [ payload load 6b @ link header + 6 => reg 9 ]
  [ meta load l4proto => reg 11 ]
  [ byteorder reg 11 = hton(reg 11, 2, 1) ] <--- should not be here
  [ lookup reg 1 set test ]
  [ counter pkts 0 bytes 0 ]

Fixes: 1017d323cafa ("src: support for selectors with different byteorder with interval concatenations")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
src/evaluate.c
tests/py/inet/meta.t
tests/py/inet/meta.t.json
tests/py/inet/meta.t.json.output
tests/py/inet/meta.t.payload

index 1b430b72de203c0855ae6ebd6326c2cd3b67b60e..92e009efd4b16ea5b848147f3999931052b1485f 100644 (file)
@@ -199,12 +199,14 @@ static int byteorder_conversion(struct eval_ctx *ctx, struct expr **expr,
 
                        assert(basetype == TYPE_INTEGER);
 
-                       op = byteorder_conversion_op(i, byteorder);
-                       unary = unary_expr_alloc(&i->location, op, i);
-                       if (expr_evaluate(ctx, &unary) < 0)
-                               return -1;
+                       if (div_round_up(i->len, BITS_PER_BYTE) >= 2) {
+                               op = byteorder_conversion_op(i, byteorder);
+                               unary = unary_expr_alloc(&i->location, op, i);
+                               if (expr_evaluate(ctx, &unary) < 0)
+                                       return -1;
 
-                       list_replace(&i->list, &unary->list);
+                               list_replace(&i->list, &unary->list);
+                       }
                }
 
                return 0;
index 5c062b39b8a928f8cbba5e1a936a9062c2ffe454..7d2515c97f47902d30ce1afc6ce11a38d871b7a8 100644 (file)
@@ -25,6 +25,7 @@ meta mark set ct mark >> 8;ok
 meta mark . tcp dport { 0x0000000a-0x00000014 . 80-90, 0x00100000-0x00100123 . 100-120 };ok
 ip saddr . meta mark { 1.2.3.4 . 0x00000100 , 1.2.3.6-1.2.3.8 . 0x00000200-0x00000300 };ok
 ip saddr . meta mark { 1.2.3.4 . 0x00000100 , 5.6.7.8 . 0x00000200 };ok
+ip saddr . ether saddr . meta l4proto { 1.2.3.4 . aa:bb:cc:dd:ee:ff . 6 };ok
 
 meta mark set ip dscp;ok
 meta mark set ip dscp | 0x40;ok
index 3ba0fd1dee2ad81b7738b8131fb147489cde6e6e..0fee165ff18a4d30cedaa47f8eb27ce3fe4eea6a 100644 (file)
     }
 ]
 
+# ip saddr . ether saddr . meta l4proto { 1.2.3.4 . aa:bb:cc:dd:ee:ff . 6 }
+[
+    {
+        "match": {
+            "left": {
+                "concat": [
+                    {
+                        "payload": {
+                            "field": "saddr",
+                            "protocol": "ip"
+                        }
+                    },
+                    {
+                        "payload": {
+                            "field": "saddr",
+                            "protocol": "ether"
+                        }
+                    },
+                    {
+                        "meta": {
+                            "key": "l4proto"
+                        }
+                    }
+                ]
+            },
+            "op": "==",
+            "right": {
+                "set": [
+                    {
+                        "concat": [
+                            "1.2.3.4",
+                            "aa:bb:cc:dd:ee:ff",
+                            "tcp"
+                        ]
+                    }
+                ]
+            }
+        }
+    }
+]
+
index 3e7dd2145e67f45ab4680a86498a6360773e1f9d..8697d5a2b9e22311c3a4fcf1884f546b3b59628a 100644 (file)
     }
 ]
 
+# ip saddr . ether saddr . meta l4proto { 1.2.3.4 . aa:bb:cc:dd:ee:ff . 6 }
+[
+    {
+        "match": {
+            "left": {
+                "concat": [
+                    {
+                        "payload": {
+                            "field": "saddr",
+                            "protocol": "ip"
+                        }
+                    },
+                    {
+                        "payload": {
+                            "field": "saddr",
+                            "protocol": "ether"
+                        }
+                    },
+                    {
+                        "meta": {
+                            "key": "l4proto"
+                        }
+                    }
+                ]
+            },
+            "op": "==",
+            "right": {
+                "set": [
+                    {
+                        "concat": [
+                            "1.2.3.4",
+                            "aa:bb:cc:dd:ee:ff",
+                            6
+                        ]
+                    }
+                ]
+            }
+        }
+    }
+]
+
index c53b5077f9a61b89a1ef2ceedd6f6233f6cbd624..7184fa0c0c9d19e8677dccd966112d8670e1f40a 100644 (file)
@@ -173,3 +173,17 @@ inet test-inet input
   [ bitwise reg 1 = ( reg 1 & 0xffffffbf ) ^ 0x00000040 ]
   [ meta set mark with reg 1 ]
 
+# ip saddr . ether saddr . meta l4proto { 1.2.3.4 . aa:bb:cc:dd:ee:ff . 6 }
+__set%d test-inet 3 size 1
+__set%d test-inet 0
+       element 04030201 ddccbbaa 0000ffee 00000006  : 0 [end]
+inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x00000002 ]
+  [ meta load iiftype => reg 1 ]
+  [ cmp eq reg 1 0x00000001 ]
+  [ payload load 4b @ network header + 12 => reg 1 ]
+  [ payload load 6b @ link header + 6 => reg 9 ]
+  [ meta load l4proto => reg 11 ]
+  [ lookup reg 1 set __set%d ]
+