summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2015-08-04 14:11:03 +0200
committerFlorian Westphal <fw@strlen.de>2015-09-18 00:06:09 +0200
commit048a5e093fde9db515ebc7b14f91bceb6cbd5949 (patch)
tree6a9192ee071c9d8bbaa05a1a12e1fb810f30fdcc /src
parenta217645763027da6856efe037c4d3e44abe9d79e (diff)
netlink: cmp: shift rhs constant if lhs offset doesn't start on byte boundary
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>
Diffstat (limited to 'src')
-rw-r--r--src/netlink_linearize.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index 63f77f65..b2cb98dd 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -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);