Skip to content

Commit

Permalink
netfilter: nf_tables: add space notation to sets
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Pablo Neira Ayuso committed Feb 8, 2017
1 parent 55af753 commit 0b5a787
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 5 deletions.
2 changes: 2 additions & 0 deletions include/net/netfilter/nf_tables.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
22 changes: 17 additions & 5 deletions net/netfilter/nf_tables_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
Expand Down
1 change: 1 addition & 0 deletions net/netfilter/nft_set_hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
1 change: 1 addition & 0 deletions net/netfilter/nft_set_rbtree.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down

0 comments on commit 0b5a787

Please sign in to comment.