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
commit3bfe9a0323df8e23fa5150b88282cc7b4a6379f0 (patch)
treee12bda8458b25c0697a8169d3e55abcdf6bd7278
parent9f1918ad12d02cf3ba02e4a43879a2a284a8289e (diff)
netlink_delinearize: prepare binop_postprocess for exthdr demux
binop_postprocess takes care of removing masks if we're dealing with payload expressions that have non-byte divisible sizes or offsets. Same can happen when matching some extension header fields, i.e. this also needs to handle exthdr expression, not just payload. So rename payload to left and move test for left type to binop_postprocess. Signed-off-by: Florian Westphal <fw@strlen.de> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--src/netlink_delinearize.c15
1 files changed, 7 insertions, 8 deletions
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index eec7d0ff..30c5f62e 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -1213,12 +1213,12 @@ static struct expr *binop_tree_to_list(struct expr *list, struct expr *expr)
static void binop_postprocess(struct rule_pp_ctx *ctx, struct expr *expr)
{
struct expr *binop = expr->left, *value = expr->right;
-
- struct expr *payload = binop->left;
+ struct expr *left = binop->left;
struct expr *mask = binop->right;
unsigned int shift;
- if (payload_expr_trim(payload, mask, &ctx->pctx, &shift)) {
+ if ((left->ops->type == EXPR_PAYLOAD &&
+ payload_expr_trim(left, mask, &ctx->pctx, &shift))) {
/* mask is implicit, binop needs to be removed.
*
* Fix all values of the expression according to the mask
@@ -1231,15 +1231,15 @@ static void binop_postprocess(struct rule_pp_ctx *ctx, struct expr *expr)
if (value->ops->type == EXPR_VALUE) {
assert(value->len >= expr->left->right->len);
mpz_rshift_ui(value->value, shift);
- value->len = payload->len;
+ value->len = left->len;
}
assert(expr->left->ops->type == EXPR_BINOP);
- assert(binop->left == payload);
- expr->left = expr_get(payload);
+ assert(binop->left == left);
+ expr->left = expr_get(left);
expr_free(binop);
- payload_match_postprocess(ctx, expr, payload);
+ payload_match_postprocess(ctx, expr, left);
}
}
@@ -1285,7 +1285,6 @@ static void relational_binop_postprocess(struct rule_pp_ctx *ctx, struct expr *e
expr_free(value);
expr_free(binop);
} else if (binop->op == OP_AND &&
- binop->left->ops->type == EXPR_PAYLOAD &&
binop->right->ops->type == EXPR_VALUE) {
/*
* This *might* be a payload match testing header fields that