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