netfilter: nf_tables: meter: pick a set backend that supports updates
in nftables, 'meter' can be used to instantiate a hash-table at run time: rule add filter forward iif "internal" meter hostacct { ip saddr counter} nft list meter ip filter hostacct table ip filter { meter hostacct { type ipv4_addr elements = { 192.168.0.1 : counter packets 8 bytes 2672, .. because elemets get added on the fly, the kernel must chose a set backend type that implements the ->update() function, otherwise rule insertion fails with EOPNOTSUPP. Therefore, skip set types that lack ->update, and also make sure we do not discard a (bad) candidate when we did yet find any candidate at all. This could happen when userspace prefers low memory footprint -- the set implementation currently checked might not be a fit at all. Make sure we pick it anyway (!bops). In case next candidate is a better fix, it will be chosen instead. But in case nothing else is found we at least have a non-ideal match rather than no match at all. Fixes: 6c03ae210ce3 ("netfilter: nft_set_hash: add non-resizable hashtable implementation") Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
36fe095606
commit
4f2921ca21
@ -2446,6 +2446,9 @@ EXPORT_SYMBOL_GPL(nft_unregister_set);
|
|||||||
|
|
||||||
static bool nft_set_ops_candidate(const struct nft_set_ops *ops, u32 flags)
|
static bool nft_set_ops_candidate(const struct nft_set_ops *ops, u32 flags)
|
||||||
{
|
{
|
||||||
|
if ((flags & NFT_SET_EVAL) && !ops->update)
|
||||||
|
return false;
|
||||||
|
|
||||||
return (flags & ops->features) == (flags & NFT_SET_FEATURES);
|
return (flags & ops->features) == (flags & NFT_SET_FEATURES);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2510,7 +2513,7 @@ nft_select_set_ops(const struct nft_ctx *ctx,
|
|||||||
if (est.space == best.space &&
|
if (est.space == best.space &&
|
||||||
est.lookup < best.lookup)
|
est.lookup < best.lookup)
|
||||||
break;
|
break;
|
||||||
} else if (est.size < best.size) {
|
} else if (est.size < best.size || !bops) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
@ -674,7 +674,7 @@ static const struct nft_set_ops *
|
|||||||
nft_hash_select_ops(const struct nft_ctx *ctx, const struct nft_set_desc *desc,
|
nft_hash_select_ops(const struct nft_ctx *ctx, const struct nft_set_desc *desc,
|
||||||
u32 flags)
|
u32 flags)
|
||||||
{
|
{
|
||||||
if (desc->size && !(flags & NFT_SET_TIMEOUT)) {
|
if (desc->size && !(flags & (NFT_SET_EVAL | NFT_SET_TIMEOUT))) {
|
||||||
switch (desc->klen) {
|
switch (desc->klen) {
|
||||||
case 4:
|
case 4:
|
||||||
return &nft_hash_fast_ops;
|
return &nft_hash_fast_ops;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user