aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2015-03-25 09:07:48 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2015-03-25 12:18:34 -0400
commitbfd6e327e118d2fe443047829047862b49012457 (patch)
tree8b71562f6117d2b3a8c487390ebaa9504cf40e0a
parent45d84751fb310fe0063cf005ffd6593b4c2321a8 (diff)
netfilter: nft_hash: convert to use rhashtable callbacks
A following patch will convert sets to use so called set extensions, where the key is not located in a fixed position anymore. This will require rhashtable hashing and comparison callbacks to be used. As preparation, convert nft_hash to use these callbacks without any functional changes. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--net/netfilter/nft_hash.c54
1 files changed, 49 insertions, 5 deletions
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
index e35f0b2d8e65..dc96a7e94f80 100644
--- a/net/netfilter/nft_hash.c
+++ b/net/netfilter/nft_hash.c
@@ -33,16 +33,50 @@ struct nft_hash_elem {
33 struct nft_data data[]; 33 struct nft_data data[];
34}; 34};
35 35
36struct nft_hash_cmp_arg {
37 const struct nft_set *set;
38 const struct nft_data *key;
39};
40
36static const struct rhashtable_params nft_hash_params; 41static const struct rhashtable_params nft_hash_params;
37 42
43static inline u32 nft_hash_key(const void *data, u32 len, u32 seed)
44{
45 const struct nft_hash_cmp_arg *arg = data;
46
47 return jhash(arg->key, len, seed);
48}
49
50static inline u32 nft_hash_obj(const void *data, u32 len, u32 seed)
51{
52 const struct nft_hash_elem *he = data;
53
54 return jhash(&he->key, len, seed);
55}
56
57static inline int nft_hash_cmp(struct rhashtable_compare_arg *arg,
58 const void *ptr)
59{
60 const struct nft_hash_cmp_arg *x = arg->key;
61 const struct nft_hash_elem *he = ptr;
62
63 if (nft_data_cmp(&he->key, x->key, x->set->klen))
64 return 1;
65 return 0;
66}
67
38static bool nft_hash_lookup(const struct nft_set *set, 68static bool nft_hash_lookup(const struct nft_set *set,
39 const struct nft_data *key, 69 const struct nft_data *key,
40 struct nft_data *data) 70 struct nft_data *data)
41{ 71{
42 struct nft_hash *priv = nft_set_priv(set); 72 struct nft_hash *priv = nft_set_priv(set);
43 const struct nft_hash_elem *he; 73 const struct nft_hash_elem *he;
74 struct nft_hash_cmp_arg arg = {
75 .set = set,
76 .key = key,
77 };
44 78
45 he = rhashtable_lookup_fast(&priv->ht, key, nft_hash_params); 79 he = rhashtable_lookup_fast(&priv->ht, &arg, nft_hash_params);
46 if (he && set->flags & NFT_SET_MAP) 80 if (he && set->flags & NFT_SET_MAP)
47 nft_data_copy(data, he->data); 81 nft_data_copy(data, he->data);
48 82
@@ -54,6 +88,10 @@ static int nft_hash_insert(const struct nft_set *set,
54{ 88{
55 struct nft_hash *priv = nft_set_priv(set); 89 struct nft_hash *priv = nft_set_priv(set);
56 struct nft_hash_elem *he; 90 struct nft_hash_elem *he;
91 struct nft_hash_cmp_arg arg = {
92 .set = set,
93 .key = &elem->key,
94 };
57 unsigned int size; 95 unsigned int size;
58 int err; 96 int err;
59 97
@@ -72,7 +110,8 @@ static int nft_hash_insert(const struct nft_set *set,
72 if (set->flags & NFT_SET_MAP) 110 if (set->flags & NFT_SET_MAP)
73 nft_data_copy(he->data, &elem->data); 111 nft_data_copy(he->data, &elem->data);
74 112
75 err = rhashtable_insert_fast(&priv->ht, &he->node, nft_hash_params); 113 err = rhashtable_lookup_insert_key(&priv->ht, &arg, &he->node,
114 nft_hash_params);
76 if (err) 115 if (err)
77 kfree(he); 116 kfree(he);
78 117
@@ -102,8 +141,12 @@ static int nft_hash_get(const struct nft_set *set, struct nft_set_elem *elem)
102{ 141{
103 struct nft_hash *priv = nft_set_priv(set); 142 struct nft_hash *priv = nft_set_priv(set);
104 struct nft_hash_elem *he; 143 struct nft_hash_elem *he;
144 struct nft_hash_cmp_arg arg = {
145 .set = set,
146 .key = &elem->key,
147 };
105 148
106 he = rhashtable_lookup_fast(&priv->ht, &elem->key, nft_hash_params); 149 he = rhashtable_lookup_fast(&priv->ht, &arg, nft_hash_params);
107 if (!he) 150 if (!he)
108 return -ENOENT; 151 return -ENOENT;
109 152
@@ -174,8 +217,9 @@ static unsigned int nft_hash_privsize(const struct nlattr * const nla[])
174 217
175static const struct rhashtable_params nft_hash_params = { 218static const struct rhashtable_params nft_hash_params = {
176 .head_offset = offsetof(struct nft_hash_elem, node), 219 .head_offset = offsetof(struct nft_hash_elem, node),
177 .key_offset = offsetof(struct nft_hash_elem, key), 220 .hashfn = nft_hash_key,
178 .hashfn = jhash, 221 .obj_hashfn = nft_hash_obj,
222 .obj_cmpfn = nft_hash_cmp,
179 .automatic_shrinking = true, 223 .automatic_shrinking = true,
180}; 224};
181 225