summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2010-07-06 05:57:20 +0200
committerPatrick McHardy <kaber@trash.net>2010-07-06 05:57:20 +0200
commit259ee5b3e29c1c76aad2fc7c2bbf470d414110f1 (patch)
tree8cf107f68018090b93bbf055e0e56cca35f6e730
parent653e35bca873414964c9cde0bd98bca3e0bf6692 (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.c1
-rw-r--r--src/netlink_delinearize.c24
-rw-r--r--src/payload.c2
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;