netfilter: nft_fib: add reduce support

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>
This commit is contained in:
Florian Westphal 2022-03-14 18:23:12 +01:00 committed by Pablo Neira Ayuso
parent 611580d2df
commit 3c1eb413a4
6 changed files with 51 additions and 0 deletions

View 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

View 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 *

View 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 *

View 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>");

View 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 = {

View 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 = {