xref: /dpdk/examples/ip_pipeline/action.c (revision d5ed626f61b2577c63e5fb67526b531150d5105c)
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
port_in_action_profile_init(void)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 *
port_in_action_profile_find(const char * name)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 *
port_in_action_profile_create(const char * name,struct port_in_action_profile_params * params)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
table_action_profile_init(void)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 *
table_action_profile_find(const char * name)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 *
table_action_profile_create(const char * name,struct table_action_profile_params * params)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 }
392