diff options
author | Thomas Graf <tgraf@suug.ch> | 2015-01-02 17:00:14 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-01-03 14:32:56 -0500 |
commit | 8d24c0b43125ec26cc80e04588477a9a2afc025c (patch) | |
tree | d02e1b74bf49017dd4fecdeaf82a1e4f8f64a25d /net/netfilter | |
parent | dd9553988879a3ff71a86323b88409e7631c4e5d (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.c | 46 |
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 | ||
97 | struct nft_compare_arg { | ||
98 | const struct nft_set *set; | ||
99 | struct nft_set_elem *elem; | ||
100 | }; | ||
101 | |||
102 | static 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 | |||
97 | static int nft_hash_get(const struct nft_set *set, struct nft_set_elem *elem) | 119 | static 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 | ||