diff options
author | Thomas Graf <tgraf@suug.ch> | 2015-01-02 23:00:14 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-01-03 14:32:56 -0500 |
commit | 8d24c0b43125ec26cc80e04588477a9a2afc025c (patch) | |
tree | d02e1b74bf49017dd4fecdeaf82a1e4f8f64a25d /net/netfilter/nft_hash.c | |
parent | dd9553988879a3ff71a86323b88409e7631c4e5d (diff) | |
download | op-kernel-dev-8d24c0b43125ec26cc80e04588477a9a2afc025c.zip op-kernel-dev-8d24c0b43125ec26cc80e04588477a9a2afc025c.tar.gz |
rhashtable: Do hashing inside of rhashtable_lookup_compare()
Hash the key inside of rhashtable_lookup_compare() like
rhashtable_lookup() does. This allows to simplify the hashing
functions and keep them private.
Signed-off-by: Thomas Graf <tgraf@suug.ch>
Cc: netfilter-devel@vger.kernel.org
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netfilter/nft_hash.c')
-rw-r--r-- | net/netfilter/nft_hash.c | 46 |
1 files changed, 29 insertions, 17 deletions
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c index 1e316ce..614ee09 100644 --- a/net/netfilter/nft_hash.c +++ b/net/netfilter/nft_hash.c @@ -94,28 +94,40 @@ static void nft_hash_remove(const struct nft_set *set, kfree(he); } +struct nft_compare_arg { + const struct nft_set *set; + struct nft_set_elem *elem; +}; + +static bool nft_hash_compare(void *ptr, void *arg) +{ + struct nft_hash_elem *he = ptr; + struct nft_compare_arg *x = arg; + + if (!nft_data_cmp(&he->key, &x->elem->key, x->set->klen)) { + x->elem->cookie = &he->node; + x->elem->flags = 0; + if (x->set->flags & NFT_SET_MAP) + nft_data_copy(&x->elem->data, he->data); + + return true; + } + + return false; +} + static int nft_hash_get(const struct nft_set *set, struct nft_set_elem *elem) { const struct rhashtable *priv = nft_set_priv(set); - const struct bucket_table *tbl = rht_dereference_rcu(priv->tbl, priv); - struct rhash_head __rcu * const *pprev; - struct nft_hash_elem *he; - u32 h; - - h = rhashtable_hashfn(priv, &elem->key, set->klen); - pprev = &tbl->buckets[h]; - rht_for_each_entry_rcu(he, tbl->buckets[h], node) { - if (nft_data_cmp(&he->key, &elem->key, set->klen)) { - pprev = &he->node.next; - continue; - } + struct nft_compare_arg arg = { + .set = set, + .elem = elem, + }; - elem->cookie = (void *)pprev; - elem->flags = 0; - if (set->flags & NFT_SET_MAP) - nft_data_copy(&elem->data, he->data); + if (rhashtable_lookup_compare(priv, &elem->key, + &nft_hash_compare, &arg)) return 0; - } + return -ENOENT; } |