]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
payload: don't kill dependency for proto_th
authorFlorian Westphal <fw@strlen.de>
Thu, 27 Feb 2025 10:47:02 +0000 (11:47 +0100)
committerFlorian Westphal <fw@strlen.de>
Thu, 6 Mar 2025 03:53:30 +0000 (04:53 +0100)
proto_th carries no information about the proto number, we need to
preserve the L4 protocol expression unless we can be sure that

For example, if "meta l4proto 91 @th,0,16 0" is simplified to
"th sport 0", the information of protocol number is lost.

Based on initial patch from Xiao Liang.

Signed-off-by: Xiao Liang <shaw.leon@gmail.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
src/netlink_delinearize.c
src/payload.c
tests/py/any/rawpayload.t
tests/py/any/rawpayload.t.json
tests/py/any/rawpayload.t.payload

index 86c8602860f63284df6b8b87f8148948e261836c..b629916ebff82e01a175280afb8f4cce0bb93743 100644 (file)
@@ -2102,6 +2102,7 @@ static void payload_match_expand(struct rule_pp_ctx *ctx,
                 */
                payload_dependency_kill(&dl->pdctx, nexpr->left,
                                        dl->pctx.family);
+               expr_set_type(tmp, nexpr->left->dtype, nexpr->byteorder);
                if (expr->op == OP_EQ && left->flags & EXPR_F_PROTOCOL)
                        payload_dependency_store(&dl->pdctx, nstmt, base);
        }
index ee6b39a34cb469b8ee0b67b3012af2a3b2143c10..0187197511033be7511fa83cddb8777a9aa68db4 100644 (file)
@@ -812,7 +812,7 @@ static bool icmp_dep_type_match(enum icmp_hdr_field_type t, uint8_t type)
        BUG("Missing icmp type mapping");
 }
 
-static bool payload_may_dependency_kill_icmp(struct payload_dep_ctx *ctx, struct expr *expr)
+static bool payload_may_dependency_kill_icmp(struct payload_dep_ctx *ctx, const struct expr *expr)
 {
        const struct expr *dep = payload_dependency_get(ctx, expr->payload.base);
        enum icmp_hdr_field_type icmp_dep;
@@ -832,7 +832,7 @@ static bool payload_may_dependency_kill_icmp(struct payload_dep_ctx *ctx, struct
        return ctx->icmp_type == icmp_dep_to_type(icmp_dep);
 }
 
-static bool payload_may_dependency_kill_ll(struct payload_dep_ctx *ctx, struct expr *expr)
+static bool payload_may_dependency_kill_ll(struct payload_dep_ctx *ctx, const struct expr *expr)
 {
        const struct expr *dep = payload_dependency_get(ctx, expr->payload.base);
 
@@ -894,6 +894,18 @@ static bool payload_may_dependency_kill(struct payload_dep_ctx *ctx,
        if (expr->payload.base != PROTO_BASE_TRANSPORT_HDR)
                return true;
 
+       if (expr->payload.desc == &proto_th) {
+               /* &proto_th could mean any of udp, tcp, dccp, ... so we
+                * cannot remove the dependency.
+                *
+                * Also prefer raw payload @th syntax, there is no
+                * 'source/destination port' protocol here.
+                */
+               expr->payload.desc = &proto_unknown;
+               expr->dtype = &xinteger_type;
+               return false;
+       }
+
        if (dep->left->etype != EXPR_PAYLOAD ||
            dep->left->payload.base != PROTO_BASE_TRANSPORT_HDR)
                return true;
index 745b4a615e6ccf11fb80dd7b9b6f06bb3484059d..118f58fd0f758f2d8ef9050a2ccec349791a58b9 100644 (file)
@@ -21,6 +21,7 @@ meta l4proto tcp @th,16,16 { 22, 23, 80};ok;tcp dport { 22, 23, 80}
 @ll,0,128 0xfedcba987654321001234567890abcde;ok
 
 meta l4proto 91 @th,400,16 0x0 accept;ok
+meta l4proto 91 @th,0,16 0x0 accept;ok
 
 @ih,32,32 0x14000000;ok
 @ih,58,6 set 0 @ih,86,6 set 0 @ih,170,22 set 0;ok;@ih,58,6 set 0x0 @ih,86,6 set 0x0 @ih,170,22 set 0x0
index 4a06c5987a7b4381d0d83ca10596b83eefc0b500..04ed0acf1ed0834341a6d4ecf4be80299f197e80 100644 (file)
     }
 ]
 
+# meta l4proto 91 @th,0,16 0x0 accept
+[
+    {
+        "match": {
+            "left": {
+                "meta": {
+                    "key": "l4proto"
+                }
+            },
+            "op": "==",
+            "right": 91
+        }
+    },
+    {
+        "match": {
+            "left": {
+                "payload": {
+                    "base": "th",
+                    "len": 16,
+                    "offset": 0
+                }
+            },
+            "op": "==",
+            "right": 0
+        }
+    },
+    {
+        "accept": null
+    }
+]
+
 # @ih,32,32 0x14000000
 [
     {
index 8984eef6a481bc8bc134a95fa5ccfbc965ddf9ff..c093d5d8932f1256d5dc940b62f4af69cce856cb 100644 (file)
@@ -56,6 +56,14 @@ inet test-inet input
   [ cmp eq reg 1 0x00000000 ]
   [ immediate reg 0 accept ]
 
+# meta l4proto 91 @th,0,16 0x0 accept
+inet test-inet input
+  [ meta load l4proto => reg 1 ]
+  [ cmp eq reg 1 0x0000005b ]
+  [ payload load 2b @ transport header + 0 => reg 1 ]
+  [ cmp eq reg 1 0x00000000 ]
+  [ immediate reg 0 accept ]
+
 # @ih,32,32 0x14000000
 inet test-inet input
   [ payload load 4b @ inner header + 4 => reg 1 ]