Commit 3c1eb413 authored by Florian Westphal's avatar Florian Westphal Committed by Pablo Neira Ayuso

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: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 611580d2
...@@ -37,4 +37,7 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs, ...@@ -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, void nft_fib_store_result(void *reg, const struct nft_fib *priv,
const struct net_device *dev); const struct net_device *dev);
bool nft_fib_reduce(struct nft_regs_track *track,
const struct nft_expr *expr);
#endif #endif
...@@ -152,6 +152,7 @@ static const struct nft_expr_ops nft_fib4_type_ops = { ...@@ -152,6 +152,7 @@ static const struct nft_expr_ops nft_fib4_type_ops = {
.init = nft_fib_init, .init = nft_fib_init,
.dump = nft_fib_dump, .dump = nft_fib_dump,
.validate = nft_fib_validate, .validate = nft_fib_validate,
.reduce = nft_fib_reduce,
}; };
static const struct nft_expr_ops nft_fib4_ops = { static const struct nft_expr_ops nft_fib4_ops = {
...@@ -161,6 +162,7 @@ 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, .init = nft_fib_init,
.dump = nft_fib_dump, .dump = nft_fib_dump,
.validate = nft_fib_validate, .validate = nft_fib_validate,
.reduce = nft_fib_reduce,
}; };
static const struct nft_expr_ops * static const struct nft_expr_ops *
......
...@@ -211,6 +211,7 @@ static const struct nft_expr_ops nft_fib6_type_ops = { ...@@ -211,6 +211,7 @@ static const struct nft_expr_ops nft_fib6_type_ops = {
.init = nft_fib_init, .init = nft_fib_init,
.dump = nft_fib_dump, .dump = nft_fib_dump,
.validate = nft_fib_validate, .validate = nft_fib_validate,
.reduce = nft_fib_reduce,
}; };
static const struct nft_expr_ops nft_fib6_ops = { static const struct nft_expr_ops nft_fib6_ops = {
...@@ -220,6 +221,7 @@ 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, .init = nft_fib_init,
.dump = nft_fib_dump, .dump = nft_fib_dump,
.validate = nft_fib_validate, .validate = nft_fib_validate,
.reduce = nft_fib_reduce,
}; };
static const struct nft_expr_ops * static const struct nft_expr_ops *
......
...@@ -156,5 +156,47 @@ void nft_fib_store_result(void *reg, const struct nft_fib *priv, ...@@ -156,5 +156,47 @@ void nft_fib_store_result(void *reg, const struct nft_fib *priv,
} }
EXPORT_SYMBOL_GPL(nft_fib_store_result); 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_LICENSE("GPL");
MODULE_AUTHOR("Florian Westphal <fw@strlen.de>"); MODULE_AUTHOR("Florian Westphal <fw@strlen.de>");
...@@ -49,6 +49,7 @@ static const struct nft_expr_ops nft_fib_inet_ops = { ...@@ -49,6 +49,7 @@ static const struct nft_expr_ops nft_fib_inet_ops = {
.init = nft_fib_init, .init = nft_fib_init,
.dump = nft_fib_dump, .dump = nft_fib_dump,
.validate = nft_fib_validate, .validate = nft_fib_validate,
.reduce = nft_fib_reduce,
}; };
static struct nft_expr_type nft_fib_inet_type __read_mostly = { static struct nft_expr_type nft_fib_inet_type __read_mostly = {
......
...@@ -58,6 +58,7 @@ static const struct nft_expr_ops nft_fib_netdev_ops = { ...@@ -58,6 +58,7 @@ static const struct nft_expr_ops nft_fib_netdev_ops = {
.init = nft_fib_init, .init = nft_fib_init,
.dump = nft_fib_dump, .dump = nft_fib_dump,
.validate = nft_fib_validate, .validate = nft_fib_validate,
.reduce = nft_fib_reduce,
}; };
static struct nft_expr_type nft_fib_netdev_type __read_mostly = { static struct nft_expr_type nft_fib_netdev_type __read_mostly = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment