netfilter: nf_tables: performance set policy skips size description in selection
Subsystems (2)
Pablo Neira Ayuso
maintainerPATCH 1/2 netfilter: nf_tables: performance set policy skips size description in selection
Use the complexity and space notations if policy is performance, this results in placing the bitmap set representation over the hashtable for key <= 16 for better performance as we discussed during the last NFWS in Faro, Portugal.
Signed-off-by Pablo Neira Ayuso <[email protected]>
--- net/netfilter/nf_tables_api.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-)
net/netfilter/nf_tables_api.c +3 -8
@@ -2549,14 +2549,9 @@ nft_select_set_ops(const struct nft_ctx *ctx,case NFT_SET_POL_PERFORMANCE :if (est.lookup < best.lookup)break ; -if (est.lookup == best.lookup) { -if (!desc->size) { -if (est.space < best.space) -break ; - }else if (est.size < best.size) { -break ; - } - } +if (est.lookup == best.lookup && + est.space < best.space) +break ;continue ;case NFT_SET_POL_MEMORY :if (!desc->size) {
Signature · 1 line
2.11.0
Pablo Neira Ayuso
maintainerPATCH 2/2 netfilter: nf_tables: get set elements via netlink
This patch adds a new get operation for sets to look up for an elements from userspace via netlink interface.
Signed-off-by Pablo Neira Ayuso <[email protected]>
--- include/net/netfilter/nf_tables.h | 5 ++ net/netfilter/nf_tables_api.c | 184 ++++++++++++++++++++++++++------------ net/netfilter/nft_set_bitmap.c | 18 ++++ net/netfilter/nft_set_hash.c | 39 ++++++++ net/netfilter/nft_set_rbtree.c | 73 +++++++++++++++ 5 files changed, 264 insertions(+), 55 deletions(-)
include/net/netfilter/nf_tables.h +5 -0
@@ -311,6 +311,7 @@ struct nft_expr;* @flush: deactivate element in the next generation * @remove: remove element from set * @walk: iterate over all set elemeennts +* @get: get set elements * @privsize: function to return size of set private data * @init: initialize private data of new set instance * @destroy: destroy private data of set instance
@@ -350,6 +351,10 @@ struct nft_set_ops {void (*walk)(const struct nft_ctx *ctx,struct nft_set *set,struct nft_set_iter *iter); +void * (*get)(const struct net *net, +const struct nft_set *set, +const struct nft_set_elem *elem, +unsigned int flags);unsigned int (*privsize)(const struct nlattr *const nla[],const struct nft_set_desc *desc);
net/netfilter/nf_tables_api.c +129 -55
202 lines not on this page · raw message
net/netfilter/nft_set_bitmap.c +18 -0
@@ -106,6 +106,23 @@ nft_bitmap_elem_find(const struct nft_set *set, struct nft_bitmap_elem *this,return NULL ; } +static void *nft_bitmap_get (const struct net *net,const struct nft_set *set, +const struct nft_set_elem *elem,unsigned int flags) +{ +const struct nft_bitmap *priv =nft_set_priv (set); +u8 genmask =nft_genmask_cur (net); +struct nft_bitmap_elem *be; + +list_for_each_entry_rcu (be, &priv->list, head) { +if (memcmp (nft_set_ext_key (&be->ext), elem->key.val.data, set->klen) || + !nft_set_elem_active (&be->ext, genmask)) +continue ; + +return be; + } +return ERR_PTR (-ENOENT ); +} +static int nft_bitmap_insert (const struct net *net,const struct nft_set *set,const struct nft_set_elem *elem,struct nft_set_ext **ext)
@@ -294,6 +311,7 @@ static struct nft_set_ops nft_bitmap_ops __read_mostly = { .activate = nft_bitmap_activate, .lookup = nft_bitmap_lookup, .walk = nft_bitmap_walk, + .get = nft_bitmap_get, };static struct nft_set_type nft_bitmap_type__read_mostly = {
net/netfilter/nft_set_hash.c +39 -0
@@ -95,6 +95,24 @@ static bool nft_rhash_lookup(const struct net *net, const struct nft_set *set,return !!he; } +static void *nft_rhash_get (const struct net *net,const struct nft_set *set, +const struct nft_set_elem *elem,unsigned int flags) +{ +struct nft_rhash *priv =nft_set_priv (set); +struct nft_rhash_elem *he; +struct nft_rhash_cmp_arg arg = { + .genmask =nft_genmask_cur (net), + .set = set, + .key = elem->key.val.data, + }; + + he =rhashtable_lookup_fast (&priv->ht, &arg, nft_rhash_params); +if (he !=NULL ) +return he; + +return ERR_PTR (-ENOENT ); +} + static bool nft_rhash_update(struct nft_set *set, const u32 *key, void *(*new)(struct nft_set *, const struct nft_expr *,
@@ -409,6 +427,24 @@ static bool nft_hash_lookup(const struct net *net, const struct nft_set *set,return false; } +static void *nft_hash_get (const struct net *net,const struct nft_set *set, +const struct nft_set_elem *elem,unsigned int flags) +{ +struct nft_hash *priv =nft_set_priv (set); +u8 genmask =nft_genmask_cur (net); +struct nft_hash_elem *he; +u32 hash; + + hash =jhash (elem->key.val.data, set->klen, priv->seed); + hash =reciprocal_scale (hash, priv->buckets); +hlist_for_each_entry_rcu (he, &priv->table[hash], node) { +if (!memcmp (nft_set_ext_key (&he->ext), elem->key.val.data, set->klen) && +nft_set_elem_active (&he->ext, genmask)) +return he; + } +return ERR_PTR (-ENOENT ); +} +/* nft_hash_select_ops() makes sure key size can be either 2 or 4 bytes . */ static inline u32 nft_hash_key (const u32 *key,u32 klen) {
@@ -600,6 +636,7 @@ static struct nft_set_ops nft_rhash_ops __read_mostly = { .lookup = nft_rhash_lookup, .update = nft_rhash_update, .walk = nft_rhash_walk, + .get = nft_rhash_get, .features = NFT_SET_MAP | NFT_SET_OBJECT | NFT_SET_TIMEOUT, };
@@ -617,6 +654,7 @@ static struct nft_set_ops nft_hash_ops __read_mostly = { .remove = nft_hash_remove, .lookup = nft_hash_lookup, .walk = nft_hash_walk, + .get = nft_hash_get, .features = NFT_SET_MAP | NFT_SET_OBJECT, };
@@ -634,6 +672,7 @@ static struct nft_set_ops nft_hash_fast_ops __read_mostly = { .remove = nft_hash_remove, .lookup = nft_hash_lookup_fast, .walk = nft_hash_walk, + .get = nft_hash_get, .features = NFT_SET_MAP | NFT_SET_OBJECT, };
net/netfilter/nft_set_rbtree.c +73 -0
85 lines not on this page · raw message
Signature · 1 line
2.11.0