]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
netlink_delinearize: remove implied meta expressions
authorPatrick McHardy <kaber@trash.net>
Wed, 8 Jan 2014 13:02:16 +0000 (13:02 +0000)
committerPatrick McHardy <kaber@trash.net>
Wed, 8 Jan 2014 13:03:19 +0000 (13:03 +0000)
Signed-off-by: Patrick McHardy <kaber@trash.net>
include/expression.h
src/netlink_delinearize.c

index 59b27c085faf813b43fcf5b705efe8e6c599f8aa..a9aa328ea96f5a21e0821aecd03db4198c940922 100644 (file)
@@ -242,6 +242,7 @@ struct expr {
                struct {
                        /* EXPR_META */
                        enum nft_meta_keys      key;
+                       enum proto_bases        base;
                } meta;
                struct {
                        /* EXPR_CT */
index c02f133d13719553c925a7125c97b9a5d544763e..5a6cbfa5c1aafaa5ffce4fb777e3e4fb6c4aa0f2 100644 (file)
@@ -588,10 +588,19 @@ static void payload_dependency_kill(struct rule_pp_ctx *ctx, struct expr *expr)
            ctx->pdep != NULL) {
                list_del(&ctx->pdep->list);
                stmt_free(ctx->pdep);
+               ctx->pbase = PROTO_BASE_INVALID;
                ctx->pdep = NULL;
        }
 }
 
+static void payload_dependency_store(struct rule_pp_ctx *ctx,
+                                    struct stmt *stmt,
+                                    enum proto_bases base)
+{
+       ctx->pbase = base;
+       ctx->pdep  = stmt;
+}
+
 static void payload_match_postprocess(struct rule_pp_ctx *ctx,
                                      struct stmt *stmt, struct expr *expr)
 {
@@ -622,10 +631,10 @@ static void payload_match_postprocess(struct rule_pp_ctx *ctx,
                         * payload expression.
                         */
                        if (ctx->pbase == PROTO_BASE_INVALID &&
-                           left->flags & EXPR_F_PROTOCOL) {
-                               ctx->pbase = left->payload.base;
-                               ctx->pdep  = nstmt;
-                       else
+                           left->flags & EXPR_F_PROTOCOL)
+                               payload_dependency_store(ctx, nstmt,
+                                                        left->payload.base);
+                       else
                                payload_dependency_kill(ctx, nexpr->left);
                }
                list_del(&stmt->list);
@@ -635,16 +644,24 @@ static void payload_match_postprocess(struct rule_pp_ctx *ctx,
                payload_expr_complete(left, &ctx->pctx);
                expr_set_type(expr->right, expr->left->dtype,
                              expr->left->byteorder);
+               payload_dependency_kill(ctx, expr->left);
                break;
        }
 }
 
-static void meta_match_postprocess(struct proto_ctx *ctx,
+static void meta_match_postprocess(struct rule_pp_ctx *ctx,
+                                  struct stmt *stmt,
                                   const struct expr *expr)
 {
+       struct expr *left = expr->left;
+
        switch (expr->op) {
        case OP_EQ:
                expr->left->ops->pctx_update(ctx, expr);
+
+               if (ctx->pbase == PROTO_BASE_INVALID &&
+                   left->flags & EXPR_F_PROTOCOL)
+                       payload_dependency_store(ctx, stmt, left->meta.base);
                break;
        default:
                break;
@@ -765,7 +782,7 @@ static void expr_postprocess(struct rule_pp_ctx *ctx,
 
                switch (expr->left->ops->type) {
                case EXPR_META:
-                       meta_match_postprocess(&ctx->pctx, expr);
+                       meta_match_postprocess(ctx, stmt, expr);
                        break;
                case EXPR_BINOP:
                        relational_binop_postprocess(expr);