diff options
author | Patrick McHardy <kaber@trash.net> | 2010-07-06 05:57:20 +0200 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2010-07-06 05:57:20 +0200 |
commit | 259ee5b3e29c1c76aad2fc7c2bbf470d414110f1 (patch) | |
tree | 8cf107f68018090b93bbf055e0e56cca35f6e730 | |
parent | 653e35bca873414964c9cde0bd98bca3e0bf6692 (diff) |
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 <kaber@trash.net>
-rw-r--r-- | src/datatype.c | 1 | ||||
-rw-r--r-- | src/netlink_delinearize.c | 24 | ||||
-rw-r--r-- | src/payload.c | 2 |
3 files changed, 18 insertions, 9 deletions
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; |