171937434SJasvinder Singh /* SPDX-License-Identifier: BSD-3-Clause
271937434SJasvinder Singh * Copyright(c) 2010-2018 Intel Corporation
371937434SJasvinder Singh */
471937434SJasvinder Singh
571937434SJasvinder Singh #include <stdint.h>
671937434SJasvinder Singh #include <stdlib.h>
771937434SJasvinder Singh #include <string.h>
871937434SJasvinder Singh
97959831bSJasvinder Singh #include <rte_string_fns.h>
10a5bd3a14SKevin Laatz #include <rte_table_hash_func.h>
117959831bSJasvinder Singh
1271937434SJasvinder Singh #include "action.h"
1371937434SJasvinder Singh
1471937434SJasvinder Singh /**
1571937434SJasvinder Singh * Input port
1671937434SJasvinder Singh */
1771937434SJasvinder Singh static struct port_in_action_profile_list port_in_action_profile_list;
1871937434SJasvinder Singh
1971937434SJasvinder Singh int
port_in_action_profile_init(void)2071937434SJasvinder Singh port_in_action_profile_init(void)
2171937434SJasvinder Singh {
2271937434SJasvinder Singh TAILQ_INIT(&port_in_action_profile_list);
2371937434SJasvinder Singh
2471937434SJasvinder Singh return 0;
2571937434SJasvinder Singh }
2671937434SJasvinder Singh
2771937434SJasvinder Singh struct port_in_action_profile *
port_in_action_profile_find(const char * name)2871937434SJasvinder Singh port_in_action_profile_find(const char *name)
2971937434SJasvinder Singh {
3071937434SJasvinder Singh struct port_in_action_profile *profile;
3171937434SJasvinder Singh
3271937434SJasvinder Singh if (name == NULL)
3371937434SJasvinder Singh return NULL;
3471937434SJasvinder Singh
3571937434SJasvinder Singh TAILQ_FOREACH(profile, &port_in_action_profile_list, node)
3671937434SJasvinder Singh if (strcmp(profile->name, name) == 0)
3771937434SJasvinder Singh return profile;
3871937434SJasvinder Singh
3971937434SJasvinder Singh return NULL;
4071937434SJasvinder Singh }
4171937434SJasvinder Singh
4271937434SJasvinder Singh struct port_in_action_profile *
port_in_action_profile_create(const char * name,struct port_in_action_profile_params * params)4371937434SJasvinder Singh port_in_action_profile_create(const char *name,
4471937434SJasvinder Singh struct port_in_action_profile_params *params)
4571937434SJasvinder Singh {
4671937434SJasvinder Singh struct port_in_action_profile *profile;
4771937434SJasvinder Singh struct rte_port_in_action_profile *ap;
4871937434SJasvinder Singh int status;
4971937434SJasvinder Singh
5071937434SJasvinder Singh /* Check input params */
5171937434SJasvinder Singh if ((name == NULL) ||
5271937434SJasvinder Singh port_in_action_profile_find(name) ||
5371937434SJasvinder Singh (params == NULL))
5471937434SJasvinder Singh return NULL;
5571937434SJasvinder Singh
5671937434SJasvinder Singh if ((params->action_mask & (1LLU << RTE_PORT_IN_ACTION_LB)) &&
5771937434SJasvinder Singh (params->lb.f_hash == NULL)) {
5871937434SJasvinder Singh switch (params->lb.key_size) {
5971937434SJasvinder Singh case 8:
60a5bd3a14SKevin Laatz params->lb.f_hash = rte_table_hash_crc_key8;
6171937434SJasvinder Singh break;
6271937434SJasvinder Singh
6371937434SJasvinder Singh case 16:
64a5bd3a14SKevin Laatz params->lb.f_hash = rte_table_hash_crc_key16;
6571937434SJasvinder Singh break;
6671937434SJasvinder Singh
6771937434SJasvinder Singh case 24:
68a5bd3a14SKevin Laatz params->lb.f_hash = rte_table_hash_crc_key24;
6971937434SJasvinder Singh break;
7071937434SJasvinder Singh
7171937434SJasvinder Singh case 32:
72a5bd3a14SKevin Laatz params->lb.f_hash = rte_table_hash_crc_key32;
7371937434SJasvinder Singh break;
7471937434SJasvinder Singh
7571937434SJasvinder Singh case 40:
76a5bd3a14SKevin Laatz params->lb.f_hash = rte_table_hash_crc_key40;
7771937434SJasvinder Singh break;
7871937434SJasvinder Singh
7971937434SJasvinder Singh case 48:
80a5bd3a14SKevin Laatz params->lb.f_hash = rte_table_hash_crc_key48;
8171937434SJasvinder Singh break;
8271937434SJasvinder Singh
8371937434SJasvinder Singh case 56:
84a5bd3a14SKevin Laatz params->lb.f_hash = rte_table_hash_crc_key56;
8571937434SJasvinder Singh break;
8671937434SJasvinder Singh
8771937434SJasvinder Singh case 64:
88a5bd3a14SKevin Laatz params->lb.f_hash = rte_table_hash_crc_key64;
8971937434SJasvinder Singh break;
9071937434SJasvinder Singh
9171937434SJasvinder Singh default:
9271937434SJasvinder Singh return NULL;
9371937434SJasvinder Singh }
9471937434SJasvinder Singh
9571937434SJasvinder Singh params->lb.seed = 0;
9671937434SJasvinder Singh }
9771937434SJasvinder Singh /* Resource */
9871937434SJasvinder Singh ap = rte_port_in_action_profile_create(0);
9971937434SJasvinder Singh if (ap == NULL)
10071937434SJasvinder Singh return NULL;
10171937434SJasvinder Singh
10271937434SJasvinder Singh if (params->action_mask & (1LLU << RTE_PORT_IN_ACTION_FLTR)) {
10371937434SJasvinder Singh status = rte_port_in_action_profile_action_register(ap,
10471937434SJasvinder Singh RTE_PORT_IN_ACTION_FLTR,
10571937434SJasvinder Singh ¶ms->fltr);
10671937434SJasvinder Singh
10771937434SJasvinder Singh if (status) {
10871937434SJasvinder Singh rte_port_in_action_profile_free(ap);
10971937434SJasvinder Singh return NULL;
11071937434SJasvinder Singh }
11171937434SJasvinder Singh }
11271937434SJasvinder Singh
11371937434SJasvinder Singh if (params->action_mask & (1LLU << RTE_PORT_IN_ACTION_LB)) {
11471937434SJasvinder Singh status = rte_port_in_action_profile_action_register(ap,
11571937434SJasvinder Singh RTE_PORT_IN_ACTION_LB,
11671937434SJasvinder Singh ¶ms->lb);
11771937434SJasvinder Singh
11871937434SJasvinder Singh if (status) {
11971937434SJasvinder Singh rte_port_in_action_profile_free(ap);
12071937434SJasvinder Singh return NULL;
12171937434SJasvinder Singh }
12271937434SJasvinder Singh }
12371937434SJasvinder Singh
12471937434SJasvinder Singh status = rte_port_in_action_profile_freeze(ap);
12571937434SJasvinder Singh if (status) {
12671937434SJasvinder Singh rte_port_in_action_profile_free(ap);
12771937434SJasvinder Singh return NULL;
12871937434SJasvinder Singh }
12971937434SJasvinder Singh
13071937434SJasvinder Singh /* Node allocation */
13171937434SJasvinder Singh profile = calloc(1, sizeof(struct port_in_action_profile));
13271937434SJasvinder Singh if (profile == NULL) {
13371937434SJasvinder Singh rte_port_in_action_profile_free(ap);
13471937434SJasvinder Singh return NULL;
13571937434SJasvinder Singh }
13671937434SJasvinder Singh
13771937434SJasvinder Singh /* Node fill in */
1387959831bSJasvinder Singh strlcpy(profile->name, name, sizeof(profile->name));
13971937434SJasvinder Singh memcpy(&profile->params, params, sizeof(*params));
14071937434SJasvinder Singh profile->ap = ap;
14171937434SJasvinder Singh
14271937434SJasvinder Singh /* Node add to list */
14371937434SJasvinder Singh TAILQ_INSERT_TAIL(&port_in_action_profile_list, profile, node);
14471937434SJasvinder Singh
14571937434SJasvinder Singh return profile;
14671937434SJasvinder Singh }
14771937434SJasvinder Singh
14871937434SJasvinder Singh /**
14971937434SJasvinder Singh * Table
15071937434SJasvinder Singh */
15171937434SJasvinder Singh static struct table_action_profile_list table_action_profile_list;
15271937434SJasvinder Singh
15371937434SJasvinder Singh int
table_action_profile_init(void)15471937434SJasvinder Singh table_action_profile_init(void)
15571937434SJasvinder Singh {
15671937434SJasvinder Singh TAILQ_INIT(&table_action_profile_list);
15771937434SJasvinder Singh
15871937434SJasvinder Singh return 0;
15971937434SJasvinder Singh }
16071937434SJasvinder Singh
16171937434SJasvinder Singh struct table_action_profile *
table_action_profile_find(const char * name)16271937434SJasvinder Singh table_action_profile_find(const char *name)
16371937434SJasvinder Singh {
16471937434SJasvinder Singh struct table_action_profile *profile;
16571937434SJasvinder Singh
16671937434SJasvinder Singh if (name == NULL)
16771937434SJasvinder Singh return NULL;
16871937434SJasvinder Singh
16971937434SJasvinder Singh TAILQ_FOREACH(profile, &table_action_profile_list, node)
17071937434SJasvinder Singh if (strcmp(profile->name, name) == 0)
17171937434SJasvinder Singh return profile;
17271937434SJasvinder Singh
17371937434SJasvinder Singh return NULL;
17471937434SJasvinder Singh }
17571937434SJasvinder Singh
17671937434SJasvinder Singh struct table_action_profile *
table_action_profile_create(const char * name,struct table_action_profile_params * params)17771937434SJasvinder Singh table_action_profile_create(const char *name,
17871937434SJasvinder Singh struct table_action_profile_params *params)
17971937434SJasvinder Singh {
18071937434SJasvinder Singh struct table_action_profile *profile;
18171937434SJasvinder Singh struct rte_table_action_profile *ap;
18271937434SJasvinder Singh int status;
18371937434SJasvinder Singh
18471937434SJasvinder Singh /* Check input params */
18571937434SJasvinder Singh if ((name == NULL) ||
18671937434SJasvinder Singh table_action_profile_find(name) ||
18771937434SJasvinder Singh (params == NULL) ||
18871937434SJasvinder Singh ((params->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) == 0))
18971937434SJasvinder Singh return NULL;
19071937434SJasvinder Singh
191085c3d8cSJasvinder Singh if ((params->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) &&
192085c3d8cSJasvinder Singh (params->lb.f_hash == NULL)) {
193085c3d8cSJasvinder Singh switch (params->lb.key_size) {
194085c3d8cSJasvinder Singh case 8:
195a5bd3a14SKevin Laatz params->lb.f_hash = rte_table_hash_crc_key8;
196085c3d8cSJasvinder Singh break;
197085c3d8cSJasvinder Singh
198085c3d8cSJasvinder Singh case 16:
199a5bd3a14SKevin Laatz params->lb.f_hash = rte_table_hash_crc_key16;
200085c3d8cSJasvinder Singh break;
201085c3d8cSJasvinder Singh
202085c3d8cSJasvinder Singh case 24:
203a5bd3a14SKevin Laatz params->lb.f_hash = rte_table_hash_crc_key24;
204085c3d8cSJasvinder Singh break;
205085c3d8cSJasvinder Singh
206085c3d8cSJasvinder Singh case 32:
207a5bd3a14SKevin Laatz params->lb.f_hash = rte_table_hash_crc_key32;
208085c3d8cSJasvinder Singh break;
209085c3d8cSJasvinder Singh
210085c3d8cSJasvinder Singh case 40:
211a5bd3a14SKevin Laatz params->lb.f_hash = rte_table_hash_crc_key40;
212085c3d8cSJasvinder Singh break;
213085c3d8cSJasvinder Singh
214085c3d8cSJasvinder Singh case 48:
215a5bd3a14SKevin Laatz params->lb.f_hash = rte_table_hash_crc_key48;
216085c3d8cSJasvinder Singh break;
217085c3d8cSJasvinder Singh
218085c3d8cSJasvinder Singh case 56:
219a5bd3a14SKevin Laatz params->lb.f_hash = rte_table_hash_crc_key56;
220085c3d8cSJasvinder Singh break;
221085c3d8cSJasvinder Singh
222085c3d8cSJasvinder Singh case 64:
223a5bd3a14SKevin Laatz params->lb.f_hash = rte_table_hash_crc_key64;
224085c3d8cSJasvinder Singh break;
225085c3d8cSJasvinder Singh
226085c3d8cSJasvinder Singh default:
227085c3d8cSJasvinder Singh return NULL;
228085c3d8cSJasvinder Singh }
229085c3d8cSJasvinder Singh
230085c3d8cSJasvinder Singh params->lb.seed = 0;
231085c3d8cSJasvinder Singh }
232085c3d8cSJasvinder Singh
23371937434SJasvinder Singh /* Resource */
23471937434SJasvinder Singh ap = rte_table_action_profile_create(¶ms->common);
23571937434SJasvinder Singh if (ap == NULL)
23671937434SJasvinder Singh return NULL;
23771937434SJasvinder Singh
23871937434SJasvinder Singh if (params->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
23971937434SJasvinder Singh status = rte_table_action_profile_action_register(ap,
24071937434SJasvinder Singh RTE_TABLE_ACTION_FWD,
24171937434SJasvinder Singh NULL);
24271937434SJasvinder Singh
24371937434SJasvinder Singh if (status) {
24471937434SJasvinder Singh rte_table_action_profile_free(ap);
24571937434SJasvinder Singh return NULL;
24671937434SJasvinder Singh }
24771937434SJasvinder Singh }
24871937434SJasvinder Singh
249802755dcSJasvinder Singh if (params->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
250802755dcSJasvinder Singh status = rte_table_action_profile_action_register(ap,
251802755dcSJasvinder Singh RTE_TABLE_ACTION_LB,
252802755dcSJasvinder Singh ¶ms->lb);
253802755dcSJasvinder Singh
254802755dcSJasvinder Singh if (status) {
255802755dcSJasvinder Singh rte_table_action_profile_free(ap);
256802755dcSJasvinder Singh return NULL;
257802755dcSJasvinder Singh }
258802755dcSJasvinder Singh }
259802755dcSJasvinder Singh
26071937434SJasvinder Singh if (params->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
26171937434SJasvinder Singh status = rte_table_action_profile_action_register(ap,
26271937434SJasvinder Singh RTE_TABLE_ACTION_MTR,
26371937434SJasvinder Singh ¶ms->mtr);
26471937434SJasvinder Singh
26571937434SJasvinder Singh if (status) {
26671937434SJasvinder Singh rte_table_action_profile_free(ap);
26771937434SJasvinder Singh return NULL;
26871937434SJasvinder Singh }
26971937434SJasvinder Singh }
27071937434SJasvinder Singh
27171937434SJasvinder Singh if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
27271937434SJasvinder Singh status = rte_table_action_profile_action_register(ap,
27371937434SJasvinder Singh RTE_TABLE_ACTION_TM,
27471937434SJasvinder Singh ¶ms->tm);
27571937434SJasvinder Singh
27671937434SJasvinder Singh if (status) {
27771937434SJasvinder Singh rte_table_action_profile_free(ap);
27871937434SJasvinder Singh return NULL;
27971937434SJasvinder Singh }
28071937434SJasvinder Singh }
28171937434SJasvinder Singh
28271937434SJasvinder Singh if (params->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
28371937434SJasvinder Singh status = rte_table_action_profile_action_register(ap,
28471937434SJasvinder Singh RTE_TABLE_ACTION_ENCAP,
28571937434SJasvinder Singh ¶ms->encap);
28671937434SJasvinder Singh
28771937434SJasvinder Singh if (status) {
28871937434SJasvinder Singh rte_table_action_profile_free(ap);
28971937434SJasvinder Singh return NULL;
29071937434SJasvinder Singh }
29171937434SJasvinder Singh }
29271937434SJasvinder Singh
29371937434SJasvinder Singh if (params->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
29471937434SJasvinder Singh status = rte_table_action_profile_action_register(ap,
29571937434SJasvinder Singh RTE_TABLE_ACTION_NAT,
29671937434SJasvinder Singh ¶ms->nat);
29771937434SJasvinder Singh
29871937434SJasvinder Singh if (status) {
29971937434SJasvinder Singh rte_table_action_profile_free(ap);
30071937434SJasvinder Singh return NULL;
30171937434SJasvinder Singh }
30271937434SJasvinder Singh }
30371937434SJasvinder Singh
30471937434SJasvinder Singh if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TTL)) {
30571937434SJasvinder Singh status = rte_table_action_profile_action_register(ap,
30671937434SJasvinder Singh RTE_TABLE_ACTION_TTL,
30771937434SJasvinder Singh ¶ms->ttl);
30871937434SJasvinder Singh
30971937434SJasvinder Singh if (status) {
31071937434SJasvinder Singh rte_table_action_profile_free(ap);
31171937434SJasvinder Singh return NULL;
31271937434SJasvinder Singh }
31371937434SJasvinder Singh }
31471937434SJasvinder Singh
31571937434SJasvinder Singh if (params->action_mask & (1LLU << RTE_TABLE_ACTION_STATS)) {
31671937434SJasvinder Singh status = rte_table_action_profile_action_register(ap,
31771937434SJasvinder Singh RTE_TABLE_ACTION_STATS,
31871937434SJasvinder Singh ¶ms->stats);
31971937434SJasvinder Singh
32071937434SJasvinder Singh if (status) {
32171937434SJasvinder Singh rte_table_action_profile_free(ap);
32271937434SJasvinder Singh return NULL;
32371937434SJasvinder Singh }
32471937434SJasvinder Singh }
32571937434SJasvinder Singh if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TIME)) {
32671937434SJasvinder Singh status = rte_table_action_profile_action_register(ap,
32771937434SJasvinder Singh RTE_TABLE_ACTION_TIME,
32871937434SJasvinder Singh NULL);
32971937434SJasvinder Singh
33071937434SJasvinder Singh if (status) {
33171937434SJasvinder Singh rte_table_action_profile_free(ap);
33271937434SJasvinder Singh return NULL;
33371937434SJasvinder Singh }
33471937434SJasvinder Singh }
33571937434SJasvinder Singh
336d46fe944SFan Zhang if (params->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) {
337d46fe944SFan Zhang status = rte_table_action_profile_action_register(ap,
338d46fe944SFan Zhang RTE_TABLE_ACTION_SYM_CRYPTO,
339d46fe944SFan Zhang ¶ms->sym_crypto);
340d46fe944SFan Zhang
341d46fe944SFan Zhang if (status) {
342d46fe944SFan Zhang rte_table_action_profile_free(ap);
343d46fe944SFan Zhang return NULL;
344d46fe944SFan Zhang }
345d46fe944SFan Zhang }
346d46fe944SFan Zhang
3471bdf2632SCristian Dumitrescu if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TAG)) {
3481bdf2632SCristian Dumitrescu status = rte_table_action_profile_action_register(ap,
3491bdf2632SCristian Dumitrescu RTE_TABLE_ACTION_TAG,
3501bdf2632SCristian Dumitrescu NULL);
3511bdf2632SCristian Dumitrescu
3521bdf2632SCristian Dumitrescu if (status) {
3531bdf2632SCristian Dumitrescu rte_table_action_profile_free(ap);
3541bdf2632SCristian Dumitrescu return NULL;
3551bdf2632SCristian Dumitrescu }
3561bdf2632SCristian Dumitrescu }
3571bdf2632SCristian Dumitrescu
358*d5ed626fSCristian Dumitrescu if (params->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP)) {
359*d5ed626fSCristian Dumitrescu status = rte_table_action_profile_action_register(ap,
360*d5ed626fSCristian Dumitrescu RTE_TABLE_ACTION_DECAP,
361*d5ed626fSCristian Dumitrescu NULL);
362*d5ed626fSCristian Dumitrescu
363*d5ed626fSCristian Dumitrescu if (status) {
364*d5ed626fSCristian Dumitrescu rte_table_action_profile_free(ap);
365*d5ed626fSCristian Dumitrescu return NULL;
366*d5ed626fSCristian Dumitrescu }
367*d5ed626fSCristian Dumitrescu }
368*d5ed626fSCristian Dumitrescu
36971937434SJasvinder Singh status = rte_table_action_profile_freeze(ap);
37071937434SJasvinder Singh if (status) {
37171937434SJasvinder Singh rte_table_action_profile_free(ap);
37271937434SJasvinder Singh return NULL;
37371937434SJasvinder Singh }
37471937434SJasvinder Singh
37571937434SJasvinder Singh /* Node allocation */
37671937434SJasvinder Singh profile = calloc(1, sizeof(struct table_action_profile));
37771937434SJasvinder Singh if (profile == NULL) {
37871937434SJasvinder Singh rte_table_action_profile_free(ap);
37971937434SJasvinder Singh return NULL;
38071937434SJasvinder Singh }
38171937434SJasvinder Singh
38271937434SJasvinder Singh /* Node fill in */
3837959831bSJasvinder Singh strlcpy(profile->name, name, sizeof(profile->name));
38471937434SJasvinder Singh memcpy(&profile->params, params, sizeof(*params));
38571937434SJasvinder Singh profile->ap = ap;
38671937434SJasvinder Singh
38771937434SJasvinder Singh /* Node add to list */
38871937434SJasvinder Singh TAILQ_INSERT_TAIL(&table_action_profile_list, profile, node);
38971937434SJasvinder Singh
39071937434SJasvinder Singh return profile;
39171937434SJasvinder Singh }
392