xref: /dpdk/examples/ip_pipeline/action.c (revision d5ed626f61b2577c63e5fb67526b531150d5105c)
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 			&params->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 			&params->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(&params->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 			&params->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 			&params->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 			&params->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 			&params->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 			&params->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 			&params->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 			&params->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 			&params->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