aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2022-01-09 17:11:22 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2022-01-09 23:35:17 +0100
commita7c176bf9f0e916f7544f6a00d898b0c90de1887 (patch)
tree85062707d32c15770a33ce5e5909ab17c71374bb /net/netfilter
parentnetfilter: nf_tables: add register tracking infrastructure (diff)
downloadlinux-dev-a7c176bf9f0e916f7544f6a00d898b0c90de1887.tar.xz
linux-dev-a7c176bf9f0e916f7544f6a00d898b0c90de1887.zip
netfilter: nft_payload: track register operations
Check if the destination register already contains the data that this payload store expression performs. This allows to skip this redundant operation. If the destination contains a different selector, update the register tracking information. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/nft_payload.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c
index f2e65df32a06..7a7c66e9a50e 100644
--- a/net/netfilter/nft_payload.c
+++ b/net/netfilter/nft_payload.c
@@ -210,6 +210,34 @@ nla_put_failure:
return -1;
}
+static bool nft_payload_reduce(struct nft_regs_track *track,
+ const struct nft_expr *expr)
+{
+ const struct nft_payload *priv = nft_expr_priv(expr);
+ const struct nft_payload *payload;
+
+ if (!track->regs[priv->dreg].selector ||
+ track->regs[priv->dreg].selector->ops != expr->ops) {
+ track->regs[priv->dreg].selector = expr;
+ track->regs[priv->dreg].bitwise = NULL;
+ return false;
+ }
+
+ payload = nft_expr_priv(track->regs[priv->dreg].selector);
+ if (priv->base != payload->base ||
+ priv->offset != payload->offset ||
+ priv->len != payload->len) {
+ track->regs[priv->dreg].selector = expr;
+ track->regs[priv->dreg].bitwise = NULL;
+ return false;
+ }
+
+ if (!track->regs[priv->dreg].bitwise)
+ return true;
+
+ return false;
+}
+
static bool nft_payload_offload_mask(struct nft_offload_reg *reg,
u32 priv_len, u32 field_len)
{
@@ -513,6 +541,7 @@ static const struct nft_expr_ops nft_payload_ops = {
.eval = nft_payload_eval,
.init = nft_payload_init,
.dump = nft_payload_dump,
+ .reduce = nft_payload_reduce,
.offload = nft_payload_offload,
};
@@ -522,6 +551,7 @@ const struct nft_expr_ops nft_payload_fast_ops = {
.eval = nft_payload_eval,
.init = nft_payload_init,
.dump = nft_payload_dump,
+ .reduce = nft_payload_reduce,
.offload = nft_payload_offload,
};