| 359 | } |
| 360 | |
| 361 | struct rte_acl_ctx * |
| 362 | rte_acl_create(const struct rte_acl_param *param) |
| 363 | { |
| 364 | size_t sz; |
| 365 | struct rte_acl_ctx *ctx; |
| 366 | struct rte_acl_list *acl_list; |
| 367 | struct rte_tailq_entry *te; |
| 368 | char name[sizeof(ctx->name)]; |
| 369 | |
| 370 | acl_list = RTE_TAILQ_CAST(rte_acl_tailq.head, rte_acl_list); |
| 371 | |
| 372 | /* check that input parameters are valid. */ |
| 373 | if (param == NULL || param->name == NULL) { |
| 374 | rte_errno = EINVAL; |
| 375 | return NULL; |
| 376 | } |
| 377 | |
| 378 | snprintf(name, sizeof(name), "ACL_%s", param->name); |
| 379 | |
| 380 | /* calculate amount of memory required for pattern set. */ |
| 381 | sz = sizeof(*ctx) + param->max_rule_num * param->rule_size; |
| 382 | |
| 383 | /* get EAL TAILQ lock. */ |
| 384 | rte_mcfg_tailq_write_lock(); |
| 385 | |
| 386 | /* if we already have one with that name */ |
| 387 | TAILQ_FOREACH(te, acl_list, next) { |
| 388 | ctx = (struct rte_acl_ctx *) te->data; |
| 389 | if (strncmp(param->name, ctx->name, sizeof(ctx->name)) == 0) |
| 390 | break; |
| 391 | } |
| 392 | |
| 393 | /* if ACL with such name doesn't exist, then create a new one. */ |
| 394 | if (te == NULL) { |
| 395 | ctx = NULL; |
| 396 | te = rte_zmalloc("ACL_TAILQ_ENTRY", sizeof(*te), 0); |
| 397 | |
| 398 | if (te == NULL) { |
| 399 | RTE_LOG(ERR, ACL, "Cannot allocate tailq entry!\n"); |
| 400 | goto exit; |
| 401 | } |
| 402 | |
| 403 | ctx = rte_zmalloc_socket(name, sz, RTE_CACHE_LINE_SIZE, param->socket_id); |
| 404 | |
| 405 | if (ctx == NULL) { |
| 406 | RTE_LOG(ERR, ACL, |
| 407 | "allocation of %zu bytes on socket %d for %s failed\n", |
| 408 | sz, param->socket_id, name); |
| 409 | rte_free(te); |
| 410 | goto exit; |
| 411 | } |
| 412 | /* init new allocated context. */ |
| 413 | ctx->rules = ctx + 1; |
| 414 | ctx->max_rules = param->max_rule_num; |
| 415 | ctx->rule_sz = param->rule_size; |
| 416 | ctx->socket_id = param->socket_id; |
| 417 | ctx->alg = acl_get_best_alg(); |
| 418 | strlcpy(ctx->name, param->name, sizeof(ctx->name)); |