|
|
1d03cd |
From 29f041b93d7fc4e23c62c2e2e3cbbeaafa83b4ef Mon Sep 17 00:00:00 2001
|
|
|
1d03cd |
From: Phil Sutter <psutter@redhat.com>
|
|
|
1d03cd |
Date: Thu, 9 Feb 2023 10:27:57 +0100
|
|
|
1d03cd |
Subject: [PATCH] netlink_delinearize: postprocess binary ands in
|
|
|
1d03cd |
concatenations
|
|
|
1d03cd |
|
|
|
1d03cd |
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2094887
|
|
|
1d03cd |
Upstream Status: nftables commit 89688c947efc3
|
|
|
1d03cd |
|
|
|
1d03cd |
commit 89688c947efc36d25c58c85650414fa3a491732e
|
|
|
1d03cd |
Author: Florian Westphal <fw@strlen.de>
|
|
|
1d03cd |
Date: Tue Jun 14 21:56:48 2022 +0200
|
|
|
1d03cd |
|
|
|
1d03cd |
netlink_delinearize: postprocess binary ands in concatenations
|
|
|
1d03cd |
|
|
|
1d03cd |
Input:
|
|
|
1d03cd |
update ether saddr . vlan id timeout 5s @macset
|
|
|
1d03cd |
ether saddr . vlan id @macset
|
|
|
1d03cd |
|
|
|
1d03cd |
Before this patch, gets rendered as:
|
|
|
1d03cd |
update @macset { @ll,48,48 . @ll,112,16 & 0xfff timeout 5s }
|
|
|
1d03cd |
@ll,48,48 . @ll,112,16 & 0xfff @macset
|
|
|
1d03cd |
|
|
|
1d03cd |
After this, listing will show:
|
|
|
1d03cd |
update @macset { @ll,48,48 . vlan id timeout 5s }
|
|
|
1d03cd |
@ll,48,48 . vlan id @macset
|
|
|
1d03cd |
|
|
|
1d03cd |
The @ll, ... is due to vlan description replacing the ethernet one,
|
|
|
1d03cd |
so payload decode fails to take the concatenation apart (the ethernet
|
|
|
1d03cd |
header payload info is matched vs. vlan template).
|
|
|
1d03cd |
|
|
|
1d03cd |
This will be adjusted by a followup patch.
|
|
|
1d03cd |
|
|
|
1d03cd |
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
1d03cd |
|
|
|
1d03cd |
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
|
1d03cd |
---
|
|
|
1d03cd |
include/netlink.h | 6 ++++++
|
|
|
1d03cd |
src/netlink_delinearize.c | 45 ++++++++++++++++++++++++++++++++++-----
|
|
|
1d03cd |
2 files changed, 46 insertions(+), 5 deletions(-)
|
|
|
1d03cd |
|
|
|
1d03cd |
diff --git a/include/netlink.h b/include/netlink.h
|
|
|
1d03cd |
index e8e0f68..71c888f 100644
|
|
|
1d03cd |
--- a/include/netlink.h
|
|
|
1d03cd |
+++ b/include/netlink.h
|
|
|
1d03cd |
@@ -42,10 +42,16 @@ struct netlink_parse_ctx {
|
|
|
1d03cd |
struct netlink_ctx *nlctx;
|
|
|
1d03cd |
};
|
|
|
1d03cd |
|
|
|
1d03cd |
+
|
|
|
1d03cd |
+#define RULE_PP_IN_CONCATENATION (1 << 0)
|
|
|
1d03cd |
+
|
|
|
1d03cd |
+#define RULE_PP_REMOVE_OP_AND (RULE_PP_IN_CONCATENATION)
|
|
|
1d03cd |
+
|
|
|
1d03cd |
struct rule_pp_ctx {
|
|
|
1d03cd |
struct proto_ctx pctx;
|
|
|
1d03cd |
struct payload_dep_ctx pdctx;
|
|
|
1d03cd |
struct stmt *stmt;
|
|
|
1d03cd |
+ unsigned int flags;
|
|
|
1d03cd |
};
|
|
|
1d03cd |
|
|
|
1d03cd |
extern const struct input_descriptor indesc_netlink;
|
|
|
1d03cd |
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
|
|
|
1d03cd |
index 2f13990..cba419d 100644
|
|
|
1d03cd |
--- a/src/netlink_delinearize.c
|
|
|
1d03cd |
+++ b/src/netlink_delinearize.c
|
|
|
1d03cd |
@@ -2259,12 +2259,13 @@ static void binop_adjust(const struct expr *binop, struct expr *right,
|
|
|
1d03cd |
}
|
|
|
1d03cd |
}
|
|
|
1d03cd |
|
|
|
1d03cd |
-static void binop_postprocess(struct rule_pp_ctx *ctx, struct expr *expr,
|
|
|
1d03cd |
- struct expr **expr_binop)
|
|
|
1d03cd |
+static void __binop_postprocess(struct rule_pp_ctx *ctx,
|
|
|
1d03cd |
+ struct expr *expr,
|
|
|
1d03cd |
+ struct expr *left,
|
|
|
1d03cd |
+ struct expr *mask,
|
|
|
1d03cd |
+ struct expr **expr_binop)
|
|
|
1d03cd |
{
|
|
|
1d03cd |
struct expr *binop = *expr_binop;
|
|
|
1d03cd |
- struct expr *left = binop->left;
|
|
|
1d03cd |
- struct expr *mask = binop->right;
|
|
|
1d03cd |
unsigned int shift;
|
|
|
1d03cd |
|
|
|
1d03cd |
assert(binop->etype == EXPR_BINOP);
|
|
|
1d03cd |
@@ -2300,15 +2301,26 @@ static void binop_postprocess(struct rule_pp_ctx *ctx, struct expr *expr,
|
|
|
1d03cd |
|
|
|
1d03cd |
assert(binop->left == left);
|
|
|
1d03cd |
*expr_binop = expr_get(left);
|
|
|
1d03cd |
- expr_free(binop);
|
|
|
1d03cd |
|
|
|
1d03cd |
if (left->etype == EXPR_PAYLOAD)
|
|
|
1d03cd |
payload_match_postprocess(ctx, expr, left);
|
|
|
1d03cd |
else if (left->etype == EXPR_EXTHDR && right)
|
|
|
1d03cd |
expr_set_type(right, left->dtype, left->byteorder);
|
|
|
1d03cd |
+
|
|
|
1d03cd |
+ expr_free(binop);
|
|
|
1d03cd |
}
|
|
|
1d03cd |
}
|
|
|
1d03cd |
|
|
|
1d03cd |
+static void binop_postprocess(struct rule_pp_ctx *ctx, struct expr *expr,
|
|
|
1d03cd |
+ struct expr **expr_binop)
|
|
|
1d03cd |
+{
|
|
|
1d03cd |
+ struct expr *binop = *expr_binop;
|
|
|
1d03cd |
+ struct expr *left = binop->left;
|
|
|
1d03cd |
+ struct expr *mask = binop->right;
|
|
|
1d03cd |
+
|
|
|
1d03cd |
+ __binop_postprocess(ctx, expr, left, mask, expr_binop);
|
|
|
1d03cd |
+}
|
|
|
1d03cd |
+
|
|
|
1d03cd |
static void map_binop_postprocess(struct rule_pp_ctx *ctx, struct expr *expr)
|
|
|
1d03cd |
{
|
|
|
1d03cd |
struct expr *binop = expr->map;
|
|
|
1d03cd |
@@ -2541,6 +2553,7 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp)
|
|
|
1d03cd |
LIST_HEAD(tmp);
|
|
|
1d03cd |
struct expr *n;
|
|
|
1d03cd |
|
|
|
1d03cd |
+ ctx->flags |= RULE_PP_IN_CONCATENATION;
|
|
|
1d03cd |
list_for_each_entry_safe(i, n, &expr->expressions, list) {
|
|
|
1d03cd |
if (type) {
|
|
|
1d03cd |
dtype = concat_subtype_lookup(type, --off);
|
|
|
1d03cd |
@@ -2552,6 +2565,7 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp)
|
|
|
1d03cd |
|
|
|
1d03cd |
ntype = concat_subtype_add(ntype, i->dtype->type);
|
|
|
1d03cd |
}
|
|
|
1d03cd |
+ ctx->flags &= ~RULE_PP_IN_CONCATENATION;
|
|
|
1d03cd |
list_splice(&tmp, &expr->expressions);
|
|
|
1d03cd |
datatype_set(expr, concat_type_alloc(ntype));
|
|
|
1d03cd |
break;
|
|
|
1d03cd |
@@ -2568,6 +2582,27 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp)
|
|
|
1d03cd |
expr_set_type(expr->right, &integer_type,
|
|
|
1d03cd |
BYTEORDER_HOST_ENDIAN);
|
|
|
1d03cd |
break;
|
|
|
1d03cd |
+ case OP_AND:
|
|
|
1d03cd |
+ expr_set_type(expr->right, expr->left->dtype,
|
|
|
1d03cd |
+ expr->left->byteorder);
|
|
|
1d03cd |
+
|
|
|
1d03cd |
+ /* Do not process OP_AND in ordinary rule context.
|
|
|
1d03cd |
+ *
|
|
|
1d03cd |
+ * Removal needs to be performed as part of the relational
|
|
|
1d03cd |
+ * operation because the RHS constant might need to be adjusted
|
|
|
1d03cd |
+ * (shifted).
|
|
|
1d03cd |
+ *
|
|
|
1d03cd |
+ * This is different in set element context or concatenations:
|
|
|
1d03cd |
+ * There is no relational operation (eq, neq and so on), thus
|
|
|
1d03cd |
+ * it needs to be processed right away.
|
|
|
1d03cd |
+ */
|
|
|
1d03cd |
+ if ((ctx->flags & RULE_PP_REMOVE_OP_AND) &&
|
|
|
1d03cd |
+ expr->left->etype == EXPR_PAYLOAD &&
|
|
|
1d03cd |
+ expr->right->etype == EXPR_VALUE) {
|
|
|
1d03cd |
+ __binop_postprocess(ctx, expr, expr->left, expr->right, exprp);
|
|
|
1d03cd |
+ return;
|
|
|
1d03cd |
+ }
|
|
|
1d03cd |
+ break;
|
|
|
1d03cd |
default:
|
|
|
1d03cd |
expr_set_type(expr->right, expr->left->dtype,
|
|
|
1d03cd |
expr->left->byteorder);
|
|
|
1d03cd |
--
|
|
|
1d03cd |
2.39.1
|
|
|
1d03cd |
|