summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2021-11-30 20:19:44 +0100
committerFlorian Westphal <fw@strlen.de>2021-12-01 14:11:23 +0100
commitfa564b6ce7e595a11f27896e47dedc7b5af2e33d (patch)
tree97e3a41bcfbb94f375d041366848ef1feec49b5e /src
parent99df9a269af74b0f5d1be89a95525fb55f689214 (diff)
netlink_delinearize: binop: make accesses to expr->left/right conditional
This function can be called for different expression types, including some (EXPR_MAP) where expr->left/right alias to different member variables. This makes accesses to those members conditional by checking the expression type ahead of the access. Signed-off-by: Florian Westphal <fw@strlen.de>
Diffstat (limited to 'src')
-rw-r--r--src/netlink_delinearize.c50
1 files changed, 31 insertions, 19 deletions
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 072ea673..1f820e68 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -2223,8 +2223,8 @@ static void binop_adjust_one(const struct expr *binop, struct expr *value,
}
}
-static void __binop_adjust(const struct expr *binop, struct expr *right,
- unsigned int shift)
+static void binop_adjust(const struct expr *binop, struct expr *right,
+ unsigned int shift)
{
struct expr *i;
@@ -2243,7 +2243,7 @@ static void __binop_adjust(const struct expr *binop, struct expr *right,
binop_adjust_one(binop, i->key->right, shift);
break;
case EXPR_SET_ELEM:
- __binop_adjust(binop, i->key->key, shift);
+ binop_adjust(binop, i->key->key, shift);
break;
default:
BUG("unknown expression type %s\n", expr_name(i->key));
@@ -2260,22 +2260,22 @@ static void __binop_adjust(const struct expr *binop, struct expr *right,
}
}
-static void binop_adjust(struct expr *expr, unsigned int shift)
+static void binop_postprocess(struct rule_pp_ctx *ctx, struct expr *expr,
+ struct expr **expr_binop)
{
- __binop_adjust(expr->left, expr->right, shift);
-}
-
-static void binop_postprocess(struct rule_pp_ctx *ctx, struct expr *expr)
-{
- struct expr *binop = expr->left;
+ struct expr *binop = *expr_binop;
struct expr *left = binop->left;
struct expr *mask = binop->right;
unsigned int shift;
+ assert(binop->etype == EXPR_BINOP);
+
if ((left->etype == EXPR_PAYLOAD &&
payload_expr_trim(left, mask, &ctx->pctx, &shift)) ||
(left->etype == EXPR_EXTHDR &&
exthdr_find_template(left, mask, &shift))) {
+ struct expr *right = NULL;
+
/* mask is implicit, binop needs to be removed.
*
* Fix all values of the expression according to the mask
@@ -2285,16 +2285,28 @@ static void binop_postprocess(struct rule_pp_ctx *ctx, struct expr *expr)
* Finally, convert the expression to 1) by replacing
* the binop with the binop payload/exthdr expression.
*/
- binop_adjust(expr, shift);
+ switch (expr->etype) {
+ case EXPR_BINOP:
+ case EXPR_RELATIONAL:
+ right = expr->right;
+ binop_adjust(binop, right, shift);
+ break;
+ case EXPR_MAP:
+ right = expr->mappings;
+ binop_adjust(binop, right, shift);
+ break;
+ default:
+ break;
+ }
- assert(expr->left->etype == EXPR_BINOP);
assert(binop->left == left);
- expr->left = expr_get(left);
+ *expr_binop = expr_get(left);
expr_free(binop);
+
if (left->etype == EXPR_PAYLOAD)
payload_match_postprocess(ctx, expr, left);
- else if (left->etype == EXPR_EXTHDR)
- expr_set_type(expr->right, left->dtype, left->byteorder);
+ else if (left->etype == EXPR_EXTHDR && right)
+ expr_set_type(right, left->dtype, left->byteorder);
}
}
@@ -2307,7 +2319,7 @@ static void map_binop_postprocess(struct rule_pp_ctx *ctx, struct expr *expr)
if (binop->left->etype == EXPR_PAYLOAD &&
binop->right->etype == EXPR_VALUE)
- binop_postprocess(ctx, expr);
+ binop_postprocess(ctx, expr, &expr->map);
}
static void relational_binop_postprocess(struct rule_pp_ctx *ctx,
@@ -2401,7 +2413,7 @@ static void relational_binop_postprocess(struct rule_pp_ctx *ctx,
* payload_expr_trim will figure out if the mask is needed to match
* templates.
*/
- binop_postprocess(ctx, expr);
+ binop_postprocess(ctx, expr, &expr->left);
}
}
@@ -2754,7 +2766,7 @@ static void stmt_payload_binop_pp(struct rule_pp_ctx *ctx, struct expr *binop)
assert(payload->etype == EXPR_PAYLOAD);
if (payload_expr_trim(payload, mask, &ctx->pctx, &shift)) {
- __binop_adjust(binop, mask, shift);
+ binop_adjust(binop, mask, shift);
payload_expr_complete(payload, &ctx->pctx);
expr_set_type(mask, payload->dtype,
payload->byteorder);
@@ -2849,7 +2861,7 @@ static void stmt_payload_binop_postprocess(struct rule_pp_ctx *ctx)
mpz_set(mask->value, bitmask);
mpz_clear(bitmask);
- binop_postprocess(ctx, expr);
+ binop_postprocess(ctx, expr, &expr->left);
if (!payload_is_known(payload)) {
mpz_set(mask->value, tmp);
mpz_clear(tmp);