Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright 2020 Mellanox Technologies, Ltd
3 : : *
4 : : * The file contains the implementations of actions generators.
5 : : * Each generator is responsible for preparing it's action instance
6 : : * and initializing it with needed data.
7 : : */
8 : :
9 : : #include <stdlib.h>
10 : : #include <sys/types.h>
11 : : #include <rte_malloc.h>
12 : : #include <rte_flow.h>
13 : : #include <rte_ethdev.h>
14 : : #include <rte_vxlan.h>
15 : : #include <rte_gtp.h>
16 : : #include <rte_gre.h>
17 : : #include <rte_geneve.h>
18 : : #include <rte_os_shim.h>
19 : :
20 : : #include "actions_gen.h"
21 : : #include "flow_gen.h"
22 : : #include "config.h"
23 : :
24 : :
25 : : /* Storage for additional parameters for actions */
26 : : struct additional_para {
27 : : uint16_t queue;
28 : : uint16_t next_table;
29 : : uint16_t *queues;
30 : : uint16_t queues_number;
31 : : uint32_t counter;
32 : : uint64_t encap_data;
33 : : uint64_t decap_data;
34 : : uint16_t dst_port;
35 : : uint8_t core_idx;
36 : : bool unique_data;
37 : : };
38 : :
39 : : /* Storage for struct rte_flow_action_raw_encap including external data. */
40 : : struct action_raw_encap_data {
41 : : struct rte_flow_action_raw_encap conf;
42 : : uint8_t data[128];
43 : : uint8_t preserve[128];
44 : : uint16_t idx;
45 : : };
46 : :
47 : : /* Storage for struct rte_flow_action_raw_decap including external data. */
48 : : struct action_raw_decap_data {
49 : : struct rte_flow_action_raw_decap conf;
50 : : uint8_t data[128];
51 : : uint16_t idx;
52 : : };
53 : :
54 : : /* Storage for struct rte_flow_action_rss including external data. */
55 : : struct action_rss_data {
56 : : struct rte_flow_action_rss conf;
57 : : uint8_t key[40];
58 : : uint16_t queue[128];
59 : : };
60 : :
61 : : static void
62 : 0 : add_mark(struct rte_flow_action *actions,
63 : : uint8_t actions_counter,
64 : : struct additional_para para)
65 : : {
66 : : static alignas(RTE_CACHE_LINE_SIZE)
67 : : struct rte_flow_action_mark mark_actions[RTE_MAX_LCORE];
68 : 0 : uint32_t counter = para.counter;
69 : :
70 : : do {
71 : : /* Random values from 1 to 256 */
72 : 0 : mark_actions[para.core_idx].id = (counter % 255) + 1;
73 : : } while (0);
74 : :
75 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_MARK;
76 : 0 : actions[actions_counter].conf = &mark_actions[para.core_idx];
77 : 0 : }
78 : :
79 : : static void
80 : 0 : add_queue(struct rte_flow_action *actions,
81 : : uint8_t actions_counter,
82 : : struct additional_para para)
83 : : {
84 : : static alignas(RTE_CACHE_LINE_SIZE)
85 : : struct rte_flow_action_queue queue_actions[RTE_MAX_LCORE];
86 : :
87 : : do {
88 : 0 : queue_actions[para.core_idx].index = para.queue;
89 : : } while (0);
90 : :
91 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_QUEUE;
92 : 0 : actions[actions_counter].conf = &queue_actions[para.core_idx];
93 : 0 : }
94 : :
95 : : static void
96 : 0 : add_jump(struct rte_flow_action *actions,
97 : : uint8_t actions_counter,
98 : : struct additional_para para)
99 : : {
100 : : static struct rte_flow_action_jump jump_action;
101 : :
102 : : do {
103 : 0 : jump_action.group = para.next_table;
104 : : } while (0);
105 : :
106 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_JUMP;
107 : 0 : actions[actions_counter].conf = &jump_action;
108 : 0 : }
109 : :
110 : : static void
111 : 0 : add_rss(struct rte_flow_action *actions,
112 : : uint8_t actions_counter,
113 : : struct additional_para para)
114 : : {
115 : : static alignas(RTE_CACHE_LINE_SIZE) struct action_rss_data *rss_data[RTE_MAX_LCORE];
116 : :
117 : : uint16_t queue;
118 : :
119 : 0 : if (rss_data[para.core_idx] == NULL)
120 : 0 : rss_data[para.core_idx] = rte_malloc("rss_data",
121 : : sizeof(struct action_rss_data), 0);
122 : :
123 : 0 : if (rss_data[para.core_idx] == NULL)
124 : 0 : rte_exit(EXIT_FAILURE, "No Memory available!");
125 : :
126 : 0 : *rss_data[para.core_idx] = (struct action_rss_data){
127 : : .conf = (struct rte_flow_action_rss){
128 : : .func = RTE_ETH_HASH_FUNCTION_DEFAULT,
129 : : .level = 0,
130 : : .types = GET_RSS_HF(),
131 : : .key_len = sizeof(rss_data[para.core_idx]->key),
132 : 0 : .queue_num = para.queues_number,
133 : 0 : .key = rss_data[para.core_idx]->key,
134 : 0 : .queue = rss_data[para.core_idx]->queue,
135 : : },
136 : : .key = { 1 },
137 : : .queue = { 0 },
138 : : };
139 : :
140 : 0 : for (queue = 0; queue < para.queues_number; queue++)
141 : 0 : rss_data[para.core_idx]->queue[queue] = para.queues[queue];
142 : :
143 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_RSS;
144 : 0 : actions[actions_counter].conf = &rss_data[para.core_idx]->conf;
145 : 0 : }
146 : :
147 : : static void
148 : 0 : add_set_meta(struct rte_flow_action *actions,
149 : : uint8_t actions_counter,
150 : : __rte_unused struct additional_para para)
151 : : {
152 : : static struct rte_flow_action_set_meta meta_action = {
153 : : .data = RTE_BE32(META_DATA),
154 : : .mask = RTE_BE32(0xffffffff),
155 : : };
156 : :
157 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_META;
158 : 0 : actions[actions_counter].conf = &meta_action;
159 : 0 : }
160 : :
161 : : static void
162 : 0 : add_set_tag(struct rte_flow_action *actions,
163 : : uint8_t actions_counter,
164 : : __rte_unused struct additional_para para)
165 : : {
166 : : static struct rte_flow_action_set_tag tag_action = {
167 : : .data = RTE_BE32(META_DATA),
168 : : .mask = RTE_BE32(0xffffffff),
169 : : .index = TAG_INDEX,
170 : : };
171 : :
172 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_TAG;
173 : 0 : actions[actions_counter].conf = &tag_action;
174 : 0 : }
175 : :
176 : : static void
177 : 0 : add_port_id(struct rte_flow_action *actions,
178 : : uint8_t actions_counter,
179 : : struct additional_para para)
180 : : {
181 : : static struct rte_flow_action_port_id port_id = {
182 : : .id = PORT_ID_DST,
183 : : };
184 : :
185 : 0 : port_id.id = para.dst_port;
186 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_PORT_ID;
187 : 0 : actions[actions_counter].conf = &port_id;
188 : 0 : }
189 : :
190 : : static void
191 : 0 : add_drop(struct rte_flow_action *actions,
192 : : uint8_t actions_counter,
193 : : __rte_unused struct additional_para para)
194 : : {
195 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_DROP;
196 : 0 : }
197 : :
198 : : static void
199 : 0 : add_count(struct rte_flow_action *actions,
200 : : uint8_t actions_counter,
201 : : __rte_unused struct additional_para para)
202 : : {
203 : : static struct rte_flow_action_count count_action;
204 : :
205 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_COUNT;
206 : 0 : actions[actions_counter].conf = &count_action;
207 : 0 : }
208 : :
209 : : static void
210 : 0 : add_set_src_mac(struct rte_flow_action *actions,
211 : : uint8_t actions_counter,
212 : : struct additional_para para)
213 : : {
214 : : static alignas(RTE_CACHE_LINE_SIZE) struct rte_flow_action_set_mac set_macs[RTE_MAX_LCORE];
215 : 0 : uint32_t mac = para.counter;
216 : : uint16_t i;
217 : :
218 : : /* Fixed value */
219 : 0 : if (!para.unique_data)
220 : : mac = 1;
221 : :
222 : : /* Mac address to be set is random each time */
223 : 0 : for (i = 0; i < RTE_ETHER_ADDR_LEN; i++) {
224 : 0 : set_macs[para.core_idx].mac_addr[i] = mac & 0xff;
225 : 0 : mac = mac >> 8;
226 : : }
227 : :
228 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_MAC_SRC;
229 : 0 : actions[actions_counter].conf = &set_macs[para.core_idx];
230 : 0 : }
231 : :
232 : : static void
233 : 0 : add_set_dst_mac(struct rte_flow_action *actions,
234 : : uint8_t actions_counter,
235 : : struct additional_para para)
236 : : {
237 : : static alignas(RTE_CACHE_LINE_SIZE) struct rte_flow_action_set_mac set_macs[RTE_MAX_LCORE];
238 : 0 : uint32_t mac = para.counter;
239 : : uint16_t i;
240 : :
241 : : /* Fixed value */
242 : 0 : if (!para.unique_data)
243 : : mac = 1;
244 : :
245 : : /* Mac address to be set is random each time */
246 : 0 : for (i = 0; i < RTE_ETHER_ADDR_LEN; i++) {
247 : 0 : set_macs[para.core_idx].mac_addr[i] = mac & 0xff;
248 : 0 : mac = mac >> 8;
249 : : }
250 : :
251 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_MAC_DST;
252 : 0 : actions[actions_counter].conf = &set_macs[para.core_idx];
253 : 0 : }
254 : :
255 : : static void
256 : 0 : add_set_src_ipv4(struct rte_flow_action *actions,
257 : : uint8_t actions_counter,
258 : : struct additional_para para)
259 : : {
260 : : static alignas(RTE_CACHE_LINE_SIZE) struct rte_flow_action_set_ipv4 set_ipv4[RTE_MAX_LCORE];
261 : 0 : uint32_t ip = para.counter;
262 : :
263 : : /* Fixed value */
264 : 0 : if (!para.unique_data)
265 : : ip = 1;
266 : :
267 : : /* IPv4 value to be set is random each time */
268 : 0 : set_ipv4[para.core_idx].ipv4_addr = RTE_BE32(ip + 1);
269 : :
270 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC;
271 : 0 : actions[actions_counter].conf = &set_ipv4[para.core_idx];
272 : 0 : }
273 : :
274 : : static void
275 : 0 : add_set_dst_ipv4(struct rte_flow_action *actions,
276 : : uint8_t actions_counter,
277 : : struct additional_para para)
278 : : {
279 : : static alignas(RTE_CACHE_LINE_SIZE) struct rte_flow_action_set_ipv4 set_ipv4[RTE_MAX_LCORE];
280 : 0 : uint32_t ip = para.counter;
281 : :
282 : : /* Fixed value */
283 : 0 : if (!para.unique_data)
284 : : ip = 1;
285 : :
286 : : /* IPv4 value to be set is random each time */
287 : 0 : set_ipv4[para.core_idx].ipv4_addr = RTE_BE32(ip + 1);
288 : :
289 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV4_DST;
290 : 0 : actions[actions_counter].conf = &set_ipv4[para.core_idx];
291 : 0 : }
292 : :
293 : : static void
294 : 0 : add_set_src_ipv6(struct rte_flow_action *actions,
295 : : uint8_t actions_counter,
296 : : struct additional_para para)
297 : : {
298 : : static alignas(RTE_CACHE_LINE_SIZE) struct rte_flow_action_set_ipv6 set_ipv6[RTE_MAX_LCORE];
299 : 0 : uint32_t ipv6 = para.counter;
300 : : uint8_t i;
301 : :
302 : : /* Fixed value */
303 : 0 : if (!para.unique_data)
304 : : ipv6 = 1;
305 : :
306 : : /* IPv6 value to set is random each time */
307 : 0 : for (i = 0; i < 16; i++) {
308 : 0 : set_ipv6[para.core_idx].ipv6_addr.a[i] = ipv6 & 0xff;
309 : 0 : ipv6 = ipv6 >> 8;
310 : : }
311 : :
312 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC;
313 : 0 : actions[actions_counter].conf = &set_ipv6[para.core_idx];
314 : 0 : }
315 : :
316 : : static void
317 : 0 : add_set_dst_ipv6(struct rte_flow_action *actions,
318 : : uint8_t actions_counter,
319 : : struct additional_para para)
320 : : {
321 : : static alignas(RTE_CACHE_LINE_SIZE) struct rte_flow_action_set_ipv6 set_ipv6[RTE_MAX_LCORE];
322 : 0 : uint32_t ipv6 = para.counter;
323 : : uint8_t i;
324 : :
325 : : /* Fixed value */
326 : 0 : if (!para.unique_data)
327 : : ipv6 = 1;
328 : :
329 : : /* IPv6 value to set is random each time */
330 : 0 : for (i = 0; i < 16; i++) {
331 : 0 : set_ipv6[para.core_idx].ipv6_addr.a[i] = ipv6 & 0xff;
332 : 0 : ipv6 = ipv6 >> 8;
333 : : }
334 : :
335 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV6_DST;
336 : 0 : actions[actions_counter].conf = &set_ipv6[para.core_idx];
337 : 0 : }
338 : :
339 : : static void
340 : 0 : add_set_src_tp(struct rte_flow_action *actions,
341 : : uint8_t actions_counter,
342 : : struct additional_para para)
343 : : {
344 : : static alignas(RTE_CACHE_LINE_SIZE) struct rte_flow_action_set_tp set_tp[RTE_MAX_LCORE];
345 : 0 : uint32_t tp = para.counter;
346 : :
347 : : /* Fixed value */
348 : 0 : if (!para.unique_data)
349 : : tp = 100;
350 : :
351 : : /* TP src port is random each time */
352 : 0 : tp = tp % 0xffff;
353 : :
354 : 0 : set_tp[para.core_idx].port = RTE_BE16(tp & 0xffff);
355 : :
356 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_TP_SRC;
357 : 0 : actions[actions_counter].conf = &set_tp[para.core_idx];
358 : 0 : }
359 : :
360 : : static void
361 : 0 : add_set_dst_tp(struct rte_flow_action *actions,
362 : : uint8_t actions_counter,
363 : : struct additional_para para)
364 : : {
365 : : static alignas(RTE_CACHE_LINE_SIZE) struct rte_flow_action_set_tp set_tp[RTE_MAX_LCORE];
366 : 0 : uint32_t tp = para.counter;
367 : :
368 : : /* Fixed value */
369 : 0 : if (!para.unique_data)
370 : : tp = 100;
371 : :
372 : : /* TP src port is random each time */
373 : 0 : if (tp > 0xffff)
374 : 0 : tp = tp >> 16;
375 : :
376 : 0 : set_tp[para.core_idx].port = RTE_BE16(tp & 0xffff);
377 : :
378 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_TP_DST;
379 : 0 : actions[actions_counter].conf = &set_tp[para.core_idx];
380 : 0 : }
381 : :
382 : : static void
383 : 0 : add_inc_tcp_ack(struct rte_flow_action *actions,
384 : : uint8_t actions_counter,
385 : : struct additional_para para)
386 : : {
387 : : static alignas(RTE_CACHE_LINE_SIZE) rte_be32_t value[RTE_MAX_LCORE];
388 : 0 : uint32_t ack_value = para.counter;
389 : :
390 : : /* Fixed value */
391 : 0 : if (!para.unique_data)
392 : : ack_value = 1;
393 : :
394 : 0 : value[para.core_idx] = RTE_BE32(ack_value);
395 : :
396 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_INC_TCP_ACK;
397 : 0 : actions[actions_counter].conf = &value[para.core_idx];
398 : 0 : }
399 : :
400 : : static void
401 : 0 : add_dec_tcp_ack(struct rte_flow_action *actions,
402 : : uint8_t actions_counter,
403 : : struct additional_para para)
404 : : {
405 : : static alignas(RTE_CACHE_LINE_SIZE) rte_be32_t value[RTE_MAX_LCORE];
406 : 0 : uint32_t ack_value = para.counter;
407 : :
408 : : /* Fixed value */
409 : 0 : if (!para.unique_data)
410 : : ack_value = 1;
411 : :
412 : 0 : value[para.core_idx] = RTE_BE32(ack_value);
413 : :
414 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK;
415 : 0 : actions[actions_counter].conf = &value[para.core_idx];
416 : 0 : }
417 : :
418 : : static void
419 : 0 : add_inc_tcp_seq(struct rte_flow_action *actions,
420 : : uint8_t actions_counter,
421 : : struct additional_para para)
422 : : {
423 : : static alignas(RTE_CACHE_LINE_SIZE) rte_be32_t value[RTE_MAX_LCORE];
424 : 0 : uint32_t seq_value = para.counter;
425 : :
426 : : /* Fixed value */
427 : 0 : if (!para.unique_data)
428 : : seq_value = 1;
429 : :
430 : 0 : value[para.core_idx] = RTE_BE32(seq_value);
431 : :
432 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ;
433 : 0 : actions[actions_counter].conf = &value[para.core_idx];
434 : 0 : }
435 : :
436 : : static void
437 : 0 : add_dec_tcp_seq(struct rte_flow_action *actions,
438 : : uint8_t actions_counter,
439 : : struct additional_para para)
440 : : {
441 : : static alignas(RTE_CACHE_LINE_SIZE) rte_be32_t value[RTE_MAX_LCORE];
442 : 0 : uint32_t seq_value = para.counter;
443 : :
444 : : /* Fixed value */
445 : 0 : if (!para.unique_data)
446 : : seq_value = 1;
447 : :
448 : 0 : value[para.core_idx] = RTE_BE32(seq_value);
449 : :
450 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_DEC_TCP_SEQ;
451 : 0 : actions[actions_counter].conf = &value[para.core_idx];
452 : 0 : }
453 : :
454 : : static void
455 : 0 : add_set_ttl(struct rte_flow_action *actions,
456 : : uint8_t actions_counter,
457 : : struct additional_para para)
458 : : {
459 : : static alignas(RTE_CACHE_LINE_SIZE) struct rte_flow_action_set_ttl set_ttl[RTE_MAX_LCORE];
460 : 0 : uint32_t ttl_value = para.counter;
461 : :
462 : : /* Fixed value */
463 : 0 : if (!para.unique_data)
464 : : ttl_value = 1;
465 : :
466 : : /* Set ttl to random value each time */
467 : 0 : ttl_value = ttl_value % 0xff;
468 : :
469 : 0 : set_ttl[para.core_idx].ttl_value = ttl_value;
470 : :
471 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_TTL;
472 : 0 : actions[actions_counter].conf = &set_ttl[para.core_idx];
473 : 0 : }
474 : :
475 : : static void
476 : 0 : add_dec_ttl(struct rte_flow_action *actions,
477 : : uint8_t actions_counter,
478 : : __rte_unused struct additional_para para)
479 : : {
480 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_DEC_TTL;
481 : 0 : }
482 : :
483 : : static void
484 : 0 : add_set_ipv4_dscp(struct rte_flow_action *actions,
485 : : uint8_t actions_counter,
486 : : struct additional_para para)
487 : : {
488 : : static alignas(RTE_CACHE_LINE_SIZE) struct rte_flow_action_set_dscp set_dscp[RTE_MAX_LCORE];
489 : 0 : uint32_t dscp_value = para.counter;
490 : :
491 : : /* Fixed value */
492 : 0 : if (!para.unique_data)
493 : : dscp_value = 1;
494 : :
495 : : /* Set dscp to random value each time */
496 : 0 : dscp_value = dscp_value % 0xff;
497 : :
498 : 0 : set_dscp[para.core_idx].dscp = dscp_value;
499 : :
500 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP;
501 : 0 : actions[actions_counter].conf = &set_dscp[para.core_idx];
502 : 0 : }
503 : :
504 : : static void
505 : 0 : add_set_ipv6_dscp(struct rte_flow_action *actions,
506 : : uint8_t actions_counter,
507 : : struct additional_para para)
508 : : {
509 : : static alignas(RTE_CACHE_LINE_SIZE) struct rte_flow_action_set_dscp set_dscp[RTE_MAX_LCORE];
510 : 0 : uint32_t dscp_value = para.counter;
511 : :
512 : : /* Fixed value */
513 : 0 : if (!para.unique_data)
514 : : dscp_value = 1;
515 : :
516 : : /* Set dscp to random value each time */
517 : 0 : dscp_value = dscp_value % 0xff;
518 : :
519 : 0 : set_dscp[para.core_idx].dscp = dscp_value;
520 : :
521 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP;
522 : 0 : actions[actions_counter].conf = &set_dscp[para.core_idx];
523 : 0 : }
524 : :
525 : : static void
526 : 0 : add_flag(struct rte_flow_action *actions,
527 : : uint8_t actions_counter,
528 : : __rte_unused struct additional_para para)
529 : : {
530 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_FLAG;
531 : 0 : }
532 : :
533 : : static void
534 : 0 : add_ether_header(uint8_t **header, uint64_t data,
535 : : __rte_unused struct additional_para para)
536 : : {
537 : : struct rte_ether_hdr eth_hdr;
538 : :
539 : 0 : if (!(data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ETH)))
540 : 0 : return;
541 : :
542 : : memset(ð_hdr, 0, sizeof(struct rte_ether_hdr));
543 : 0 : if (data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VLAN))
544 : 0 : eth_hdr.ether_type = RTE_BE16(RTE_ETHER_TYPE_VLAN);
545 : 0 : else if (data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV4))
546 : 0 : eth_hdr.ether_type = RTE_BE16(RTE_ETHER_TYPE_IPV4);
547 : 0 : else if (data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV6))
548 : 0 : eth_hdr.ether_type = RTE_BE16(RTE_ETHER_TYPE_IPV6);
549 : 0 : memcpy(*header, ð_hdr, sizeof(eth_hdr));
550 : 0 : *header += sizeof(eth_hdr);
551 : : }
552 : :
553 : : static void
554 : 0 : add_vlan_header(uint8_t **header, uint64_t data,
555 : : __rte_unused struct additional_para para)
556 : : {
557 : : struct rte_vlan_hdr vlan_hdr;
558 : : uint16_t vlan_value;
559 : :
560 : 0 : if (!(data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VLAN)))
561 : 0 : return;
562 : :
563 : : vlan_value = VLAN_VALUE;
564 : :
565 : : memset(&vlan_hdr, 0, sizeof(struct rte_vlan_hdr));
566 : 0 : vlan_hdr.vlan_tci = RTE_BE16(vlan_value);
567 : :
568 : 0 : if (data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV4))
569 : 0 : vlan_hdr.eth_proto = RTE_BE16(RTE_ETHER_TYPE_IPV4);
570 : 0 : if (data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV6))
571 : 0 : vlan_hdr.eth_proto = RTE_BE16(RTE_ETHER_TYPE_IPV6);
572 : 0 : memcpy(*header, &vlan_hdr, sizeof(vlan_hdr));
573 : 0 : *header += sizeof(vlan_hdr);
574 : : }
575 : :
576 : : static void
577 : 0 : add_ipv4_header(uint8_t **header, uint64_t data,
578 : : struct additional_para para)
579 : : {
580 : : struct rte_ipv4_hdr ipv4_hdr;
581 : 0 : uint32_t ip_dst = para.counter;
582 : :
583 : 0 : if (!(data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV4)))
584 : 0 : return;
585 : :
586 : : /* Fixed value */
587 : 0 : if (!para.unique_data)
588 : : ip_dst = 1;
589 : :
590 : : memset(&ipv4_hdr, 0, sizeof(struct rte_ipv4_hdr));
591 : 0 : ipv4_hdr.src_addr = RTE_IPV4(127, 0, 0, 1);
592 : 0 : ipv4_hdr.dst_addr = RTE_BE32(ip_dst);
593 : 0 : ipv4_hdr.version_ihl = RTE_IPV4_VHL_DEF;
594 : 0 : if (data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_UDP))
595 : 0 : ipv4_hdr.next_proto_id = RTE_IP_TYPE_UDP;
596 : 0 : if (data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GRE))
597 : 0 : ipv4_hdr.next_proto_id = RTE_IP_TYPE_GRE;
598 : 0 : memcpy(*header, &ipv4_hdr, sizeof(ipv4_hdr));
599 : 0 : *header += sizeof(ipv4_hdr);
600 : : }
601 : :
602 : : static void
603 : 0 : add_ipv6_header(uint8_t **header, uint64_t data,
604 : : __rte_unused struct additional_para para)
605 : : {
606 : : struct rte_ipv6_hdr ipv6_hdr;
607 : :
608 : 0 : if (!(data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV6)))
609 : 0 : return;
610 : :
611 : : memset(&ipv6_hdr, 0, sizeof(struct rte_ipv6_hdr));
612 : 0 : if (data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_UDP))
613 : 0 : ipv6_hdr.proto = RTE_IP_TYPE_UDP;
614 : 0 : if (data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GRE))
615 : 0 : ipv6_hdr.proto = RTE_IP_TYPE_GRE;
616 : 0 : memcpy(*header, &ipv6_hdr, sizeof(ipv6_hdr));
617 : 0 : *header += sizeof(ipv6_hdr);
618 : : }
619 : :
620 : : static void
621 : 0 : add_udp_header(uint8_t **header, uint64_t data,
622 : : __rte_unused struct additional_para para)
623 : : {
624 : : struct rte_udp_hdr udp_hdr;
625 : :
626 : 0 : if (!(data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_UDP)))
627 : 0 : return;
628 : :
629 : : memset(&udp_hdr, 0, sizeof(struct rte_flow_item_udp));
630 : 0 : if (data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN))
631 : 0 : udp_hdr.dst_port = RTE_BE16(RTE_VXLAN_DEFAULT_PORT);
632 : 0 : if (data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN_GPE))
633 : 0 : udp_hdr.dst_port = RTE_BE16(RTE_VXLAN_GPE_UDP_PORT);
634 : 0 : if (data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GENEVE))
635 : 0 : udp_hdr.dst_port = RTE_BE16(RTE_GENEVE_UDP_PORT);
636 : 0 : if (data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GTP))
637 : 0 : udp_hdr.dst_port = RTE_BE16(RTE_GTPU_UDP_PORT);
638 : 0 : memcpy(*header, &udp_hdr, sizeof(udp_hdr));
639 : 0 : *header += sizeof(udp_hdr);
640 : : }
641 : :
642 : : static void
643 : 0 : add_vxlan_header(uint8_t **header, uint64_t data,
644 : : struct additional_para para)
645 : : {
646 : : struct rte_vxlan_hdr vxlan_hdr;
647 : 0 : uint32_t vni_value = para.counter;
648 : :
649 : 0 : if (!(data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN)))
650 : 0 : return;
651 : :
652 : : /* Fixed value */
653 : 0 : if (!para.unique_data)
654 : : vni_value = 1;
655 : :
656 : : memset(&vxlan_hdr, 0, sizeof(struct rte_vxlan_hdr));
657 : :
658 : 0 : vxlan_hdr.vx_vni = (RTE_BE32(vni_value)) >> 16;
659 : 0 : vxlan_hdr.vx_flags = 0x8;
660 : :
661 : 0 : memcpy(*header, &vxlan_hdr, sizeof(vxlan_hdr));
662 : 0 : *header += sizeof(vxlan_hdr);
663 : : }
664 : :
665 : : static void
666 : 0 : add_vxlan_gpe_header(uint8_t **header, uint64_t data,
667 : : struct additional_para para)
668 : : {
669 : : struct rte_vxlan_gpe_hdr vxlan_gpe_hdr;
670 : 0 : uint32_t vni_value = para.counter;
671 : :
672 : 0 : if (!(data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN_GPE)))
673 : 0 : return;
674 : :
675 : : /* Fixed value */
676 : 0 : if (!para.unique_data)
677 : : vni_value = 1;
678 : :
679 : : memset(&vxlan_gpe_hdr, 0, sizeof(struct rte_vxlan_gpe_hdr));
680 : :
681 : 0 : vxlan_gpe_hdr.vx_vni = (RTE_BE32(vni_value)) >> 16;
682 : 0 : vxlan_gpe_hdr.vx_flags = 0x0c;
683 : :
684 : 0 : memcpy(*header, &vxlan_gpe_hdr, sizeof(vxlan_gpe_hdr));
685 : 0 : *header += sizeof(vxlan_gpe_hdr);
686 : : }
687 : :
688 : : static void
689 : 0 : add_gre_header(uint8_t **header, uint64_t data,
690 : : __rte_unused struct additional_para para)
691 : : {
692 : : struct rte_gre_hdr gre_hdr;
693 : :
694 : 0 : if (!(data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GRE)))
695 : 0 : return;
696 : :
697 : : memset(&gre_hdr, 0, sizeof(struct rte_gre_hdr));
698 : :
699 : 0 : gre_hdr.proto = RTE_BE16(RTE_ETHER_TYPE_TEB);
700 : :
701 : 0 : memcpy(*header, &gre_hdr, sizeof(gre_hdr));
702 : 0 : *header += sizeof(gre_hdr);
703 : : }
704 : :
705 : : static void
706 : 0 : add_geneve_header(uint8_t **header, uint64_t data,
707 : : struct additional_para para)
708 : : {
709 : : struct rte_geneve_hdr geneve_hdr;
710 : 0 : uint32_t vni_value = para.counter;
711 : : uint8_t i;
712 : :
713 : 0 : if (!(data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GENEVE)))
714 : 0 : return;
715 : :
716 : : /* Fixed value */
717 : 0 : if (!para.unique_data)
718 : : vni_value = 1;
719 : :
720 : : memset(&geneve_hdr, 0, sizeof(struct rte_geneve_hdr));
721 : :
722 : 0 : for (i = 0; i < 3; i++)
723 : 0 : geneve_hdr.vni[2 - i] = vni_value >> (i * 8);
724 : :
725 : 0 : memcpy(*header, &geneve_hdr, sizeof(geneve_hdr));
726 : 0 : *header += sizeof(geneve_hdr);
727 : : }
728 : :
729 : : static void
730 : 0 : add_gtp_header(uint8_t **header, uint64_t data,
731 : : struct additional_para para)
732 : : {
733 : : struct rte_gtp_hdr gtp_hdr;
734 : 0 : uint32_t teid_value = para.counter;
735 : :
736 : 0 : if (!(data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GTP)))
737 : 0 : return;
738 : :
739 : : /* Fixed value */
740 : 0 : if (!para.unique_data)
741 : : teid_value = 1;
742 : :
743 : : memset(>p_hdr, 0, sizeof(struct rte_flow_item_gtp));
744 : :
745 : 0 : gtp_hdr.teid = RTE_BE32(teid_value);
746 : 0 : gtp_hdr.msg_type = 255;
747 : :
748 : 0 : memcpy(*header, >p_hdr, sizeof(gtp_hdr));
749 : 0 : *header += sizeof(gtp_hdr);
750 : : }
751 : :
752 : : static const struct encap_decap_headers {
753 : : void (*funct)(
754 : : uint8_t **header,
755 : : uint64_t data,
756 : : struct additional_para para
757 : : );
758 : : } headers[] = {
759 : : {.funct = add_ether_header},
760 : : {.funct = add_vlan_header},
761 : : {.funct = add_ipv4_header},
762 : : {.funct = add_ipv6_header},
763 : : {.funct = add_udp_header},
764 : : {.funct = add_vxlan_header},
765 : : {.funct = add_vxlan_gpe_header},
766 : : {.funct = add_gre_header},
767 : : {.funct = add_geneve_header},
768 : : {.funct = add_gtp_header},
769 : : };
770 : :
771 : : static void
772 : 0 : add_raw_encap(struct rte_flow_action *actions,
773 : : uint8_t actions_counter,
774 : : struct additional_para para)
775 : : {
776 : : static alignas(RTE_CACHE_LINE_SIZE)
777 : : struct action_raw_encap_data *action_encap_data[RTE_MAX_LCORE];
778 : 0 : uint64_t encap_data = para.encap_data;
779 : : uint8_t *header;
780 : : uint8_t i;
781 : :
782 : : /* Avoid double allocation. */
783 : 0 : if (action_encap_data[para.core_idx] == NULL)
784 : 0 : action_encap_data[para.core_idx] = rte_malloc("encap_data",
785 : : sizeof(struct action_raw_encap_data), 0);
786 : :
787 : : /* Check if allocation failed. */
788 : 0 : if (action_encap_data[para.core_idx] == NULL)
789 : 0 : rte_exit(EXIT_FAILURE, "No Memory available!");
790 : :
791 : 0 : *action_encap_data[para.core_idx] = (struct action_raw_encap_data) {
792 : : .conf = (struct rte_flow_action_raw_encap) {
793 : 0 : .data = action_encap_data[para.core_idx]->data,
794 : : },
795 : : .data = {},
796 : : };
797 : 0 : header = action_encap_data[para.core_idx]->data;
798 : :
799 : 0 : for (i = 0; i < RTE_DIM(headers); i++)
800 : 0 : headers[i].funct(&header, encap_data, para);
801 : :
802 : 0 : action_encap_data[para.core_idx]->conf.size = header -
803 : 0 : action_encap_data[para.core_idx]->data;
804 : :
805 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_RAW_ENCAP;
806 : 0 : actions[actions_counter].conf = &action_encap_data[para.core_idx]->conf;
807 : 0 : }
808 : :
809 : : static void
810 : 0 : add_raw_decap(struct rte_flow_action *actions,
811 : : uint8_t actions_counter,
812 : : struct additional_para para)
813 : : {
814 : : static alignas(RTE_CACHE_LINE_SIZE)
815 : : struct action_raw_decap_data *action_decap_data[RTE_MAX_LCORE];
816 : 0 : uint64_t decap_data = para.decap_data;
817 : : uint8_t *header;
818 : : uint8_t i;
819 : :
820 : : /* Avoid double allocation. */
821 : 0 : if (action_decap_data[para.core_idx] == NULL)
822 : 0 : action_decap_data[para.core_idx] = rte_malloc("decap_data",
823 : : sizeof(struct action_raw_decap_data), 0);
824 : :
825 : : /* Check if allocation failed. */
826 : 0 : if (action_decap_data[para.core_idx] == NULL)
827 : 0 : rte_exit(EXIT_FAILURE, "No Memory available!");
828 : :
829 : 0 : *action_decap_data[para.core_idx] = (struct action_raw_decap_data) {
830 : : .conf = (struct rte_flow_action_raw_decap) {
831 : 0 : .data = action_decap_data[para.core_idx]->data,
832 : : },
833 : : .data = {},
834 : : };
835 : 0 : header = action_decap_data[para.core_idx]->data;
836 : :
837 : 0 : for (i = 0; i < RTE_DIM(headers); i++)
838 : 0 : headers[i].funct(&header, decap_data, para);
839 : :
840 : 0 : action_decap_data[para.core_idx]->conf.size = header -
841 : 0 : action_decap_data[para.core_idx]->data;
842 : :
843 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_RAW_DECAP;
844 : 0 : actions[actions_counter].conf = &action_decap_data[para.core_idx]->conf;
845 : 0 : }
846 : :
847 : : static void
848 : 0 : add_vxlan_encap(struct rte_flow_action *actions,
849 : : uint8_t actions_counter,
850 : : __rte_unused struct additional_para para)
851 : : {
852 : : static alignas(RTE_CACHE_LINE_SIZE)
853 : : struct rte_flow_action_vxlan_encap vxlan_encap[RTE_MAX_LCORE];
854 : : static struct rte_flow_item items[5];
855 : : static struct rte_flow_item_eth item_eth;
856 : : static struct rte_flow_item_ipv4 item_ipv4;
857 : : static struct rte_flow_item_udp item_udp;
858 : : static struct rte_flow_item_vxlan item_vxlan;
859 : 0 : uint32_t ip_dst = para.counter;
860 : :
861 : : /* Fixed value */
862 : 0 : if (!para.unique_data)
863 : : ip_dst = 1;
864 : :
865 : 0 : items[0].spec = &item_eth;
866 : 0 : items[0].mask = &item_eth;
867 : 0 : items[0].type = RTE_FLOW_ITEM_TYPE_ETH;
868 : :
869 : 0 : item_ipv4.hdr.src_addr = RTE_IPV4(127, 0, 0, 1);
870 : 0 : item_ipv4.hdr.dst_addr = RTE_BE32(ip_dst);
871 : 0 : item_ipv4.hdr.version_ihl = RTE_IPV4_VHL_DEF;
872 : 0 : items[1].spec = &item_ipv4;
873 : 0 : items[1].mask = &item_ipv4;
874 : 0 : items[1].type = RTE_FLOW_ITEM_TYPE_IPV4;
875 : :
876 : :
877 : 0 : item_udp.hdr.dst_port = RTE_BE16(RTE_VXLAN_DEFAULT_PORT);
878 : 0 : items[2].spec = &item_udp;
879 : 0 : items[2].mask = &item_udp;
880 : 0 : items[2].type = RTE_FLOW_ITEM_TYPE_UDP;
881 : :
882 : :
883 : 0 : item_vxlan.hdr.vni[2] = 1;
884 : 0 : items[3].spec = &item_vxlan;
885 : 0 : items[3].mask = &item_vxlan;
886 : 0 : items[3].type = RTE_FLOW_ITEM_TYPE_VXLAN;
887 : :
888 : 0 : items[4].type = RTE_FLOW_ITEM_TYPE_END;
889 : :
890 : 0 : vxlan_encap[para.core_idx].definition = items;
891 : :
892 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP;
893 : 0 : actions[actions_counter].conf = &vxlan_encap[para.core_idx];
894 : 0 : }
895 : :
896 : : static void
897 : 0 : add_vxlan_decap(struct rte_flow_action *actions,
898 : : uint8_t actions_counter,
899 : : __rte_unused struct additional_para para)
900 : : {
901 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_VXLAN_DECAP;
902 : 0 : }
903 : :
904 : : static void
905 : 0 : add_meter(struct rte_flow_action *actions,
906 : : uint8_t actions_counter,
907 : : __rte_unused struct additional_para para)
908 : : {
909 : : static alignas(RTE_CACHE_LINE_SIZE) struct rte_flow_action_meter
910 : : meters[RTE_MAX_LCORE];
911 : :
912 : 0 : meters[para.core_idx].mtr_id = para.counter;
913 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_METER;
914 : 0 : actions[actions_counter].conf = &meters[para.core_idx];
915 : 0 : }
916 : :
917 : : void
918 : 0 : fill_actions(struct rte_flow_action *actions, uint64_t *flow_actions,
919 : : uint32_t counter, uint16_t next_table, uint16_t hairpinq,
920 : : uint64_t encap_data, uint64_t decap_data, uint8_t core_idx,
921 : : bool unique_data, uint8_t rx_queues_count, uint16_t dst_port)
922 : : {
923 : : struct additional_para additional_para_data;
924 : : uint8_t actions_counter = 0;
925 : : uint16_t *hairpin_queues;
926 : : uint16_t *queues;
927 : : uint16_t i, j;
928 : :
929 : 0 : hairpin_queues = calloc(hairpinq, sizeof(uint16_t));
930 : 0 : if (hairpin_queues == NULL)
931 : 0 : rte_exit(EXIT_FAILURE, "No Memory available!");
932 : 0 : queues = calloc(rx_queues_count, sizeof(uint16_t));
933 : 0 : if (queues == NULL) {
934 : 0 : free(hairpin_queues);
935 : 0 : rte_exit(EXIT_FAILURE, "No Memory available!");
936 : : }
937 : :
938 : 0 : for (i = 0; i < rx_queues_count; i++)
939 : 0 : queues[i] = i;
940 : :
941 : 0 : for (i = 0; i < hairpinq; i++)
942 : 0 : hairpin_queues[i] = i + rx_queues_count;
943 : :
944 : 0 : additional_para_data = (struct additional_para){
945 : 0 : .queue = counter % rx_queues_count,
946 : : .next_table = next_table,
947 : : .queues = queues,
948 : : .queues_number = rx_queues_count,
949 : : .counter = counter,
950 : : .encap_data = encap_data,
951 : : .decap_data = decap_data,
952 : : .core_idx = core_idx,
953 : : .unique_data = unique_data,
954 : : .dst_port = dst_port,
955 : : };
956 : :
957 : 0 : if (hairpinq != 0) {
958 : 0 : additional_para_data.queues = hairpin_queues;
959 : 0 : additional_para_data.queues_number = hairpinq;
960 : 0 : additional_para_data.queue = (counter % hairpinq) + rx_queues_count;
961 : : }
962 : :
963 : : static const struct actions_dict {
964 : : uint64_t mask;
965 : : void (*funct)(
966 : : struct rte_flow_action *actions,
967 : : uint8_t actions_counter,
968 : : struct additional_para para
969 : : );
970 : : } actions_list[] = {
971 : : {
972 : : .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_MARK),
973 : : .funct = add_mark,
974 : : },
975 : : {
976 : : .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_COUNT),
977 : : .funct = add_count,
978 : : },
979 : : {
980 : : .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_META),
981 : : .funct = add_set_meta,
982 : : },
983 : : {
984 : : .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_TAG),
985 : : .funct = add_set_tag,
986 : : },
987 : : {
988 : : .mask = FLOW_ACTION_MASK(
989 : : RTE_FLOW_ACTION_TYPE_FLAG
990 : : ),
991 : : .funct = add_flag,
992 : : },
993 : : {
994 : : .mask = FLOW_ACTION_MASK(
995 : : RTE_FLOW_ACTION_TYPE_SET_MAC_SRC
996 : : ),
997 : : .funct = add_set_src_mac,
998 : : },
999 : : {
1000 : : .mask = FLOW_ACTION_MASK(
1001 : : RTE_FLOW_ACTION_TYPE_SET_MAC_DST
1002 : : ),
1003 : : .funct = add_set_dst_mac,
1004 : : },
1005 : : {
1006 : : .mask = FLOW_ACTION_MASK(
1007 : : RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC
1008 : : ),
1009 : : .funct = add_set_src_ipv4,
1010 : : },
1011 : : {
1012 : : .mask = FLOW_ACTION_MASK(
1013 : : RTE_FLOW_ACTION_TYPE_SET_IPV4_DST
1014 : : ),
1015 : : .funct = add_set_dst_ipv4,
1016 : : },
1017 : : {
1018 : : .mask = FLOW_ACTION_MASK(
1019 : : RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC
1020 : : ),
1021 : : .funct = add_set_src_ipv6,
1022 : : },
1023 : : {
1024 : : .mask = FLOW_ACTION_MASK(
1025 : : RTE_FLOW_ACTION_TYPE_SET_IPV6_DST
1026 : : ),
1027 : : .funct = add_set_dst_ipv6,
1028 : : },
1029 : : {
1030 : : .mask = FLOW_ACTION_MASK(
1031 : : RTE_FLOW_ACTION_TYPE_SET_TP_SRC
1032 : : ),
1033 : : .funct = add_set_src_tp,
1034 : : },
1035 : : {
1036 : : .mask = FLOW_ACTION_MASK(
1037 : : RTE_FLOW_ACTION_TYPE_SET_TP_DST
1038 : : ),
1039 : : .funct = add_set_dst_tp,
1040 : : },
1041 : : {
1042 : : .mask = FLOW_ACTION_MASK(
1043 : : RTE_FLOW_ACTION_TYPE_INC_TCP_ACK
1044 : : ),
1045 : : .funct = add_inc_tcp_ack,
1046 : : },
1047 : : {
1048 : : .mask = FLOW_ACTION_MASK(
1049 : : RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK
1050 : : ),
1051 : : .funct = add_dec_tcp_ack,
1052 : : },
1053 : : {
1054 : : .mask = FLOW_ACTION_MASK(
1055 : : RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ
1056 : : ),
1057 : : .funct = add_inc_tcp_seq,
1058 : : },
1059 : : {
1060 : : .mask = FLOW_ACTION_MASK(
1061 : : RTE_FLOW_ACTION_TYPE_DEC_TCP_SEQ
1062 : : ),
1063 : : .funct = add_dec_tcp_seq,
1064 : : },
1065 : : {
1066 : : .mask = FLOW_ACTION_MASK(
1067 : : RTE_FLOW_ACTION_TYPE_SET_TTL
1068 : : ),
1069 : : .funct = add_set_ttl,
1070 : : },
1071 : : {
1072 : : .mask = FLOW_ACTION_MASK(
1073 : : RTE_FLOW_ACTION_TYPE_DEC_TTL
1074 : : ),
1075 : : .funct = add_dec_ttl,
1076 : : },
1077 : : {
1078 : : .mask = FLOW_ACTION_MASK(
1079 : : RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP
1080 : : ),
1081 : : .funct = add_set_ipv4_dscp,
1082 : : },
1083 : : {
1084 : : .mask = FLOW_ACTION_MASK(
1085 : : RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP
1086 : : ),
1087 : : .funct = add_set_ipv6_dscp,
1088 : : },
1089 : : {
1090 : : .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_QUEUE),
1091 : : .funct = add_queue,
1092 : : },
1093 : : {
1094 : : .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_RSS),
1095 : : .funct = add_rss,
1096 : : },
1097 : : {
1098 : : .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_JUMP),
1099 : : .funct = add_jump,
1100 : : },
1101 : : {
1102 : : .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_PORT_ID),
1103 : : .funct = add_port_id
1104 : : },
1105 : : {
1106 : : .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_DROP),
1107 : : .funct = add_drop,
1108 : : },
1109 : : {
1110 : : .mask = HAIRPIN_QUEUE_ACTION,
1111 : : .funct = add_queue,
1112 : : },
1113 : : {
1114 : : .mask = HAIRPIN_RSS_ACTION,
1115 : : .funct = add_rss,
1116 : : },
1117 : : {
1118 : : .mask = FLOW_ACTION_MASK(
1119 : : RTE_FLOW_ACTION_TYPE_RAW_ENCAP
1120 : : ),
1121 : : .funct = add_raw_encap,
1122 : : },
1123 : : {
1124 : : .mask = FLOW_ACTION_MASK(
1125 : : RTE_FLOW_ACTION_TYPE_RAW_DECAP
1126 : : ),
1127 : : .funct = add_raw_decap,
1128 : : },
1129 : : {
1130 : : .mask = FLOW_ACTION_MASK(
1131 : : RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP
1132 : : ),
1133 : : .funct = add_vxlan_encap,
1134 : : },
1135 : : {
1136 : : .mask = FLOW_ACTION_MASK(
1137 : : RTE_FLOW_ACTION_TYPE_VXLAN_DECAP
1138 : : ),
1139 : : .funct = add_vxlan_decap,
1140 : : },
1141 : : {
1142 : : .mask = FLOW_ACTION_MASK(
1143 : : RTE_FLOW_ACTION_TYPE_METER
1144 : : ),
1145 : : .funct = add_meter,
1146 : : },
1147 : : };
1148 : :
1149 : 0 : for (j = 0; j < MAX_ACTIONS_NUM; j++) {
1150 : 0 : if (flow_actions[j] == 0)
1151 : : break;
1152 : 0 : for (i = 0; i < RTE_DIM(actions_list); i++) {
1153 : 0 : if ((flow_actions[j] &
1154 : 0 : actions_list[i].mask) == 0)
1155 : : continue;
1156 : 0 : actions_list[i].funct(
1157 : 0 : actions, actions_counter++,
1158 : : additional_para_data
1159 : : );
1160 : 0 : break;
1161 : : }
1162 : : }
1163 : 0 : actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_END;
1164 : :
1165 : 0 : free(queues);
1166 : 0 : free(hairpin_queues);
1167 : 0 : }
|