From 259ee5b3e29c1c76aad2fc7c2bbf470d414110f1 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 6 Jul 2010 05:57:20 +0200 Subject: netlink: fix byteorder of RHS of relational meta expression The RHS needs to be postprocessed before updating the payload context for byteorder conversion. Fixes iiftype match reconstruction. Signed-off-by: Patrick McHardy --- src/datatype.c | 1 + src/netlink_delinearize.c | 24 ++++++++++++++++-------- src/payload.c | 2 +- 3 files changed, 18 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/datatype.c b/src/datatype.c index 589a3528..80271043 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -309,6 +309,7 @@ const struct datatype lladdr_type = { .type = TYPE_LLADDR, .name = "lladdr", .desc = "link layer address", + .byteorder = BYTEORDER_HOST_ENDIAN, .basetype = &integer_type, .print = lladdr_type_print, .parse = lladdr_type_parse, diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index e71c129d..a8f700aa 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -491,6 +491,9 @@ static void payload_match_postprocess(struct payload_ctx *ctx, list_for_each_entry(left, &list, list) { tmp = constant_expr_splice(right, left->len); expr_set_type(tmp, left->dtype, left->byteorder); + if (tmp->byteorder == BYTEORDER_HOST_ENDIAN) + mpz_switch_byteorder(tmp->value, tmp->len / BITS_PER_BYTE); + nexpr = relational_expr_alloc(&expr->location, expr->op, left, tmp); payload_ctx_update(ctx, nexpr); @@ -525,6 +528,7 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, struct stmt *stmt, struct expr **exprp) { struct expr *expr = *exprp, *i; + unsigned int n; //pr_debug("%s len %u\n", expr->ops->name, expr->len); @@ -562,9 +566,6 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, case EXPR_PAYLOAD: payload_match_postprocess(&ctx->pctx, stmt, expr); return; - case EXPR_META: - meta_match_postprocess(&ctx->pctx, expr); - break; default: expr_postprocess(ctx, stmt, &expr->left); break; @@ -573,11 +574,15 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, expr_set_type(expr->right, expr->left->dtype, expr->left->byteorder); expr_postprocess(ctx, stmt, &expr->right); - if (expr->left->ops->type == EXPR_BINOP && - expr->left->op == OP_AND && - expr->op == OP_NEQ && - expr->right->dtype->basetype->type == TYPE_BITMASK) { - unsigned int n; + switch (expr->left->ops->type) { + case EXPR_META: + meta_match_postprocess(&ctx->pctx, expr); + break; + case EXPR_BINOP: + if (expr->left->op != OP_AND || + expr->op != OP_NEQ || + expr->right->dtype->basetype->type != TYPE_BITMASK) + break; expr_free(expr->right); expr->right = list_expr_alloc(&expr->left->left->location); @@ -594,6 +599,9 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, } expr->left = expr->left->left; expr->op = OP_FLAGCMP; + break; + default: + break; } break; case EXPR_PAYLOAD: diff --git a/src/payload.c b/src/payload.c index a24748d5..003d84b8 100644 --- a/src/payload.c +++ b/src/payload.c @@ -99,7 +99,7 @@ struct expr *payload_expr_alloc(const struct location *loc, } expr = expr_alloc(loc, &payload_expr_ops, tmpl->dtype, - BYTEORDER_BIG_ENDIAN, tmpl->len); + tmpl->dtype->byteorder, tmpl->len); expr->payload.desc = desc; expr->payload.tmpl = tmpl; expr->payload.base = base; -- cgit v1.2.3