netfilter: nf_tables: add space notation to sets
The space notation allows us to classify the set backend implementation based on the amount of required memory. This provides an order of the set representation scalability in terms of memory. The size field is still left in place so use this if the userspace provides no explicit number of elements, so we cannot calculate the real memory that this set needs. This also helps us break ties in the set backend selection routine, eg. two backend implementations provide the same performance. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
Родитель
55af753cd9
Коммит
0b5a787492
|
@ -245,10 +245,12 @@ enum nft_set_class {
|
|||
*
|
||||
* @size: required memory
|
||||
* @lookup: lookup performance class
|
||||
* @space: memory class
|
||||
*/
|
||||
struct nft_set_estimate {
|
||||
unsigned int size;
|
||||
enum nft_set_class lookup;
|
||||
enum nft_set_class space;
|
||||
};
|
||||
|
||||
struct nft_set_ext;
|
||||
|
|
|
@ -2404,6 +2404,7 @@ nft_select_set_ops(const struct nlattr * const nla[],
|
|||
bops = NULL;
|
||||
best.size = ~0;
|
||||
best.lookup = ~0;
|
||||
best.space = ~0;
|
||||
|
||||
list_for_each_entry(ops, &nf_tables_set_ops, list) {
|
||||
if ((ops->features & features) != features)
|
||||
|
@ -2415,14 +2416,25 @@ nft_select_set_ops(const struct nlattr * const nla[],
|
|||
case NFT_SET_POL_PERFORMANCE:
|
||||
if (est.lookup < best.lookup)
|
||||
break;
|
||||
if (est.lookup == best.lookup && est.size < best.size)
|
||||
break;
|
||||
if (est.lookup == best.lookup) {
|
||||
if (!desc->size) {
|
||||
if (est.space < best.space)
|
||||
break;
|
||||
} else if (est.size < best.size) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
case NFT_SET_POL_MEMORY:
|
||||
if (est.size < best.size)
|
||||
break;
|
||||
if (est.size == best.size && est.lookup < best.lookup)
|
||||
if (!desc->size) {
|
||||
if (est.space < best.space)
|
||||
break;
|
||||
if (est.space == best.space &&
|
||||
est.lookup < best.lookup)
|
||||
break;
|
||||
} else if (est.size < best.size) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -385,6 +385,7 @@ static bool nft_hash_estimate(const struct nft_set_desc *desc, u32 features,
|
|||
}
|
||||
|
||||
est->lookup = NFT_SET_CLASS_O_1;
|
||||
est->space = NFT_SET_CLASS_O_N;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -292,6 +292,7 @@ static bool nft_rbtree_estimate(const struct nft_set_desc *desc, u32 features,
|
|||
est->size = nsize;
|
||||
|
||||
est->lookup = NFT_SET_CLASS_O_LOG_N;
|
||||
est->space = NFT_SET_CLASS_O_N;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче