]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
payload: add payload_is_stacked()
authorPatrick McHardy <kaber@trash.net>
Sun, 24 Apr 2016 21:15:08 +0000 (22:15 +0100)
committerPatrick McHardy <kaber@trash.net>
Sun, 24 Apr 2016 21:15:08 +0000 (22:15 +0100)
Add payload_is_stacked() to determine whether a protocol expression match defines
a stacked protocol on the same layer.

Signed-off-by: Patrick McHardy <kaber@trash.net>
include/payload.h
src/netlink_delinearize.c
src/payload.c

index eb9ff17d7e70e376c3a3e6646c9ca3fff876333e..b180ff5369cd769a584295ba2fc03b1fae01ab48 100644 (file)
@@ -30,6 +30,8 @@ struct payload_dep_ctx {
        struct stmt             *prev;
 };
 
+extern bool payload_is_stacked(const struct proto_desc *desc,
+                              const struct expr *expr);
 extern void payload_dependency_store(struct payload_dep_ctx *ctx,
                                     struct stmt *stmt,
                                     enum proto_bases base);
index 59e5f3e6988186264a0b325398487c2f0afd4917..84f94fc31f995f1d56936d745e1316ac425b580e 100644 (file)
@@ -1032,27 +1032,6 @@ static void integer_type_postprocess(struct expr *expr)
        }
 }
 
-static void payload_dependency_save(struct rule_pp_ctx *ctx, unsigned int base,
-                                   struct stmt *nstmt, struct expr *tmp)
-{
-       unsigned int proto = mpz_get_be16(tmp->value);
-       const struct proto_desc *desc, *next;
-       bool stacked_header = false;
-
-       desc = ctx->pctx.protocol[base].desc;
-
-       assert(desc);
-       if (desc) {
-               next = proto_find_upper(desc, proto);
-               stacked_header = next && next->base == base;
-       }
-
-       if (stacked_header)
-               payload_dependency_store(&ctx->pdctx, nstmt, base - 1);
-       else
-               payload_dependency_store(&ctx->pdctx, nstmt, base);
-}
-
 static void payload_match_expand(struct rule_pp_ctx *ctx,
                                 struct expr *expr,
                                 struct expr *payload)
@@ -1063,6 +1042,7 @@ static void payload_match_expand(struct rule_pp_ctx *ctx,
        struct expr *nexpr = NULL;
        enum proto_bases base = left->payload.base;
        const struct expr_ops *payload_ops = left->ops;
+       bool stacked;
 
        payload_expr_expand(&list, left, &ctx->pctx);
 
@@ -1084,6 +1064,8 @@ static void payload_match_expand(struct rule_pp_ctx *ctx,
                assert(left->payload.base);
                assert(base == left->payload.base);
 
+               stacked = payload_is_stacked(ctx->pctx.protocol[base].desc, nexpr);
+
                /* Remember the first payload protocol expression to
                 * kill it later on if made redundant by a higher layer
                 * payload expression.
@@ -1091,11 +1073,11 @@ static void payload_match_expand(struct rule_pp_ctx *ctx,
                if (ctx->pdctx.pbase == PROTO_BASE_INVALID &&
                    expr->op == OP_EQ &&
                    left->flags & EXPR_F_PROTOCOL) {
-                       payload_dependency_save(ctx, base, nstmt, tmp);
+                       payload_dependency_store(&ctx->pdctx, nstmt, base - stacked);
                } else {
                        payload_dependency_kill(&ctx->pdctx, nexpr->left);
                        if (left->flags & EXPR_F_PROTOCOL)
-                               payload_dependency_save(ctx, base, nstmt, tmp);
+                               payload_dependency_store(&ctx->pdctx, nstmt, base - stacked);
                }
        }
        list_del(&ctx->stmt->list);
index 9dca56bedc6f63519eed4889b30237f09d34dd02..0bbfb5428e79f79c1744350f079b81cde8fead7b 100644 (file)
@@ -321,6 +321,26 @@ int exthdr_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
        return payload_add_dependency(ctx, desc, &proto_ip6, expr, res);
 }
 
+/**
+ * payload_is_stacked - return whether a payload protocol match defines a stacked
+ *                     protocol on the same layer
+ *
+ * @desc: current protocol description on this layer
+ * @expr: payload match
+ */
+bool payload_is_stacked(const struct proto_desc *desc, const struct expr *expr)
+{
+       const struct proto_desc *next;
+
+       if (expr->left->ops->type != EXPR_PAYLOAD ||
+           !(expr->left->flags & EXPR_F_PROTOCOL) ||
+           expr->op != OP_EQ)
+               return false;
+
+       next = proto_find_upper(desc, mpz_get_be16(expr->right->value));
+       return next && next->base == desc->base;
+}
+
 /**
  * payload_dependency_store - store a possibly redundant protocol match
  *