1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2020 Mellanox Technologies, Ltd
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.
10 #include <rte_malloc.h>
12 #include <rte_ethdev.h>
14 #include "actions_gen.h"
18 /* Storage for additional parameters for actions */
19 struct additional_para {
23 uint16_t queues_number;
27 /* Storage for struct rte_flow_action_rss including external data. */
28 struct action_rss_data {
29 struct rte_flow_action_rss conf;
35 add_mark(struct rte_flow_action *actions,
36 uint8_t actions_counter,
37 __rte_unused struct additional_para para)
39 static struct rte_flow_action_mark mark_action;
42 mark_action.id = MARK_ID;
45 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_MARK;
46 actions[actions_counter].conf = &mark_action;
50 add_queue(struct rte_flow_action *actions,
51 uint8_t actions_counter,
52 struct additional_para para)
54 static struct rte_flow_action_queue queue_action;
57 queue_action.index = para.queue;
60 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_QUEUE;
61 actions[actions_counter].conf = &queue_action;
65 add_jump(struct rte_flow_action *actions,
66 uint8_t actions_counter,
67 struct additional_para para)
69 static struct rte_flow_action_jump jump_action;
72 jump_action.group = para.next_table;
75 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_JUMP;
76 actions[actions_counter].conf = &jump_action;
80 add_rss(struct rte_flow_action *actions,
81 uint8_t actions_counter,
82 struct additional_para para)
84 static struct rte_flow_action_rss *rss_action;
85 static struct action_rss_data *rss_data;
90 rss_data = rte_malloc("rss_data",
91 sizeof(struct action_rss_data), 0);
94 rte_exit(EXIT_FAILURE, "No Memory available!");
96 *rss_data = (struct action_rss_data){
97 .conf = (struct rte_flow_action_rss){
98 .func = RTE_ETH_HASH_FUNCTION_DEFAULT,
100 .types = GET_RSS_HF(),
101 .key_len = sizeof(rss_data->key),
102 .queue_num = para.queues_number,
103 .key = rss_data->key,
104 .queue = rss_data->queue,
110 for (queue = 0; queue < para.queues_number; queue++)
111 rss_data->queue[queue] = para.queues[queue];
113 rss_action = &rss_data->conf;
115 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_RSS;
116 actions[actions_counter].conf = rss_action;
120 add_set_meta(struct rte_flow_action *actions,
121 uint8_t actions_counter,
122 __rte_unused struct additional_para para)
124 static struct rte_flow_action_set_meta meta_action;
127 meta_action.data = RTE_BE32(META_DATA);
128 meta_action.mask = RTE_BE32(0xffffffff);
131 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_META;
132 actions[actions_counter].conf = &meta_action;
136 add_set_tag(struct rte_flow_action *actions,
137 uint8_t actions_counter,
138 __rte_unused struct additional_para para)
140 static struct rte_flow_action_set_tag tag_action;
143 tag_action.data = RTE_BE32(META_DATA);
144 tag_action.mask = RTE_BE32(0xffffffff);
145 tag_action.index = TAG_INDEX;
148 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_TAG;
149 actions[actions_counter].conf = &tag_action;
153 add_port_id(struct rte_flow_action *actions,
154 uint8_t actions_counter,
155 __rte_unused struct additional_para para)
157 static struct rte_flow_action_port_id port_id;
160 port_id.id = PORT_ID_DST;
163 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_PORT_ID;
164 actions[actions_counter].conf = &port_id;
168 add_drop(struct rte_flow_action *actions,
169 uint8_t actions_counter,
170 __rte_unused struct additional_para para)
172 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_DROP;
176 add_count(struct rte_flow_action *actions,
177 uint8_t actions_counter,
178 __rte_unused struct additional_para para)
180 static struct rte_flow_action_count count_action;
182 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_COUNT;
183 actions[actions_counter].conf = &count_action;
187 add_set_src_mac(struct rte_flow_action *actions,
188 uint8_t actions_counter,
189 __rte_unused struct additional_para para)
191 static struct rte_flow_action_set_mac set_mac;
192 uint32_t mac = para.counter;
195 /* Mac address to be set is random each time */
196 for (i = 0; i < RTE_ETHER_ADDR_LEN; i++) {
197 set_mac.mac_addr[i] = mac & 0xff;
201 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_MAC_SRC;
202 actions[actions_counter].conf = &set_mac;
206 add_set_dst_mac(struct rte_flow_action *actions,
207 uint8_t actions_counter,
208 __rte_unused struct additional_para para)
210 static struct rte_flow_action_set_mac set_mac;
211 uint32_t mac = para.counter;
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;
220 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_MAC_DST;
221 actions[actions_counter].conf = &set_mac;
225 add_set_src_ipv4(struct rte_flow_action *actions,
226 uint8_t actions_counter,
227 __rte_unused struct additional_para para)
229 static struct rte_flow_action_set_ipv4 set_ipv4;
231 /* IPv4 value to be set is random each time */
232 set_ipv4.ipv4_addr = RTE_BE32(para.counter + 1);
234 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC;
235 actions[actions_counter].conf = &set_ipv4;
239 add_set_dst_ipv4(struct rte_flow_action *actions,
240 uint8_t actions_counter,
241 __rte_unused struct additional_para para)
243 static struct rte_flow_action_set_ipv4 set_ipv4;
245 /* IPv4 value to be set is random each time */
246 set_ipv4.ipv4_addr = RTE_BE32(para.counter + 1);
248 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV4_DST;
249 actions[actions_counter].conf = &set_ipv4;
253 add_set_src_ipv6(struct rte_flow_action *actions,
254 uint8_t actions_counter,
255 __rte_unused struct additional_para para)
257 static struct rte_flow_action_set_ipv6 set_ipv6;
258 uint32_t ipv6 = para.counter;
261 /* IPv6 value to set is random each time */
262 for (i = 0; i < 16; i++) {
263 set_ipv6.ipv6_addr[i] = ipv6 & 0xff;
267 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC;
268 actions[actions_counter].conf = &set_ipv6;
272 add_set_dst_ipv6(struct rte_flow_action *actions,
273 uint8_t actions_counter,
274 __rte_unused struct additional_para para)
276 static struct rte_flow_action_set_ipv6 set_ipv6;
277 uint32_t ipv6 = para.counter;
280 /* IPv6 value to set is random each time */
281 for (i = 0; i < 16; i++) {
282 set_ipv6.ipv6_addr[i] = ipv6 & 0xff;
286 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV6_DST;
287 actions[actions_counter].conf = &set_ipv6;
291 add_set_src_tp(struct rte_flow_action *actions,
292 uint8_t actions_counter,
293 __rte_unused struct additional_para para)
295 static struct rte_flow_action_set_tp set_tp;
296 uint32_t tp = para.counter;
298 /* TP src port is random each time */
302 set_tp.port = RTE_BE16(tp & 0xffff);
304 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_TP_SRC;
305 actions[actions_counter].conf = &set_tp;
309 add_set_dst_tp(struct rte_flow_action *actions,
310 uint8_t actions_counter,
311 __rte_unused struct additional_para para)
313 static struct rte_flow_action_set_tp set_tp;
314 uint32_t tp = para.counter;
316 /* TP src port is random each time */
320 set_tp.port = RTE_BE16(tp & 0xffff);
322 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_TP_DST;
323 actions[actions_counter].conf = &set_tp;
327 add_inc_tcp_ack(struct rte_flow_action *actions,
328 uint8_t actions_counter,
329 __rte_unused struct additional_para para)
331 static rte_be32_t value = RTE_BE32(1);
333 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_INC_TCP_ACK;
334 actions[actions_counter].conf = &value;
338 add_dec_tcp_ack(struct rte_flow_action *actions,
339 uint8_t actions_counter,
340 __rte_unused struct additional_para para)
342 static rte_be32_t value = RTE_BE32(1);
344 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK;
345 actions[actions_counter].conf = &value;
349 add_inc_tcp_seq(struct rte_flow_action *actions,
350 uint8_t actions_counter,
351 __rte_unused struct additional_para para)
353 static rte_be32_t value = RTE_BE32(1);
355 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ;
356 actions[actions_counter].conf = &value;
360 add_dec_tcp_seq(struct rte_flow_action *actions,
361 uint8_t actions_counter,
362 __rte_unused struct additional_para para)
364 static rte_be32_t value = RTE_BE32(1);
366 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_DEC_TCP_SEQ;
367 actions[actions_counter].conf = &value;
371 add_set_ttl(struct rte_flow_action *actions,
372 uint8_t actions_counter,
373 __rte_unused struct additional_para para)
375 static struct rte_flow_action_set_ttl set_ttl;
376 uint32_t ttl_value = para.counter;
378 /* Set ttl to random value each time */
379 while (ttl_value > 0xff)
380 ttl_value = ttl_value >> 8;
382 set_ttl.ttl_value = ttl_value;
384 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_TTL;
385 actions[actions_counter].conf = &set_ttl;
389 add_dec_ttl(struct rte_flow_action *actions,
390 uint8_t actions_counter,
391 __rte_unused struct additional_para para)
393 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_DEC_TTL;
397 add_set_ipv4_dscp(struct rte_flow_action *actions,
398 uint8_t actions_counter,
399 __rte_unused struct additional_para para)
401 static struct rte_flow_action_set_dscp set_dscp;
402 uint32_t dscp_value = para.counter;
404 /* Set dscp to random value each time */
405 while (dscp_value > 0xff)
406 dscp_value = dscp_value >> 8;
408 set_dscp.dscp = dscp_value;
410 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP;
411 actions[actions_counter].conf = &set_dscp;
415 add_set_ipv6_dscp(struct rte_flow_action *actions,
416 uint8_t actions_counter,
417 __rte_unused struct additional_para para)
419 static struct rte_flow_action_set_dscp set_dscp;
420 uint32_t dscp_value = para.counter;
422 /* Set dscp to random value each time */
423 while (dscp_value > 0xff)
424 dscp_value = dscp_value >> 8;
426 set_dscp.dscp = dscp_value;
428 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP;
429 actions[actions_counter].conf = &set_dscp;
433 add_flag(struct rte_flow_action *actions,
434 uint8_t actions_counter,
435 __rte_unused struct additional_para para)
437 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_FLAG;
441 fill_actions(struct rte_flow_action *actions, uint64_t *flow_actions,
442 uint32_t counter, uint16_t next_table, uint16_t hairpinq)
444 struct additional_para additional_para_data;
445 uint8_t actions_counter = 0;
446 uint16_t hairpin_queues[hairpinq];
447 uint16_t queues[RXQ_NUM];
450 for (i = 0; i < RXQ_NUM; i++)
453 for (i = 0; i < hairpinq; i++)
454 hairpin_queues[i] = i + RXQ_NUM;
456 additional_para_data = (struct additional_para){
457 .queue = counter % RXQ_NUM,
458 .next_table = next_table,
460 .queues_number = RXQ_NUM,
465 additional_para_data.queues = hairpin_queues;
466 additional_para_data.queues_number = hairpinq;
467 additional_para_data.queue = (counter % hairpinq) + RXQ_NUM;
470 static const struct actions_dict {
473 struct rte_flow_action *actions,
474 uint8_t actions_counter,
475 struct additional_para para
479 .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_MARK),
483 .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_COUNT),
487 .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_META),
488 .funct = add_set_meta,
491 .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_TAG),
492 .funct = add_set_tag,
495 .mask = FLOW_ACTION_MASK(
496 RTE_FLOW_ACTION_TYPE_FLAG
501 .mask = FLOW_ACTION_MASK(
502 RTE_FLOW_ACTION_TYPE_SET_MAC_SRC
504 .funct = add_set_src_mac,
507 .mask = FLOW_ACTION_MASK(
508 RTE_FLOW_ACTION_TYPE_SET_MAC_DST
510 .funct = add_set_dst_mac,
513 .mask = FLOW_ACTION_MASK(
514 RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC
516 .funct = add_set_src_ipv4,
519 .mask = FLOW_ACTION_MASK(
520 RTE_FLOW_ACTION_TYPE_SET_IPV4_DST
522 .funct = add_set_dst_ipv4,
525 .mask = FLOW_ACTION_MASK(
526 RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC
528 .funct = add_set_src_ipv6,
531 .mask = FLOW_ACTION_MASK(
532 RTE_FLOW_ACTION_TYPE_SET_IPV6_DST
534 .funct = add_set_dst_ipv6,
537 .mask = FLOW_ACTION_MASK(
538 RTE_FLOW_ACTION_TYPE_SET_TP_SRC
540 .funct = add_set_src_tp,
543 .mask = FLOW_ACTION_MASK(
544 RTE_FLOW_ACTION_TYPE_SET_TP_DST
546 .funct = add_set_dst_tp,
549 .mask = FLOW_ACTION_MASK(
550 RTE_FLOW_ACTION_TYPE_INC_TCP_ACK
552 .funct = add_inc_tcp_ack,
555 .mask = FLOW_ACTION_MASK(
556 RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK
558 .funct = add_dec_tcp_ack,
561 .mask = FLOW_ACTION_MASK(
562 RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ
564 .funct = add_inc_tcp_seq,
567 .mask = FLOW_ACTION_MASK(
568 RTE_FLOW_ACTION_TYPE_DEC_TCP_SEQ
570 .funct = add_dec_tcp_seq,
573 .mask = FLOW_ACTION_MASK(
574 RTE_FLOW_ACTION_TYPE_SET_TTL
576 .funct = add_set_ttl,
579 .mask = FLOW_ACTION_MASK(
580 RTE_FLOW_ACTION_TYPE_DEC_TTL
582 .funct = add_dec_ttl,
585 .mask = FLOW_ACTION_MASK(
586 RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP
588 .funct = add_set_ipv4_dscp,
591 .mask = FLOW_ACTION_MASK(
592 RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP
594 .funct = add_set_ipv6_dscp,
597 .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_QUEUE),
601 .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_RSS),
605 .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_JUMP),
609 .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_PORT_ID),
613 .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_DROP),
617 .mask = HAIRPIN_QUEUE_ACTION,
621 .mask = HAIRPIN_RSS_ACTION,
626 for (j = 0; j < MAX_ACTIONS_NUM; j++) {
627 if (flow_actions[j] == 0)
629 for (i = 0; i < RTE_DIM(actions_list); i++) {
630 if ((flow_actions[j] &
631 actions_list[i].mask) == 0)
633 actions_list[i].funct(
634 actions, actions_counter++,
640 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_END;