diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2022-01-09 17:11:22 +0100 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2022-01-09 23:35:17 +0100 |
commit | a7c176bf9f0e916f7544f6a00d898b0c90de1887 (patch) | |
tree | 85062707d32c15770a33ce5e5909ab17c71374bb /net/netfilter | |
parent | 12e4ecfa244be2f117ef5304d2d866b65e70bff3 (diff) | |
download | linux-stable-a7c176bf9f0e916f7544f6a00d898b0c90de1887.tar.gz linux-stable-a7c176bf9f0e916f7544f6a00d898b0c90de1887.tar.bz2 linux-stable-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.c | 30 |
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, }; |