From: Florian Westphal <fw@strlen.de>
To: <netfilter-devel@vger.kernel.org>
Cc: Florian Westphal <fw@strlen.de>
Subject: [PATCH nft 2/2] src: propagate key datatype for anonymous sets
Date: Thu, 9 Dec 2021 16:11:31 +0100 [thread overview]
Message-ID: <20211209151131.22618-3-fw@strlen.de> (raw)
In-Reply-To: <20211209151131.22618-1-fw@strlen.de>
set s10 {
typeof tcp option mptcp subtype
elements = { mp-join, dss }
}
is listed correctly: typeof provides the 'mptcpopt_subtype'
datatype, so listing will print the elements with their sybolic types.
In anon case this doesn't work:
tcp option mptcp subtype { mp-join, dss }
gets shown as 'tcp option mptcp subtype { 1, 2}' because the anon
set has integer type.
This change propagates the datatype to the individual members
of the anon set.
After this change, multiple existing data types such as
TYPE_ICMP_TYPE could be replaced by integer-type aliases, but those
data types are already exposed to userspace via the 'set type'
directive so doing this may break existing set definitions.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
src/expression.c | 34 ++++++++++++++++++++++++++++++++++
tests/py/any/tcpopt.t | 2 +-
tests/py/any/tcpopt.t.payload | 10 +++++-----
3 files changed, 40 insertions(+), 6 deletions(-)
diff --git a/src/expression.c b/src/expression.c
index f1cca8845376..9de70c6cc1a4 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -1249,6 +1249,31 @@ static void set_ref_expr_destroy(struct expr *expr)
set_free(expr->set);
}
+static void set_ref_expr_set_type(const struct expr *expr,
+ const struct datatype *dtype,
+ enum byteorder byteorder)
+{
+ const struct set *s = expr->set;
+
+ /* normal sets already have a precise datatype that is given in
+ * the set definition via type foo.
+ *
+ * Anon sets do not have this, and need to rely on type info
+ * generated at rule creation time.
+ *
+ * For most cases, the type info is correct.
+ * In some cases however, the kernel only stores TYPE_INTEGER.
+ *
+ * This happens with expressions that only use an integer alias
+ * type, such as mptcp_suboption.
+ *
+ * In this case nft would print '1', '2', etc. instead of symbolic
+ * names because the base type lacks ->sym_tbl information.
+ */
+ if (s->init && set_is_anonymous(s->flags))
+ expr_set_type(s->init, dtype, byteorder);
+}
+
static const struct expr_ops set_ref_expr_ops = {
.type = EXPR_SET_REF,
.name = "set reference",
@@ -1256,6 +1281,7 @@ static const struct expr_ops set_ref_expr_ops = {
.json = set_ref_expr_json,
.clone = set_ref_expr_clone,
.destroy = set_ref_expr_destroy,
+ .set_type = set_ref_expr_set_type,
};
struct expr *set_ref_expr_alloc(const struct location *loc, struct set *set)
@@ -1310,6 +1336,13 @@ static void set_elem_expr_clone(struct expr *new, const struct expr *expr)
init_list_head(&new->stmt_list);
}
+static void set_elem_expr_set_type(const struct expr *expr,
+ const struct datatype *dtype,
+ enum byteorder byteorder)
+{
+ expr_set_type(expr->key, dtype, byteorder);
+}
+
static const struct expr_ops set_elem_expr_ops = {
.type = EXPR_SET_ELEM,
.name = "set element",
@@ -1317,6 +1350,7 @@ static const struct expr_ops set_elem_expr_ops = {
.print = set_elem_expr_print,
.json = set_elem_expr_json,
.destroy = set_elem_expr_destroy,
+ .set_type = set_elem_expr_set_type,
};
struct expr *set_elem_expr_alloc(const struct location *loc, struct expr *key)
diff --git a/tests/py/any/tcpopt.t b/tests/py/any/tcpopt.t
index a5ac1e86e207..f57532c3016d 100644
--- a/tests/py/any/tcpopt.t
+++ b/tests/py/any/tcpopt.t
@@ -53,4 +53,4 @@ tcp option mptcp exists;ok
tcp option mptcp subtype mp-capable;ok
tcp option mptcp subtype 1;ok;tcp option mptcp subtype mp-join
-tcp option mptcp subtype { 0, 2};ok
+tcp option mptcp subtype { mp-capable, mp-join, remove-addr, mp-prio, mp-fail, mp-fastclose, mp-tcprst };ok
diff --git a/tests/py/any/tcpopt.t.payload b/tests/py/any/tcpopt.t.payload
index 269dee0aedb6..5a3102f9b459 100644
--- a/tests/py/any/tcpopt.t.payload
+++ b/tests/py/any/tcpopt.t.payload
@@ -180,11 +180,11 @@ inet
[ bitwise reg 1 = ( reg 1 & 0x000000f0 ) ^ 0x00000000 ]
[ cmp eq reg 1 0x00000010 ]
-# tcp option mptcp subtype { 0, 2}
-__set%d test-inet 3 size 2
-__set%d test-inet 0
- element 00000000 : 0 [end] element 00000020 : 0 [end]
-inet
+# tcp option mptcp subtype { mp-capable, mp-join, remove-addr, mp-prio, mp-fail, mp-fastclose, mp-tcprst }
+__set%d test-ip4 3 size 7
+__set%d test-ip4 0
+ element 00000000 : 0 [end] element 00000010 : 0 [end] element 00000040 : 0 [end] element 00000050 : 0 [end] element 00000060 : 0 [end] element 00000070 : 0 [end] element 00000080 : 0 [end]
+ip test-ip4 input
[ exthdr load tcpopt 1b @ 30 + 2 => reg 1 ]
[ bitwise reg 1 = ( reg 1 & 0x000000f0 ) ^ 0x00000000 ]
[ lookup reg 1 set __set%d ]
--
2.32.0
next prev parent reply other threads:[~2021-12-09 15:11 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-09 15:11 [PATCH 0/2 nft] mptcp: add mptcp subtype mnemonics Florian Westphal
2021-12-09 15:11 ` [PATCH nft 1/2] tcpopt: add phony mptcp suboption datatype Florian Westphal
2021-12-09 15:11 ` Florian Westphal [this message]
2021-12-15 23:22 ` [PATCH nft 2/2] src: propagate key datatype for anonymous sets Pablo Neira Ayuso
2021-12-17 11:22 ` Florian Westphal
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=20211209151131.22618-3-fw@strlen.de \
--to=fw@strlen.de \
--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