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