examples/ip_pipeline: add action profile objects
[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         /* Resource */
190         ap = rte_table_action_profile_create(&params->common);
191         if (ap == NULL)
192                 return NULL;
193
194         if (params->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
195                 status = rte_table_action_profile_action_register(ap,
196                         RTE_TABLE_ACTION_FWD,
197                         NULL);
198
199                 if (status) {
200                         rte_table_action_profile_free(ap);
201                         return NULL;
202                 }
203         }
204
205         if (params->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
206                 status = rte_table_action_profile_action_register(ap,
207                         RTE_TABLE_ACTION_MTR,
208                         &params->mtr);
209
210                 if (status) {
211                         rte_table_action_profile_free(ap);
212                         return NULL;
213                 }
214         }
215
216         if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
217                 status = rte_table_action_profile_action_register(ap,
218                         RTE_TABLE_ACTION_TM,
219                         &params->tm);
220
221                 if (status) {
222                         rte_table_action_profile_free(ap);
223                         return NULL;
224                 }
225         }
226
227         if (params->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
228                 status = rte_table_action_profile_action_register(ap,
229                         RTE_TABLE_ACTION_ENCAP,
230                         &params->encap);
231
232                 if (status) {
233                         rte_table_action_profile_free(ap);
234                         return NULL;
235                 }
236         }
237
238         if (params->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
239                 status = rte_table_action_profile_action_register(ap,
240                         RTE_TABLE_ACTION_NAT,
241                         &params->nat);
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_TTL)) {
250                 status = rte_table_action_profile_action_register(ap,
251                         RTE_TABLE_ACTION_TTL,
252                         &params->ttl);
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_STATS)) {
261                 status = rte_table_action_profile_action_register(ap,
262                         RTE_TABLE_ACTION_STATS,
263                         &params->stats);
264
265                 if (status) {
266                         rte_table_action_profile_free(ap);
267                         return NULL;
268                 }
269         }
270         if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TIME)) {
271                 status = rte_table_action_profile_action_register(ap,
272                         RTE_TABLE_ACTION_TIME,
273                         NULL);
274
275                 if (status) {
276                         rte_table_action_profile_free(ap);
277                         return NULL;
278                 }
279         }
280
281         status = rte_table_action_profile_freeze(ap);
282         if (status) {
283                 rte_table_action_profile_free(ap);
284                 return NULL;
285         }
286
287         /* Node allocation */
288         profile = calloc(1, sizeof(struct table_action_profile));
289         if (profile == NULL) {
290                 rte_table_action_profile_free(ap);
291                 return NULL;
292         }
293
294         /* Node fill in */
295         strncpy(profile->name, name, sizeof(profile->name));
296         memcpy(&profile->params, params, sizeof(*params));
297         profile->ap = ap;
298
299         /* Node add to list */
300         TAILQ_INSERT_TAIL(&table_action_profile_list, profile, node);
301
302         return profile;
303 }