diff options
author | Patrick McHardy <kaber@trash.net> | 2014-01-08 13:02:16 +0000 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2014-01-08 13:03:19 +0000 |
commit | 1249b7b0b47bca67cf3adac4143b4bda43e4c582 (patch) | |
tree | 0f0e668a040d8b83a01a18acfec1c9dcec947d08 | |
parent | 7a61addda5dc095645640f10ff4425db0d533b2c (diff) |
netlink_delinearize: remove implied meta expressions
Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r-- | include/expression.h | 1 | ||||
-rw-r--r-- | src/netlink_delinearize.c | 29 |
2 files changed, 24 insertions, 6 deletions
diff --git a/include/expression.h b/include/expression.h index 59b27c08..a9aa328e 100644 --- a/include/expression.h +++ b/include/expression.h @@ -242,6 +242,7 @@ struct expr { struct { /* EXPR_META */ enum nft_meta_keys key; + enum proto_bases base; } meta; struct { /* EXPR_CT */ diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index c02f133d..5a6cbfa5 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -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); |