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;
89 rss_data = rte_malloc("rss_data",
90 sizeof(struct action_rss_data), 0);
93 rte_exit(EXIT_FAILURE, "No Memory available!");
95 *rss_data = (struct action_rss_data){
96 .conf = (struct rte_flow_action_rss){
97 .func = RTE_ETH_HASH_FUNCTION_DEFAULT,
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,
109 for (queue = 0; queue < para.queues_number; queue++)
110 rss_data->queue[queue] = para.queues[queue];
112 rss_action = &rss_data->conf;
114 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_RSS;
115 actions[actions_counter].conf = rss_action;
119 add_set_meta(struct rte_flow_action *actions,
120 uint8_t actions_counter,
121 __rte_unused struct additional_para para)
123 static struct rte_flow_action_set_meta meta_action;
126 meta_action.data = RTE_BE32(META_DATA);
127 meta_action.mask = RTE_BE32(0xffffffff);
130 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_META;
131 actions[actions_counter].conf = &meta_action;
135 add_set_tag(struct rte_flow_action *actions,
136 uint8_t actions_counter,
137 __rte_unused struct additional_para para)
139 static struct rte_flow_action_set_tag tag_action;
142 tag_action.data = RTE_BE32(META_DATA);
143 tag_action.mask = RTE_BE32(0xffffffff);
144 tag_action.index = TAG_INDEX;
147 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_TAG;
148 actions[actions_counter].conf = &tag_action;
152 add_port_id(struct rte_flow_action *actions,
153 uint8_t actions_counter,
154 __rte_unused struct additional_para para)
156 static struct rte_flow_action_port_id port_id;
159 port_id.id = PORT_ID_DST;
162 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_PORT_ID;
163 actions[actions_counter].conf = &port_id;
167 add_drop(struct rte_flow_action *actions,
168 uint8_t actions_counter,
169 __rte_unused struct additional_para para)
171 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_DROP;
175 add_count(struct rte_flow_action *actions,
176 uint8_t actions_counter,
177 __rte_unused struct additional_para para)
179 static struct rte_flow_action_count count_action;
181 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_COUNT;
182 actions[actions_counter].conf = &count_action;
186 add_set_src_mac(struct rte_flow_action *actions,
187 uint8_t actions_counter,
188 __rte_unused struct additional_para para)
190 static struct rte_flow_action_set_mac set_mac;
191 uint32_t mac = para.counter;
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;
200 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_MAC_SRC;
201 actions[actions_counter].conf = &set_mac;
205 add_set_dst_mac(struct rte_flow_action *actions,
206 uint8_t actions_counter,
207 __rte_unused struct additional_para para)
209 static struct rte_flow_action_set_mac set_mac;
210 uint32_t mac = para.counter;
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;
219 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_MAC_DST;
220 actions[actions_counter].conf = &set_mac;
224 add_set_src_ipv4(struct rte_flow_action *actions,
225 uint8_t actions_counter,
226 __rte_unused struct additional_para para)
228 static struct rte_flow_action_set_ipv4 set_ipv4;
230 /* IPv4 value to be set is random each time */
231 set_ipv4.ipv4_addr = RTE_BE32(para.counter + 1);
233 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC;
234 actions[actions_counter].conf = &set_ipv4;
238 add_set_dst_ipv4(struct rte_flow_action *actions,
239 uint8_t actions_counter,
240 __rte_unused struct additional_para para)
242 static struct rte_flow_action_set_ipv4 set_ipv4;
244 /* IPv4 value to be set is random each time */
245 set_ipv4.ipv4_addr = RTE_BE32(para.counter + 1);
247 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV4_DST;
248 actions[actions_counter].conf = &set_ipv4;
252 add_set_src_ipv6(struct rte_flow_action *actions,
253 uint8_t actions_counter,
254 __rte_unused struct additional_para para)
256 static struct rte_flow_action_set_ipv6 set_ipv6;
257 uint32_t ipv6 = para.counter;
260 /* IPv6 value to set is random each time */
261 for (i = 0; i < 16; i++) {
262 set_ipv6.ipv6_addr[i] = ipv6 & 0xff;
266 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC;
267 actions[actions_counter].conf = &set_ipv6;
271 add_set_dst_ipv6(struct rte_flow_action *actions,
272 uint8_t actions_counter,
273 __rte_unused struct additional_para para)
275 static struct rte_flow_action_set_ipv6 set_ipv6;
276 uint32_t ipv6 = para.counter;
279 /* IPv6 value to set is random each time */
280 for (i = 0; i < 16; i++) {
281 set_ipv6.ipv6_addr[i] = ipv6 & 0xff;
285 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV6_DST;
286 actions[actions_counter].conf = &set_ipv6;
290 add_set_src_tp(struct rte_flow_action *actions,
291 uint8_t actions_counter,
292 __rte_unused struct additional_para para)
294 static struct rte_flow_action_set_tp set_tp;
295 uint32_t tp = para.counter;
297 /* TP src port is random each time */
301 set_tp.port = RTE_BE16(tp & 0xffff);
303 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_TP_SRC;
304 actions[actions_counter].conf = &set_tp;
308 add_set_dst_tp(struct rte_flow_action *actions,
309 uint8_t actions_counter,
310 __rte_unused struct additional_para para)
312 static struct rte_flow_action_set_tp set_tp;
313 uint32_t tp = para.counter;
315 /* TP src port is random each time */
319 set_tp.port = RTE_BE16(tp & 0xffff);
321 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_TP_DST;
322 actions[actions_counter].conf = &set_tp;
326 add_inc_tcp_ack(struct rte_flow_action *actions,
327 uint8_t actions_counter,
328 __rte_unused struct additional_para para)
330 static rte_be32_t value = RTE_BE32(1);
332 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_INC_TCP_ACK;
333 actions[actions_counter].conf = &value;
337 add_dec_tcp_ack(struct rte_flow_action *actions,
338 uint8_t actions_counter,
339 __rte_unused struct additional_para para)
341 static rte_be32_t value = RTE_BE32(1);
343 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK;
344 actions[actions_counter].conf = &value;
348 add_inc_tcp_seq(struct rte_flow_action *actions,
349 uint8_t actions_counter,
350 __rte_unused struct additional_para para)
352 static rte_be32_t value = RTE_BE32(1);
354 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ;
355 actions[actions_counter].conf = &value;
359 add_dec_tcp_seq(struct rte_flow_action *actions,
360 uint8_t actions_counter,
361 __rte_unused struct additional_para para)
363 static rte_be32_t value = RTE_BE32(1);
365 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_DEC_TCP_SEQ;
366 actions[actions_counter].conf = &value;
370 add_set_ttl(struct rte_flow_action *actions,
371 uint8_t actions_counter,
372 __rte_unused struct additional_para para)
374 static struct rte_flow_action_set_ttl set_ttl;
375 uint32_t ttl_value = para.counter;
377 /* Set ttl to random value each time */
378 while (ttl_value > 0xff)
379 ttl_value = ttl_value >> 8;
381 set_ttl.ttl_value = ttl_value;
383 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_TTL;
384 actions[actions_counter].conf = &set_ttl;
388 add_dec_ttl(struct rte_flow_action *actions,
389 uint8_t actions_counter,
390 __rte_unused struct additional_para para)
392 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_DEC_TTL;
396 add_set_ipv4_dscp(struct rte_flow_action *actions,
397 uint8_t actions_counter,
398 __rte_unused struct additional_para para)
400 static struct rte_flow_action_set_dscp set_dscp;
401 uint32_t dscp_value = para.counter;
403 /* Set dscp to random value each time */
404 while (dscp_value > 0xff)
405 dscp_value = dscp_value >> 8;
407 set_dscp.dscp = dscp_value;
409 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP;
410 actions[actions_counter].conf = &set_dscp;
414 add_set_ipv6_dscp(struct rte_flow_action *actions,
415 uint8_t actions_counter,
416 __rte_unused struct additional_para para)
418 static struct rte_flow_action_set_dscp set_dscp;
419 uint32_t dscp_value = para.counter;
421 /* Set dscp to random value each time */
422 while (dscp_value > 0xff)
423 dscp_value = dscp_value >> 8;
425 set_dscp.dscp = dscp_value;
427 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP;
428 actions[actions_counter].conf = &set_dscp;
432 fill_actions(struct rte_flow_action *actions, uint64_t *flow_actions,
433 uint32_t counter, uint16_t next_table, uint16_t hairpinq)
435 struct additional_para additional_para_data;
436 uint8_t actions_counter = 0;
437 uint16_t hairpin_queues[hairpinq];
438 uint16_t queues[RXQ_NUM];
441 for (i = 0; i < RXQ_NUM; i++)
444 for (i = 0; i < hairpinq; i++)
445 hairpin_queues[i] = i + RXQ_NUM;
447 additional_para_data = (struct additional_para){
448 .queue = counter % RXQ_NUM,
449 .next_table = next_table,
451 .queues_number = RXQ_NUM,
456 additional_para_data.queues = hairpin_queues;
457 additional_para_data.queues_number = hairpinq;
458 additional_para_data.queue = (counter % hairpinq) + RXQ_NUM;
461 static const struct actions_dict {
464 struct rte_flow_action *actions,
465 uint8_t actions_counter,
466 struct additional_para para
470 .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_MARK),
474 .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_COUNT),
478 .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_META),
479 .funct = add_set_meta,
482 .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_TAG),
483 .funct = add_set_tag,
486 .mask = FLOW_ACTION_MASK(
487 RTE_FLOW_ACTION_TYPE_SET_MAC_SRC
489 .funct = add_set_src_mac,
492 .mask = FLOW_ACTION_MASK(
493 RTE_FLOW_ACTION_TYPE_SET_MAC_DST
495 .funct = add_set_dst_mac,
498 .mask = FLOW_ACTION_MASK(
499 RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC
501 .funct = add_set_src_ipv4,
504 .mask = FLOW_ACTION_MASK(
505 RTE_FLOW_ACTION_TYPE_SET_IPV4_DST
507 .funct = add_set_dst_ipv4,
510 .mask = FLOW_ACTION_MASK(
511 RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC
513 .funct = add_set_src_ipv6,
516 .mask = FLOW_ACTION_MASK(
517 RTE_FLOW_ACTION_TYPE_SET_IPV6_DST
519 .funct = add_set_dst_ipv6,
522 .mask = FLOW_ACTION_MASK(
523 RTE_FLOW_ACTION_TYPE_SET_TP_SRC
525 .funct = add_set_src_tp,
528 .mask = FLOW_ACTION_MASK(
529 RTE_FLOW_ACTION_TYPE_SET_TP_DST
531 .funct = add_set_dst_tp,
534 .mask = FLOW_ACTION_MASK(
535 RTE_FLOW_ACTION_TYPE_INC_TCP_ACK
537 .funct = add_inc_tcp_ack,
540 .mask = FLOW_ACTION_MASK(
541 RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK
543 .funct = add_dec_tcp_ack,
546 .mask = FLOW_ACTION_MASK(
547 RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ
549 .funct = add_inc_tcp_seq,
552 .mask = FLOW_ACTION_MASK(
553 RTE_FLOW_ACTION_TYPE_DEC_TCP_SEQ
555 .funct = add_dec_tcp_seq,
558 .mask = FLOW_ACTION_MASK(
559 RTE_FLOW_ACTION_TYPE_SET_TTL
561 .funct = add_set_ttl,
564 .mask = FLOW_ACTION_MASK(
565 RTE_FLOW_ACTION_TYPE_DEC_TTL
567 .funct = add_dec_ttl,
570 .mask = FLOW_ACTION_MASK(
571 RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP
573 .funct = add_set_ipv4_dscp,
576 .mask = FLOW_ACTION_MASK(
577 RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP
579 .funct = add_set_ipv6_dscp,
582 .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_QUEUE),
586 .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_RSS),
590 .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_JUMP),
594 .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_PORT_ID),
598 .mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_DROP),
602 .mask = HAIRPIN_QUEUE_ACTION,
606 .mask = HAIRPIN_RSS_ACTION,
611 for (j = 0; j < MAX_ACTIONS_NUM; j++) {
612 if (flow_actions[j] == 0)
614 for (i = 0; i < RTE_DIM(actions_list); i++) {
615 if ((flow_actions[j] &
616 actions_list[i].mask) == 0)
618 actions_list[i].funct(
619 actions, actions_counter++,
625 actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_END;