]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
netlink: fix byteorder of RHS of relational meta expression
authorPatrick McHardy <kaber@trash.net>
Tue, 6 Jul 2010 03:57:20 +0000 (05:57 +0200)
committerPatrick McHardy <kaber@trash.net>
Tue, 6 Jul 2010 03:57:20 +0000 (05:57 +0200)
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>
src/datatype.c
src/netlink_delinearize.c
src/payload.c

index 589a35285aa679a869675bf4bd54c90d7a878b58..80271043535fef281bc4f8a817a2c1a161451d82 100644 (file)
@@ -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,
index e71c129d282b87546d812943137e3761478d8c83..a8f700aa69b2445fe21e1623689d0964bb096930 100644 (file)
@@ -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:
index a24748d5cd98e75efa516c3c7f7866baa2429c11..003d84b8c75d42d856e1ddf6cb6ddd426546a007 100644 (file)
@@ -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;