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