xref: /dpdk/examples/ip_pipeline/action.c (revision fb73e096110a41b77448fe27fd9be8c489ec5d82)
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 }
357