netfilter: nft_fib: add reduce support
authorFlorian Westphal <fw@strlen.de>
Mon, 14 Mar 2022 17:23:12 +0000 (18:23 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Sat, 19 Mar 2022 23:29:47 +0000 (00:29 +0100)
The fib expression stores to a register, so we can't add empty stub.
Check that the register that is being written is in fact redundant.

In most cases, this is expected to cancel tracking as re-use is
unlikely.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/net/netfilter/nft_fib.h
net/ipv4/netfilter/nft_fib_ipv4.c
net/ipv6/netfilter/nft_fib_ipv6.c
net/netfilter/nft_fib.c
net/netfilter/nft_fib_inet.c
net/netfilter/nft_fib_netdev.c

index 237f375..eed099e 100644 (file)
@@ -37,4 +37,7 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs,
 
 void nft_fib_store_result(void *reg, const struct nft_fib *priv,
                          const struct net_device *dev);
+
+bool nft_fib_reduce(struct nft_regs_track *track,
+                   const struct nft_expr *expr);
 #endif
index 03df986..4151eb1 100644 (file)
@@ -152,6 +152,7 @@ static const struct nft_expr_ops nft_fib4_type_ops = {
        .init           = nft_fib_init,
        .dump           = nft_fib_dump,
        .validate       = nft_fib_validate,
+       .reduce         = nft_fib_reduce,
 };
 
 static const struct nft_expr_ops nft_fib4_ops = {
@@ -161,6 +162,7 @@ static const struct nft_expr_ops nft_fib4_ops = {
        .init           = nft_fib_init,
        .dump           = nft_fib_dump,
        .validate       = nft_fib_validate,
+       .reduce         = nft_fib_reduce,
 };
 
 static const struct nft_expr_ops *
index 92f3235..b3f163b 100644 (file)
@@ -211,6 +211,7 @@ static const struct nft_expr_ops nft_fib6_type_ops = {
        .init           = nft_fib_init,
        .dump           = nft_fib_dump,
        .validate       = nft_fib_validate,
+       .reduce         = nft_fib_reduce,
 };
 
 static const struct nft_expr_ops nft_fib6_ops = {
@@ -220,6 +221,7 @@ static const struct nft_expr_ops nft_fib6_ops = {
        .init           = nft_fib_init,
        .dump           = nft_fib_dump,
        .validate       = nft_fib_validate,
+       .reduce         = nft_fib_reduce,
 };
 
 static const struct nft_expr_ops *
index b10ce73..f198f2d 100644 (file)
@@ -156,5 +156,47 @@ void nft_fib_store_result(void *reg, const struct nft_fib *priv,
 }
 EXPORT_SYMBOL_GPL(nft_fib_store_result);
 
+bool nft_fib_reduce(struct nft_regs_track *track,
+                   const struct nft_expr *expr)
+{
+       const struct nft_fib *priv = nft_expr_priv(expr);
+       unsigned int len = NFT_REG32_SIZE;
+       const struct nft_fib *fib;
+
+       switch (priv->result) {
+       case NFT_FIB_RESULT_OIF:
+               break;
+       case NFT_FIB_RESULT_OIFNAME:
+               if (priv->flags & NFTA_FIB_F_PRESENT)
+                       len = NFT_REG32_SIZE;
+               else
+                       len = IFNAMSIZ;
+               break;
+       case NFT_FIB_RESULT_ADDRTYPE:
+            break;
+       default:
+               WARN_ON_ONCE(1);
+               break;
+       }
+
+       if (!nft_reg_track_cmp(track, expr, priv->dreg)) {
+               nft_reg_track_update(track, expr, priv->dreg, len);
+               return false;
+       }
+
+       fib = nft_expr_priv(track->regs[priv->dreg].selector);
+       if (priv->result != fib->result ||
+           priv->flags != fib->flags) {
+               nft_reg_track_update(track, expr, priv->dreg, len);
+               return false;
+       }
+
+       if (!track->regs[priv->dreg].bitwise)
+               return true;
+
+       return false;
+}
+EXPORT_SYMBOL_GPL(nft_fib_reduce);
+
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Florian Westphal <fw@strlen.de>");
index a88d44e..666a374 100644 (file)
@@ -49,6 +49,7 @@ static const struct nft_expr_ops nft_fib_inet_ops = {
        .init           = nft_fib_init,
        .dump           = nft_fib_dump,
        .validate       = nft_fib_validate,
+       .reduce         = nft_fib_reduce,
 };
 
 static struct nft_expr_type nft_fib_inet_type __read_mostly = {
index 3f3478a..9121ec6 100644 (file)
@@ -58,6 +58,7 @@ static const struct nft_expr_ops nft_fib_netdev_ops = {
        .init           = nft_fib_init,
        .dump           = nft_fib_dump,
        .validate       = nft_fib_validate,
+       .reduce         = nft_fib_reduce,
 };
 
 static struct nft_expr_type nft_fib_netdev_type __read_mostly = {