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 }; 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 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 * 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 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 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 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 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 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 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 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_DEFAULT(librte_member_logtype, DEBUG); 301