]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
netlink: cmp: shift rhs constant if lhs offset doesn't start on byte boundary
authorFlorian Westphal <fw@strlen.de>
Tue, 4 Aug 2015 12:11:03 +0000 (14:11 +0200)
committerFlorian Westphal <fw@strlen.de>
Thu, 17 Sep 2015 22:06:09 +0000 (00:06 +0200)
if we have payload(someoffset) == 42, then shift 42 in case someoffset
doesn't start on a byte boundary.

We already insert a mask instruction to only load those bits into
the register that we were interested in, but the cmp will fail without
also adjusting rhs accordingly.

Needs additional patch in reverse direction to undo the shift again
when dumping ruleset.

Signed-off-by: Florian Westphal <fw@strlen.de>
src/netlink_linearize.c

index 63f77f659abe3b68dbba98510253a6a03c74817f..b2cb98dd5a6db7fde98c606ad906e51332b99e52 100644 (file)
@@ -277,6 +277,15 @@ static void netlink_gen_range(struct netlink_linearize_ctx *ctx,
                              const struct expr *expr,
                              enum nft_registers dreg);
 
+static void payload_shift_value(const struct expr *left, struct expr *right)
+{
+       if (right->ops->type != EXPR_VALUE ||
+           left->ops->type != EXPR_PAYLOAD)
+               return;
+
+       mpz_lshift_ui(right->value, left->payload.offset % BITS_PER_BYTE);
+}
+
 static void netlink_gen_cmp(struct netlink_linearize_ctx *ctx,
                            const struct expr *expr,
                            enum nft_registers dreg)
@@ -325,6 +334,7 @@ static void netlink_gen_cmp(struct netlink_linearize_ctx *ctx,
        netlink_put_register(nle, NFTNL_EXPR_CMP_SREG, sreg);
        nftnl_expr_set_u32(nle, NFTNL_EXPR_CMP_OP,
                              netlink_gen_cmp_op(expr->op));
+       payload_shift_value(expr->left, right);
        netlink_gen_data(right, &nld);
        nftnl_expr_set(nle, NFTNL_EXPR_CMP_DATA, nld.value, nld.len);
        release_register(ctx, expr->left);