summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2016-03-02 13:56:43 +0100
committerFlorian Westphal <fw@strlen.de>2016-03-02 13:56:43 +0100
commitff04f644d8b3ebb32d297b3d06fb965c8b616cf8 (patch)
tree76ef23562da7067da1a1511b3b05838a85b8cdaf
parentdf5f0e21be1fe5b3ac14c879c85ac781278e876c (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>
-rw-r--r--src/payload.c66
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);
}
/**