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 | ||
