From: Jeremy Sowden <jeremy@azazel.net>
To: Netfilter Devel <netfilter-devel@vger.kernel.org>
Subject: [PATCH nft v3 8/9] netlink: add support for handling shift expressions.
Date: Sun, 19 Jan 2020 22:57:09 +0000 [thread overview]
Message-ID: <20200119225710.222976-9-jeremy@azazel.net> (raw)
In-Reply-To: <20200119225710.222976-1-jeremy@azazel.net>
The kernel supports bitwise shift operations, so add support to the
netlink linearization and delinearization code. The number of bits (the
righthand operand) is expected to be a 32-bit value in host endianness.
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
---
src/netlink_delinearize.c | 87 ++++++++++++++++++++++++++++++++-------
src/netlink_linearize.c | 50 ++++++++++++++++++++--
2 files changed, 120 insertions(+), 17 deletions(-)
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 8f2a5dfacd3e..4dcaaba6218a 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -356,22 +356,17 @@ static void netlink_parse_lookup(struct netlink_parse_ctx *ctx,
ctx->stmt = expr_stmt_alloc(loc, expr);
}
-static void netlink_parse_bitwise(struct netlink_parse_ctx *ctx,
- const struct location *loc,
- const struct nftnl_expr *nle)
+static struct expr *netlink_parse_bitwise_bool(struct netlink_parse_ctx *ctx,
+ const struct location *loc,
+ const struct nftnl_expr *nle,
+ enum nft_registers sreg,
+ struct expr *left)
+
{
struct nft_data_delinearize nld;
- enum nft_registers sreg, dreg;
- struct expr *expr, *left, *mask, *xor, *or;
+ struct expr *expr, *mask, *xor, *or;
mpz_t m, x, o;
- sreg = netlink_parse_register(nle, NFTNL_EXPR_BITWISE_SREG);
- left = netlink_get_register(ctx, loc, sreg);
- if (left == NULL)
- return netlink_error(ctx, loc,
- "Bitwise expression has no left "
- "hand side");
-
expr = left;
nld.value = nftnl_expr_get(nle, NFTNL_EXPR_BITWISE_MASK, &nld.len);
@@ -423,6 +418,62 @@ static void netlink_parse_bitwise(struct netlink_parse_ctx *ctx,
mpz_clear(x);
mpz_clear(o);
+ return expr;
+}
+
+static struct expr *netlink_parse_bitwise_shift(struct netlink_parse_ctx *ctx,
+ const struct location *loc,
+ const struct nftnl_expr *nle,
+ enum ops op,
+ enum nft_registers sreg,
+ struct expr *left)
+{
+ struct nft_data_delinearize nld;
+ struct expr *expr, *right;
+
+ nld.value = nftnl_expr_get(nle, NFTNL_EXPR_BITWISE_DATA, &nld.len);
+ right = netlink_alloc_value(loc, &nld);
+
+ expr = binop_expr_alloc(loc, op, left, right);
+ expr->len = left->len;
+
+ return expr;
+}
+
+static void netlink_parse_bitwise(struct netlink_parse_ctx *ctx,
+ const struct location *loc,
+ const struct nftnl_expr *nle)
+{
+ enum nft_registers sreg, dreg;
+ struct expr *expr, *left;
+ enum nft_bitwise_ops op;
+
+ sreg = netlink_parse_register(nle, NFTNL_EXPR_BITWISE_SREG);
+ left = netlink_get_register(ctx, loc, sreg);
+ if (left == NULL)
+ return netlink_error(ctx, loc,
+ "Bitwise expression has no left "
+ "hand side");
+
+ op = nftnl_expr_get_u32(nle, NFTNL_EXPR_BITWISE_OP);
+
+ switch (op) {
+ case NFT_BITWISE_BOOL:
+ expr = netlink_parse_bitwise_bool(ctx, loc, nle, sreg,
+ left);
+ break;
+ case NFT_BITWISE_LSHIFT:
+ expr = netlink_parse_bitwise_shift(ctx, loc, nle, OP_LSHIFT,
+ sreg, left);
+ break;
+ case NFT_BITWISE_RSHIFT:
+ expr = netlink_parse_bitwise_shift(ctx, loc, nle, OP_RSHIFT,
+ sreg, left);
+ break;
+ default:
+ BUG("invalid bitwise operation %u\n", op);
+ }
+
dreg = netlink_parse_register(nle, NFTNL_EXPR_BITWISE_DREG);
netlink_set_register(ctx, dreg, expr);
}
@@ -2091,8 +2142,16 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp)
break;
case EXPR_BINOP:
expr_postprocess(ctx, &expr->left);
- expr_set_type(expr->right, expr->left->dtype,
- expr->left->byteorder);
+ switch (expr->op) {
+ case OP_LSHIFT:
+ case OP_RSHIFT:
+ expr_set_type(expr->right, &integer_type,
+ BYTEORDER_HOST_ENDIAN);
+ break;
+ default:
+ expr_set_type(expr->right, expr->left->dtype,
+ expr->left->byteorder);
+ }
expr_postprocess(ctx, &expr->right);
expr_set_type(expr, expr->left->dtype,
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index d5e177d5e75c..1b9abb379577 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -545,9 +545,36 @@ static void combine_binop(mpz_t mask, mpz_t xor, const mpz_t m, const mpz_t x)
mpz_and(mask, mask, m);
}
-static void netlink_gen_binop(struct netlink_linearize_ctx *ctx,
+static void netlink_gen_shift(struct netlink_linearize_ctx *ctx,
const struct expr *expr,
enum nft_registers dreg)
+{
+ enum nft_bitwise_ops op = expr->op == OP_LSHIFT ?
+ NFT_BITWISE_LSHIFT : NFT_BITWISE_RSHIFT;
+ unsigned int len = div_round_up(expr->len, BITS_PER_BYTE);
+ struct nft_data_linearize nld;
+ struct nftnl_expr *nle;
+
+ netlink_gen_expr(ctx, expr->left, dreg);
+
+ nle = alloc_nft_expr("bitwise");
+ netlink_put_register(nle, NFTNL_EXPR_BITWISE_SREG, dreg);
+ netlink_put_register(nle, NFTNL_EXPR_BITWISE_DREG, dreg);
+ nftnl_expr_set_u32(nle, NFTNL_EXPR_BITWISE_OP, op);
+ nftnl_expr_set_u32(nle, NFTNL_EXPR_BITWISE_LEN, len);
+
+ netlink_gen_raw_data(expr->right->value, expr->right->byteorder,
+ sizeof(uint32_t), &nld);
+
+ nftnl_expr_set(nle, NFTNL_EXPR_BITWISE_DATA, nld.value,
+ nld.len);
+
+ nftnl_rule_add_expr(ctx->nlr, nle);
+}
+
+static void netlink_gen_bitwise(struct netlink_linearize_ctx *ctx,
+ const struct expr *expr,
+ enum nft_registers dreg)
{
struct nftnl_expr *nle;
struct nft_data_linearize nld;
@@ -562,8 +589,9 @@ static void netlink_gen_binop(struct netlink_linearize_ctx *ctx,
mpz_init(val);
mpz_init(tmp);
- binops[n++] = left = (void *)expr;
- while (left->etype == EXPR_BINOP && left->left != NULL)
+ binops[n++] = left = (struct expr *) expr;
+ while (left->etype == EXPR_BINOP && left->left != NULL &&
+ (left->op == OP_AND || left->op == OP_OR || left->op == OP_XOR))
binops[n++] = left = left->left;
n--;
@@ -598,6 +626,7 @@ static void netlink_gen_binop(struct netlink_linearize_ctx *ctx,
nle = alloc_nft_expr("bitwise");
netlink_put_register(nle, NFTNL_EXPR_BITWISE_SREG, dreg);
netlink_put_register(nle, NFTNL_EXPR_BITWISE_DREG, dreg);
+ nftnl_expr_set_u32(nle, NFTNL_EXPR_BITWISE_OP, NFT_BITWISE_BOOL);
nftnl_expr_set_u32(nle, NFTNL_EXPR_BITWISE_LEN, len);
netlink_gen_raw_data(mask, expr->byteorder, len, &nld);
@@ -613,6 +642,21 @@ static void netlink_gen_binop(struct netlink_linearize_ctx *ctx,
nftnl_rule_add_expr(ctx->nlr, nle);
}
+static void netlink_gen_binop(struct netlink_linearize_ctx *ctx,
+ const struct expr *expr,
+ enum nft_registers dreg)
+{
+ switch(expr->op) {
+ case OP_LSHIFT:
+ case OP_RSHIFT:
+ netlink_gen_shift(ctx, expr, dreg);
+ break;
+ default:
+ netlink_gen_bitwise(ctx, expr, dreg);
+ break;
+ }
+}
+
static enum nft_byteorder_ops netlink_gen_unary_op(enum ops op)
{
switch (op) {
--
2.24.1
next prev parent reply other threads:[~2020-01-19 22:57 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-01-19 22:57 [PATCH nft v3 0/9] bitwise shift support Jeremy Sowden
2020-01-19 22:57 ` [PATCH nft v3 1/9] Update gitignore Jeremy Sowden
2020-01-19 22:57 ` [PATCH nft v3 2/9] src: white-space fixes Jeremy Sowden
2020-01-19 22:57 ` [PATCH nft v3 3/9] netlink_delinearize: fix typo Jeremy Sowden
2020-01-19 22:57 ` [PATCH nft v3 4/9] netlink_delinearize: remove commented out pr_debug statement Jeremy Sowden
2020-01-19 22:57 ` [PATCH nft v3 5/9] parser: add parenthesized statement expressions Jeremy Sowden
2020-01-19 22:57 ` [PATCH nft v3 6/9] evaluate: change shift byte-order to host-endian Jeremy Sowden
2020-01-19 22:57 ` [PATCH nft v3 7/9] include: update nf_tables.h Jeremy Sowden
2020-01-19 22:57 ` Jeremy Sowden [this message]
2020-01-19 22:57 ` [PATCH nft v3 9/9] tests: shell: add bit-shift tests Jeremy Sowden
2020-01-28 19:20 ` Pablo Neira Ayuso
2020-02-01 12:32 ` Jeremy Sowden
2020-01-28 19:09 ` [PATCH nft v3 0/9] bitwise shift support Pablo Neira Ayuso
2020-02-01 12:32 ` Jeremy Sowden
2020-02-02 22:28 ` Jeremy Sowden
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=20200119225710.222976-9-jeremy@azazel.net \
--to=jeremy@azazel.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).