1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2017 Intel Corporation
3 */
4
5 #include <string.h>
6
7 #include <rte_string_fns.h>
8 #include <rte_eal.h>
9 #include <rte_eal_memconfig.h>
10 #include <rte_memory.h>
11 #include <rte_malloc.h>
12 #include <rte_errno.h>
13 #include <rte_tailq.h>
14
15 #include "rte_member.h"
16 #include "rte_member_ht.h"
17 #include "rte_member_vbf.h"
18
19 TAILQ_HEAD(rte_member_list, rte_tailq_entry);
20 static struct rte_tailq_elem rte_member_tailq = {
21 .name = "RTE_MEMBER",
22 };
EAL_REGISTER_TAILQ(rte_member_tailq)23 EAL_REGISTER_TAILQ(rte_member_tailq)
24
25 struct rte_member_setsum *
26 rte_member_find_existing(const char *name)
27 {
28 struct rte_member_setsum *setsum = NULL;
29 struct rte_tailq_entry *te;
30 struct rte_member_list *member_list;
31
32 member_list = RTE_TAILQ_CAST(rte_member_tailq.head, rte_member_list);
33
34 rte_mcfg_tailq_read_lock();
35 TAILQ_FOREACH(te, member_list, next) {
36 setsum = (struct rte_member_setsum *) te->data;
37 if (strncmp(name, setsum->name, RTE_MEMBER_NAMESIZE) == 0)
38 break;
39 }
40 rte_mcfg_tailq_read_unlock();
41
42 if (te == NULL) {
43 rte_errno = ENOENT;
44 return NULL;
45 }
46 return setsum;
47 }
48
49 void
rte_member_free(struct rte_member_setsum * setsum)50 rte_member_free(struct rte_member_setsum *setsum)
51 {
52 struct rte_member_list *member_list;
53 struct rte_tailq_entry *te;
54
55 if (setsum == NULL)
56 return;
57 member_list = RTE_TAILQ_CAST(rte_member_tailq.head, rte_member_list);
58 rte_mcfg_tailq_write_lock();
59 TAILQ_FOREACH(te, member_list, next) {
60 if (te->data == (void *)setsum)
61 break;
62 }
63 if (te == NULL) {
64 rte_mcfg_tailq_write_unlock();
65 return;
66 }
67 TAILQ_REMOVE(member_list, te, next);
68 rte_mcfg_tailq_write_unlock();
69
70 switch (setsum->type) {
71 case RTE_MEMBER_TYPE_HT:
72 rte_member_free_ht(setsum);
73 break;
74 case RTE_MEMBER_TYPE_VBF:
75 rte_member_free_vbf(setsum);
76 break;
77 default:
78 break;
79 }
80 rte_free(setsum);
81 rte_free(te);
82 }
83
84 struct rte_member_setsum *
rte_member_create(const struct rte_member_parameters * params)85 rte_member_create(const struct rte_member_parameters *params)
86 {
87 struct rte_tailq_entry *te;
88 struct rte_member_list *member_list;
89 struct rte_member_setsum *setsum;
90 int ret;
91
92 if (params == NULL) {
93 rte_errno = EINVAL;
94 return NULL;
95 }
96
97 if (params->key_len == 0 ||
98 params->prim_hash_seed == params->sec_hash_seed) {
99 rte_errno = EINVAL;
100 RTE_MEMBER_LOG(ERR, "Create setsummary with "
101 "invalid parameters\n");
102 return NULL;
103 }
104
105 member_list = RTE_TAILQ_CAST(rte_member_tailq.head, rte_member_list);
106
107 rte_mcfg_tailq_write_lock();
108
109 TAILQ_FOREACH(te, member_list, next) {
110 setsum = te->data;
111 if (strncmp(params->name, setsum->name,
112 RTE_MEMBER_NAMESIZE) == 0)
113 break;
114 }
115 setsum = NULL;
116 if (te != NULL) {
117 rte_errno = EEXIST;
118 te = NULL;
119 goto error_unlock_exit;
120 }
121 te = rte_zmalloc("MEMBER_TAILQ_ENTRY", sizeof(*te), 0);
122 if (te == NULL) {
123 RTE_MEMBER_LOG(ERR, "tailq entry allocation failed\n");
124 goto error_unlock_exit;
125 }
126
127 /* Create a new setsum structure */
128 setsum = rte_zmalloc_socket(params->name,
129 sizeof(struct rte_member_setsum), RTE_CACHE_LINE_SIZE,
130 params->socket_id);
131 if (setsum == NULL) {
132 RTE_MEMBER_LOG(ERR, "Create setsummary failed\n");
133 goto error_unlock_exit;
134 }
135 strlcpy(setsum->name, params->name, sizeof(setsum->name));
136 setsum->type = params->type;
137 setsum->socket_id = params->socket_id;
138 setsum->key_len = params->key_len;
139 setsum->num_set = params->num_set;
140 setsum->prim_hash_seed = params->prim_hash_seed;
141 setsum->sec_hash_seed = params->sec_hash_seed;
142
143 switch (setsum->type) {
144 case RTE_MEMBER_TYPE_HT:
145 ret = rte_member_create_ht(setsum, params);
146 break;
147 case RTE_MEMBER_TYPE_VBF:
148 ret = rte_member_create_vbf(setsum, params);
149 break;
150 default:
151 goto error_unlock_exit;
152 }
153 if (ret < 0)
154 goto error_unlock_exit;
155
156 RTE_MEMBER_LOG(DEBUG, "Creating a setsummary table with "
157 "mode %u\n", setsum->type);
158
159 te->data = (void *)setsum;
160 TAILQ_INSERT_TAIL(member_list, te, next);
161 rte_mcfg_tailq_write_unlock();
162 return setsum;
163
164 error_unlock_exit:
165 rte_free(te);
166 rte_free(setsum);
167 rte_mcfg_tailq_write_unlock();
168 return NULL;
169 }
170
171 int
rte_member_add(const struct rte_member_setsum * setsum,const void * key,member_set_t set_id)172 rte_member_add(const struct rte_member_setsum *setsum, const void *key,
173 member_set_t set_id)
174 {
175 if (setsum == NULL || key == NULL)
176 return -EINVAL;
177
178 switch (setsum->type) {
179 case RTE_MEMBER_TYPE_HT:
180 return rte_member_add_ht(setsum, key, set_id);
181 case RTE_MEMBER_TYPE_VBF:
182 return rte_member_add_vbf(setsum, key, set_id);
183 default:
184 return -EINVAL;
185 }
186 }
187
188 int
rte_member_lookup(const struct rte_member_setsum * setsum,const void * key,member_set_t * set_id)189 rte_member_lookup(const struct rte_member_setsum *setsum, const void *key,
190 member_set_t *set_id)
191 {
192 if (setsum == NULL || key == NULL || set_id == NULL)
193 return -EINVAL;
194
195 switch (setsum->type) {
196 case RTE_MEMBER_TYPE_HT:
197 return rte_member_lookup_ht(setsum, key, set_id);
198 case RTE_MEMBER_TYPE_VBF:
199 return rte_member_lookup_vbf(setsum, key, set_id);
200 default:
201 return -EINVAL;
202 }
203 }
204
205 int
rte_member_lookup_bulk(const struct rte_member_setsum * setsum,const void ** keys,uint32_t num_keys,member_set_t * set_ids)206 rte_member_lookup_bulk(const struct rte_member_setsum *setsum,
207 const void **keys, uint32_t num_keys,
208 member_set_t *set_ids)
209 {
210 if (setsum == NULL || keys == NULL || set_ids == NULL)
211 return -EINVAL;
212
213 switch (setsum->type) {
214 case RTE_MEMBER_TYPE_HT:
215 return rte_member_lookup_bulk_ht(setsum, keys, num_keys,
216 set_ids);
217 case RTE_MEMBER_TYPE_VBF:
218 return rte_member_lookup_bulk_vbf(setsum, keys, num_keys,
219 set_ids);
220 default:
221 return -EINVAL;
222 }
223 }
224
225 int
rte_member_lookup_multi(const struct rte_member_setsum * setsum,const void * key,uint32_t match_per_key,member_set_t * set_id)226 rte_member_lookup_multi(const struct rte_member_setsum *setsum, const void *key,
227 uint32_t match_per_key, member_set_t *set_id)
228 {
229 if (setsum == NULL || key == NULL || set_id == NULL)
230 return -EINVAL;
231
232 switch (setsum->type) {
233 case RTE_MEMBER_TYPE_HT:
234 return rte_member_lookup_multi_ht(setsum, key, match_per_key,
235 set_id);
236 case RTE_MEMBER_TYPE_VBF:
237 return rte_member_lookup_multi_vbf(setsum, key, match_per_key,
238 set_id);
239 default:
240 return -EINVAL;
241 }
242 }
243
244 int
rte_member_lookup_multi_bulk(const struct rte_member_setsum * setsum,const void ** keys,uint32_t num_keys,uint32_t max_match_per_key,uint32_t * match_count,member_set_t * set_ids)245 rte_member_lookup_multi_bulk(const struct rte_member_setsum *setsum,
246 const void **keys, uint32_t num_keys,
247 uint32_t max_match_per_key, uint32_t *match_count,
248 member_set_t *set_ids)
249 {
250 if (setsum == NULL || keys == NULL || set_ids == NULL ||
251 match_count == NULL)
252 return -EINVAL;
253
254 switch (setsum->type) {
255 case RTE_MEMBER_TYPE_HT:
256 return rte_member_lookup_multi_bulk_ht(setsum, keys, num_keys,
257 max_match_per_key, match_count, set_ids);
258 case RTE_MEMBER_TYPE_VBF:
259 return rte_member_lookup_multi_bulk_vbf(setsum, keys, num_keys,
260 max_match_per_key, match_count, set_ids);
261 default:
262 return -EINVAL;
263 }
264 }
265
266 int
rte_member_delete(const struct rte_member_setsum * setsum,const void * key,member_set_t set_id)267 rte_member_delete(const struct rte_member_setsum *setsum, const void *key,
268 member_set_t set_id)
269 {
270 if (setsum == NULL || key == NULL)
271 return -EINVAL;
272
273 switch (setsum->type) {
274 case RTE_MEMBER_TYPE_HT:
275 return rte_member_delete_ht(setsum, key, set_id);
276 /* current vBF implementation does not support delete function */
277 case RTE_MEMBER_TYPE_VBF:
278 default:
279 return -EINVAL;
280 }
281 }
282
283 void
rte_member_reset(const struct rte_member_setsum * setsum)284 rte_member_reset(const struct rte_member_setsum *setsum)
285 {
286 if (setsum == NULL)
287 return;
288 switch (setsum->type) {
289 case RTE_MEMBER_TYPE_HT:
290 rte_member_reset_ht(setsum);
291 return;
292 case RTE_MEMBER_TYPE_VBF:
293 rte_member_reset_vbf(setsum);
294 return;
295 default:
296 return;
297 }
298 }
299
300 RTE_LOG_REGISTER(librte_member_logtype, lib.member, DEBUG);
301