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

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
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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
+2 −0
Original line number Diff line number Diff line
@@ -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 *
+2 −0
Original line number Diff line number Diff line
@@ -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 *
+42 −0
Original line number Diff line number Diff line
@@ -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>");
+1 −0
Original line number Diff line number Diff line
@@ -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 = {
Loading