netfilter: nft_payload: track register operations
authorPablo Neira Ayuso <pablo@netfilter.org>
Sun, 9 Jan 2022 16:11:22 +0000 (17:11 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Sun, 9 Jan 2022 22:35:17 +0000 (23:35 +0100)
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>
net/netfilter/nft_payload.c

index f2e65df..7a7c66e 100644 (file)
@@ -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,
 };