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