From: Pablo Neira Ayuso <pablo@netfilter.org>
To: netfilter-devel@vger.kernel.org
Cc: kaber@trash.net, fw@strlen.de
Subject: [PATCH nft] src: perform sub-byte length matching from the evaluation step
Date: Sat, 28 Nov 2015 13:50:52 +0100 [thread overview]
Message-ID: <1448715052-5705-1-git-send-email-pablo@netfilter.org> (raw)
This patch reworks c3f0501 ("src: netlink_linearize: handle sub-byte lengths")
to perform the required sub-byte transformations from the evaluation step.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
@Patrick, @Florian: It seems we're falling into subbyte handling
problems from different fronts, I just hit this while further testing of
my dscp patch.
I'm sending this because I think it's sort of ready so we avoid overlap.
I'm working on a follow up patch (almost done here) to cover another
corner case that we don't handle correctly, which is basically this:
4 bits 6 bits
+-+-+-+-+-+-+-+-+-+-+
| vers | dscp |
+-+-+-+-+-+-+-+-+-+-+
^
|
byte boundary
To match dscp in IPv6, we have to fetch 2 bytes from offset 0 via
payload expression and the bitmask must be 00ffc000.
I got the code generation correctly, but I'm adjusting the
payload_expr_trim() function now.
So I'm basically working on the netlink code generation part.
I'm not working on the protocol definition problem:
http://marc.info/?l=netfilter-devel&m=144862242521205&w=2, but I also
need this gets fixed. Let me know if you will be looking into this, just
to avoid overlap.
Thanks!
include/expression.h | 2 ++
src/evaluate.c | 46 +++++++++++++++++++++++++++++++++++++++++---
src/netlink_linearize.c | 51 -------------------------------------------------
3 files changed, 45 insertions(+), 54 deletions(-)
diff --git a/include/expression.h b/include/expression.h
index 010cb95..bbb92a5 100644
--- a/include/expression.h
+++ b/include/expression.h
@@ -100,11 +100,13 @@ enum symbol_types {
* @dtype: expected datatype
* @byteorder: expected byteorder
* @len: expected len
+ * @shift: required value shift
*/
struct expr_ctx {
const struct datatype *dtype;
enum byteorder byteorder;
unsigned int len;
+ unsigned int shift;
};
static inline void __expr_set_context(struct expr_ctx *ctx,
diff --git a/src/evaluate.c b/src/evaluate.c
index d44cecc..4b8b5ea 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -285,6 +285,8 @@ static int expr_evaluate_value(struct eval_ctx *ctx, struct expr **expr)
(*expr)->byteorder = ctx->ectx.byteorder;
(*expr)->len = ctx->ectx.len;
mpz_clear(mask);
+ if (ctx->ectx.shift)
+ mpz_lshift_ui((*expr)->value, ctx->ectx.shift);
break;
case TYPE_STRING:
if (expr_evaluate_string(ctx, expr) < 0)
@@ -457,12 +459,50 @@ static int __expr_evaluate_payload(struct eval_ctx *ctx, struct expr *expr)
return 0;
}
-static int expr_evaluate_payload(struct eval_ctx *ctx, struct expr **expr)
+static void expr_evaluate_payload_subbyte(struct eval_ctx *ctx,
+ struct expr **exprp)
{
- if (__expr_evaluate_payload(ctx, *expr) < 0)
+ struct expr *expr = *exprp, *and, *mask;
+ unsigned int shift, masklen;
+ mpz_t bitmask;
+
+ shift = expr->payload.offset % BITS_PER_BYTE;
+ masklen = expr->len + shift;
+
+ if (masklen > 128)
+ BUG("expr mask length is %u (len %u, shift %u)\n",
+ masklen, expr->len, shift);
+
+ mpz_init2(bitmask, masklen);
+ mpz_bitmask(bitmask, expr->len);
+ if (shift)
+ mpz_lshift_ui(bitmask, shift);
+
+ mask = constant_expr_alloc(&expr->location, expr_basetype(expr),
+ BYTEORDER_HOST_ENDIAN, masklen, NULL);
+ mpz_set(mask->value, bitmask);
+
+ and = binop_expr_alloc(&expr->location, OP_AND, expr, mask);
+ and->dtype = expr->dtype;
+ and->byteorder = expr->byteorder;
+ and->len = masklen;
+
+ *exprp = and;
+
+ ctx->ectx.shift = shift;
+}
+
+static int expr_evaluate_payload(struct eval_ctx *ctx, struct expr **exprp)
+{
+ struct expr *expr = *exprp;
+
+ if (__expr_evaluate_payload(ctx, expr) < 0)
return -1;
- return expr_evaluate_primary(ctx, expr);
+ if (expr->len % BITS_PER_BYTE)
+ expr_evaluate_payload_subbyte(ctx, exprp);
+
+ return expr_evaluate_primary(ctx, &expr);
}
/*
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index 432068d..ee072b8 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -103,44 +103,6 @@ static void netlink_gen_concat(struct netlink_linearize_ctx *ctx,
}
}
-static void netlink_gen_payload_mask(struct netlink_linearize_ctx *ctx,
- const struct expr *expr,
- enum nft_registers dreg)
-{
- struct nft_data_linearize nld, zero = {};
- struct nftnl_expr *nle;
- unsigned int offset, len, masklen;
- mpz_t mask;
-
- offset = expr->payload.offset % BITS_PER_BYTE;
- masklen = expr->len + offset;
-
- if (masklen > 128)
- BUG("expr mask length is %u (len %u, offset %u)\n",
- masklen, expr->len, offset);
-
- mpz_init2(mask, masklen);
- mpz_bitmask(mask, expr->len);
-
- if (offset)
- mpz_lshift_ui(mask, offset);
-
- nle = alloc_nft_expr("bitwise");
-
- len = div_round_up(expr->len, BITS_PER_BYTE);
-
- nftnl_expr_set_u32(nle, NFT_EXPR_BITWISE_SREG, dreg);
- nftnl_expr_set_u32(nle, NFT_EXPR_BITWISE_DREG, dreg);
- nftnl_expr_set_u32(nle, NFT_EXPR_BITWISE_LEN, len);
-
- netlink_gen_raw_data(mask, expr->byteorder, len, &nld);
- nftnl_expr_set(nle, NFT_EXPR_BITWISE_MASK, nld.value, nld.len);
- nftnl_expr_set(nle, NFT_EXPR_BITWISE_XOR, &zero.value, nld.len);
-
- mpz_clear(mask);
- nftnl_rule_add_expr(ctx->nlr, nle);
-}
-
static void netlink_gen_payload(struct netlink_linearize_ctx *ctx,
const struct expr *expr,
enum nft_registers dreg)
@@ -157,9 +119,6 @@ static void netlink_gen_payload(struct netlink_linearize_ctx *ctx,
div_round_up(expr->len, BITS_PER_BYTE));
nftnl_rule_add_expr(ctx->nlr, nle);
-
- if (expr->len % BITS_PER_BYTE)
- netlink_gen_payload_mask(ctx, expr, dreg);
}
static void netlink_gen_exthdr(struct netlink_linearize_ctx *ctx,
@@ -281,15 +240,6 @@ 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 struct expr *netlink_gen_prefix(struct netlink_linearize_ctx *ctx,
const struct expr *expr,
enum nft_registers sreg)
@@ -358,7 +308,6 @@ 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, len);
release_register(ctx, expr->left);
--
2.1.4
next reply other threads:[~2015-11-28 12:51 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-11-28 12:50 Pablo Neira Ayuso [this message]
2015-11-28 13:20 ` [PATCH nft] src: perform sub-byte length matching from the evaluation step Patrick McHardy
2015-11-28 18:01 ` Pablo Neira Ayuso
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1448715052-5705-1-git-send-email-pablo@netfilter.org \
--to=pablo@netfilter.org \
--cc=fw@strlen.de \
--cc=kaber@trash.net \
--cc=netfilter-devel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).