1*d30ea906Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause
2*d30ea906Sjfb8856606 * Copyright(c) 2010-2018 Intel Corporation
3*d30ea906Sjfb8856606 */
4*d30ea906Sjfb8856606
5*d30ea906Sjfb8856606 #include <stdint.h>
6*d30ea906Sjfb8856606 #include <stdlib.h>
7*d30ea906Sjfb8856606 #include <string.h>
8*d30ea906Sjfb8856606
9*d30ea906Sjfb8856606 #include <rte_string_fns.h>
10*d30ea906Sjfb8856606 #include <rte_table_hash_func.h>
11*d30ea906Sjfb8856606
12*d30ea906Sjfb8856606 #include "action.h"
13*d30ea906Sjfb8856606
14*d30ea906Sjfb8856606 /**
15*d30ea906Sjfb8856606 * Input port
16*d30ea906Sjfb8856606 */
17*d30ea906Sjfb8856606 static struct port_in_action_profile_list port_in_action_profile_list;
18*d30ea906Sjfb8856606
19*d30ea906Sjfb8856606 int
port_in_action_profile_init(void)20*d30ea906Sjfb8856606 port_in_action_profile_init(void)
21*d30ea906Sjfb8856606 {
22*d30ea906Sjfb8856606 TAILQ_INIT(&port_in_action_profile_list);
23*d30ea906Sjfb8856606
24*d30ea906Sjfb8856606 return 0;
25*d30ea906Sjfb8856606 }
26*d30ea906Sjfb8856606
27*d30ea906Sjfb8856606 struct port_in_action_profile *
port_in_action_profile_find(const char * name)28*d30ea906Sjfb8856606 port_in_action_profile_find(const char *name)
29*d30ea906Sjfb8856606 {
30*d30ea906Sjfb8856606 struct port_in_action_profile *profile;
31*d30ea906Sjfb8856606
32*d30ea906Sjfb8856606 if (name == NULL)
33*d30ea906Sjfb8856606 return NULL;
34*d30ea906Sjfb8856606
35*d30ea906Sjfb8856606 TAILQ_FOREACH(profile, &port_in_action_profile_list, node)
36*d30ea906Sjfb8856606 if (strcmp(profile->name, name) == 0)
37*d30ea906Sjfb8856606 return profile;
38*d30ea906Sjfb8856606
39*d30ea906Sjfb8856606 return NULL;
40*d30ea906Sjfb8856606 }
41*d30ea906Sjfb8856606
42*d30ea906Sjfb8856606 struct port_in_action_profile *
port_in_action_profile_create(const char * name,struct port_in_action_profile_params * params)43*d30ea906Sjfb8856606 port_in_action_profile_create(const char *name,
44*d30ea906Sjfb8856606 struct port_in_action_profile_params *params)
45*d30ea906Sjfb8856606 {
46*d30ea906Sjfb8856606 struct port_in_action_profile *profile;
47*d30ea906Sjfb8856606 struct rte_port_in_action_profile *ap;
48*d30ea906Sjfb8856606 int status;
49*d30ea906Sjfb8856606
50*d30ea906Sjfb8856606 /* Check input params */
51*d30ea906Sjfb8856606 if ((name == NULL) ||
52*d30ea906Sjfb8856606 port_in_action_profile_find(name) ||
53*d30ea906Sjfb8856606 (params == NULL))
54*d30ea906Sjfb8856606 return NULL;
55*d30ea906Sjfb8856606
56*d30ea906Sjfb8856606 if ((params->action_mask & (1LLU << RTE_PORT_IN_ACTION_LB)) &&
57*d30ea906Sjfb8856606 (params->lb.f_hash == NULL)) {
58*d30ea906Sjfb8856606 switch (params->lb.key_size) {
59*d30ea906Sjfb8856606 case 8:
60*d30ea906Sjfb8856606 params->lb.f_hash = rte_table_hash_crc_key8;
61*d30ea906Sjfb8856606 break;
62*d30ea906Sjfb8856606
63*d30ea906Sjfb8856606 case 16:
64*d30ea906Sjfb8856606 params->lb.f_hash = rte_table_hash_crc_key16;
65*d30ea906Sjfb8856606 break;
66*d30ea906Sjfb8856606
67*d30ea906Sjfb8856606 case 24:
68*d30ea906Sjfb8856606 params->lb.f_hash = rte_table_hash_crc_key24;
69*d30ea906Sjfb8856606 break;
70*d30ea906Sjfb8856606
71*d30ea906Sjfb8856606 case 32:
72*d30ea906Sjfb8856606 params->lb.f_hash = rte_table_hash_crc_key32;
73*d30ea906Sjfb8856606 break;
74*d30ea906Sjfb8856606
75*d30ea906Sjfb8856606 case 40:
76*d30ea906Sjfb8856606 params->lb.f_hash = rte_table_hash_crc_key40;
77*d30ea906Sjfb8856606 break;
78*d30ea906Sjfb8856606
79*d30ea906Sjfb8856606 case 48:
80*d30ea906Sjfb8856606 params->lb.f_hash = rte_table_hash_crc_key48;
81*d30ea906Sjfb8856606 break;
82*d30ea906Sjfb8856606
83*d30ea906Sjfb8856606 case 56:
84*d30ea906Sjfb8856606 params->lb.f_hash = rte_table_hash_crc_key56;
85*d30ea906Sjfb8856606 break;
86*d30ea906Sjfb8856606
87*d30ea906Sjfb8856606 case 64:
88*d30ea906Sjfb8856606 params->lb.f_hash = rte_table_hash_crc_key64;
89*d30ea906Sjfb8856606 break;
90*d30ea906Sjfb8856606
91*d30ea906Sjfb8856606 default:
92*d30ea906Sjfb8856606 return NULL;
93*d30ea906Sjfb8856606 }
94*d30ea906Sjfb8856606
95*d30ea906Sjfb8856606 params->lb.seed = 0;
96*d30ea906Sjfb8856606 }
97*d30ea906Sjfb8856606 /* Resource */
98*d30ea906Sjfb8856606 ap = rte_port_in_action_profile_create(0);
99*d30ea906Sjfb8856606 if (ap == NULL)
100*d30ea906Sjfb8856606 return NULL;
101*d30ea906Sjfb8856606
102*d30ea906Sjfb8856606 if (params->action_mask & (1LLU << RTE_PORT_IN_ACTION_FLTR)) {
103*d30ea906Sjfb8856606 status = rte_port_in_action_profile_action_register(ap,
104*d30ea906Sjfb8856606 RTE_PORT_IN_ACTION_FLTR,
105*d30ea906Sjfb8856606 ¶ms->fltr);
106*d30ea906Sjfb8856606
107*d30ea906Sjfb8856606 if (status) {
108*d30ea906Sjfb8856606 rte_port_in_action_profile_free(ap);
109*d30ea906Sjfb8856606 return NULL;
110*d30ea906Sjfb8856606 }
111*d30ea906Sjfb8856606 }
112*d30ea906Sjfb8856606
113*d30ea906Sjfb8856606 if (params->action_mask & (1LLU << RTE_PORT_IN_ACTION_LB)) {
114*d30ea906Sjfb8856606 status = rte_port_in_action_profile_action_register(ap,
115*d30ea906Sjfb8856606 RTE_PORT_IN_ACTION_LB,
116*d30ea906Sjfb8856606 ¶ms->lb);
117*d30ea906Sjfb8856606
118*d30ea906Sjfb8856606 if (status) {
119*d30ea906Sjfb8856606 rte_port_in_action_profile_free(ap);
120*d30ea906Sjfb8856606 return NULL;
121*d30ea906Sjfb8856606 }
122*d30ea906Sjfb8856606 }
123*d30ea906Sjfb8856606
124*d30ea906Sjfb8856606 status = rte_port_in_action_profile_freeze(ap);
125*d30ea906Sjfb8856606 if (status) {
126*d30ea906Sjfb8856606 rte_port_in_action_profile_free(ap);
127*d30ea906Sjfb8856606 return NULL;
128*d30ea906Sjfb8856606 }
129*d30ea906Sjfb8856606
130*d30ea906Sjfb8856606 /* Node allocation */
131*d30ea906Sjfb8856606 profile = calloc(1, sizeof(struct port_in_action_profile));
132*d30ea906Sjfb8856606 if (profile == NULL) {
133*d30ea906Sjfb8856606 rte_port_in_action_profile_free(ap);
134*d30ea906Sjfb8856606 return NULL;
135*d30ea906Sjfb8856606 }
136*d30ea906Sjfb8856606
137*d30ea906Sjfb8856606 /* Node fill in */
138*d30ea906Sjfb8856606 strlcpy(profile->name, name, sizeof(profile->name));
139*d30ea906Sjfb8856606 memcpy(&profile->params, params, sizeof(*params));
140*d30ea906Sjfb8856606 profile->ap = ap;
141*d30ea906Sjfb8856606
142*d30ea906Sjfb8856606 /* Node add to list */
143*d30ea906Sjfb8856606 TAILQ_INSERT_TAIL(&port_in_action_profile_list, profile, node);
144*d30ea906Sjfb8856606
145*d30ea906Sjfb8856606 return profile;
146*d30ea906Sjfb8856606 }
147*d30ea906Sjfb8856606
148*d30ea906Sjfb8856606 /**
149*d30ea906Sjfb8856606 * Table
150*d30ea906Sjfb8856606 */
151*d30ea906Sjfb8856606 static struct table_action_profile_list table_action_profile_list;
152*d30ea906Sjfb8856606
153*d30ea906Sjfb8856606 int
table_action_profile_init(void)154*d30ea906Sjfb8856606 table_action_profile_init(void)
155*d30ea906Sjfb8856606 {
156*d30ea906Sjfb8856606 TAILQ_INIT(&table_action_profile_list);
157*d30ea906Sjfb8856606
158*d30ea906Sjfb8856606 return 0;
159*d30ea906Sjfb8856606 }
160*d30ea906Sjfb8856606
161*d30ea906Sjfb8856606 struct table_action_profile *
table_action_profile_find(const char * name)162*d30ea906Sjfb8856606 table_action_profile_find(const char *name)
163*d30ea906Sjfb8856606 {
164*d30ea906Sjfb8856606 struct table_action_profile *profile;
165*d30ea906Sjfb8856606
166*d30ea906Sjfb8856606 if (name == NULL)
167*d30ea906Sjfb8856606 return NULL;
168*d30ea906Sjfb8856606
169*d30ea906Sjfb8856606 TAILQ_FOREACH(profile, &table_action_profile_list, node)
170*d30ea906Sjfb8856606 if (strcmp(profile->name, name) == 0)
171*d30ea906Sjfb8856606 return profile;
172*d30ea906Sjfb8856606
173*d30ea906Sjfb8856606 return NULL;
174*d30ea906Sjfb8856606 }
175*d30ea906Sjfb8856606
176*d30ea906Sjfb8856606 struct table_action_profile *
table_action_profile_create(const char * name,struct table_action_profile_params * params)177*d30ea906Sjfb8856606 table_action_profile_create(const char *name,
178*d30ea906Sjfb8856606 struct table_action_profile_params *params)
179*d30ea906Sjfb8856606 {
180*d30ea906Sjfb8856606 struct table_action_profile *profile;
181*d30ea906Sjfb8856606 struct rte_table_action_profile *ap;
182*d30ea906Sjfb8856606 int status;
183*d30ea906Sjfb8856606
184*d30ea906Sjfb8856606 /* Check input params */
185*d30ea906Sjfb8856606 if ((name == NULL) ||
186*d30ea906Sjfb8856606 table_action_profile_find(name) ||
187*d30ea906Sjfb8856606 (params == NULL) ||
188*d30ea906Sjfb8856606 ((params->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) == 0))
189*d30ea906Sjfb8856606 return NULL;
190*d30ea906Sjfb8856606
191*d30ea906Sjfb8856606 if ((params->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) &&
192*d30ea906Sjfb8856606 (params->lb.f_hash == NULL)) {
193*d30ea906Sjfb8856606 switch (params->lb.key_size) {
194*d30ea906Sjfb8856606 case 8:
195*d30ea906Sjfb8856606 params->lb.f_hash = rte_table_hash_crc_key8;
196*d30ea906Sjfb8856606 break;
197*d30ea906Sjfb8856606
198*d30ea906Sjfb8856606 case 16:
199*d30ea906Sjfb8856606 params->lb.f_hash = rte_table_hash_crc_key16;
200*d30ea906Sjfb8856606 break;
201*d30ea906Sjfb8856606
202*d30ea906Sjfb8856606 case 24:
203*d30ea906Sjfb8856606 params->lb.f_hash = rte_table_hash_crc_key24;
204*d30ea906Sjfb8856606 break;
205*d30ea906Sjfb8856606
206*d30ea906Sjfb8856606 case 32:
207*d30ea906Sjfb8856606 params->lb.f_hash = rte_table_hash_crc_key32;
208*d30ea906Sjfb8856606 break;
209*d30ea906Sjfb8856606
210*d30ea906Sjfb8856606 case 40:
211*d30ea906Sjfb8856606 params->lb.f_hash = rte_table_hash_crc_key40;
212*d30ea906Sjfb8856606 break;
213*d30ea906Sjfb8856606
214*d30ea906Sjfb8856606 case 48:
215*d30ea906Sjfb8856606 params->lb.f_hash = rte_table_hash_crc_key48;
216*d30ea906Sjfb8856606 break;
217*d30ea906Sjfb8856606
218*d30ea906Sjfb8856606 case 56:
219*d30ea906Sjfb8856606 params->lb.f_hash = rte_table_hash_crc_key56;
220*d30ea906Sjfb8856606 break;
221*d30ea906Sjfb8856606
222*d30ea906Sjfb8856606 case 64:
223*d30ea906Sjfb8856606 params->lb.f_hash = rte_table_hash_crc_key64;
224*d30ea906Sjfb8856606 break;
225*d30ea906Sjfb8856606
226*d30ea906Sjfb8856606 default:
227*d30ea906Sjfb8856606 return NULL;
228*d30ea906Sjfb8856606 }
229*d30ea906Sjfb8856606
230*d30ea906Sjfb8856606 params->lb.seed = 0;
231*d30ea906Sjfb8856606 }
232*d30ea906Sjfb8856606
233*d30ea906Sjfb8856606 /* Resource */
234*d30ea906Sjfb8856606 ap = rte_table_action_profile_create(¶ms->common);
235*d30ea906Sjfb8856606 if (ap == NULL)
236*d30ea906Sjfb8856606 return NULL;
237*d30ea906Sjfb8856606
238*d30ea906Sjfb8856606 if (params->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
239*d30ea906Sjfb8856606 status = rte_table_action_profile_action_register(ap,
240*d30ea906Sjfb8856606 RTE_TABLE_ACTION_FWD,
241*d30ea906Sjfb8856606 NULL);
242*d30ea906Sjfb8856606
243*d30ea906Sjfb8856606 if (status) {
244*d30ea906Sjfb8856606 rte_table_action_profile_free(ap);
245*d30ea906Sjfb8856606 return NULL;
246*d30ea906Sjfb8856606 }
247*d30ea906Sjfb8856606 }
248*d30ea906Sjfb8856606
249*d30ea906Sjfb8856606 if (params->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
250*d30ea906Sjfb8856606 status = rte_table_action_profile_action_register(ap,
251*d30ea906Sjfb8856606 RTE_TABLE_ACTION_LB,
252*d30ea906Sjfb8856606 ¶ms->lb);
253*d30ea906Sjfb8856606
254*d30ea906Sjfb8856606 if (status) {
255*d30ea906Sjfb8856606 rte_table_action_profile_free(ap);
256*d30ea906Sjfb8856606 return NULL;
257*d30ea906Sjfb8856606 }
258*d30ea906Sjfb8856606 }
259*d30ea906Sjfb8856606
260*d30ea906Sjfb8856606 if (params->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
261*d30ea906Sjfb8856606 status = rte_table_action_profile_action_register(ap,
262*d30ea906Sjfb8856606 RTE_TABLE_ACTION_MTR,
263*d30ea906Sjfb8856606 ¶ms->mtr);
264*d30ea906Sjfb8856606
265*d30ea906Sjfb8856606 if (status) {
266*d30ea906Sjfb8856606 rte_table_action_profile_free(ap);
267*d30ea906Sjfb8856606 return NULL;
268*d30ea906Sjfb8856606 }
269*d30ea906Sjfb8856606 }
270*d30ea906Sjfb8856606
271*d30ea906Sjfb8856606 if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
272*d30ea906Sjfb8856606 status = rte_table_action_profile_action_register(ap,
273*d30ea906Sjfb8856606 RTE_TABLE_ACTION_TM,
274*d30ea906Sjfb8856606 ¶ms->tm);
275*d30ea906Sjfb8856606
276*d30ea906Sjfb8856606 if (status) {
277*d30ea906Sjfb8856606 rte_table_action_profile_free(ap);
278*d30ea906Sjfb8856606 return NULL;
279*d30ea906Sjfb8856606 }
280*d30ea906Sjfb8856606 }
281*d30ea906Sjfb8856606
282*d30ea906Sjfb8856606 if (params->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
283*d30ea906Sjfb8856606 status = rte_table_action_profile_action_register(ap,
284*d30ea906Sjfb8856606 RTE_TABLE_ACTION_ENCAP,
285*d30ea906Sjfb8856606 ¶ms->encap);
286*d30ea906Sjfb8856606
287*d30ea906Sjfb8856606 if (status) {
288*d30ea906Sjfb8856606 rte_table_action_profile_free(ap);
289*d30ea906Sjfb8856606 return NULL;
290*d30ea906Sjfb8856606 }
291*d30ea906Sjfb8856606 }
292*d30ea906Sjfb8856606
293*d30ea906Sjfb8856606 if (params->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
294*d30ea906Sjfb8856606 status = rte_table_action_profile_action_register(ap,
295*d30ea906Sjfb8856606 RTE_TABLE_ACTION_NAT,
296*d30ea906Sjfb8856606 ¶ms->nat);
297*d30ea906Sjfb8856606
298*d30ea906Sjfb8856606 if (status) {
299*d30ea906Sjfb8856606 rte_table_action_profile_free(ap);
300*d30ea906Sjfb8856606 return NULL;
301*d30ea906Sjfb8856606 }
302*d30ea906Sjfb8856606 }
303*d30ea906Sjfb8856606
304*d30ea906Sjfb8856606 if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TTL)) {
305*d30ea906Sjfb8856606 status = rte_table_action_profile_action_register(ap,
306*d30ea906Sjfb8856606 RTE_TABLE_ACTION_TTL,
307*d30ea906Sjfb8856606 ¶ms->ttl);
308*d30ea906Sjfb8856606
309*d30ea906Sjfb8856606 if (status) {
310*d30ea906Sjfb8856606 rte_table_action_profile_free(ap);
311*d30ea906Sjfb8856606 return NULL;
312*d30ea906Sjfb8856606 }
313*d30ea906Sjfb8856606 }
314*d30ea906Sjfb8856606
315*d30ea906Sjfb8856606 if (params->action_mask & (1LLU << RTE_TABLE_ACTION_STATS)) {
316*d30ea906Sjfb8856606 status = rte_table_action_profile_action_register(ap,
317*d30ea906Sjfb8856606 RTE_TABLE_ACTION_STATS,
318*d30ea906Sjfb8856606 ¶ms->stats);
319*d30ea906Sjfb8856606
320*d30ea906Sjfb8856606 if (status) {
321*d30ea906Sjfb8856606 rte_table_action_profile_free(ap);
322*d30ea906Sjfb8856606 return NULL;
323*d30ea906Sjfb8856606 }
324*d30ea906Sjfb8856606 }
325*d30ea906Sjfb8856606 if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TIME)) {
326*d30ea906Sjfb8856606 status = rte_table_action_profile_action_register(ap,
327*d30ea906Sjfb8856606 RTE_TABLE_ACTION_TIME,
328*d30ea906Sjfb8856606 NULL);
329*d30ea906Sjfb8856606
330*d30ea906Sjfb8856606 if (status) {
331*d30ea906Sjfb8856606 rte_table_action_profile_free(ap);
332*d30ea906Sjfb8856606 return NULL;
333*d30ea906Sjfb8856606 }
334*d30ea906Sjfb8856606 }
335*d30ea906Sjfb8856606
336*d30ea906Sjfb8856606 if (params->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) {
337*d30ea906Sjfb8856606 status = rte_table_action_profile_action_register(ap,
338*d30ea906Sjfb8856606 RTE_TABLE_ACTION_SYM_CRYPTO,
339*d30ea906Sjfb8856606 ¶ms->sym_crypto);
340*d30ea906Sjfb8856606
341*d30ea906Sjfb8856606 if (status) {
342*d30ea906Sjfb8856606 rte_table_action_profile_free(ap);
343*d30ea906Sjfb8856606 return NULL;
344*d30ea906Sjfb8856606 }
345*d30ea906Sjfb8856606 }
346*d30ea906Sjfb8856606
347*d30ea906Sjfb8856606 if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TAG)) {
348*d30ea906Sjfb8856606 status = rte_table_action_profile_action_register(ap,
349*d30ea906Sjfb8856606 RTE_TABLE_ACTION_TAG,
350*d30ea906Sjfb8856606 NULL);
351*d30ea906Sjfb8856606
352*d30ea906Sjfb8856606 if (status) {
353*d30ea906Sjfb8856606 rte_table_action_profile_free(ap);
354*d30ea906Sjfb8856606 return NULL;
355*d30ea906Sjfb8856606 }
356*d30ea906Sjfb8856606 }
357*d30ea906Sjfb8856606
358*d30ea906Sjfb8856606 if (params->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP)) {
359*d30ea906Sjfb8856606 status = rte_table_action_profile_action_register(ap,
360*d30ea906Sjfb8856606 RTE_TABLE_ACTION_DECAP,
361*d30ea906Sjfb8856606 NULL);
362*d30ea906Sjfb8856606
363*d30ea906Sjfb8856606 if (status) {
364*d30ea906Sjfb8856606 rte_table_action_profile_free(ap);
365*d30ea906Sjfb8856606 return NULL;
366*d30ea906Sjfb8856606 }
367*d30ea906Sjfb8856606 }
368*d30ea906Sjfb8856606
369*d30ea906Sjfb8856606 status = rte_table_action_profile_freeze(ap);
370*d30ea906Sjfb8856606 if (status) {
371*d30ea906Sjfb8856606 rte_table_action_profile_free(ap);
372*d30ea906Sjfb8856606 return NULL;
373*d30ea906Sjfb8856606 }
374*d30ea906Sjfb8856606
375*d30ea906Sjfb8856606 /* Node allocation */
376*d30ea906Sjfb8856606 profile = calloc(1, sizeof(struct table_action_profile));
377*d30ea906Sjfb8856606 if (profile == NULL) {
378*d30ea906Sjfb8856606 rte_table_action_profile_free(ap);
379*d30ea906Sjfb8856606 return NULL;
380*d30ea906Sjfb8856606 }
381*d30ea906Sjfb8856606
382*d30ea906Sjfb8856606 /* Node fill in */
383*d30ea906Sjfb8856606 strlcpy(profile->name, name, sizeof(profile->name));
384*d30ea906Sjfb8856606 memcpy(&profile->params, params, sizeof(*params));
385*d30ea906Sjfb8856606 profile->ap = ap;
386*d30ea906Sjfb8856606
387*d30ea906Sjfb8856606 /* Node add to list */
388*d30ea906Sjfb8856606 TAILQ_INSERT_TAIL(&table_action_profile_list, profile, node);
389*d30ea906Sjfb8856606
390*d30ea906Sjfb8856606 return profile;
391*d30ea906Sjfb8856606 }
392