| 232 | } |
| 233 | |
| 234 | struct rte_thash_ctx * |
| 235 | rte_thash_init_ctx(const char *name, uint32_t key_len, uint32_t reta_sz, |
| 236 | uint8_t *key, uint32_t flags) |
| 237 | { |
| 238 | struct rte_thash_ctx *ctx; |
| 239 | struct rte_tailq_entry *te; |
| 240 | struct rte_thash_list *thash_list; |
| 241 | uint32_t i; |
| 242 | |
| 243 | if ((name == NULL) || (key_len == 0) || !RETA_SZ_IN_RANGE(reta_sz)) { |
| 244 | rte_errno = EINVAL; |
| 245 | return NULL; |
| 246 | } |
| 247 | |
| 248 | thash_list = RTE_TAILQ_CAST(rte_thash_tailq.head, rte_thash_list); |
| 249 | |
| 250 | rte_mcfg_tailq_write_lock(); |
| 251 | |
| 252 | /* guarantee there's no existing */ |
| 253 | TAILQ_FOREACH(te, thash_list, next) { |
| 254 | ctx = (struct rte_thash_ctx *)te->data; |
| 255 | if (strncmp(name, ctx->name, sizeof(ctx->name)) == 0) |
| 256 | break; |
| 257 | } |
| 258 | ctx = NULL; |
| 259 | if (te != NULL) { |
| 260 | rte_errno = EEXIST; |
| 261 | goto exit; |
| 262 | } |
| 263 | |
| 264 | /* allocate tailq entry */ |
| 265 | te = rte_zmalloc("THASH_TAILQ_ENTRY", sizeof(*te), 0); |
| 266 | if (te == NULL) { |
| 267 | RTE_LOG(ERR, HASH, |
| 268 | "Can not allocate tailq entry for thash context %s\n", |
| 269 | name); |
| 270 | rte_errno = ENOMEM; |
| 271 | goto exit; |
| 272 | } |
| 273 | |
| 274 | ctx = rte_zmalloc(NULL, sizeof(struct rte_thash_ctx) + key_len, 0); |
| 275 | if (ctx == NULL) { |
| 276 | RTE_LOG(ERR, HASH, "thash ctx %s memory allocation failed\n", |
| 277 | name); |
| 278 | rte_errno = ENOMEM; |
| 279 | goto free_te; |
| 280 | } |
| 281 | |
| 282 | rte_strlcpy(ctx->name, name, sizeof(ctx->name)); |
| 283 | ctx->key_len = key_len; |
| 284 | ctx->reta_sz_log = reta_sz; |
| 285 | LIST_INIT(&ctx->head); |
| 286 | ctx->flags = flags; |
| 287 | |
| 288 | if (key) |
| 289 | rte_memcpy(ctx->hash_key, key, key_len); |
| 290 | else { |
| 291 | for (i = 0; i < key_len; i++) |