aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2015-01-02 17:00:14 -0500
committerDavid S. Miller <davem@davemloft.net>2015-01-03 14:32:56 -0500
commit8d24c0b43125ec26cc80e04588477a9a2afc025c (patch)
treed02e1b74bf49017dd4fecdeaf82a1e4f8f64a25d /net/netfilter
parentdd9553988879a3ff71a86323b88409e7631c4e5d (diff)
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')
-rw-r--r--net/netfilter/nft_hash.c46
1 files changed, 29 insertions, 17 deletions
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
index 1e316ce4cb5d..614ee099ba36 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,
94 kfree(he); 94 kfree(he);
95} 95}
96 96
97struct nft_compare_arg {
98 const struct nft_set *set;
99 struct nft_set_elem *elem;
100};
101
102static bool nft_hash_compare(void *ptr, void *arg)
103{
104 struct nft_hash_elem *he = ptr;
105 struct nft_compare_arg *x = arg;
106
107 if (!nft_data_cmp(&he->key, &x->elem->key, x->set->klen)) {
108 x->elem->cookie = &he->node;
109 x->elem->flags = 0;
110 if (x->set->flags & NFT_SET_MAP)
111 nft_data_copy(&x->elem->data, he->data);
112
113 return true;
114 }
115
116 return false;
117}
118
97static int nft_hash_get(const struct nft_set *set, struct nft_set_elem *elem) 119static int nft_hash_get(const struct nft_set *set, struct nft_set_elem *elem)
98{ 120{
99 const struct rhashtable *priv = nft_set_priv(set); 121 const struct rhashtable *priv = nft_set_priv(set);
100 const struct bucket_table *tbl = rht_dereference_rcu(priv->tbl, priv); 122 struct nft_compare_arg arg = {
101 struct rhash_head __rcu * const *pprev; 123 .set = set,
102 struct nft_hash_elem *he; 124 .elem = elem,
103 u32 h; 125 };
104
105 h = rhashtable_hashfn(priv, &elem->key, set->klen);
106 pprev = &tbl->buckets[h];
107 rht_for_each_entry_rcu(he, tbl->buckets[h], node) {
108 if (nft_data_cmp(&he->key, &elem->key, set->klen)) {
109 pprev = &he->node.next;
110 continue;
111 }
112 126
113 elem->cookie = (void *)pprev; 127 if (rhashtable_lookup_compare(priv, &elem->key,
114 elem->flags = 0; 128 &nft_hash_compare, &arg))
115 if (set->flags & NFT_SET_MAP)
116 nft_data_copy(&elem->data, he->data);
117 return 0; 129 return 0;
118 } 130
119 return -ENOENT; 131 return -ENOENT;
120} 132}
121 133