]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
netlink_linearize: fix flagcmp op
authorPatrick McHardy <kaber@trash.net>
Sun, 16 Feb 2014 18:33:16 +0000 (18:33 +0000)
committerPatrick McHardy <kaber@trash.net>
Sun, 16 Feb 2014 18:33:24 +0000 (18:33 +0000)
Florian reports that flag comparisons generate incorrect instructions:

$ nft --debug=netlink add rule filter output ct labels foo
ip filter output 0 0
 [ ct load labels => reg 1 ]
 [ bitwise reg 1 = (reg=1 & 0x00000001 0x00000000 0x00000000 0x00000000 ) ^ 0x00000000 0x00000000 0x00000000 0x00000000 ]
 [ cmp neq reg 1 0x00000001 0x00000000 0x00000000 0x00000000 ]

The "cmp new" should compare to zero. This was broken by commit aae836a7
(src: use libnftables by using expr->right instead of zero.

Slightly rearrange the code as well to prevent similar problems in the
future.

Signed-off-by: Patrick McHardy <kaber@trash.net>
src/netlink_linearize.c

index 332383afad0c8edc9149557d3b3c1ef036554add..e5fb536b53914a765cd5e73bb22b3e07b141eaca 100644 (file)
@@ -271,21 +271,20 @@ static void netlink_gen_flagcmp(struct netlink_linearize_ctx *ctx,
 
        mpz_init_set_ui(zero, 0);
 
-       nle = alloc_nft_expr("bitwise");
        netlink_gen_raw_data(zero, expr->right->byteorder, len, &nld);
+       netlink_gen_data(expr->right, &nld2);
+
+       nle = alloc_nft_expr("bitwise");
        nft_rule_expr_set_u32(nle, NFT_EXPR_BITWISE_SREG, sreg);
        nft_rule_expr_set_u32(nle, NFT_EXPR_BITWISE_DREG, sreg);
        nft_rule_expr_set_u32(nle, NFT_EXPR_BITWISE_LEN, len);
-       netlink_gen_data(expr->right, &nld2);
        nft_rule_expr_set(nle, NFT_EXPR_BITWISE_MASK, &nld2.value, nld2.len);
        nft_rule_expr_set(nle, NFT_EXPR_BITWISE_XOR, &nld.value, nld.len);
        nft_rule_add_expr(ctx->nlr, nle);
 
        nle = alloc_nft_expr("cmp");
-       netlink_gen_raw_data(zero, expr->right->byteorder, len, &nld);
        nft_rule_expr_set_u32(nle, NFT_EXPR_CMP_SREG, sreg);
        nft_rule_expr_set_u32(nle, NFT_EXPR_CMP_OP, NFT_CMP_NEQ);
-       netlink_gen_data(expr->right, &nld);
        nft_rule_expr_set(nle, NFT_EXPR_CMP_DATA, nld.value, nld.len);
        nft_rule_add_expr(ctx->nlr, nle);