3ae6059fb1790e9eba44f410879e50543bfec3ed
[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
16 #include "actions_gen.h"
17 #include "flow_gen.h"
18 #include "config.h"
19
20 /* Storage for additional parameters for actions */
21 struct additional_para {
22         uint16_t queue;
23         uint16_t next_table;
24         uint16_t *queues;
25         uint16_t queues_number;
26         uint32_t counter;
27         uint64_t encap_data;
28         uint64_t decap_data;
29 };
30
31 /* Storage for struct rte_flow_action_raw_encap including external data. */
32 struct action_raw_encap_data {
33         struct rte_flow_action_raw_encap conf;
34         uint8_t data[128];
35         uint8_t preserve[128];
36         uint16_t idx;
37 };
38
39 /* Storage for struct rte_flow_action_raw_decap including external data. */
40 struct action_raw_decap_data {
41         struct rte_flow_action_raw_decap conf;
42         uint8_t data[128];
43         uint16_t idx;
44 };
45
46 /* Storage for struct rte_flow_action_rss including external data. */
47 struct action_rss_data {
48         struct rte_flow_action_rss conf;
49         uint8_t key[40];
50         uint16_t queue[128];
51 };
52
53 static void
54 add_mark(struct rte_flow_action *actions,
55         uint8_t actions_counter,
56         __rte_unused struct additional_para para)
57 {
58         static struct rte_flow_action_mark mark_action;
59
60         do {
61                 mark_action.id = MARK_ID;
62         } while (0);
63
64         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_MARK;
65         actions[actions_counter].conf = &mark_action;
66 }
67
68 static void
69 add_queue(struct rte_flow_action *actions,
70         uint8_t actions_counter,
71         struct additional_para para)
72 {
73         static struct rte_flow_action_queue queue_action;
74
75         do {
76                 queue_action.index = para.queue;
77         } while (0);
78
79         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_QUEUE;
80         actions[actions_counter].conf = &queue_action;
81 }
82
83 static void
84 add_jump(struct rte_flow_action *actions,
85         uint8_t actions_counter,
86         struct additional_para para)
87 {
88         static struct rte_flow_action_jump jump_action;
89
90         do {
91                 jump_action.group = para.next_table;
92         } while (0);
93
94         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_JUMP;
95         actions[actions_counter].conf = &jump_action;
96 }
97
98 static void
99 add_rss(struct rte_flow_action *actions,
100         uint8_t actions_counter,
101         struct additional_para para)
102 {
103         static struct rte_flow_action_rss *rss_action;
104         static struct action_rss_data *rss_data;
105
106         uint16_t queue;
107
108         if (rss_data == NULL)
109                 rss_data = rte_malloc("rss_data",
110                         sizeof(struct action_rss_data), 0);
111
112         if (rss_data == NULL)
113                 rte_exit(EXIT_FAILURE, "No Memory available!");
114
115         *rss_data = (struct action_rss_data){
116                 .conf = (struct rte_flow_action_rss){
117                         .func = RTE_ETH_HASH_FUNCTION_DEFAULT,
118                         .level = 0,
119                         .types = GET_RSS_HF(),
120                         .key_len = sizeof(rss_data->key),
121                         .queue_num = para.queues_number,
122                         .key = rss_data->key,
123                         .queue = rss_data->queue,
124                 },
125                 .key = { 1 },
126                 .queue = { 0 },
127         };
128
129         for (queue = 0; queue < para.queues_number; queue++)
130                 rss_data->queue[queue] = para.queues[queue];
131
132         rss_action = &rss_data->conf;
133
134         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_RSS;
135         actions[actions_counter].conf = rss_action;
136 }
137
138 static void
139 add_set_meta(struct rte_flow_action *actions,
140         uint8_t actions_counter,
141         __rte_unused struct additional_para para)
142 {
143         static struct rte_flow_action_set_meta meta_action;
144
145         do {
146                 meta_action.data = RTE_BE32(META_DATA);
147                 meta_action.mask = RTE_BE32(0xffffffff);
148         } while (0);
149
150         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_META;
151         actions[actions_counter].conf = &meta_action;
152 }
153
154 static void
155 add_set_tag(struct rte_flow_action *actions,
156         uint8_t actions_counter,
157         __rte_unused struct additional_para para)
158 {
159         static struct rte_flow_action_set_tag tag_action;
160
161         do {
162                 tag_action.data = RTE_BE32(META_DATA);
163                 tag_action.mask = RTE_BE32(0xffffffff);
164                 tag_action.index = TAG_INDEX;
165         } while (0);
166
167         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_TAG;
168         actions[actions_counter].conf = &tag_action;
169 }
170
171 static void
172 add_port_id(struct rte_flow_action *actions,
173         uint8_t actions_counter,
174         __rte_unused struct additional_para para)
175 {
176         static struct rte_flow_action_port_id port_id;
177
178         do {
179                 port_id.id = PORT_ID_DST;
180         } while (0);
181
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         __rte_unused struct additional_para para)
209 {
210         static struct rte_flow_action_set_mac set_mac;
211         uint32_t mac = para.counter;
212         uint16_t i;
213
214         /* Mac address to be set is random each time */
215         for (i = 0; i < RTE_ETHER_ADDR_LEN; i++) {
216                 set_mac.mac_addr[i] = mac & 0xff;
217                 mac = mac >> 8;
218         }
219
220         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_MAC_SRC;
221         actions[actions_counter].conf = &set_mac;
222 }
223
224 static void
225 add_set_dst_mac(struct rte_flow_action *actions,
226         uint8_t actions_counter,
227         __rte_unused struct additional_para para)
228 {
229         static struct rte_flow_action_set_mac set_mac;
230         uint32_t mac = para.counter;
231         uint16_t i;
232
233         /* Mac address to be set is random each time */
234         for (i = 0; i < RTE_ETHER_ADDR_LEN; i++) {
235                 set_mac.mac_addr[i] = mac & 0xff;
236                 mac = mac >> 8;
237         }
238
239         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_MAC_DST;
240         actions[actions_counter].conf = &set_mac;
241 }
242
243 static void
244 add_set_src_ipv4(struct rte_flow_action *actions,
245         uint8_t actions_counter,
246         __rte_unused struct additional_para para)
247 {
248         static struct rte_flow_action_set_ipv4 set_ipv4;
249
250         /* IPv4 value to be set is random each time */
251         set_ipv4.ipv4_addr = RTE_BE32(para.counter + 1);
252
253         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC;
254         actions[actions_counter].conf = &set_ipv4;
255 }
256
257 static void
258 add_set_dst_ipv4(struct rte_flow_action *actions,
259         uint8_t actions_counter,
260         __rte_unused struct additional_para para)
261 {
262         static struct rte_flow_action_set_ipv4 set_ipv4;
263
264         /* IPv4 value to be set is random each time */
265         set_ipv4.ipv4_addr = RTE_BE32(para.counter + 1);
266
267         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV4_DST;
268         actions[actions_counter].conf = &set_ipv4;
269 }
270
271 static void
272 add_set_src_ipv6(struct rte_flow_action *actions,
273         uint8_t actions_counter,
274         __rte_unused struct additional_para para)
275 {
276         static struct rte_flow_action_set_ipv6 set_ipv6;
277         uint32_t ipv6 = para.counter;
278         uint8_t i;
279
280         /* IPv6 value to set is random each time */
281         for (i = 0; i < 16; i++) {
282                 set_ipv6.ipv6_addr[i] = ipv6 & 0xff;
283                 ipv6 = ipv6 >> 8;
284         }
285
286         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC;
287         actions[actions_counter].conf = &set_ipv6;
288 }
289
290 static void
291 add_set_dst_ipv6(struct rte_flow_action *actions,
292         uint8_t actions_counter,
293         __rte_unused struct additional_para para)
294 {
295         static struct rte_flow_action_set_ipv6 set_ipv6;
296         uint32_t ipv6 = para.counter;
297         uint8_t i;
298
299         /* IPv6 value to set is random each time */
300         for (i = 0; i < 16; i++) {
301                 set_ipv6.ipv6_addr[i] = ipv6 & 0xff;
302                 ipv6 = ipv6 >> 8;
303         }
304
305         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV6_DST;
306         actions[actions_counter].conf = &set_ipv6;
307 }
308
309 static void
310 add_set_src_tp(struct rte_flow_action *actions,
311         uint8_t actions_counter,
312         __rte_unused struct additional_para para)
313 {
314         static struct rte_flow_action_set_tp set_tp;
315         uint32_t tp = para.counter;
316
317         /* TP src port is random each time */
318         if (tp > 0xffff)
319                 tp = tp >> 16;
320
321         set_tp.port = RTE_BE16(tp & 0xffff);
322
323         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_TP_SRC;
324         actions[actions_counter].conf = &set_tp;
325 }
326
327 static void
328 add_set_dst_tp(struct rte_flow_action *actions,
329         uint8_t actions_counter,
330         __rte_unused struct additional_para para)
331 {
332         static struct rte_flow_action_set_tp set_tp;
333         uint32_t tp = para.counter;
334
335         /* TP src port is random each time */
336         if (tp > 0xffff)
337                 tp = tp >> 16;
338
339         set_tp.port = RTE_BE16(tp & 0xffff);
340
341         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_TP_DST;
342         actions[actions_counter].conf = &set_tp;
343 }
344
345 static void
346 add_inc_tcp_ack(struct rte_flow_action *actions,
347         uint8_t actions_counter,
348         __rte_unused struct additional_para para)
349 {
350         static rte_be32_t value = RTE_BE32(1);
351
352         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_INC_TCP_ACK;
353         actions[actions_counter].conf = &value;
354 }
355
356 static void
357 add_dec_tcp_ack(struct rte_flow_action *actions,
358         uint8_t actions_counter,
359         __rte_unused struct additional_para para)
360 {
361         static rte_be32_t value = RTE_BE32(1);
362
363         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK;
364         actions[actions_counter].conf = &value;
365 }
366
367 static void
368 add_inc_tcp_seq(struct rte_flow_action *actions,
369         uint8_t actions_counter,
370         __rte_unused struct additional_para para)
371 {
372         static rte_be32_t value = RTE_BE32(1);
373
374         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ;
375         actions[actions_counter].conf = &value;
376 }
377
378 static void
379 add_dec_tcp_seq(struct rte_flow_action *actions,
380         uint8_t actions_counter,
381         __rte_unused struct additional_para para)
382 {
383         static rte_be32_t value = RTE_BE32(1);
384
385         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_DEC_TCP_SEQ;
386         actions[actions_counter].conf = &value;
387 }
388
389 static void
390 add_set_ttl(struct rte_flow_action *actions,
391         uint8_t actions_counter,
392         __rte_unused struct additional_para para)
393 {
394         static struct rte_flow_action_set_ttl set_ttl;
395         uint32_t ttl_value = para.counter;
396
397         /* Set ttl to random value each time */
398         while (ttl_value > 0xff)
399                 ttl_value = ttl_value >> 8;
400
401         set_ttl.ttl_value = ttl_value;
402
403         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_TTL;
404         actions[actions_counter].conf = &set_ttl;
405 }
406
407 static void
408 add_dec_ttl(struct rte_flow_action *actions,
409         uint8_t actions_counter,
410         __rte_unused struct additional_para para)
411 {
412         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_DEC_TTL;
413 }
414
415 static void
416 add_set_ipv4_dscp(struct rte_flow_action *actions,
417         uint8_t actions_counter,
418         __rte_unused struct additional_para para)
419 {
420         static struct rte_flow_action_set_dscp set_dscp;
421         uint32_t dscp_value = para.counter;
422
423         /* Set dscp to random value each time */
424         while (dscp_value > 0xff)
425                 dscp_value = dscp_value >> 8;
426
427         set_dscp.dscp = dscp_value;
428
429         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP;
430         actions[actions_counter].conf = &set_dscp;
431 }
432
433 static void
434 add_set_ipv6_dscp(struct rte_flow_action *actions,
435         uint8_t actions_counter,
436         __rte_unused struct additional_para para)
437 {
438         static struct rte_flow_action_set_dscp set_dscp;
439         uint32_t dscp_value = para.counter;
440
441         /* Set dscp to random value each time */
442         while (dscp_value > 0xff)
443                 dscp_value = dscp_value >> 8;
444
445         set_dscp.dscp = dscp_value;
446
447         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP;
448         actions[actions_counter].conf = &set_dscp;
449 }
450
451 static void
452 add_flag(struct rte_flow_action *actions,
453         uint8_t actions_counter,
454         __rte_unused struct additional_para para)
455 {
456         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_FLAG;
457 }
458
459 static void
460 add_ether_header(uint8_t **header, uint64_t data,
461         __rte_unused struct additional_para para)
462 {
463         struct rte_flow_item_eth eth_item;
464
465         if (!(data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ETH)))
466                 return;
467
468         memset(&eth_item, 0, sizeof(struct rte_flow_item_eth));
469         if (data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VLAN))
470                 eth_item.type = RTE_BE16(RTE_ETHER_TYPE_VLAN);
471         else if (data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV4))
472                 eth_item.type = RTE_BE16(RTE_ETHER_TYPE_IPV4);
473         else if (data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV6))
474                 eth_item.type = RTE_BE16(RTE_ETHER_TYPE_IPV6);
475         memcpy(*header, &eth_item, sizeof(eth_item));
476         *header += sizeof(eth_item);
477 }
478
479 static void
480 add_vlan_header(uint8_t **header, uint64_t data,
481         __rte_unused struct additional_para para)
482 {
483         struct rte_flow_item_vlan vlan_item;
484         uint16_t vlan_value;
485
486         if (!(data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VLAN)))
487                 return;
488
489         vlan_value = VLAN_VALUE;
490
491         memset(&vlan_item, 0, sizeof(struct rte_flow_item_vlan));
492         vlan_item.tci = RTE_BE16(vlan_value);
493
494         if (data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV4))
495                 vlan_item.inner_type = RTE_BE16(RTE_ETHER_TYPE_IPV4);
496         if (data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV6))
497                 vlan_item.inner_type = RTE_BE16(RTE_ETHER_TYPE_IPV6);
498         memcpy(*header, &vlan_item, sizeof(vlan_item));
499         *header += sizeof(vlan_item);
500 }
501
502 static void
503 add_ipv4_header(uint8_t **header, uint64_t data,
504         struct additional_para para)
505 {
506         struct rte_flow_item_ipv4 ipv4_item;
507
508         if (!(data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV4)))
509                 return;
510
511         memset(&ipv4_item, 0, sizeof(struct rte_flow_item_ipv4));
512         ipv4_item.hdr.src_addr = RTE_IPV4(127, 0, 0, 1);
513         ipv4_item.hdr.dst_addr = RTE_BE32(para.counter);
514         ipv4_item.hdr.version_ihl = RTE_IPV4_VHL_DEF;
515         if (data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_UDP))
516                 ipv4_item.hdr.next_proto_id = RTE_IP_TYPE_UDP;
517         if (data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GRE))
518                 ipv4_item.hdr.next_proto_id = RTE_IP_TYPE_GRE;
519         memcpy(*header, &ipv4_item, sizeof(ipv4_item));
520         *header += sizeof(ipv4_item);
521 }
522
523 static void
524 add_ipv6_header(uint8_t **header, uint64_t data,
525         __rte_unused struct additional_para para)
526 {
527         struct rte_flow_item_ipv6 ipv6_item;
528
529         if (!(data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV6)))
530                 return;
531
532         memset(&ipv6_item, 0, sizeof(struct rte_flow_item_ipv6));
533         if (data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_UDP))
534                 ipv6_item.hdr.proto = RTE_IP_TYPE_UDP;
535         if (data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GRE))
536                 ipv6_item.hdr.proto = RTE_IP_TYPE_GRE;
537         memcpy(*header, &ipv6_item, sizeof(ipv6_item));
538         *header += sizeof(ipv6_item);
539 }
540
541 static void
542 add_udp_header(uint8_t **header, uint64_t data,
543         __rte_unused struct additional_para para)
544 {
545         struct rte_flow_item_udp udp_item;
546
547         if (!(data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_UDP)))
548                 return;
549
550         memset(&udp_item, 0, sizeof(struct rte_flow_item_udp));
551         if (data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN))
552                 udp_item.hdr.dst_port = RTE_BE16(RTE_VXLAN_DEFAULT_PORT);
553         if (data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN_GPE))
554                 udp_item.hdr.dst_port = RTE_BE16(RTE_VXLAN_GPE_UDP_PORT);
555         if (data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GENEVE))
556                 udp_item.hdr.dst_port = RTE_BE16(RTE_GENEVE_UDP_PORT);
557         if (data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GTP))
558                 udp_item.hdr.dst_port = RTE_BE16(RTE_GTPU_UDP_PORT);
559          memcpy(*header, &udp_item, sizeof(udp_item));
560          *header += sizeof(udp_item);
561 }
562
563 static void
564 add_vxlan_header(uint8_t **header, uint64_t data,
565         struct additional_para para)
566 {
567         struct rte_flow_item_vxlan vxlan_item;
568         uint32_t vni_value = para.counter;
569         uint8_t i;
570
571         if (!(data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN)))
572                 return;
573
574         memset(&vxlan_item, 0, sizeof(struct rte_flow_item_vxlan));
575
576         for (i = 0; i < 3; i++)
577                 vxlan_item.vni[2 - i] = vni_value >> (i * 8);
578         vxlan_item.flags = 0x8;
579
580         memcpy(*header, &vxlan_item, sizeof(vxlan_item));
581         *header += sizeof(vxlan_item);
582 }
583
584 static void
585 add_vxlan_gpe_header(uint8_t **header, uint64_t data,
586         struct additional_para para)
587 {
588         struct rte_flow_item_vxlan_gpe vxlan_gpe_item;
589         uint32_t vni_value = para.counter;
590         uint8_t i;
591
592         if (!(data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN_GPE)))
593                 return;
594
595         memset(&vxlan_gpe_item, 0, sizeof(struct rte_flow_item_vxlan_gpe));
596
597         for (i = 0; i < 3; i++)
598                 vxlan_gpe_item.vni[2 - i] = vni_value >> (i * 8);
599         vxlan_gpe_item.flags = 0x0c;
600
601         memcpy(*header, &vxlan_gpe_item, sizeof(vxlan_gpe_item));
602         *header += sizeof(vxlan_gpe_item);
603 }
604
605 static void
606 add_gre_header(uint8_t **header, uint64_t data,
607         __rte_unused struct additional_para para)
608 {
609         struct rte_flow_item_gre gre_item;
610
611         if (!(data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GRE)))
612                 return;
613
614         memset(&gre_item, 0, sizeof(struct rte_flow_item_gre));
615
616         gre_item.protocol = RTE_BE16(RTE_ETHER_TYPE_TEB);
617
618         memcpy(*header, &gre_item, sizeof(gre_item));
619         *header += sizeof(gre_item);
620 }
621
622 static void
623 add_geneve_header(uint8_t **header, uint64_t data,
624         struct additional_para para)
625 {
626         struct rte_flow_item_geneve geneve_item;
627         uint32_t vni_value = para.counter;
628         uint8_t i;
629
630         if (!(data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GENEVE)))
631                 return;
632
633         memset(&geneve_item, 0, sizeof(struct rte_flow_item_geneve));
634
635         for (i = 0; i < 3; i++)
636                 geneve_item.vni[2 - i] = vni_value >> (i * 8);
637
638         memcpy(*header, &geneve_item, sizeof(geneve_item));
639         *header += sizeof(geneve_item);
640 }
641
642 static void
643 add_gtp_header(uint8_t **header, uint64_t data,
644         struct additional_para para)
645 {
646         struct rte_flow_item_gtp gtp_item;
647
648         if (!(data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GTP)))
649                 return;
650
651         memset(&gtp_item, 0, sizeof(struct rte_flow_item_gtp));
652
653         gtp_item.teid = RTE_BE32(para.counter);
654         gtp_item.msg_type = 255;
655
656         memcpy(*header, &gtp_item, sizeof(gtp_item));
657         *header += sizeof(gtp_item);
658 }
659
660 static const struct encap_decap_headers {
661         void (*funct)(
662                 uint8_t **header,
663                 uint64_t data,
664                 struct additional_para para
665                 );
666 } headers[] = {
667         {.funct = add_ether_header},
668         {.funct = add_vlan_header},
669         {.funct = add_ipv4_header},
670         {.funct = add_ipv6_header},
671         {.funct = add_udp_header},
672         {.funct = add_vxlan_header},
673         {.funct = add_vxlan_gpe_header},
674         {.funct = add_gre_header},
675         {.funct = add_geneve_header},
676         {.funct = add_gtp_header},
677 };
678
679 static void
680 add_raw_encap(struct rte_flow_action *actions,
681         uint8_t actions_counter,
682         struct additional_para para)
683 {
684         static struct action_raw_encap_data *action_encap_data;
685         uint64_t encap_data = para.encap_data;
686         uint8_t *header;
687         uint8_t i;
688
689         /* Avoid double allocation. */
690         if (action_encap_data == NULL)
691                 action_encap_data = rte_malloc("encap_data",
692                         sizeof(struct action_raw_encap_data), 0);
693
694         /* Check if allocation failed. */
695         if (action_encap_data == NULL)
696                 rte_exit(EXIT_FAILURE, "No Memory available!");
697
698         *action_encap_data = (struct action_raw_encap_data) {
699                 .conf = (struct rte_flow_action_raw_encap) {
700                         .data = action_encap_data->data,
701                 },
702                         .data = {},
703         };
704         header = action_encap_data->data;
705
706         for (i = 0; i < RTE_DIM(headers); i++)
707                 headers[i].funct(&header, encap_data, para);
708
709         action_encap_data->conf.size = header -
710                 action_encap_data->data;
711
712         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_RAW_ENCAP;
713         actions[actions_counter].conf = &action_encap_data->conf;
714 }
715
716 static void
717 add_raw_decap(struct rte_flow_action *actions,
718         uint8_t actions_counter,
719         struct additional_para para)
720 {
721         static struct action_raw_decap_data *action_decap_data;
722         uint64_t decap_data = para.decap_data;
723         uint8_t *header;
724         uint8_t i;
725
726         /* Avoid double allocation. */
727         if (action_decap_data == NULL)
728                 action_decap_data = rte_malloc("decap_data",
729                         sizeof(struct action_raw_decap_data), 0);
730
731         /* Check if allocation failed. */
732         if (action_decap_data == NULL)
733                 rte_exit(EXIT_FAILURE, "No Memory available!");
734
735         *action_decap_data = (struct action_raw_decap_data) {
736                 .conf = (struct rte_flow_action_raw_decap) {
737                         .data = action_decap_data->data,
738                 },
739                         .data = {},
740         };
741         header = action_decap_data->data;
742
743         for (i = 0; i < RTE_DIM(headers); i++)
744                 headers[i].funct(&header, decap_data, para);
745
746         action_decap_data->conf.size = header -
747                 action_decap_data->data;
748
749         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_RAW_DECAP;
750         actions[actions_counter].conf = &action_decap_data->conf;
751 }
752
753 void
754 fill_actions(struct rte_flow_action *actions, uint64_t *flow_actions,
755         uint32_t counter, uint16_t next_table, uint16_t hairpinq,
756         uint64_t encap_data, uint64_t decap_data)
757 {
758         struct additional_para additional_para_data;
759         uint8_t actions_counter = 0;
760         uint16_t hairpin_queues[hairpinq];
761         uint16_t queues[RXQ_NUM];
762         uint16_t i, j;
763
764         for (i = 0; i < RXQ_NUM; i++)
765                 queues[i] = i;
766
767         for (i = 0; i < hairpinq; i++)
768                 hairpin_queues[i] = i + RXQ_NUM;
769
770         additional_para_data = (struct additional_para){
771                 .queue = counter % RXQ_NUM,
772                 .next_table = next_table,
773                 .queues = queues,
774                 .queues_number = RXQ_NUM,
775                 .counter = counter,
776                 .encap_data = encap_data,
777                 .decap_data = decap_data,
778         };
779
780         if (hairpinq != 0) {
781                 additional_para_data.queues = hairpin_queues;
782                 additional_para_data.queues_number = hairpinq;
783                 additional_para_data.queue = (counter % hairpinq) + RXQ_NUM;
784         }
785
786         static const struct actions_dict {
787                 uint64_t mask;
788                 void (*funct)(
789                         struct rte_flow_action *actions,
790                         uint8_t actions_counter,
791                         struct additional_para para
792                         );
793         } actions_list[] = {
794                 {
795                         .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_MARK),
796                         .funct = add_mark,
797                 },
798                 {
799                         .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_COUNT),
800                         .funct = add_count,
801                 },
802                 {
803                         .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_META),
804                         .funct = add_set_meta,
805                 },
806                 {
807                         .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_TAG),
808                         .funct = add_set_tag,
809                 },
810                 {
811                         .mask = FLOW_ACTION_MASK(
812                                 RTE_FLOW_ACTION_TYPE_FLAG
813                         ),
814                         .funct = add_flag,
815                 },
816                 {
817                         .mask = FLOW_ACTION_MASK(
818                                 RTE_FLOW_ACTION_TYPE_SET_MAC_SRC
819                         ),
820                         .funct = add_set_src_mac,
821                 },
822                 {
823                         .mask = FLOW_ACTION_MASK(
824                                 RTE_FLOW_ACTION_TYPE_SET_MAC_DST
825                         ),
826                         .funct = add_set_dst_mac,
827                 },
828                 {
829                         .mask = FLOW_ACTION_MASK(
830                                 RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC
831                         ),
832                         .funct = add_set_src_ipv4,
833                 },
834                 {
835                         .mask = FLOW_ACTION_MASK(
836                                 RTE_FLOW_ACTION_TYPE_SET_IPV4_DST
837                         ),
838                         .funct = add_set_dst_ipv4,
839                 },
840                 {
841                         .mask = FLOW_ACTION_MASK(
842                                 RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC
843                         ),
844                         .funct = add_set_src_ipv6,
845                 },
846                 {
847                         .mask = FLOW_ACTION_MASK(
848                                 RTE_FLOW_ACTION_TYPE_SET_IPV6_DST
849                         ),
850                         .funct = add_set_dst_ipv6,
851                 },
852                 {
853                         .mask = FLOW_ACTION_MASK(
854                                 RTE_FLOW_ACTION_TYPE_SET_TP_SRC
855                         ),
856                         .funct = add_set_src_tp,
857                 },
858                 {
859                         .mask = FLOW_ACTION_MASK(
860                                 RTE_FLOW_ACTION_TYPE_SET_TP_DST
861                         ),
862                         .funct = add_set_dst_tp,
863                 },
864                 {
865                         .mask = FLOW_ACTION_MASK(
866                                 RTE_FLOW_ACTION_TYPE_INC_TCP_ACK
867                         ),
868                         .funct = add_inc_tcp_ack,
869                 },
870                 {
871                         .mask = FLOW_ACTION_MASK(
872                                 RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK
873                         ),
874                         .funct = add_dec_tcp_ack,
875                 },
876                 {
877                         .mask = FLOW_ACTION_MASK(
878                                 RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ
879                         ),
880                         .funct = add_inc_tcp_seq,
881                 },
882                 {
883                         .mask = FLOW_ACTION_MASK(
884                                 RTE_FLOW_ACTION_TYPE_DEC_TCP_SEQ
885                         ),
886                         .funct = add_dec_tcp_seq,
887                 },
888                 {
889                         .mask = FLOW_ACTION_MASK(
890                                 RTE_FLOW_ACTION_TYPE_SET_TTL
891                         ),
892                         .funct = add_set_ttl,
893                 },
894                 {
895                         .mask = FLOW_ACTION_MASK(
896                                 RTE_FLOW_ACTION_TYPE_DEC_TTL
897                         ),
898                         .funct = add_dec_ttl,
899                 },
900                 {
901                         .mask = FLOW_ACTION_MASK(
902                                 RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP
903                         ),
904                         .funct = add_set_ipv4_dscp,
905                 },
906                 {
907                         .mask = FLOW_ACTION_MASK(
908                                 RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP
909                         ),
910                         .funct = add_set_ipv6_dscp,
911                 },
912                 {
913                         .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_QUEUE),
914                         .funct = add_queue,
915                 },
916                 {
917                         .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_RSS),
918                         .funct = add_rss,
919                 },
920                 {
921                         .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_JUMP),
922                         .funct = add_jump,
923                 },
924                 {
925                         .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_PORT_ID),
926                         .funct = add_port_id
927                 },
928                 {
929                         .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_DROP),
930                         .funct = add_drop,
931                 },
932                 {
933                         .mask = HAIRPIN_QUEUE_ACTION,
934                         .funct = add_queue,
935                 },
936                 {
937                         .mask = HAIRPIN_RSS_ACTION,
938                         .funct = add_rss,
939                 },
940                 {
941                         .mask = FLOW_ACTION_MASK(
942                                 RTE_FLOW_ACTION_TYPE_RAW_ENCAP
943                         ),
944                         .funct = add_raw_encap,
945                 },
946                 {
947                         .mask = FLOW_ACTION_MASK(
948                                 RTE_FLOW_ACTION_TYPE_RAW_DECAP
949                         ),
950                         .funct = add_raw_decap,
951                 },
952         };
953
954         for (j = 0; j < MAX_ACTIONS_NUM; j++) {
955                 if (flow_actions[j] == 0)
956                         break;
957                 for (i = 0; i < RTE_DIM(actions_list); i++) {
958                         if ((flow_actions[j] &
959                                 actions_list[i].mask) == 0)
960                                 continue;
961                         actions_list[i].funct(
962                                 actions, actions_counter++,
963                                 additional_para_data
964                         );
965                         break;
966                 }
967         }
968         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_END;
969 }