net/avp: remove resources when port is closed
[dpdk.git] / drivers / net / softnic / rte_eth_softnic_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 "rte_eth_softnic_internals.h"
13
14 /**
15  * Input port
16  */
17 int
18 softnic_port_in_action_profile_init(struct pmd_internals *p)
19 {
20         TAILQ_INIT(&p->port_in_action_profile_list);
21
22         return 0;
23 }
24
25 void
26 softnic_port_in_action_profile_free(struct pmd_internals *p)
27 {
28         for ( ; ; ) {
29                 struct softnic_port_in_action_profile *profile;
30
31                 profile = TAILQ_FIRST(&p->port_in_action_profile_list);
32                 if (profile == NULL)
33                         break;
34
35                 TAILQ_REMOVE(&p->port_in_action_profile_list, profile, node);
36                 free(profile);
37         }
38 }
39
40 struct softnic_port_in_action_profile *
41 softnic_port_in_action_profile_find(struct pmd_internals *p,
42         const char *name)
43 {
44         struct softnic_port_in_action_profile *profile;
45
46         if (name == NULL)
47                 return NULL;
48
49         TAILQ_FOREACH(profile, &p->port_in_action_profile_list, node)
50                 if (strcmp(profile->name, name) == 0)
51                         return profile;
52
53         return NULL;
54 }
55
56 struct softnic_port_in_action_profile *
57 softnic_port_in_action_profile_create(struct pmd_internals *p,
58         const char *name,
59         struct softnic_port_in_action_profile_params *params)
60 {
61         struct softnic_port_in_action_profile *profile;
62         struct rte_port_in_action_profile *ap;
63         int status;
64
65         /* Check input params */
66         if (name == NULL ||
67                 softnic_port_in_action_profile_find(p, name) ||
68                 params == NULL)
69                 return NULL;
70
71         if ((params->action_mask & (1LLU << RTE_PORT_IN_ACTION_LB)) &&
72                 params->lb.f_hash == NULL) {
73                 switch (params->lb.key_size) {
74                 case  8:
75                         params->lb.f_hash = rte_table_hash_crc_key8;
76                         break;
77
78                 case 16:
79                         params->lb.f_hash = rte_table_hash_crc_key16;
80                         break;
81
82                 case 24:
83                         params->lb.f_hash = rte_table_hash_crc_key24;
84                         break;
85
86                 case 32:
87                         params->lb.f_hash = rte_table_hash_crc_key32;
88                         break;
89
90                 case 40:
91                         params->lb.f_hash = rte_table_hash_crc_key40;
92                         break;
93
94                 case 48:
95                         params->lb.f_hash = rte_table_hash_crc_key48;
96                         break;
97
98                 case 56:
99                         params->lb.f_hash = rte_table_hash_crc_key56;
100                         break;
101
102                 case 64:
103                         params->lb.f_hash = rte_table_hash_crc_key64;
104                         break;
105
106                 default:
107                         return NULL;
108                 }
109
110                 params->lb.seed = 0;
111         }
112
113         /* Resource */
114         ap = rte_port_in_action_profile_create(0);
115         if (ap == NULL)
116                 return NULL;
117
118         if (params->action_mask & (1LLU << RTE_PORT_IN_ACTION_FLTR)) {
119                 status = rte_port_in_action_profile_action_register(ap,
120                         RTE_PORT_IN_ACTION_FLTR,
121                         &params->fltr);
122
123                 if (status) {
124                         rte_port_in_action_profile_free(ap);
125                         return NULL;
126                 }
127         }
128
129         if (params->action_mask & (1LLU << RTE_PORT_IN_ACTION_LB)) {
130                 status = rte_port_in_action_profile_action_register(ap,
131                         RTE_PORT_IN_ACTION_LB,
132                         &params->lb);
133
134                 if (status) {
135                         rte_port_in_action_profile_free(ap);
136                         return NULL;
137                 }
138         }
139
140         status = rte_port_in_action_profile_freeze(ap);
141         if (status) {
142                 rte_port_in_action_profile_free(ap);
143                 return NULL;
144         }
145
146         /* Node allocation */
147         profile = calloc(1, sizeof(struct softnic_port_in_action_profile));
148         if (profile == NULL) {
149                 rte_port_in_action_profile_free(ap);
150                 return NULL;
151         }
152
153         /* Node fill in */
154         strlcpy(profile->name, name, sizeof(profile->name));
155         memcpy(&profile->params, params, sizeof(*params));
156         profile->ap = ap;
157
158         /* Node add to list */
159         TAILQ_INSERT_TAIL(&p->port_in_action_profile_list, profile, node);
160
161         return profile;
162 }
163
164 /**
165  * Table
166  */
167 int
168 softnic_table_action_profile_init(struct pmd_internals *p)
169 {
170         TAILQ_INIT(&p->table_action_profile_list);
171
172         return 0;
173 }
174
175 void
176 softnic_table_action_profile_free(struct pmd_internals *p)
177 {
178         for ( ; ; ) {
179                 struct softnic_table_action_profile *profile;
180
181                 profile = TAILQ_FIRST(&p->table_action_profile_list);
182                 if (profile == NULL)
183                         break;
184
185                 TAILQ_REMOVE(&p->table_action_profile_list, profile, node);
186                 free(profile);
187         }
188 }
189
190 struct softnic_table_action_profile *
191 softnic_table_action_profile_find(struct pmd_internals *p,
192         const char *name)
193 {
194         struct softnic_table_action_profile *profile;
195
196         if (name == NULL)
197                 return NULL;
198
199         TAILQ_FOREACH(profile, &p->table_action_profile_list, node)
200                 if (strcmp(profile->name, name) == 0)
201                         return profile;
202
203         return NULL;
204 }
205
206 struct softnic_table_action_profile *
207 softnic_table_action_profile_create(struct pmd_internals *p,
208         const char *name,
209         struct softnic_table_action_profile_params *params)
210 {
211         struct softnic_table_action_profile *profile;
212         struct rte_table_action_profile *ap;
213         int status;
214
215         /* Check input params */
216         if (name == NULL ||
217                 softnic_table_action_profile_find(p, name) ||
218                 params == NULL ||
219                 ((params->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) == 0))
220                 return NULL;
221
222         if ((params->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) &&
223                 params->lb.f_hash == NULL) {
224                 switch (params->lb.key_size) {
225                 case 8:
226                         params->lb.f_hash = rte_table_hash_crc_key8;
227                         break;
228
229                 case 16:
230                         params->lb.f_hash = rte_table_hash_crc_key16;
231                         break;
232
233                 case 24:
234                         params->lb.f_hash = rte_table_hash_crc_key24;
235                         break;
236
237                 case 32:
238                         params->lb.f_hash = rte_table_hash_crc_key32;
239                         break;
240
241                 case 40:
242                         params->lb.f_hash = rte_table_hash_crc_key40;
243                         break;
244
245                 case 48:
246                         params->lb.f_hash = rte_table_hash_crc_key48;
247                         break;
248
249                 case 56:
250                         params->lb.f_hash = rte_table_hash_crc_key56;
251                         break;
252
253                 case 64:
254                         params->lb.f_hash = rte_table_hash_crc_key64;
255                         break;
256
257                 default:
258                         return NULL;
259                 }
260
261                 params->lb.seed = 0;
262         }
263
264         /* Resource */
265         ap = rte_table_action_profile_create(&params->common);
266         if (ap == NULL)
267                 return NULL;
268
269         if (params->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
270                 status = rte_table_action_profile_action_register(ap,
271                         RTE_TABLE_ACTION_FWD,
272                         NULL);
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_LB)) {
281                 status = rte_table_action_profile_action_register(ap,
282                         RTE_TABLE_ACTION_LB,
283                         &params->lb);
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_MTR)) {
292                 status = rte_table_action_profile_action_register(ap,
293                         RTE_TABLE_ACTION_MTR,
294                         &params->mtr);
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_TM)) {
303                 status = rte_table_action_profile_action_register(ap,
304                         RTE_TABLE_ACTION_TM,
305                         &params->tm);
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_ENCAP)) {
314                 status = rte_table_action_profile_action_register(ap,
315                         RTE_TABLE_ACTION_ENCAP,
316                         &params->encap);
317
318                 if (status) {
319                         rte_table_action_profile_free(ap);
320                         return NULL;
321                 }
322         }
323
324         if (params->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
325                 status = rte_table_action_profile_action_register(ap,
326                         RTE_TABLE_ACTION_NAT,
327                         &params->nat);
328
329                 if (status) {
330                         rte_table_action_profile_free(ap);
331                         return NULL;
332                 }
333         }
334
335         if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TTL)) {
336                 status = rte_table_action_profile_action_register(ap,
337                         RTE_TABLE_ACTION_TTL,
338                         &params->ttl);
339
340                 if (status) {
341                         rte_table_action_profile_free(ap);
342                         return NULL;
343                 }
344         }
345
346         if (params->action_mask & (1LLU << RTE_TABLE_ACTION_STATS)) {
347                 status = rte_table_action_profile_action_register(ap,
348                         RTE_TABLE_ACTION_STATS,
349                         &params->stats);
350
351                 if (status) {
352                         rte_table_action_profile_free(ap);
353                         return NULL;
354                 }
355         }
356         if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TIME)) {
357                 status = rte_table_action_profile_action_register(ap,
358                         RTE_TABLE_ACTION_TIME,
359                         NULL);
360
361                 if (status) {
362                         rte_table_action_profile_free(ap);
363                         return NULL;
364                 }
365         }
366
367         if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TAG)) {
368                 status = rte_table_action_profile_action_register(ap,
369                         RTE_TABLE_ACTION_TAG,
370                         NULL);
371
372                 if (status) {
373                         rte_table_action_profile_free(ap);
374                         return NULL;
375                 }
376         }
377
378         if (params->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP)) {
379                 status = rte_table_action_profile_action_register(ap,
380                         RTE_TABLE_ACTION_DECAP,
381                         NULL);
382
383                 if (status) {
384                         rte_table_action_profile_free(ap);
385                         return NULL;
386                 }
387         }
388
389         if (params->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) {
390                 status = rte_table_action_profile_action_register(ap,
391                         RTE_TABLE_ACTION_SYM_CRYPTO,
392                         &params->sym_crypto);
393
394                 if (status) {
395                         rte_table_action_profile_free(ap);
396                         return NULL;
397                 }
398         }
399
400         status = rte_table_action_profile_freeze(ap);
401         if (status) {
402                 rte_table_action_profile_free(ap);
403                 return NULL;
404         }
405
406         /* Node allocation */
407         profile = calloc(1, sizeof(struct softnic_table_action_profile));
408         if (profile == NULL) {
409                 rte_table_action_profile_free(ap);
410                 return NULL;
411         }
412
413         /* Node fill in */
414         strlcpy(profile->name, name, sizeof(profile->name));
415         memcpy(&profile->params, params, sizeof(*params));
416         profile->ap = ap;
417
418         /* Node add to list */
419         TAILQ_INSERT_TAIL(&p->table_action_profile_list, profile, node);
420
421         return profile;
422 }