9fe11abc9433ceb9ad59f5e4881bef4b01114b88
[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
14 #include "actions_gen.h"
15 #include "flow_gen.h"
16 #include "config.h"
17
18 /* Storage for additional parameters for actions */
19 struct additional_para {
20         uint16_t queue;
21         uint16_t next_table;
22         uint16_t *queues;
23         uint16_t queues_number;
24         uint32_t counter;
25 };
26
27 /* Storage for struct rte_flow_action_rss including external data. */
28 struct action_rss_data {
29         struct rte_flow_action_rss conf;
30         uint8_t key[40];
31         uint16_t queue[128];
32 };
33
34 static void
35 add_mark(struct rte_flow_action *actions,
36         uint8_t actions_counter,
37         __rte_unused struct additional_para para)
38 {
39         static struct rte_flow_action_mark mark_action;
40
41         do {
42                 mark_action.id = MARK_ID;
43         } while (0);
44
45         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_MARK;
46         actions[actions_counter].conf = &mark_action;
47 }
48
49 static void
50 add_queue(struct rte_flow_action *actions,
51         uint8_t actions_counter,
52         struct additional_para para)
53 {
54         static struct rte_flow_action_queue queue_action;
55
56         do {
57                 queue_action.index = para.queue;
58         } while (0);
59
60         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_QUEUE;
61         actions[actions_counter].conf = &queue_action;
62 }
63
64 static void
65 add_jump(struct rte_flow_action *actions,
66         uint8_t actions_counter,
67         struct additional_para para)
68 {
69         static struct rte_flow_action_jump jump_action;
70
71         do {
72                 jump_action.group = para.next_table;
73         } while (0);
74
75         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_JUMP;
76         actions[actions_counter].conf = &jump_action;
77 }
78
79 static void
80 add_rss(struct rte_flow_action *actions,
81         uint8_t actions_counter,
82         struct additional_para para)
83 {
84         static struct rte_flow_action_rss *rss_action;
85         static struct action_rss_data *rss_data;
86
87         uint16_t queue;
88
89         rss_data = rte_malloc("rss_data",
90                 sizeof(struct action_rss_data), 0);
91
92         if (rss_data == NULL)
93                 rte_exit(EXIT_FAILURE, "No Memory available!");
94
95         *rss_data = (struct action_rss_data){
96                 .conf = (struct rte_flow_action_rss){
97                         .func = RTE_ETH_HASH_FUNCTION_DEFAULT,
98                         .level = 0,
99                         .types = GET_RSS_HF(),
100                         .key_len = sizeof(rss_data->key),
101                         .queue_num = para.queues_number,
102                         .key = rss_data->key,
103                         .queue = rss_data->queue,
104                 },
105                 .key = { 1 },
106                 .queue = { 0 },
107         };
108
109         for (queue = 0; queue < para.queues_number; queue++)
110                 rss_data->queue[queue] = para.queues[queue];
111
112         rss_action = &rss_data->conf;
113
114         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_RSS;
115         actions[actions_counter].conf = rss_action;
116 }
117
118 static void
119 add_set_meta(struct rte_flow_action *actions,
120         uint8_t actions_counter,
121         __rte_unused struct additional_para para)
122 {
123         static struct rte_flow_action_set_meta meta_action;
124
125         do {
126                 meta_action.data = RTE_BE32(META_DATA);
127                 meta_action.mask = RTE_BE32(0xffffffff);
128         } while (0);
129
130         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_META;
131         actions[actions_counter].conf = &meta_action;
132 }
133
134 static void
135 add_set_tag(struct rte_flow_action *actions,
136         uint8_t actions_counter,
137         __rte_unused struct additional_para para)
138 {
139         static struct rte_flow_action_set_tag tag_action;
140
141         do {
142                 tag_action.data = RTE_BE32(META_DATA);
143                 tag_action.mask = RTE_BE32(0xffffffff);
144                 tag_action.index = TAG_INDEX;
145         } while (0);
146
147         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_TAG;
148         actions[actions_counter].conf = &tag_action;
149 }
150
151 static void
152 add_port_id(struct rte_flow_action *actions,
153         uint8_t actions_counter,
154         __rte_unused struct additional_para para)
155 {
156         static struct rte_flow_action_port_id port_id;
157
158         do {
159                 port_id.id = PORT_ID_DST;
160         } while (0);
161
162         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_PORT_ID;
163         actions[actions_counter].conf = &port_id;
164 }
165
166 static void
167 add_drop(struct rte_flow_action *actions,
168         uint8_t actions_counter,
169         __rte_unused struct additional_para para)
170 {
171         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_DROP;
172 }
173
174 static void
175 add_count(struct rte_flow_action *actions,
176         uint8_t actions_counter,
177         __rte_unused struct additional_para para)
178 {
179         static struct rte_flow_action_count count_action;
180
181         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_COUNT;
182         actions[actions_counter].conf = &count_action;
183 }
184
185 static void
186 add_set_src_mac(struct rte_flow_action *actions,
187         uint8_t actions_counter,
188         __rte_unused struct additional_para para)
189 {
190         static struct rte_flow_action_set_mac set_mac;
191         uint32_t mac = para.counter;
192         uint16_t i;
193
194         /* Mac address to be set is random each time */
195         for (i = 0; i < RTE_ETHER_ADDR_LEN; i++) {
196                 set_mac.mac_addr[i] = mac & 0xff;
197                 mac = mac >> 8;
198         }
199
200         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_MAC_SRC;
201         actions[actions_counter].conf = &set_mac;
202 }
203
204 static void
205 add_set_dst_mac(struct rte_flow_action *actions,
206         uint8_t actions_counter,
207         __rte_unused struct additional_para para)
208 {
209         static struct rte_flow_action_set_mac set_mac;
210         uint32_t mac = para.counter;
211         uint16_t i;
212
213         /* Mac address to be set is random each time */
214         for (i = 0; i < RTE_ETHER_ADDR_LEN; i++) {
215                 set_mac.mac_addr[i] = mac & 0xff;
216                 mac = mac >> 8;
217         }
218
219         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_MAC_DST;
220         actions[actions_counter].conf = &set_mac;
221 }
222
223 static void
224 add_set_src_ipv4(struct rte_flow_action *actions,
225         uint8_t actions_counter,
226         __rte_unused struct additional_para para)
227 {
228         static struct rte_flow_action_set_ipv4 set_ipv4;
229
230         /* IPv4 value to be set is random each time */
231         set_ipv4.ipv4_addr = RTE_BE32(para.counter + 1);
232
233         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC;
234         actions[actions_counter].conf = &set_ipv4;
235 }
236
237 static void
238 add_set_dst_ipv4(struct rte_flow_action *actions,
239         uint8_t actions_counter,
240         __rte_unused struct additional_para para)
241 {
242         static struct rte_flow_action_set_ipv4 set_ipv4;
243
244         /* IPv4 value to be set is random each time */
245         set_ipv4.ipv4_addr = RTE_BE32(para.counter + 1);
246
247         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV4_DST;
248         actions[actions_counter].conf = &set_ipv4;
249 }
250
251 static void
252 add_set_src_ipv6(struct rte_flow_action *actions,
253         uint8_t actions_counter,
254         __rte_unused struct additional_para para)
255 {
256         static struct rte_flow_action_set_ipv6 set_ipv6;
257         uint32_t ipv6 = para.counter;
258         uint8_t i;
259
260         /* IPv6 value to set is random each time */
261         for (i = 0; i < 16; i++) {
262                 set_ipv6.ipv6_addr[i] = ipv6 & 0xff;
263                 ipv6 = ipv6 >> 8;
264         }
265
266         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC;
267         actions[actions_counter].conf = &set_ipv6;
268 }
269
270 static void
271 add_set_dst_ipv6(struct rte_flow_action *actions,
272         uint8_t actions_counter,
273         __rte_unused struct additional_para para)
274 {
275         static struct rte_flow_action_set_ipv6 set_ipv6;
276         uint32_t ipv6 = para.counter;
277         uint8_t i;
278
279         /* IPv6 value to set is random each time */
280         for (i = 0; i < 16; i++) {
281                 set_ipv6.ipv6_addr[i] = ipv6 & 0xff;
282                 ipv6 = ipv6 >> 8;
283         }
284
285         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV6_DST;
286         actions[actions_counter].conf = &set_ipv6;
287 }
288
289 static void
290 add_set_src_tp(struct rte_flow_action *actions,
291         uint8_t actions_counter,
292         __rte_unused struct additional_para para)
293 {
294         static struct rte_flow_action_set_tp set_tp;
295         uint32_t tp = para.counter;
296
297         /* TP src port is random each time */
298         if (tp > 0xffff)
299                 tp = tp >> 16;
300
301         set_tp.port = RTE_BE16(tp & 0xffff);
302
303         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_TP_SRC;
304         actions[actions_counter].conf = &set_tp;
305 }
306
307 static void
308 add_set_dst_tp(struct rte_flow_action *actions,
309         uint8_t actions_counter,
310         __rte_unused struct additional_para para)
311 {
312         static struct rte_flow_action_set_tp set_tp;
313         uint32_t tp = para.counter;
314
315         /* TP src port is random each time */
316         if (tp > 0xffff)
317                 tp = tp >> 16;
318
319         set_tp.port = RTE_BE16(tp & 0xffff);
320
321         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_TP_DST;
322         actions[actions_counter].conf = &set_tp;
323 }
324
325 static void
326 add_inc_tcp_ack(struct rte_flow_action *actions,
327         uint8_t actions_counter,
328         __rte_unused struct additional_para para)
329 {
330         static rte_be32_t value = RTE_BE32(1);
331
332         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_INC_TCP_ACK;
333         actions[actions_counter].conf = &value;
334 }
335
336 static void
337 add_dec_tcp_ack(struct rte_flow_action *actions,
338         uint8_t actions_counter,
339         __rte_unused struct additional_para para)
340 {
341         static rte_be32_t value = RTE_BE32(1);
342
343         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK;
344         actions[actions_counter].conf = &value;
345 }
346
347 static void
348 add_inc_tcp_seq(struct rte_flow_action *actions,
349         uint8_t actions_counter,
350         __rte_unused struct additional_para para)
351 {
352         static rte_be32_t value = RTE_BE32(1);
353
354         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ;
355         actions[actions_counter].conf = &value;
356 }
357
358 static void
359 add_dec_tcp_seq(struct rte_flow_action *actions,
360         uint8_t actions_counter,
361         __rte_unused struct additional_para para)
362 {
363         static rte_be32_t value = RTE_BE32(1);
364
365         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_DEC_TCP_SEQ;
366         actions[actions_counter].conf = &value;
367 }
368
369 static void
370 add_set_ttl(struct rte_flow_action *actions,
371         uint8_t actions_counter,
372         __rte_unused struct additional_para para)
373 {
374         static struct rte_flow_action_set_ttl set_ttl;
375         uint32_t ttl_value = para.counter;
376
377         /* Set ttl to random value each time */
378         while (ttl_value > 0xff)
379                 ttl_value = ttl_value >> 8;
380
381         set_ttl.ttl_value = ttl_value;
382
383         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_TTL;
384         actions[actions_counter].conf = &set_ttl;
385 }
386
387 static void
388 add_dec_ttl(struct rte_flow_action *actions,
389         uint8_t actions_counter,
390         __rte_unused struct additional_para para)
391 {
392         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_DEC_TTL;
393 }
394
395 static void
396 add_set_ipv4_dscp(struct rte_flow_action *actions,
397         uint8_t actions_counter,
398         __rte_unused struct additional_para para)
399 {
400         static struct rte_flow_action_set_dscp set_dscp;
401         uint32_t dscp_value = para.counter;
402
403         /* Set dscp to random value each time */
404         while (dscp_value > 0xff)
405                 dscp_value = dscp_value >> 8;
406
407         set_dscp.dscp = dscp_value;
408
409         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP;
410         actions[actions_counter].conf = &set_dscp;
411 }
412
413 static void
414 add_set_ipv6_dscp(struct rte_flow_action *actions,
415         uint8_t actions_counter,
416         __rte_unused struct additional_para para)
417 {
418         static struct rte_flow_action_set_dscp set_dscp;
419         uint32_t dscp_value = para.counter;
420
421         /* Set dscp to random value each time */
422         while (dscp_value > 0xff)
423                 dscp_value = dscp_value >> 8;
424
425         set_dscp.dscp = dscp_value;
426
427         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP;
428         actions[actions_counter].conf = &set_dscp;
429 }
430
431 static void
432 add_flag(struct rte_flow_action *actions,
433         uint8_t actions_counter,
434         __rte_unused struct additional_para para)
435 {
436         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_FLAG;
437 }
438
439 void
440 fill_actions(struct rte_flow_action *actions, uint64_t *flow_actions,
441         uint32_t counter, uint16_t next_table, uint16_t hairpinq)
442 {
443         struct additional_para additional_para_data;
444         uint8_t actions_counter = 0;
445         uint16_t hairpin_queues[hairpinq];
446         uint16_t queues[RXQ_NUM];
447         uint16_t i, j;
448
449         for (i = 0; i < RXQ_NUM; i++)
450                 queues[i] = i;
451
452         for (i = 0; i < hairpinq; i++)
453                 hairpin_queues[i] = i + RXQ_NUM;
454
455         additional_para_data = (struct additional_para){
456                 .queue = counter % RXQ_NUM,
457                 .next_table = next_table,
458                 .queues = queues,
459                 .queues_number = RXQ_NUM,
460                 .counter = counter,
461         };
462
463         if (hairpinq != 0) {
464                 additional_para_data.queues = hairpin_queues;
465                 additional_para_data.queues_number = hairpinq;
466                 additional_para_data.queue = (counter % hairpinq) + RXQ_NUM;
467         }
468
469         static const struct actions_dict {
470                 uint64_t mask;
471                 void (*funct)(
472                         struct rte_flow_action *actions,
473                         uint8_t actions_counter,
474                         struct additional_para para
475                         );
476         } actions_list[] = {
477                 {
478                         .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_MARK),
479                         .funct = add_mark,
480                 },
481                 {
482                         .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_COUNT),
483                         .funct = add_count,
484                 },
485                 {
486                         .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_META),
487                         .funct = add_set_meta,
488                 },
489                 {
490                         .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_TAG),
491                         .funct = add_set_tag,
492                 },
493                 {
494                         .mask = FLOW_ACTION_MASK(
495                                 RTE_FLOW_ACTION_TYPE_FLAG
496                         ),
497                         .funct = add_flag,
498                 },
499                 {
500                         .mask = FLOW_ACTION_MASK(
501                                 RTE_FLOW_ACTION_TYPE_SET_MAC_SRC
502                         ),
503                         .funct = add_set_src_mac,
504                 },
505                 {
506                         .mask = FLOW_ACTION_MASK(
507                                 RTE_FLOW_ACTION_TYPE_SET_MAC_DST
508                         ),
509                         .funct = add_set_dst_mac,
510                 },
511                 {
512                         .mask = FLOW_ACTION_MASK(
513                                 RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC
514                         ),
515                         .funct = add_set_src_ipv4,
516                 },
517                 {
518                         .mask = FLOW_ACTION_MASK(
519                                 RTE_FLOW_ACTION_TYPE_SET_IPV4_DST
520                         ),
521                         .funct = add_set_dst_ipv4,
522                 },
523                 {
524                         .mask = FLOW_ACTION_MASK(
525                                 RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC
526                         ),
527                         .funct = add_set_src_ipv6,
528                 },
529                 {
530                         .mask = FLOW_ACTION_MASK(
531                                 RTE_FLOW_ACTION_TYPE_SET_IPV6_DST
532                         ),
533                         .funct = add_set_dst_ipv6,
534                 },
535                 {
536                         .mask = FLOW_ACTION_MASK(
537                                 RTE_FLOW_ACTION_TYPE_SET_TP_SRC
538                         ),
539                         .funct = add_set_src_tp,
540                 },
541                 {
542                         .mask = FLOW_ACTION_MASK(
543                                 RTE_FLOW_ACTION_TYPE_SET_TP_DST
544                         ),
545                         .funct = add_set_dst_tp,
546                 },
547                 {
548                         .mask = FLOW_ACTION_MASK(
549                                 RTE_FLOW_ACTION_TYPE_INC_TCP_ACK
550                         ),
551                         .funct = add_inc_tcp_ack,
552                 },
553                 {
554                         .mask = FLOW_ACTION_MASK(
555                                 RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK
556                         ),
557                         .funct = add_dec_tcp_ack,
558                 },
559                 {
560                         .mask = FLOW_ACTION_MASK(
561                                 RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ
562                         ),
563                         .funct = add_inc_tcp_seq,
564                 },
565                 {
566                         .mask = FLOW_ACTION_MASK(
567                                 RTE_FLOW_ACTION_TYPE_DEC_TCP_SEQ
568                         ),
569                         .funct = add_dec_tcp_seq,
570                 },
571                 {
572                         .mask = FLOW_ACTION_MASK(
573                                 RTE_FLOW_ACTION_TYPE_SET_TTL
574                         ),
575                         .funct = add_set_ttl,
576                 },
577                 {
578                         .mask = FLOW_ACTION_MASK(
579                                 RTE_FLOW_ACTION_TYPE_DEC_TTL
580                         ),
581                         .funct = add_dec_ttl,
582                 },
583                 {
584                         .mask = FLOW_ACTION_MASK(
585                                 RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP
586                         ),
587                         .funct = add_set_ipv4_dscp,
588                 },
589                 {
590                         .mask = FLOW_ACTION_MASK(
591                                 RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP
592                         ),
593                         .funct = add_set_ipv6_dscp,
594                 },
595                 {
596                         .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_QUEUE),
597                         .funct = add_queue,
598                 },
599                 {
600                         .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_RSS),
601                         .funct = add_rss,
602                 },
603                 {
604                         .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_JUMP),
605                         .funct = add_jump,
606                 },
607                 {
608                         .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_PORT_ID),
609                         .funct = add_port_id
610                 },
611                 {
612                         .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_DROP),
613                         .funct = add_drop,
614                 },
615                 {
616                         .mask = HAIRPIN_QUEUE_ACTION,
617                         .funct = add_queue,
618                 },
619                 {
620                         .mask = HAIRPIN_RSS_ACTION,
621                         .funct = add_rss,
622                 },
623         };
624
625         for (j = 0; j < MAX_ACTIONS_NUM; j++) {
626                 if (flow_actions[j] == 0)
627                         break;
628                 for (i = 0; i < RTE_DIM(actions_list); i++) {
629                         if ((flow_actions[j] &
630                                 actions_list[i].mask) == 0)
631                                 continue;
632                         actions_list[i].funct(
633                                 actions, actions_counter++,
634                                 additional_para_data
635                         );
636                         break;
637                 }
638         }
639         actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_END;
640 }