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