From: Pablo Neira Ayuso <pablo@netfilter.org>
To: netfilter-devel@vger.kernel.org
Cc: phil@nwl.cc
Subject: [PATCH nft 2/2] rule: remove redundant meta protocol from the evaluation step
Date: Tue, 31 Aug 2021 00:34:12 +0200 [thread overview]
Message-ID: <20210830223412.12865-2-pablo@netfilter.org> (raw)
In-Reply-To: <20210830223412.12865-1-pablo@netfilter.org>
567ea4774e13 ("netlink_delinearize: incorrect meta protocol dependency kill")
does not document two cases that are handled in this patch:
- 'meta protocol ip' is removed if used in the ip family.
- 'meta protocol ip6' is removed if used in the ip6 family.
This patch removes this redundancy earlier, from the evaluation step
before netlink bytecode generation.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
src/rule.c | 77 ++++++++++++++++++++++++++-----------
tests/py/ip/meta.t | 2 +-
tests/py/ip/meta.t.payload | 2 -
tests/py/ip6/meta.t | 2 +-
tests/py/ip6/meta.t.payload | 2 -
5 files changed, 56 insertions(+), 29 deletions(-)
diff --git a/src/rule.c b/src/rule.c
index 3e59f27c69be..6091067f608b 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -2757,49 +2757,80 @@ static void payload_do_merge(struct stmt *sa[], unsigned int n)
}
/**
- * payload_try_merge - try to merge consecutive payload match statements
+ * stmt_reduce - reduce statements in rule
*
* @rule: nftables rule
*
+ * This function aims to:
+ *
+ * - remove redundant statement, e.g. remove 'meta protocol ip' if family is ip
+ * - merge consecutive payload match statements
+ *
* Locate sequences of payload match statements referring to adjacent
* header locations and merge those using only equality relations.
*
* As a side-effect, payload match statements are ordered in ascending
* order according to the location of the payload.
*/
-static void payload_try_merge(const struct rule *rule)
+static void stmt_reduce(const struct rule *rule)
{
+ struct stmt *stmt, *dstmt = NULL, *next;
struct stmt *sa[rule->num_stmts];
- struct stmt *stmt, *next;
unsigned int idx = 0;
list_for_each_entry_safe(stmt, next, &rule->stmts, list) {
+ /* delete this redundant statement */
+ if (dstmt) {
+ list_del(&dstmt->list);
+ stmt_free(dstmt);
+ dstmt = NULL;
+ }
+
/* Must not merge across other statements */
- if (stmt->ops->type != STMT_EXPRESSION)
- goto do_merge;
+ if (stmt->ops->type != STMT_EXPRESSION) {
+ if (idx < 2)
+ continue;
- if (stmt->expr->etype != EXPR_RELATIONAL)
+ payload_do_merge(sa, idx);
+ idx = 0;
continue;
- if (stmt->expr->left->etype != EXPR_PAYLOAD)
+ }
+
+ if (stmt->expr->etype != EXPR_RELATIONAL)
continue;
if (stmt->expr->right->etype != EXPR_VALUE)
continue;
- switch (stmt->expr->op) {
- case OP_EQ:
- case OP_IMPLICIT:
- case OP_NEQ:
- break;
- default:
- continue;
- }
- sa[idx++] = stmt;
- continue;
-do_merge:
- if (idx < 2)
- continue;
- payload_do_merge(sa, idx);
- idx = 0;
+ if (stmt->expr->left->etype == EXPR_PAYLOAD) {
+ switch (stmt->expr->op) {
+ case OP_EQ:
+ case OP_IMPLICIT:
+ case OP_NEQ:
+ break;
+ default:
+ continue;
+ }
+
+ sa[idx++] = stmt;
+ } else if (stmt->expr->left->etype == EXPR_META) {
+ switch (stmt->expr->op) {
+ case OP_EQ:
+ case OP_IMPLICIT:
+ if (stmt->expr->left->meta.key == NFT_META_PROTOCOL) {
+ uint16_t protocol;
+
+ protocol = mpz_get_uint16(stmt->expr->right->value);
+ if ((rule->handle.family == NFPROTO_IPV4 &&
+ protocol == ETH_P_IP) ||
+ (rule->handle.family == NFPROTO_IPV6 &&
+ protocol == ETH_P_IPV6))
+ dstmt = stmt;
+ }
+ break;
+ default:
+ break;
+ }
+ }
}
if (idx > 1)
@@ -2808,6 +2839,6 @@ do_merge:
struct error_record *rule_postprocess(struct rule *rule)
{
- payload_try_merge(rule);
+ stmt_reduce(rule);
return NULL;
}
diff --git a/tests/py/ip/meta.t b/tests/py/ip/meta.t
index fecd0caf71a7..5a05923a1ce1 100644
--- a/tests/py/ip/meta.t
+++ b/tests/py/ip/meta.t
@@ -8,7 +8,7 @@ meta l4proto ipv6-icmp icmpv6 type nd-router-advert;ok;icmpv6 type nd-router-adv
meta l4proto 58 icmpv6 type nd-router-advert;ok;icmpv6 type nd-router-advert
icmpv6 type nd-router-advert;ok
-meta protocol ip udp dport 67;ok
+meta protocol ip udp dport 67;ok;udp dport 67
meta ibrname "br0";fail
meta obrname "br0";fail
diff --git a/tests/py/ip/meta.t.payload b/tests/py/ip/meta.t.payload
index a1fd00864ef9..afde5cc13ac5 100644
--- a/tests/py/ip/meta.t.payload
+++ b/tests/py/ip/meta.t.payload
@@ -47,8 +47,6 @@ ip6 test-ip4 input
# meta protocol ip udp dport 67
ip test-ip4 input
- [ meta load protocol => reg 1 ]
- [ cmp eq reg 1 0x00000008 ]
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000011 ]
[ payload load 2b @ transport header + 2 => reg 1 ]
diff --git a/tests/py/ip6/meta.t b/tests/py/ip6/meta.t
index 2c1aee2309a9..471e14811975 100644
--- a/tests/py/ip6/meta.t
+++ b/tests/py/ip6/meta.t
@@ -10,7 +10,7 @@ meta l4proto 1 icmp type echo-request;ok;icmp type echo-request
icmp type echo-request;ok
meta protocol ip udp dport 67;ok
-meta protocol ip6 udp dport 67;ok
+meta protocol ip6 udp dport 67;ok;udp dport 67
meta sdif "lo" accept;ok
meta sdifname != "vrf1" accept;ok
diff --git a/tests/py/ip6/meta.t.payload b/tests/py/ip6/meta.t.payload
index 59c20d994138..0e3db6ba07f9 100644
--- a/tests/py/ip6/meta.t.payload
+++ b/tests/py/ip6/meta.t.payload
@@ -56,8 +56,6 @@ ip6 test-ip6 input
# meta protocol ip6 udp dport 67
ip6 test-ip6 input
- [ meta load protocol => reg 1 ]
- [ cmp eq reg 1 0x0000dd86 ]
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000011 ]
[ payload load 2b @ transport header + 2 => reg 1 ]
--
2.20.1
prev parent reply other threads:[~2021-08-30 22:34 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-08-30 22:34 [PATCH nft 1/2] netlink_delinearize: incorrect meta protocol dependency kill again Pablo Neira Ayuso
2021-08-30 22:34 ` Pablo Neira Ayuso [this message]
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=20210830223412.12865-2-pablo@netfilter.org \
--to=pablo@netfilter.org \
--cc=netfilter-devel@vger.kernel.org \
--cc=phil@nwl.cc \
/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).