If a user uses a variable payload expression in a payload statement, we need to undo any munging during delinearization. Signed-off-by: Jeremy Sowden <jeremy@xxxxxxxxxx> --- src/netlink_delinearize.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index 571cab1d932b..73faa93c862e 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -2125,6 +2125,30 @@ static void relational_binop_postprocess(struct rule_pp_ctx *ctx, struct expr *e } } +static bool payload_binop_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp) +{ + struct expr *expr = *exprp; + + if (expr->op != OP_RSHIFT) + return false; + + if (expr->left->etype != EXPR_BINOP || expr->left->op != OP_AND) + return false; + + if (expr->left->left->etype != EXPR_PAYLOAD) + return false; + + expr_set_type(expr->right, &integer_type, + BYTEORDER_HOST_ENDIAN); + expr_postprocess(ctx, &expr->right); + + binop_postprocess(ctx, expr); + *exprp = expr_get(expr->left); + expr_free(expr); + + return true; +} + static struct expr *string_wildcard_expr_alloc(struct location *loc, const struct expr *mask, const struct expr *expr) @@ -2258,6 +2282,9 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp) expr_set_type(expr, expr->arg->dtype, !expr->arg->byteorder); break; case EXPR_BINOP: + if (payload_binop_postprocess(ctx, exprp)) + break; + expr_postprocess(ctx, &expr->left); switch (expr->op) { case OP_LSHIFT: -- 2.25.0