diff options
author | Florian Westphal <fw@strlen.de> | 2016-03-02 13:56:43 +0100 |
---|---|---|
committer | Florian Westphal <fw@strlen.de> | 2016-03-02 13:56:43 +0100 |
commit | ff04f644d8b3ebb32d297b3d06fb965c8b616cf8 (patch) | |
tree | 76ef23562da7067da1a1511b3b05838a85b8cdaf /src/payload.c | |
parent | df5f0e21be1fe5b3ac14c879c85ac781278e876c (diff) |
payload: move payload_gen_dependency generic part to helper
We should treat exthdr just as if user asked for e.g. ip6 saddr
and inject the needed dependency statement.
payload_gen_dependency cannot be used since the *expr needs
to be a payload expression, but the actual dependency generation
doesn't depend on a particular expression type.
In order to reuse this part for future exthdr dependency injection
move it to a helper.
Signed-off-by: Florian Westphal <fw@strlen.de>
Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/payload.c')
-rw-r--r-- | src/payload.c | 66 |
1 files changed, 38 insertions, 28 deletions
diff --git a/src/payload.c b/src/payload.c index 6a977e8d..8f67b6ec 100644 --- a/src/payload.c +++ b/src/payload.c @@ -162,6 +162,43 @@ struct stmt *payload_stmt_alloc(const struct location *loc, return stmt; } +static int payload_add_dependency(struct eval_ctx *ctx, + const struct proto_desc *desc, + const struct proto_desc *upper, + const struct expr *expr, + struct stmt **res) +{ + const struct proto_hdr_template *tmpl; + struct expr *dep, *left, *right; + struct stmt *stmt; + int protocol = proto_find_num(desc, upper); + + if (protocol < 0) + return expr_error(ctx->msgs, expr, + "conflicting protocols specified: %s vs. %s", + desc->name, upper->name); + + tmpl = &desc->templates[desc->protocol_key]; + if (tmpl->meta_key) + left = meta_expr_alloc(&expr->location, tmpl->meta_key); + else + left = payload_expr_alloc(&expr->location, desc, desc->protocol_key); + + right = constant_expr_alloc(&expr->location, tmpl->dtype, + tmpl->dtype->byteorder, tmpl->len, + constant_data_ptr(protocol, tmpl->len)); + + dep = relational_expr_alloc(&expr->location, OP_EQ, left, right); + stmt = expr_stmt_alloc(&dep->location, dep); + if (stmt_evaluate(ctx, stmt) < 0) { + return expr_error(ctx->msgs, expr, + "dependency statement is invalid"); + } + left->ops->pctx_update(&ctx->pctx, dep); + *res = stmt; + return 0; +} + /** * payload_gen_dependency - generate match expression on payload dependency * @@ -190,10 +227,7 @@ int payload_gen_dependency(struct eval_ctx *ctx, const struct expr *expr, { const struct hook_proto_desc *h = &hook_proto_desc[ctx->pctx.family]; const struct proto_desc *desc; - const struct proto_hdr_template *tmpl; - struct expr *dep, *left, *right; struct stmt *stmt; - int protocol; uint16_t type; if (expr->payload.base < h->base) { @@ -265,31 +299,7 @@ int payload_gen_dependency(struct eval_ctx *ctx, const struct expr *expr, "no %s protocol specified", proto_base_names[expr->payload.base - 1]); - protocol = proto_find_num(desc, expr->payload.desc); - if (protocol < 0) - return expr_error(ctx->msgs, expr, - "conflicting protocols specified: %s vs. %s", - desc->name, expr->payload.desc->name); - - tmpl = &desc->templates[desc->protocol_key]; - if (tmpl->meta_key) - left = meta_expr_alloc(&expr->location, tmpl->meta_key); - else - left = payload_expr_alloc(&expr->location, desc, desc->protocol_key); - - right = constant_expr_alloc(&expr->location, tmpl->dtype, - tmpl->dtype->byteorder, tmpl->len, - constant_data_ptr(protocol, tmpl->len)); - - dep = relational_expr_alloc(&expr->location, OP_EQ, left, right); - stmt = expr_stmt_alloc(&dep->location, dep); - if (stmt_evaluate(ctx, stmt) < 0) { - return expr_error(ctx->msgs, expr, - "dependency statement is invalid"); - } - left->ops->pctx_update(&ctx->pctx, dep); - *res = stmt; - return 0; + return payload_add_dependency(ctx, desc, expr->payload.desc, expr, res); } /** |