1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2018 Marvell International Ltd. 3 * Copyright(c) 2018 Semihalf. 4 * All rights reserved. 5 */ 6 7 #include <rte_flow.h> 8 #include <rte_flow_driver.h> 9 #include <rte_malloc.h> 10 #include <rte_log.h> 11 12 #include <arpa/inet.h> 13 14 #include "mrvl_flow.h" 15 #include "mrvl_qos.h" 16 17 /** Number of rules in the classifier table. */ 18 #define MRVL_CLS_MAX_NUM_RULES 20 19 20 /** Size of the classifier key and mask strings. */ 21 #define MRVL_CLS_STR_SIZE_MAX 40 22 23 static const enum rte_flow_item_type pattern_eth[] = { 24 RTE_FLOW_ITEM_TYPE_ETH, 25 RTE_FLOW_ITEM_TYPE_END 26 }; 27 28 static const enum rte_flow_item_type pattern_eth_vlan[] = { 29 RTE_FLOW_ITEM_TYPE_ETH, 30 RTE_FLOW_ITEM_TYPE_VLAN, 31 RTE_FLOW_ITEM_TYPE_END 32 }; 33 34 static const enum rte_flow_item_type pattern_eth_vlan_ip[] = { 35 RTE_FLOW_ITEM_TYPE_ETH, 36 RTE_FLOW_ITEM_TYPE_VLAN, 37 RTE_FLOW_ITEM_TYPE_IPV4, 38 RTE_FLOW_ITEM_TYPE_END 39 }; 40 41 static const enum rte_flow_item_type pattern_eth_vlan_ip6[] = { 42 RTE_FLOW_ITEM_TYPE_ETH, 43 RTE_FLOW_ITEM_TYPE_VLAN, 44 RTE_FLOW_ITEM_TYPE_IPV6, 45 RTE_FLOW_ITEM_TYPE_END 46 }; 47 48 static const enum rte_flow_item_type pattern_eth_ip4[] = { 49 RTE_FLOW_ITEM_TYPE_ETH, 50 RTE_FLOW_ITEM_TYPE_IPV4, 51 RTE_FLOW_ITEM_TYPE_END 52 }; 53 54 static const enum rte_flow_item_type pattern_eth_ip4_tcp[] = { 55 RTE_FLOW_ITEM_TYPE_ETH, 56 RTE_FLOW_ITEM_TYPE_IPV4, 57 RTE_FLOW_ITEM_TYPE_TCP, 58 RTE_FLOW_ITEM_TYPE_END 59 }; 60 61 static const enum rte_flow_item_type pattern_eth_ip4_udp[] = { 62 RTE_FLOW_ITEM_TYPE_ETH, 63 RTE_FLOW_ITEM_TYPE_IPV4, 64 RTE_FLOW_ITEM_TYPE_UDP, 65 RTE_FLOW_ITEM_TYPE_END 66 }; 67 68 static const enum rte_flow_item_type pattern_eth_ip6[] = { 69 RTE_FLOW_ITEM_TYPE_ETH, 70 RTE_FLOW_ITEM_TYPE_IPV6, 71 RTE_FLOW_ITEM_TYPE_END 72 }; 73 74 static const enum rte_flow_item_type pattern_eth_ip6_tcp[] = { 75 RTE_FLOW_ITEM_TYPE_ETH, 76 RTE_FLOW_ITEM_TYPE_IPV6, 77 RTE_FLOW_ITEM_TYPE_TCP, 78 RTE_FLOW_ITEM_TYPE_END 79 }; 80 81 static const enum rte_flow_item_type pattern_eth_ip6_udp[] = { 82 RTE_FLOW_ITEM_TYPE_ETH, 83 RTE_FLOW_ITEM_TYPE_IPV6, 84 RTE_FLOW_ITEM_TYPE_UDP, 85 RTE_FLOW_ITEM_TYPE_END 86 }; 87 88 static const enum rte_flow_item_type pattern_vlan[] = { 89 RTE_FLOW_ITEM_TYPE_VLAN, 90 RTE_FLOW_ITEM_TYPE_END 91 }; 92 93 static const enum rte_flow_item_type pattern_vlan_ip[] = { 94 RTE_FLOW_ITEM_TYPE_VLAN, 95 RTE_FLOW_ITEM_TYPE_IPV4, 96 RTE_FLOW_ITEM_TYPE_END 97 }; 98 99 static const enum rte_flow_item_type pattern_vlan_ip_tcp[] = { 100 RTE_FLOW_ITEM_TYPE_VLAN, 101 RTE_FLOW_ITEM_TYPE_IPV4, 102 RTE_FLOW_ITEM_TYPE_TCP, 103 RTE_FLOW_ITEM_TYPE_END 104 }; 105 106 static const enum rte_flow_item_type pattern_vlan_ip_udp[] = { 107 RTE_FLOW_ITEM_TYPE_VLAN, 108 RTE_FLOW_ITEM_TYPE_IPV4, 109 RTE_FLOW_ITEM_TYPE_UDP, 110 RTE_FLOW_ITEM_TYPE_END 111 }; 112 113 static const enum rte_flow_item_type pattern_vlan_ip6[] = { 114 RTE_FLOW_ITEM_TYPE_VLAN, 115 RTE_FLOW_ITEM_TYPE_IPV6, 116 RTE_FLOW_ITEM_TYPE_END 117 }; 118 119 static const enum rte_flow_item_type pattern_vlan_ip6_tcp[] = { 120 RTE_FLOW_ITEM_TYPE_VLAN, 121 RTE_FLOW_ITEM_TYPE_IPV6, 122 RTE_FLOW_ITEM_TYPE_TCP, 123 RTE_FLOW_ITEM_TYPE_END 124 }; 125 126 static const enum rte_flow_item_type pattern_vlan_ip6_udp[] = { 127 RTE_FLOW_ITEM_TYPE_VLAN, 128 RTE_FLOW_ITEM_TYPE_IPV6, 129 RTE_FLOW_ITEM_TYPE_UDP, 130 RTE_FLOW_ITEM_TYPE_END 131 }; 132 133 static const enum rte_flow_item_type pattern_ip[] = { 134 RTE_FLOW_ITEM_TYPE_IPV4, 135 RTE_FLOW_ITEM_TYPE_END 136 }; 137 138 static const enum rte_flow_item_type pattern_ip6[] = { 139 RTE_FLOW_ITEM_TYPE_IPV6, 140 RTE_FLOW_ITEM_TYPE_END 141 }; 142 143 static const enum rte_flow_item_type pattern_ip_tcp[] = { 144 RTE_FLOW_ITEM_TYPE_IPV4, 145 RTE_FLOW_ITEM_TYPE_TCP, 146 RTE_FLOW_ITEM_TYPE_END 147 }; 148 149 static const enum rte_flow_item_type pattern_ip6_tcp[] = { 150 RTE_FLOW_ITEM_TYPE_IPV6, 151 RTE_FLOW_ITEM_TYPE_TCP, 152 RTE_FLOW_ITEM_TYPE_END 153 }; 154 155 static const enum rte_flow_item_type pattern_ip_udp[] = { 156 RTE_FLOW_ITEM_TYPE_IPV4, 157 RTE_FLOW_ITEM_TYPE_UDP, 158 RTE_FLOW_ITEM_TYPE_END 159 }; 160 161 static const enum rte_flow_item_type pattern_ip6_udp[] = { 162 RTE_FLOW_ITEM_TYPE_IPV6, 163 RTE_FLOW_ITEM_TYPE_UDP, 164 RTE_FLOW_ITEM_TYPE_END 165 }; 166 167 static const enum rte_flow_item_type pattern_tcp[] = { 168 RTE_FLOW_ITEM_TYPE_TCP, 169 RTE_FLOW_ITEM_TYPE_END 170 }; 171 172 static const enum rte_flow_item_type pattern_udp[] = { 173 RTE_FLOW_ITEM_TYPE_UDP, 174 RTE_FLOW_ITEM_TYPE_END 175 }; 176 177 #define MRVL_VLAN_ID_MASK 0x0fff 178 #define MRVL_VLAN_PRI_MASK 0x7000 179 #define MRVL_IPV4_DSCP_MASK 0xfc 180 #define MRVL_IPV4_ADDR_MASK 0xffffffff 181 #define MRVL_IPV6_FLOW_MASK 0x0fffff 182 183 /** 184 * Given a flow item, return the next non-void one. 185 * 186 * @param items Pointer to the item in the table. 187 * @returns Next not-void item, NULL otherwise. 188 */ 189 static const struct rte_flow_item * 190 mrvl_next_item(const struct rte_flow_item *items) 191 { 192 const struct rte_flow_item *item = items; 193 194 for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) { 195 if (item->type != RTE_FLOW_ITEM_TYPE_VOID) 196 return item; 197 } 198 199 return NULL; 200 } 201 202 /** 203 * Allocate memory for classifier rule key and mask fields. 204 * 205 * @param field Pointer to the classifier rule. 206 * @returns 0 in case of success, negative value otherwise. 207 */ 208 static int 209 mrvl_alloc_key_mask(struct pp2_cls_rule_key_field *field) 210 { 211 unsigned int id = rte_socket_id(); 212 213 field->key = rte_zmalloc_socket(NULL, MRVL_CLS_STR_SIZE_MAX, 0, id); 214 if (!field->key) 215 goto out; 216 217 field->mask = rte_zmalloc_socket(NULL, MRVL_CLS_STR_SIZE_MAX, 0, id); 218 if (!field->mask) 219 goto out_mask; 220 221 return 0; 222 out_mask: 223 rte_free(field->key); 224 out: 225 field->key = NULL; 226 field->mask = NULL; 227 return -1; 228 } 229 230 /** 231 * Free memory allocated for classifier rule key and mask fields. 232 * 233 * @param field Pointer to the classifier rule. 234 */ 235 static void 236 mrvl_free_key_mask(struct pp2_cls_rule_key_field *field) 237 { 238 rte_free(field->key); 239 rte_free(field->mask); 240 field->key = NULL; 241 field->mask = NULL; 242 } 243 244 /** 245 * Free memory allocated for all classifier rule key and mask fields. 246 * 247 * @param rule Pointer to the classifier table rule. 248 */ 249 static void 250 mrvl_free_all_key_mask(struct pp2_cls_tbl_rule *rule) 251 { 252 int i; 253 254 for (i = 0; i < rule->num_fields; i++) 255 mrvl_free_key_mask(&rule->fields[i]); 256 rule->num_fields = 0; 257 } 258 259 /* 260 * Initialize rte flow item parsing. 261 * 262 * @param item Pointer to the flow item. 263 * @param spec_ptr Pointer to the specific item pointer. 264 * @param mask_ptr Pointer to the specific item's mask pointer. 265 * @def_mask Pointer to the default mask. 266 * @size Size of the flow item. 267 * @error Pointer to the rte flow error. 268 * @returns 0 in case of success, negative value otherwise. 269 */ 270 static int 271 mrvl_parse_init(const struct rte_flow_item *item, 272 const void **spec_ptr, 273 const void **mask_ptr, 274 const void *def_mask, 275 unsigned int size, 276 struct rte_flow_error *error) 277 { 278 const uint8_t *spec; 279 const uint8_t *mask; 280 const uint8_t *last; 281 uint8_t zeros[size]; 282 283 memset(zeros, 0, size); 284 285 if (item == NULL) { 286 rte_flow_error_set(error, EINVAL, 287 RTE_FLOW_ERROR_TYPE_ITEM, NULL, 288 "NULL item\n"); 289 return -rte_errno; 290 } 291 292 if ((item->last != NULL || item->mask != NULL) && item->spec == NULL) { 293 rte_flow_error_set(error, EINVAL, 294 RTE_FLOW_ERROR_TYPE_ITEM, item, 295 "Mask or last is set without spec\n"); 296 return -rte_errno; 297 } 298 299 /* 300 * If "mask" is not set, default mask is used, 301 * but if default mask is NULL, "mask" should be set. 302 */ 303 if (item->mask == NULL) { 304 if (def_mask == NULL) { 305 rte_flow_error_set(error, EINVAL, 306 RTE_FLOW_ERROR_TYPE_ITEM, NULL, 307 "Mask should be specified\n"); 308 return -rte_errno; 309 } 310 311 mask = (const uint8_t *)def_mask; 312 } else { 313 mask = (const uint8_t *)item->mask; 314 } 315 316 spec = (const uint8_t *)item->spec; 317 last = (const uint8_t *)item->last; 318 319 if (spec == NULL) { 320 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, 321 NULL, "Spec should be specified\n"); 322 return -rte_errno; 323 } 324 325 /* 326 * If field values in "last" are either 0 or equal to the corresponding 327 * values in "spec" then they are ignored. 328 */ 329 if (last != NULL && 330 !memcmp(last, zeros, size) && 331 memcmp(last, spec, size) != 0) { 332 rte_flow_error_set(error, ENOTSUP, 333 RTE_FLOW_ERROR_TYPE_ITEM, NULL, 334 "Ranging is not supported\n"); 335 return -rte_errno; 336 } 337 338 *spec_ptr = spec; 339 *mask_ptr = mask; 340 341 return 0; 342 } 343 344 /** 345 * Parse the eth flow item. 346 * 347 * This will create classifier rule that matches either destination or source 348 * mac. 349 * 350 * @param spec Pointer to the specific flow item. 351 * @param mask Pointer to the specific flow item's mask. 352 * @param parse_dst Parse either destination or source mac address. 353 * @param flow Pointer to the flow. 354 * @return 0 in case of success, negative error value otherwise. 355 */ 356 static int 357 mrvl_parse_mac(const struct rte_flow_item_eth *spec, 358 const struct rte_flow_item_eth *mask, 359 int parse_dst, struct rte_flow *flow) 360 { 361 struct pp2_cls_rule_key_field *key_field; 362 const uint8_t *k, *m; 363 364 if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS) 365 return -ENOSPC; 366 367 if (parse_dst) { 368 k = spec->dst.addr_bytes; 369 m = mask->dst.addr_bytes; 370 371 flow->pattern |= F_DMAC; 372 } else { 373 k = spec->src.addr_bytes; 374 m = mask->src.addr_bytes; 375 376 flow->pattern |= F_SMAC; 377 } 378 379 key_field = &flow->rule.fields[flow->rule.num_fields]; 380 mrvl_alloc_key_mask(key_field); 381 key_field->size = 6; 382 383 snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, 384 "%02x:%02x:%02x:%02x:%02x:%02x", 385 k[0], k[1], k[2], k[3], k[4], k[5]); 386 387 snprintf((char *)key_field->mask, MRVL_CLS_STR_SIZE_MAX, 388 "%02x:%02x:%02x:%02x:%02x:%02x", 389 m[0], m[1], m[2], m[3], m[4], m[5]); 390 391 flow->rule.num_fields += 1; 392 393 return 0; 394 } 395 396 /** 397 * Helper for parsing the eth flow item destination mac address. 398 * 399 * @param spec Pointer to the specific flow item. 400 * @param mask Pointer to the specific flow item's mask. 401 * @param flow Pointer to the flow. 402 * @return 0 in case of success, negative error value otherwise. 403 */ 404 static inline int 405 mrvl_parse_dmac(const struct rte_flow_item_eth *spec, 406 const struct rte_flow_item_eth *mask, 407 struct rte_flow *flow) 408 { 409 return mrvl_parse_mac(spec, mask, 1, flow); 410 } 411 412 /** 413 * Helper for parsing the eth flow item source mac address. 414 * 415 * @param spec Pointer to the specific flow item. 416 * @param mask Pointer to the specific flow item's mask. 417 * @param flow Pointer to the flow. 418 * @return 0 in case of success, negative error value otherwise. 419 */ 420 static inline int 421 mrvl_parse_smac(const struct rte_flow_item_eth *spec, 422 const struct rte_flow_item_eth *mask, 423 struct rte_flow *flow) 424 { 425 return mrvl_parse_mac(spec, mask, 0, flow); 426 } 427 428 /** 429 * Parse the ether type field of the eth flow item. 430 * 431 * @param spec Pointer to the specific flow item. 432 * @param mask Pointer to the specific flow item's mask. 433 * @param flow Pointer to the flow. 434 * @return 0 in case of success, negative error value otherwise. 435 */ 436 static int 437 mrvl_parse_type(const struct rte_flow_item_eth *spec, 438 const struct rte_flow_item_eth *mask __rte_unused, 439 struct rte_flow *flow) 440 { 441 struct pp2_cls_rule_key_field *key_field; 442 uint16_t k; 443 444 if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS) 445 return -ENOSPC; 446 447 key_field = &flow->rule.fields[flow->rule.num_fields]; 448 mrvl_alloc_key_mask(key_field); 449 key_field->size = 2; 450 451 k = rte_be_to_cpu_16(spec->type); 452 snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k); 453 454 flow->pattern |= F_TYPE; 455 flow->rule.num_fields += 1; 456 457 return 0; 458 } 459 460 /** 461 * Parse the vid field of the vlan rte flow item. 462 * 463 * This will create classifier rule that matches vid. 464 * 465 * @param spec Pointer to the specific flow item. 466 * @param mask Pointer to the specific flow item's mask. 467 * @param flow Pointer to the flow. 468 * @return 0 in case of success, negative error value otherwise. 469 */ 470 static int 471 mrvl_parse_vlan_id(const struct rte_flow_item_vlan *spec, 472 const struct rte_flow_item_vlan *mask __rte_unused, 473 struct rte_flow *flow) 474 { 475 struct pp2_cls_rule_key_field *key_field; 476 uint16_t k; 477 478 if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS) 479 return -ENOSPC; 480 481 key_field = &flow->rule.fields[flow->rule.num_fields]; 482 mrvl_alloc_key_mask(key_field); 483 key_field->size = 2; 484 485 k = rte_be_to_cpu_16(spec->tci) & MRVL_VLAN_ID_MASK; 486 snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k); 487 488 flow->pattern |= F_VLAN_ID; 489 flow->rule.num_fields += 1; 490 491 return 0; 492 } 493 494 /** 495 * Parse the pri field of the vlan rte flow item. 496 * 497 * This will create classifier rule that matches pri. 498 * 499 * @param spec Pointer to the specific flow item. 500 * @param mask Pointer to the specific flow item's mask. 501 * @param flow Pointer to the flow. 502 * @return 0 in case of success, negative error value otherwise. 503 */ 504 static int 505 mrvl_parse_vlan_pri(const struct rte_flow_item_vlan *spec, 506 const struct rte_flow_item_vlan *mask __rte_unused, 507 struct rte_flow *flow) 508 { 509 struct pp2_cls_rule_key_field *key_field; 510 uint16_t k; 511 512 if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS) 513 return -ENOSPC; 514 515 key_field = &flow->rule.fields[flow->rule.num_fields]; 516 mrvl_alloc_key_mask(key_field); 517 key_field->size = 1; 518 519 k = (rte_be_to_cpu_16(spec->tci) & MRVL_VLAN_PRI_MASK) >> 13; 520 snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k); 521 522 flow->pattern |= F_VLAN_PRI; 523 flow->rule.num_fields += 1; 524 525 return 0; 526 } 527 528 /** 529 * Parse the dscp field of the ipv4 rte flow item. 530 * 531 * This will create classifier rule that matches dscp field. 532 * 533 * @param spec Pointer to the specific flow item. 534 * @param mask Pointer to the specific flow item's mask. 535 * @param flow Pointer to the flow. 536 * @return 0 in case of success, negative error value otherwise. 537 */ 538 static int 539 mrvl_parse_ip4_dscp(const struct rte_flow_item_ipv4 *spec, 540 const struct rte_flow_item_ipv4 *mask, 541 struct rte_flow *flow) 542 { 543 struct pp2_cls_rule_key_field *key_field; 544 uint8_t k, m; 545 546 if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS) 547 return -ENOSPC; 548 549 key_field = &flow->rule.fields[flow->rule.num_fields]; 550 mrvl_alloc_key_mask(key_field); 551 key_field->size = 1; 552 553 k = (spec->hdr.type_of_service & MRVL_IPV4_DSCP_MASK) >> 2; 554 m = (mask->hdr.type_of_service & MRVL_IPV4_DSCP_MASK) >> 2; 555 snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k); 556 snprintf((char *)key_field->mask, MRVL_CLS_STR_SIZE_MAX, "%u", m); 557 558 flow->pattern |= F_IP4_TOS; 559 flow->rule.num_fields += 1; 560 561 return 0; 562 } 563 564 /** 565 * Parse either source or destination ip addresses of the ipv4 flow item. 566 * 567 * This will create classifier rule that matches either destination 568 * or source ip field. 569 * 570 * @param spec Pointer to the specific flow item. 571 * @param mask Pointer to the specific flow item's mask. 572 * @param parse_dst Parse either destination or source ip address. 573 * @param flow Pointer to the flow. 574 * @return 0 in case of success, negative error value otherwise. 575 */ 576 static int 577 mrvl_parse_ip4_addr(const struct rte_flow_item_ipv4 *spec, 578 const struct rte_flow_item_ipv4 *mask, 579 int parse_dst, struct rte_flow *flow) 580 { 581 struct pp2_cls_rule_key_field *key_field; 582 struct in_addr k; 583 uint32_t m; 584 585 if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS) 586 return -ENOSPC; 587 588 memset(&k, 0, sizeof(k)); 589 if (parse_dst) { 590 k.s_addr = spec->hdr.dst_addr; 591 m = rte_be_to_cpu_32(mask->hdr.dst_addr); 592 593 flow->pattern |= F_IP4_DIP; 594 } else { 595 k.s_addr = spec->hdr.src_addr; 596 m = rte_be_to_cpu_32(mask->hdr.src_addr); 597 598 flow->pattern |= F_IP4_SIP; 599 } 600 601 key_field = &flow->rule.fields[flow->rule.num_fields]; 602 mrvl_alloc_key_mask(key_field); 603 key_field->size = 4; 604 605 inet_ntop(AF_INET, &k, (char *)key_field->key, MRVL_CLS_STR_SIZE_MAX); 606 snprintf((char *)key_field->mask, MRVL_CLS_STR_SIZE_MAX, "0x%x", m); 607 608 flow->rule.num_fields += 1; 609 610 return 0; 611 } 612 613 /** 614 * Helper for parsing destination ip of the ipv4 flow item. 615 * 616 * @param spec Pointer to the specific flow item. 617 * @param mask Pointer to the specific flow item's mask. 618 * @param flow Pointer to the flow. 619 * @return 0 in case of success, negative error value otherwise. 620 */ 621 static inline int 622 mrvl_parse_ip4_dip(const struct rte_flow_item_ipv4 *spec, 623 const struct rte_flow_item_ipv4 *mask, 624 struct rte_flow *flow) 625 { 626 return mrvl_parse_ip4_addr(spec, mask, 1, flow); 627 } 628 629 /** 630 * Helper for parsing source ip of the ipv4 flow item. 631 * 632 * @param spec Pointer to the specific flow item. 633 * @param mask Pointer to the specific flow item's mask. 634 * @param flow Pointer to the flow. 635 * @return 0 in case of success, negative error value otherwise. 636 */ 637 static inline int 638 mrvl_parse_ip4_sip(const struct rte_flow_item_ipv4 *spec, 639 const struct rte_flow_item_ipv4 *mask, 640 struct rte_flow *flow) 641 { 642 return mrvl_parse_ip4_addr(spec, mask, 0, flow); 643 } 644 645 /** 646 * Parse the proto field of the ipv4 rte flow item. 647 * 648 * This will create classifier rule that matches proto field. 649 * 650 * @param spec Pointer to the specific flow item. 651 * @param mask Pointer to the specific flow item's mask. 652 * @param flow Pointer to the flow. 653 * @return 0 in case of success, negative error value otherwise. 654 */ 655 static int 656 mrvl_parse_ip4_proto(const struct rte_flow_item_ipv4 *spec, 657 const struct rte_flow_item_ipv4 *mask __rte_unused, 658 struct rte_flow *flow) 659 { 660 struct pp2_cls_rule_key_field *key_field; 661 uint8_t k = spec->hdr.next_proto_id; 662 663 if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS) 664 return -ENOSPC; 665 666 key_field = &flow->rule.fields[flow->rule.num_fields]; 667 mrvl_alloc_key_mask(key_field); 668 key_field->size = 1; 669 670 snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k); 671 672 flow->pattern |= F_IP4_PROTO; 673 flow->rule.num_fields += 1; 674 675 return 0; 676 } 677 678 /** 679 * Parse either source or destination ip addresses of the ipv6 rte flow item. 680 * 681 * This will create classifier rule that matches either destination 682 * or source ip field. 683 * 684 * @param spec Pointer to the specific flow item. 685 * @param mask Pointer to the specific flow item's mask. 686 * @param parse_dst Parse either destination or source ipv6 address. 687 * @param flow Pointer to the flow. 688 * @return 0 in case of success, negative error value otherwise. 689 */ 690 static int 691 mrvl_parse_ip6_addr(const struct rte_flow_item_ipv6 *spec, 692 const struct rte_flow_item_ipv6 *mask, 693 int parse_dst, struct rte_flow *flow) 694 { 695 struct pp2_cls_rule_key_field *key_field; 696 int size = sizeof(spec->hdr.dst_addr); 697 struct in6_addr k, m; 698 699 if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS) 700 return -ENOSPC; 701 702 memset(&k, 0, sizeof(k)); 703 if (parse_dst) { 704 memcpy(k.s6_addr, spec->hdr.dst_addr, size); 705 memcpy(m.s6_addr, mask->hdr.dst_addr, size); 706 707 flow->pattern |= F_IP6_DIP; 708 } else { 709 memcpy(k.s6_addr, spec->hdr.src_addr, size); 710 memcpy(m.s6_addr, mask->hdr.src_addr, size); 711 712 flow->pattern |= F_IP6_SIP; 713 } 714 715 key_field = &flow->rule.fields[flow->rule.num_fields]; 716 mrvl_alloc_key_mask(key_field); 717 key_field->size = 16; 718 719 inet_ntop(AF_INET6, &k, (char *)key_field->key, MRVL_CLS_STR_SIZE_MAX); 720 inet_ntop(AF_INET6, &m, (char *)key_field->mask, MRVL_CLS_STR_SIZE_MAX); 721 722 flow->rule.num_fields += 1; 723 724 return 0; 725 } 726 727 /** 728 * Helper for parsing destination ip of the ipv6 flow item. 729 * 730 * @param spec Pointer to the specific flow item. 731 * @param mask Pointer to the specific flow item's mask. 732 * @param flow Pointer to the flow. 733 * @return 0 in case of success, negative error value otherwise. 734 */ 735 static inline int 736 mrvl_parse_ip6_dip(const struct rte_flow_item_ipv6 *spec, 737 const struct rte_flow_item_ipv6 *mask, 738 struct rte_flow *flow) 739 { 740 return mrvl_parse_ip6_addr(spec, mask, 1, flow); 741 } 742 743 /** 744 * Helper for parsing source ip of the ipv6 flow item. 745 * 746 * @param spec Pointer to the specific flow item. 747 * @param mask Pointer to the specific flow item's mask. 748 * @param flow Pointer to the flow. 749 * @return 0 in case of success, negative error value otherwise. 750 */ 751 static inline int 752 mrvl_parse_ip6_sip(const struct rte_flow_item_ipv6 *spec, 753 const struct rte_flow_item_ipv6 *mask, 754 struct rte_flow *flow) 755 { 756 return mrvl_parse_ip6_addr(spec, mask, 0, flow); 757 } 758 759 /** 760 * Parse the flow label of the ipv6 flow item. 761 * 762 * This will create classifier rule that matches flow field. 763 * 764 * @param spec Pointer to the specific flow item. 765 * @param mask Pointer to the specific flow item's mask. 766 * @param flow Pointer to the flow. 767 * @return 0 in case of success, negative error value otherwise. 768 */ 769 static int 770 mrvl_parse_ip6_flow(const struct rte_flow_item_ipv6 *spec, 771 const struct rte_flow_item_ipv6 *mask, 772 struct rte_flow *flow) 773 { 774 struct pp2_cls_rule_key_field *key_field; 775 uint32_t k = rte_be_to_cpu_32(spec->hdr.vtc_flow) & MRVL_IPV6_FLOW_MASK, 776 m = rte_be_to_cpu_32(mask->hdr.vtc_flow) & MRVL_IPV6_FLOW_MASK; 777 778 if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS) 779 return -ENOSPC; 780 781 key_field = &flow->rule.fields[flow->rule.num_fields]; 782 mrvl_alloc_key_mask(key_field); 783 key_field->size = 3; 784 785 snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k); 786 snprintf((char *)key_field->mask, MRVL_CLS_STR_SIZE_MAX, "%u", m); 787 788 flow->pattern |= F_IP6_FLOW; 789 flow->rule.num_fields += 1; 790 791 return 0; 792 } 793 794 /** 795 * Parse the next header of the ipv6 flow item. 796 * 797 * This will create classifier rule that matches next header field. 798 * 799 * @param spec Pointer to the specific flow item. 800 * @param mask Pointer to the specific flow item's mask. 801 * @param flow Pointer to the flow. 802 * @return 0 in case of success, negative error value otherwise. 803 */ 804 static int 805 mrvl_parse_ip6_next_hdr(const struct rte_flow_item_ipv6 *spec, 806 const struct rte_flow_item_ipv6 *mask __rte_unused, 807 struct rte_flow *flow) 808 { 809 struct pp2_cls_rule_key_field *key_field; 810 uint8_t k = spec->hdr.proto; 811 812 if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS) 813 return -ENOSPC; 814 815 key_field = &flow->rule.fields[flow->rule.num_fields]; 816 mrvl_alloc_key_mask(key_field); 817 key_field->size = 1; 818 819 snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k); 820 821 flow->pattern |= F_IP6_NEXT_HDR; 822 flow->rule.num_fields += 1; 823 824 return 0; 825 } 826 827 /** 828 * Parse destination or source port of the tcp flow item. 829 * 830 * This will create classifier rule that matches either destination or 831 * source tcp port. 832 * 833 * @param spec Pointer to the specific flow item. 834 * @param mask Pointer to the specific flow item's mask. 835 * @param parse_dst Parse either destination or source port. 836 * @param flow Pointer to the flow. 837 * @return 0 in case of success, negative error value otherwise. 838 */ 839 static int 840 mrvl_parse_tcp_port(const struct rte_flow_item_tcp *spec, 841 const struct rte_flow_item_tcp *mask __rte_unused, 842 int parse_dst, struct rte_flow *flow) 843 { 844 struct pp2_cls_rule_key_field *key_field; 845 uint16_t k; 846 847 if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS) 848 return -ENOSPC; 849 850 key_field = &flow->rule.fields[flow->rule.num_fields]; 851 mrvl_alloc_key_mask(key_field); 852 key_field->size = 2; 853 854 if (parse_dst) { 855 k = rte_be_to_cpu_16(spec->hdr.dst_port); 856 857 flow->pattern |= F_TCP_DPORT; 858 } else { 859 k = rte_be_to_cpu_16(spec->hdr.src_port); 860 861 flow->pattern |= F_TCP_SPORT; 862 } 863 864 snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k); 865 866 flow->rule.num_fields += 1; 867 868 return 0; 869 } 870 871 /** 872 * Helper for parsing the tcp source port of the tcp flow item. 873 * 874 * @param spec Pointer to the specific flow item. 875 * @param mask Pointer to the specific flow item's mask. 876 * @param flow Pointer to the flow. 877 * @return 0 in case of success, negative error value otherwise. 878 */ 879 static inline int 880 mrvl_parse_tcp_sport(const struct rte_flow_item_tcp *spec, 881 const struct rte_flow_item_tcp *mask, 882 struct rte_flow *flow) 883 { 884 return mrvl_parse_tcp_port(spec, mask, 0, flow); 885 } 886 887 /** 888 * Helper for parsing the tcp destination port of the tcp flow item. 889 * 890 * @param spec Pointer to the specific flow item. 891 * @param mask Pointer to the specific flow item's mask. 892 * @param flow Pointer to the flow. 893 * @return 0 in case of success, negative error value otherwise. 894 */ 895 static inline int 896 mrvl_parse_tcp_dport(const struct rte_flow_item_tcp *spec, 897 const struct rte_flow_item_tcp *mask, 898 struct rte_flow *flow) 899 { 900 return mrvl_parse_tcp_port(spec, mask, 1, flow); 901 } 902 903 /** 904 * Parse destination or source port of the udp flow item. 905 * 906 * This will create classifier rule that matches either destination or 907 * source udp port. 908 * 909 * @param spec Pointer to the specific flow item. 910 * @param mask Pointer to the specific flow item's mask. 911 * @param parse_dst Parse either destination or source port. 912 * @param flow Pointer to the flow. 913 * @return 0 in case of success, negative error value otherwise. 914 */ 915 static int 916 mrvl_parse_udp_port(const struct rte_flow_item_udp *spec, 917 const struct rte_flow_item_udp *mask __rte_unused, 918 int parse_dst, struct rte_flow *flow) 919 { 920 struct pp2_cls_rule_key_field *key_field; 921 uint16_t k; 922 923 if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS) 924 return -ENOSPC; 925 926 key_field = &flow->rule.fields[flow->rule.num_fields]; 927 mrvl_alloc_key_mask(key_field); 928 key_field->size = 2; 929 930 if (parse_dst) { 931 k = rte_be_to_cpu_16(spec->hdr.dst_port); 932 933 flow->pattern |= F_UDP_DPORT; 934 } else { 935 k = rte_be_to_cpu_16(spec->hdr.src_port); 936 937 flow->pattern |= F_UDP_SPORT; 938 } 939 940 snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k); 941 942 flow->rule.num_fields += 1; 943 944 return 0; 945 } 946 947 /** 948 * Helper for parsing the udp source port of the udp flow item. 949 * 950 * @param spec Pointer to the specific flow item. 951 * @param mask Pointer to the specific flow item's mask. 952 * @param flow Pointer to the flow. 953 * @return 0 in case of success, negative error value otherwise. 954 */ 955 static inline int 956 mrvl_parse_udp_sport(const struct rte_flow_item_udp *spec, 957 const struct rte_flow_item_udp *mask, 958 struct rte_flow *flow) 959 { 960 return mrvl_parse_udp_port(spec, mask, 0, flow); 961 } 962 963 /** 964 * Helper for parsing the udp destination port of the udp flow item. 965 * 966 * @param spec Pointer to the specific flow item. 967 * @param mask Pointer to the specific flow item's mask. 968 * @param flow Pointer to the flow. 969 * @return 0 in case of success, negative error value otherwise. 970 */ 971 static inline int 972 mrvl_parse_udp_dport(const struct rte_flow_item_udp *spec, 973 const struct rte_flow_item_udp *mask, 974 struct rte_flow *flow) 975 { 976 return mrvl_parse_udp_port(spec, mask, 1, flow); 977 } 978 979 /** 980 * Parse eth flow item. 981 * 982 * @param item Pointer to the flow item. 983 * @param flow Pointer to the flow. 984 * @param error Pointer to the flow error. 985 * @returns 0 on success, negative value otherwise. 986 */ 987 static int 988 mrvl_parse_eth(const struct rte_flow_item *item, struct rte_flow *flow, 989 struct rte_flow_error *error) 990 { 991 const struct rte_flow_item_eth *spec = NULL, *mask = NULL; 992 struct ether_addr zero; 993 int ret; 994 995 ret = mrvl_parse_init(item, (const void **)&spec, (const void **)&mask, 996 &rte_flow_item_eth_mask, 997 sizeof(struct rte_flow_item_eth), error); 998 if (ret) 999 return ret; 1000 1001 memset(&zero, 0, sizeof(zero)); 1002 1003 if (memcmp(&mask->dst, &zero, sizeof(mask->dst))) { 1004 ret = mrvl_parse_dmac(spec, mask, flow); 1005 if (ret) 1006 goto out; 1007 } 1008 1009 if (memcmp(&mask->src, &zero, sizeof(mask->src))) { 1010 ret = mrvl_parse_smac(spec, mask, flow); 1011 if (ret) 1012 goto out; 1013 } 1014 1015 if (mask->type) { 1016 MRVL_LOG(WARNING, "eth type mask is ignored"); 1017 ret = mrvl_parse_type(spec, mask, flow); 1018 if (ret) 1019 goto out; 1020 } 1021 1022 return 0; 1023 out: 1024 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 1025 "Reached maximum number of fields in cls tbl key\n"); 1026 return -rte_errno; 1027 } 1028 1029 /** 1030 * Parse vlan flow item. 1031 * 1032 * @param item Pointer to the flow item. 1033 * @param flow Pointer to the flow. 1034 * @param error Pointer to the flow error. 1035 * @returns 0 on success, negative value otherwise. 1036 */ 1037 static int 1038 mrvl_parse_vlan(const struct rte_flow_item *item, 1039 struct rte_flow *flow, 1040 struct rte_flow_error *error) 1041 { 1042 const struct rte_flow_item_vlan *spec = NULL, *mask = NULL; 1043 uint16_t m; 1044 int ret; 1045 1046 ret = mrvl_parse_init(item, (const void **)&spec, (const void **)&mask, 1047 &rte_flow_item_vlan_mask, 1048 sizeof(struct rte_flow_item_vlan), error); 1049 if (ret) 1050 return ret; 1051 1052 m = rte_be_to_cpu_16(mask->tci); 1053 if (m & MRVL_VLAN_ID_MASK) { 1054 MRVL_LOG(WARNING, "vlan id mask is ignored"); 1055 ret = mrvl_parse_vlan_id(spec, mask, flow); 1056 if (ret) 1057 goto out; 1058 } 1059 1060 if (m & MRVL_VLAN_PRI_MASK) { 1061 MRVL_LOG(WARNING, "vlan pri mask is ignored"); 1062 ret = mrvl_parse_vlan_pri(spec, mask, flow); 1063 if (ret) 1064 goto out; 1065 } 1066 1067 if (flow->pattern & F_TYPE) { 1068 rte_flow_error_set(error, ENOTSUP, 1069 RTE_FLOW_ERROR_TYPE_ITEM, item, 1070 "VLAN TPID matching is not supported"); 1071 return -rte_errno; 1072 } 1073 if (mask->inner_type) { 1074 struct rte_flow_item_eth spec_eth = { 1075 .type = spec->inner_type, 1076 }; 1077 struct rte_flow_item_eth mask_eth = { 1078 .type = mask->inner_type, 1079 }; 1080 1081 MRVL_LOG(WARNING, "inner eth type mask is ignored"); 1082 ret = mrvl_parse_type(&spec_eth, &mask_eth, flow); 1083 if (ret) 1084 goto out; 1085 } 1086 1087 return 0; 1088 out: 1089 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 1090 "Reached maximum number of fields in cls tbl key\n"); 1091 return -rte_errno; 1092 } 1093 1094 /** 1095 * Parse ipv4 flow item. 1096 * 1097 * @param item Pointer to the flow item. 1098 * @param flow Pointer to the flow. 1099 * @param error Pointer to the flow error. 1100 * @returns 0 on success, negative value otherwise. 1101 */ 1102 static int 1103 mrvl_parse_ip4(const struct rte_flow_item *item, 1104 struct rte_flow *flow, 1105 struct rte_flow_error *error) 1106 { 1107 const struct rte_flow_item_ipv4 *spec = NULL, *mask = NULL; 1108 int ret; 1109 1110 ret = mrvl_parse_init(item, (const void **)&spec, (const void **)&mask, 1111 &rte_flow_item_ipv4_mask, 1112 sizeof(struct rte_flow_item_ipv4), error); 1113 if (ret) 1114 return ret; 1115 1116 if (mask->hdr.version_ihl || 1117 mask->hdr.total_length || 1118 mask->hdr.packet_id || 1119 mask->hdr.fragment_offset || 1120 mask->hdr.time_to_live || 1121 mask->hdr.hdr_checksum) { 1122 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, 1123 NULL, "Not supported by classifier\n"); 1124 return -rte_errno; 1125 } 1126 1127 if (mask->hdr.type_of_service & MRVL_IPV4_DSCP_MASK) { 1128 ret = mrvl_parse_ip4_dscp(spec, mask, flow); 1129 if (ret) 1130 goto out; 1131 } 1132 1133 if (mask->hdr.src_addr) { 1134 ret = mrvl_parse_ip4_sip(spec, mask, flow); 1135 if (ret) 1136 goto out; 1137 } 1138 1139 if (mask->hdr.dst_addr) { 1140 ret = mrvl_parse_ip4_dip(spec, mask, flow); 1141 if (ret) 1142 goto out; 1143 } 1144 1145 if (mask->hdr.next_proto_id) { 1146 MRVL_LOG(WARNING, "next proto id mask is ignored"); 1147 ret = mrvl_parse_ip4_proto(spec, mask, flow); 1148 if (ret) 1149 goto out; 1150 } 1151 1152 return 0; 1153 out: 1154 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 1155 "Reached maximum number of fields in cls tbl key\n"); 1156 return -rte_errno; 1157 } 1158 1159 /** 1160 * Parse ipv6 flow item. 1161 * 1162 * @param item Pointer to the flow item. 1163 * @param flow Pointer to the flow. 1164 * @param error Pointer to the flow error. 1165 * @returns 0 on success, negative value otherwise. 1166 */ 1167 static int 1168 mrvl_parse_ip6(const struct rte_flow_item *item, 1169 struct rte_flow *flow, 1170 struct rte_flow_error *error) 1171 { 1172 const struct rte_flow_item_ipv6 *spec = NULL, *mask = NULL; 1173 struct ipv6_hdr zero; 1174 uint32_t flow_mask; 1175 int ret; 1176 1177 ret = mrvl_parse_init(item, (const void **)&spec, 1178 (const void **)&mask, 1179 &rte_flow_item_ipv6_mask, 1180 sizeof(struct rte_flow_item_ipv6), 1181 error); 1182 if (ret) 1183 return ret; 1184 1185 memset(&zero, 0, sizeof(zero)); 1186 1187 if (mask->hdr.payload_len || 1188 mask->hdr.hop_limits) { 1189 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, 1190 NULL, "Not supported by classifier\n"); 1191 return -rte_errno; 1192 } 1193 1194 if (memcmp(mask->hdr.src_addr, 1195 zero.src_addr, sizeof(mask->hdr.src_addr))) { 1196 ret = mrvl_parse_ip6_sip(spec, mask, flow); 1197 if (ret) 1198 goto out; 1199 } 1200 1201 if (memcmp(mask->hdr.dst_addr, 1202 zero.dst_addr, sizeof(mask->hdr.dst_addr))) { 1203 ret = mrvl_parse_ip6_dip(spec, mask, flow); 1204 if (ret) 1205 goto out; 1206 } 1207 1208 flow_mask = rte_be_to_cpu_32(mask->hdr.vtc_flow) & MRVL_IPV6_FLOW_MASK; 1209 if (flow_mask) { 1210 ret = mrvl_parse_ip6_flow(spec, mask, flow); 1211 if (ret) 1212 goto out; 1213 } 1214 1215 if (mask->hdr.proto) { 1216 MRVL_LOG(WARNING, "next header mask is ignored"); 1217 ret = mrvl_parse_ip6_next_hdr(spec, mask, flow); 1218 if (ret) 1219 goto out; 1220 } 1221 1222 return 0; 1223 out: 1224 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 1225 "Reached maximum number of fields in cls tbl key\n"); 1226 return -rte_errno; 1227 } 1228 1229 /** 1230 * Parse tcp flow item. 1231 * 1232 * @param item Pointer to the flow item. 1233 * @param flow Pointer to the flow. 1234 * @param error Pointer to the flow error. 1235 * @returns 0 on success, negative value otherwise. 1236 */ 1237 static int 1238 mrvl_parse_tcp(const struct rte_flow_item *item, 1239 struct rte_flow *flow, 1240 struct rte_flow_error *error) 1241 { 1242 const struct rte_flow_item_tcp *spec = NULL, *mask = NULL; 1243 int ret; 1244 1245 ret = mrvl_parse_init(item, (const void **)&spec, (const void **)&mask, 1246 &rte_flow_item_ipv4_mask, 1247 sizeof(struct rte_flow_item_ipv4), error); 1248 if (ret) 1249 return ret; 1250 1251 if (mask->hdr.sent_seq || 1252 mask->hdr.recv_ack || 1253 mask->hdr.data_off || 1254 mask->hdr.tcp_flags || 1255 mask->hdr.rx_win || 1256 mask->hdr.cksum || 1257 mask->hdr.tcp_urp) { 1258 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, 1259 NULL, "Not supported by classifier\n"); 1260 return -rte_errno; 1261 } 1262 1263 if (mask->hdr.src_port) { 1264 MRVL_LOG(WARNING, "tcp sport mask is ignored"); 1265 ret = mrvl_parse_tcp_sport(spec, mask, flow); 1266 if (ret) 1267 goto out; 1268 } 1269 1270 if (mask->hdr.dst_port) { 1271 MRVL_LOG(WARNING, "tcp dport mask is ignored"); 1272 ret = mrvl_parse_tcp_dport(spec, mask, flow); 1273 if (ret) 1274 goto out; 1275 } 1276 1277 return 0; 1278 out: 1279 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 1280 "Reached maximum number of fields in cls tbl key\n"); 1281 return -rte_errno; 1282 } 1283 1284 /** 1285 * Parse udp flow item. 1286 * 1287 * @param item Pointer to the flow item. 1288 * @param flow Pointer to the flow. 1289 * @param error Pointer to the flow error. 1290 * @returns 0 on success, negative value otherwise. 1291 */ 1292 static int 1293 mrvl_parse_udp(const struct rte_flow_item *item, 1294 struct rte_flow *flow, 1295 struct rte_flow_error *error) 1296 { 1297 const struct rte_flow_item_udp *spec = NULL, *mask = NULL; 1298 int ret; 1299 1300 ret = mrvl_parse_init(item, (const void **)&spec, (const void **)&mask, 1301 &rte_flow_item_ipv4_mask, 1302 sizeof(struct rte_flow_item_ipv4), error); 1303 if (ret) 1304 return ret; 1305 1306 if (mask->hdr.dgram_len || 1307 mask->hdr.dgram_cksum) { 1308 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, 1309 NULL, "Not supported by classifier\n"); 1310 return -rte_errno; 1311 } 1312 1313 if (mask->hdr.src_port) { 1314 MRVL_LOG(WARNING, "udp sport mask is ignored"); 1315 ret = mrvl_parse_udp_sport(spec, mask, flow); 1316 if (ret) 1317 goto out; 1318 } 1319 1320 if (mask->hdr.dst_port) { 1321 MRVL_LOG(WARNING, "udp dport mask is ignored"); 1322 ret = mrvl_parse_udp_dport(spec, mask, flow); 1323 if (ret) 1324 goto out; 1325 } 1326 1327 return 0; 1328 out: 1329 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 1330 "Reached maximum number of fields in cls tbl key\n"); 1331 return -rte_errno; 1332 } 1333 1334 /** 1335 * Parse flow pattern composed of the the eth item. 1336 * 1337 * @param pattern Pointer to the flow pattern table. 1338 * @param flow Pointer to the flow. 1339 * @param error Pointer to the flow error. 1340 * @returns 0 in case of success, negative value otherwise. 1341 */ 1342 static int 1343 mrvl_parse_pattern_eth(const struct rte_flow_item pattern[], 1344 struct rte_flow *flow, 1345 struct rte_flow_error *error) 1346 { 1347 return mrvl_parse_eth(pattern, flow, error); 1348 } 1349 1350 /** 1351 * Parse flow pattern composed of the eth and vlan items. 1352 * 1353 * @param pattern Pointer to the flow pattern table. 1354 * @param flow Pointer to the flow. 1355 * @param error Pointer to the flow error. 1356 * @returns 0 in case of success, negative value otherwise. 1357 */ 1358 static int 1359 mrvl_parse_pattern_eth_vlan(const struct rte_flow_item pattern[], 1360 struct rte_flow *flow, 1361 struct rte_flow_error *error) 1362 { 1363 const struct rte_flow_item *item = mrvl_next_item(pattern); 1364 int ret; 1365 1366 ret = mrvl_parse_eth(item, flow, error); 1367 if (ret) 1368 return ret; 1369 1370 item = mrvl_next_item(item + 1); 1371 1372 return mrvl_parse_vlan(item, flow, error); 1373 } 1374 1375 /** 1376 * Parse flow pattern composed of the eth, vlan and ip4/ip6 items. 1377 * 1378 * @param pattern Pointer to the flow pattern table. 1379 * @param flow Pointer to the flow. 1380 * @param error Pointer to the flow error. 1381 * @param ip6 1 to parse ip6 item, 0 to parse ip4 item. 1382 * @returns 0 in case of success, negative value otherwise. 1383 */ 1384 static int 1385 mrvl_parse_pattern_eth_vlan_ip4_ip6(const struct rte_flow_item pattern[], 1386 struct rte_flow *flow, 1387 struct rte_flow_error *error, int ip6) 1388 { 1389 const struct rte_flow_item *item = mrvl_next_item(pattern); 1390 int ret; 1391 1392 ret = mrvl_parse_eth(item, flow, error); 1393 if (ret) 1394 return ret; 1395 1396 item = mrvl_next_item(item + 1); 1397 ret = mrvl_parse_vlan(item, flow, error); 1398 if (ret) 1399 return ret; 1400 1401 item = mrvl_next_item(item + 1); 1402 1403 return ip6 ? mrvl_parse_ip6(item, flow, error) : 1404 mrvl_parse_ip4(item, flow, error); 1405 } 1406 1407 /** 1408 * Parse flow pattern composed of the eth, vlan and ipv4 items. 1409 * 1410 * @param pattern Pointer to the flow pattern table. 1411 * @param flow Pointer to the flow. 1412 * @param error Pointer to the flow error. 1413 * @returns 0 in case of success, negative value otherwise. 1414 */ 1415 static int 1416 mrvl_parse_pattern_eth_vlan_ip4(const struct rte_flow_item pattern[], 1417 struct rte_flow *flow, 1418 struct rte_flow_error *error) 1419 { 1420 return mrvl_parse_pattern_eth_vlan_ip4_ip6(pattern, flow, error, 0); 1421 } 1422 1423 /** 1424 * Parse flow pattern composed of the eth, vlan and ipv6 items. 1425 * 1426 * @param pattern Pointer to the flow pattern table. 1427 * @param flow Pointer to the flow. 1428 * @param error Pointer to the flow error. 1429 * @returns 0 in case of success, negative value otherwise. 1430 */ 1431 static int 1432 mrvl_parse_pattern_eth_vlan_ip6(const struct rte_flow_item pattern[], 1433 struct rte_flow *flow, 1434 struct rte_flow_error *error) 1435 { 1436 return mrvl_parse_pattern_eth_vlan_ip4_ip6(pattern, flow, error, 1); 1437 } 1438 1439 /** 1440 * Parse flow pattern composed of the eth and ip4/ip6 items. 1441 * 1442 * @param pattern Pointer to the flow pattern table. 1443 * @param flow Pointer to the flow. 1444 * @param error Pointer to the flow error. 1445 * @param ip6 1 to parse ip6 item, 0 to parse ip4 item. 1446 * @returns 0 in case of success, negative value otherwise. 1447 */ 1448 static int 1449 mrvl_parse_pattern_eth_ip4_ip6(const struct rte_flow_item pattern[], 1450 struct rte_flow *flow, 1451 struct rte_flow_error *error, int ip6) 1452 { 1453 const struct rte_flow_item *item = mrvl_next_item(pattern); 1454 int ret; 1455 1456 ret = mrvl_parse_eth(item, flow, error); 1457 if (ret) 1458 return ret; 1459 1460 item = mrvl_next_item(item + 1); 1461 1462 return ip6 ? mrvl_parse_ip6(item, flow, error) : 1463 mrvl_parse_ip4(item, flow, error); 1464 } 1465 1466 /** 1467 * Parse flow pattern composed of the eth and ipv4 items. 1468 * 1469 * @param pattern Pointer to the flow pattern table. 1470 * @param flow Pointer to the flow. 1471 * @param error Pointer to the flow error. 1472 * @returns 0 in case of success, negative value otherwise. 1473 */ 1474 static inline int 1475 mrvl_parse_pattern_eth_ip4(const struct rte_flow_item pattern[], 1476 struct rte_flow *flow, 1477 struct rte_flow_error *error) 1478 { 1479 return mrvl_parse_pattern_eth_ip4_ip6(pattern, flow, error, 0); 1480 } 1481 1482 /** 1483 * Parse flow pattern composed of the eth and ipv6 items. 1484 * 1485 * @param pattern Pointer to the flow pattern table. 1486 * @param flow Pointer to the flow. 1487 * @param error Pointer to the flow error. 1488 * @returns 0 in case of success, negative value otherwise. 1489 */ 1490 static inline int 1491 mrvl_parse_pattern_eth_ip6(const struct rte_flow_item pattern[], 1492 struct rte_flow *flow, 1493 struct rte_flow_error *error) 1494 { 1495 return mrvl_parse_pattern_eth_ip4_ip6(pattern, flow, error, 1); 1496 } 1497 1498 /** 1499 * Parse flow pattern composed of the eth, ip4 and tcp/udp items. 1500 * 1501 * @param pattern Pointer to the flow pattern table. 1502 * @param flow Pointer to the flow. 1503 * @param error Pointer to the flow error. 1504 * @param tcp 1 to parse tcp item, 0 to parse udp item. 1505 * @returns 0 in case of success, negative value otherwise. 1506 */ 1507 static int 1508 mrvl_parse_pattern_eth_ip4_tcp_udp(const struct rte_flow_item pattern[], 1509 struct rte_flow *flow, 1510 struct rte_flow_error *error, int tcp) 1511 { 1512 const struct rte_flow_item *item = mrvl_next_item(pattern); 1513 int ret; 1514 1515 ret = mrvl_parse_pattern_eth_ip4_ip6(pattern, flow, error, 0); 1516 if (ret) 1517 return ret; 1518 1519 item = mrvl_next_item(item + 1); 1520 item = mrvl_next_item(item + 1); 1521 1522 if (tcp) 1523 return mrvl_parse_tcp(item, flow, error); 1524 1525 return mrvl_parse_udp(item, flow, error); 1526 } 1527 1528 /** 1529 * Parse flow pattern composed of the eth, ipv4 and tcp items. 1530 * 1531 * @param pattern Pointer to the flow pattern table. 1532 * @param flow Pointer to the flow. 1533 * @param error Pointer to the flow error. 1534 * @returns 0 in case of success, negative value otherwise. 1535 */ 1536 static inline int 1537 mrvl_parse_pattern_eth_ip4_tcp(const struct rte_flow_item pattern[], 1538 struct rte_flow *flow, 1539 struct rte_flow_error *error) 1540 { 1541 return mrvl_parse_pattern_eth_ip4_tcp_udp(pattern, flow, error, 1); 1542 } 1543 1544 /** 1545 * Parse flow pattern composed of the eth, ipv4 and udp items. 1546 * 1547 * @param pattern Pointer to the flow pattern table. 1548 * @param flow Pointer to the flow. 1549 * @param error Pointer to the flow error. 1550 * @returns 0 in case of success, negative value otherwise. 1551 */ 1552 static inline int 1553 mrvl_parse_pattern_eth_ip4_udp(const struct rte_flow_item pattern[], 1554 struct rte_flow *flow, 1555 struct rte_flow_error *error) 1556 { 1557 return mrvl_parse_pattern_eth_ip4_tcp_udp(pattern, flow, error, 0); 1558 } 1559 1560 /** 1561 * Parse flow pattern composed of the eth, ipv6 and tcp/udp items. 1562 * 1563 * @param pattern Pointer to the flow pattern table. 1564 * @param flow Pointer to the flow. 1565 * @param error Pointer to the flow error. 1566 * @param tcp 1 to parse tcp item, 0 to parse udp item. 1567 * @returns 0 in case of success, negative value otherwise. 1568 */ 1569 static int 1570 mrvl_parse_pattern_eth_ip6_tcp_udp(const struct rte_flow_item pattern[], 1571 struct rte_flow *flow, 1572 struct rte_flow_error *error, int tcp) 1573 { 1574 const struct rte_flow_item *item = mrvl_next_item(pattern); 1575 int ret; 1576 1577 ret = mrvl_parse_pattern_eth_ip4_ip6(pattern, flow, error, 1); 1578 if (ret) 1579 return ret; 1580 1581 item = mrvl_next_item(item + 1); 1582 item = mrvl_next_item(item + 1); 1583 1584 if (tcp) 1585 return mrvl_parse_tcp(item, flow, error); 1586 1587 return mrvl_parse_udp(item, flow, error); 1588 } 1589 1590 /** 1591 * Parse flow pattern composed of the eth, ipv6 and tcp items. 1592 * 1593 * @param pattern Pointer to the flow pattern table. 1594 * @param flow Pointer to the flow. 1595 * @param error Pointer to the flow error. 1596 * @returns 0 in case of success, negative value otherwise. 1597 */ 1598 static inline int 1599 mrvl_parse_pattern_eth_ip6_tcp(const struct rte_flow_item pattern[], 1600 struct rte_flow *flow, 1601 struct rte_flow_error *error) 1602 { 1603 return mrvl_parse_pattern_eth_ip6_tcp_udp(pattern, flow, error, 1); 1604 } 1605 1606 /** 1607 * Parse flow pattern composed of the eth, ipv6 and udp items. 1608 * 1609 * @param pattern Pointer to the flow pattern table. 1610 * @param flow Pointer to the flow. 1611 * @param error Pointer to the flow error. 1612 * @returns 0 in case of success, negative value otherwise. 1613 */ 1614 static inline int 1615 mrvl_parse_pattern_eth_ip6_udp(const struct rte_flow_item pattern[], 1616 struct rte_flow *flow, 1617 struct rte_flow_error *error) 1618 { 1619 return mrvl_parse_pattern_eth_ip6_tcp_udp(pattern, flow, error, 0); 1620 } 1621 1622 /** 1623 * Parse flow pattern composed of the vlan item. 1624 * 1625 * @param pattern Pointer to the flow pattern table. 1626 * @param flow Pointer to the flow. 1627 * @param error Pointer to the flow error. 1628 * @returns 0 in case of success, negative value otherwise. 1629 */ 1630 static int 1631 mrvl_parse_pattern_vlan(const struct rte_flow_item pattern[], 1632 struct rte_flow *flow, 1633 struct rte_flow_error *error) 1634 { 1635 const struct rte_flow_item *item = mrvl_next_item(pattern); 1636 1637 return mrvl_parse_vlan(item, flow, error); 1638 } 1639 1640 /** 1641 * Parse flow pattern composed of the vlan and ip4/ip6 items. 1642 * 1643 * @param pattern Pointer to the flow pattern table. 1644 * @param flow Pointer to the flow. 1645 * @param error Pointer to the flow error. 1646 * @param ip6 1 to parse ip6 item, 0 to parse ip4 item. 1647 * @returns 0 in case of success, negative value otherwise. 1648 */ 1649 static int 1650 mrvl_parse_pattern_vlan_ip4_ip6(const struct rte_flow_item pattern[], 1651 struct rte_flow *flow, 1652 struct rte_flow_error *error, int ip6) 1653 { 1654 const struct rte_flow_item *item = mrvl_next_item(pattern); 1655 int ret; 1656 1657 ret = mrvl_parse_vlan(item, flow, error); 1658 if (ret) 1659 return ret; 1660 1661 item = mrvl_next_item(item + 1); 1662 1663 return ip6 ? mrvl_parse_ip6(item, flow, error) : 1664 mrvl_parse_ip4(item, flow, error); 1665 } 1666 1667 /** 1668 * Parse flow pattern composed of the vlan and ipv4 items. 1669 * 1670 * @param pattern Pointer to the flow pattern table. 1671 * @param flow Pointer to the flow. 1672 * @param error Pointer to the flow error. 1673 * @returns 0 in case of success, negative value otherwise. 1674 */ 1675 static inline int 1676 mrvl_parse_pattern_vlan_ip4(const struct rte_flow_item pattern[], 1677 struct rte_flow *flow, 1678 struct rte_flow_error *error) 1679 { 1680 return mrvl_parse_pattern_vlan_ip4_ip6(pattern, flow, error, 0); 1681 } 1682 1683 /** 1684 * Parse flow pattern composed of the vlan, ipv4 and tcp/udp items. 1685 * 1686 * @param pattern Pointer to the flow pattern table. 1687 * @param flow Pointer to the flow. 1688 * @param error Pointer to the flow error. 1689 * @returns 0 in case of success, negative value otherwise. 1690 */ 1691 static int 1692 mrvl_parse_pattern_vlan_ip_tcp_udp(const struct rte_flow_item pattern[], 1693 struct rte_flow *flow, 1694 struct rte_flow_error *error, int tcp) 1695 { 1696 const struct rte_flow_item *item = mrvl_next_item(pattern); 1697 int ret; 1698 1699 ret = mrvl_parse_pattern_vlan_ip4_ip6(pattern, flow, error, 0); 1700 if (ret) 1701 return ret; 1702 1703 item = mrvl_next_item(item + 1); 1704 item = mrvl_next_item(item + 1); 1705 1706 if (tcp) 1707 return mrvl_parse_tcp(item, flow, error); 1708 1709 return mrvl_parse_udp(item, flow, error); 1710 } 1711 1712 /** 1713 * Parse flow pattern composed of the vlan, ipv4 and tcp items. 1714 * 1715 * @param pattern Pointer to the flow pattern table. 1716 * @param flow Pointer to the flow. 1717 * @param error Pointer to the flow error. 1718 * @returns 0 in case of success, negative value otherwise. 1719 */ 1720 static inline int 1721 mrvl_parse_pattern_vlan_ip_tcp(const struct rte_flow_item pattern[], 1722 struct rte_flow *flow, 1723 struct rte_flow_error *error) 1724 { 1725 return mrvl_parse_pattern_vlan_ip_tcp_udp(pattern, flow, error, 1); 1726 } 1727 1728 /** 1729 * Parse flow pattern composed of the vlan, ipv4 and udp items. 1730 * 1731 * @param pattern Pointer to the flow pattern table. 1732 * @param flow Pointer to the flow. 1733 * @param error Pointer to the flow error. 1734 * @returns 0 in case of success, negative value otherwise. 1735 */ 1736 static inline int 1737 mrvl_parse_pattern_vlan_ip_udp(const struct rte_flow_item pattern[], 1738 struct rte_flow *flow, 1739 struct rte_flow_error *error) 1740 { 1741 return mrvl_parse_pattern_vlan_ip_tcp_udp(pattern, flow, error, 0); 1742 } 1743 1744 /** 1745 * Parse flow pattern composed of the vlan and ipv6 items. 1746 * 1747 * @param pattern Pointer to the flow pattern table. 1748 * @param flow Pointer to the flow. 1749 * @param error Pointer to the flow error. 1750 * @returns 0 in case of success, negative value otherwise. 1751 */ 1752 static inline int 1753 mrvl_parse_pattern_vlan_ip6(const struct rte_flow_item pattern[], 1754 struct rte_flow *flow, 1755 struct rte_flow_error *error) 1756 { 1757 return mrvl_parse_pattern_vlan_ip4_ip6(pattern, flow, error, 1); 1758 } 1759 1760 /** 1761 * Parse flow pattern composed of the vlan, ipv6 and tcp/udp items. 1762 * 1763 * @param pattern Pointer to the flow pattern table. 1764 * @param flow Pointer to the flow. 1765 * @param error Pointer to the flow error. 1766 * @returns 0 in case of success, negative value otherwise. 1767 */ 1768 static int 1769 mrvl_parse_pattern_vlan_ip6_tcp_udp(const struct rte_flow_item pattern[], 1770 struct rte_flow *flow, 1771 struct rte_flow_error *error, int tcp) 1772 { 1773 const struct rte_flow_item *item = mrvl_next_item(pattern); 1774 int ret; 1775 1776 ret = mrvl_parse_pattern_vlan_ip4_ip6(pattern, flow, error, 1); 1777 if (ret) 1778 return ret; 1779 1780 item = mrvl_next_item(item + 1); 1781 item = mrvl_next_item(item + 1); 1782 1783 if (tcp) 1784 return mrvl_parse_tcp(item, flow, error); 1785 1786 return mrvl_parse_udp(item, flow, error); 1787 } 1788 1789 /** 1790 * Parse flow pattern composed of the vlan, ipv6 and tcp items. 1791 * 1792 * @param pattern Pointer to the flow pattern table. 1793 * @param flow Pointer to the flow. 1794 * @param error Pointer to the flow error. 1795 * @returns 0 in case of success, negative value otherwise. 1796 */ 1797 static inline int 1798 mrvl_parse_pattern_vlan_ip6_tcp(const struct rte_flow_item pattern[], 1799 struct rte_flow *flow, 1800 struct rte_flow_error *error) 1801 { 1802 return mrvl_parse_pattern_vlan_ip6_tcp_udp(pattern, flow, error, 1); 1803 } 1804 1805 /** 1806 * Parse flow pattern composed of the vlan, ipv6 and udp items. 1807 * 1808 * @param pattern Pointer to the flow pattern table. 1809 * @param flow Pointer to the flow. 1810 * @param error Pointer to the flow error. 1811 * @returns 0 in case of success, negative value otherwise. 1812 */ 1813 static inline int 1814 mrvl_parse_pattern_vlan_ip6_udp(const struct rte_flow_item pattern[], 1815 struct rte_flow *flow, 1816 struct rte_flow_error *error) 1817 { 1818 return mrvl_parse_pattern_vlan_ip6_tcp_udp(pattern, flow, error, 0); 1819 } 1820 1821 /** 1822 * Parse flow pattern composed of the ip4/ip6 item. 1823 * 1824 * @param pattern Pointer to the flow pattern table. 1825 * @param flow Pointer to the flow. 1826 * @param error Pointer to the flow error. 1827 * @param ip6 1 to parse ip6 item, 0 to parse ip4 item. 1828 * @returns 0 in case of success, negative value otherwise. 1829 */ 1830 static int 1831 mrvl_parse_pattern_ip4_ip6(const struct rte_flow_item pattern[], 1832 struct rte_flow *flow, 1833 struct rte_flow_error *error, int ip6) 1834 { 1835 const struct rte_flow_item *item = mrvl_next_item(pattern); 1836 1837 return ip6 ? mrvl_parse_ip6(item, flow, error) : 1838 mrvl_parse_ip4(item, flow, error); 1839 } 1840 1841 /** 1842 * Parse flow pattern composed of the ipv4 item. 1843 * 1844 * @param pattern Pointer to the flow pattern table. 1845 * @param flow Pointer to the flow. 1846 * @param error Pointer to the flow error. 1847 * @returns 0 in case of success, negative value otherwise. 1848 */ 1849 static inline int 1850 mrvl_parse_pattern_ip4(const struct rte_flow_item pattern[], 1851 struct rte_flow *flow, 1852 struct rte_flow_error *error) 1853 { 1854 return mrvl_parse_pattern_ip4_ip6(pattern, flow, error, 0); 1855 } 1856 1857 /** 1858 * Parse flow pattern composed of the ipv6 item. 1859 * 1860 * @param pattern Pointer to the flow pattern table. 1861 * @param flow Pointer to the flow. 1862 * @param error Pointer to the flow error. 1863 * @returns 0 in case of success, negative value otherwise. 1864 */ 1865 static inline int 1866 mrvl_parse_pattern_ip6(const struct rte_flow_item pattern[], 1867 struct rte_flow *flow, 1868 struct rte_flow_error *error) 1869 { 1870 return mrvl_parse_pattern_ip4_ip6(pattern, flow, error, 1); 1871 } 1872 1873 /** 1874 * Parse flow pattern composed of the ip4/ip6 and tcp items. 1875 * 1876 * @param pattern Pointer to the flow pattern table. 1877 * @param flow Pointer to the flow. 1878 * @param error Pointer to the flow error. 1879 * @param ip6 1 to parse ip6 item, 0 to parse ip4 item. 1880 * @returns 0 in case of success, negative value otherwise. 1881 */ 1882 static int 1883 mrvl_parse_pattern_ip4_ip6_tcp(const struct rte_flow_item pattern[], 1884 struct rte_flow *flow, 1885 struct rte_flow_error *error, int ip6) 1886 { 1887 const struct rte_flow_item *item = mrvl_next_item(pattern); 1888 int ret; 1889 1890 ret = ip6 ? mrvl_parse_ip6(item, flow, error) : 1891 mrvl_parse_ip4(item, flow, error); 1892 if (ret) 1893 return ret; 1894 1895 item = mrvl_next_item(item + 1); 1896 1897 return mrvl_parse_tcp(item, flow, error); 1898 } 1899 1900 /** 1901 * Parse flow pattern composed of the ipv4 and tcp items. 1902 * 1903 * @param pattern Pointer to the flow pattern table. 1904 * @param flow Pointer to the flow. 1905 * @param error Pointer to the flow error. 1906 * @returns 0 in case of success, negative value otherwise. 1907 */ 1908 static inline int 1909 mrvl_parse_pattern_ip4_tcp(const struct rte_flow_item pattern[], 1910 struct rte_flow *flow, 1911 struct rte_flow_error *error) 1912 { 1913 return mrvl_parse_pattern_ip4_ip6_tcp(pattern, flow, error, 0); 1914 } 1915 1916 /** 1917 * Parse flow pattern composed of the ipv6 and tcp items. 1918 * 1919 * @param pattern Pointer to the flow pattern table. 1920 * @param flow Pointer to the flow. 1921 * @param error Pointer to the flow error. 1922 * @returns 0 in case of success, negative value otherwise. 1923 */ 1924 static inline int 1925 mrvl_parse_pattern_ip6_tcp(const struct rte_flow_item pattern[], 1926 struct rte_flow *flow, 1927 struct rte_flow_error *error) 1928 { 1929 return mrvl_parse_pattern_ip4_ip6_tcp(pattern, flow, error, 1); 1930 } 1931 1932 /** 1933 * Parse flow pattern composed of the ipv4/ipv6 and udp items. 1934 * 1935 * @param pattern Pointer to the flow pattern table. 1936 * @param flow Pointer to the flow. 1937 * @param error Pointer to the flow error. 1938 * @param ip6 1 to parse ip6 item, 0 to parse ip4 item. 1939 * @returns 0 in case of success, negative value otherwise. 1940 */ 1941 static int 1942 mrvl_parse_pattern_ip4_ip6_udp(const struct rte_flow_item pattern[], 1943 struct rte_flow *flow, 1944 struct rte_flow_error *error, int ip6) 1945 { 1946 const struct rte_flow_item *item = mrvl_next_item(pattern); 1947 int ret; 1948 1949 ret = ip6 ? mrvl_parse_ip6(item, flow, error) : 1950 mrvl_parse_ip4(item, flow, error); 1951 if (ret) 1952 return ret; 1953 1954 item = mrvl_next_item(item + 1); 1955 1956 return mrvl_parse_udp(item, flow, error); 1957 } 1958 1959 /** 1960 * Parse flow pattern composed of the ipv4 and udp items. 1961 * 1962 * @param pattern Pointer to the flow pattern table. 1963 * @param flow Pointer to the flow. 1964 * @param error Pointer to the flow error. 1965 * @returns 0 in case of success, negative value otherwise. 1966 */ 1967 static inline int 1968 mrvl_parse_pattern_ip4_udp(const struct rte_flow_item pattern[], 1969 struct rte_flow *flow, 1970 struct rte_flow_error *error) 1971 { 1972 return mrvl_parse_pattern_ip4_ip6_udp(pattern, flow, error, 0); 1973 } 1974 1975 /** 1976 * Parse flow pattern composed of the ipv6 and udp items. 1977 * 1978 * @param pattern Pointer to the flow pattern table. 1979 * @param flow Pointer to the flow. 1980 * @param error Pointer to the flow error. 1981 * @returns 0 in case of success, negative value otherwise. 1982 */ 1983 static inline int 1984 mrvl_parse_pattern_ip6_udp(const struct rte_flow_item pattern[], 1985 struct rte_flow *flow, 1986 struct rte_flow_error *error) 1987 { 1988 return mrvl_parse_pattern_ip4_ip6_udp(pattern, flow, error, 1); 1989 } 1990 1991 /** 1992 * Parse flow pattern composed of the tcp item. 1993 * 1994 * @param pattern Pointer to the flow pattern table. 1995 * @param flow Pointer to the flow. 1996 * @param error Pointer to the flow error. 1997 * @returns 0 in case of success, negative value otherwise. 1998 */ 1999 static int 2000 mrvl_parse_pattern_tcp(const struct rte_flow_item pattern[], 2001 struct rte_flow *flow, 2002 struct rte_flow_error *error) 2003 { 2004 const struct rte_flow_item *item = mrvl_next_item(pattern); 2005 2006 return mrvl_parse_tcp(item, flow, error); 2007 } 2008 2009 /** 2010 * Parse flow pattern composed of the udp item. 2011 * 2012 * @param pattern Pointer to the flow pattern table. 2013 * @param flow Pointer to the flow. 2014 * @param error Pointer to the flow error. 2015 * @returns 0 in case of success, negative value otherwise. 2016 */ 2017 static int 2018 mrvl_parse_pattern_udp(const struct rte_flow_item pattern[], 2019 struct rte_flow *flow, 2020 struct rte_flow_error *error) 2021 { 2022 const struct rte_flow_item *item = mrvl_next_item(pattern); 2023 2024 return mrvl_parse_udp(item, flow, error); 2025 } 2026 2027 /** 2028 * Structure used to map specific flow pattern to the pattern parse callback 2029 * which will iterate over each pattern item and extract relevant data. 2030 */ 2031 static const struct { 2032 const enum rte_flow_item_type *pattern; 2033 int (*parse)(const struct rte_flow_item pattern[], 2034 struct rte_flow *flow, 2035 struct rte_flow_error *error); 2036 } mrvl_patterns[] = { 2037 { pattern_eth, mrvl_parse_pattern_eth }, 2038 { pattern_eth_vlan, mrvl_parse_pattern_eth_vlan }, 2039 { pattern_eth_vlan_ip, mrvl_parse_pattern_eth_vlan_ip4 }, 2040 { pattern_eth_vlan_ip6, mrvl_parse_pattern_eth_vlan_ip6 }, 2041 { pattern_eth_ip4, mrvl_parse_pattern_eth_ip4 }, 2042 { pattern_eth_ip4_tcp, mrvl_parse_pattern_eth_ip4_tcp }, 2043 { pattern_eth_ip4_udp, mrvl_parse_pattern_eth_ip4_udp }, 2044 { pattern_eth_ip6, mrvl_parse_pattern_eth_ip6 }, 2045 { pattern_eth_ip6_tcp, mrvl_parse_pattern_eth_ip6_tcp }, 2046 { pattern_eth_ip6_udp, mrvl_parse_pattern_eth_ip6_udp }, 2047 { pattern_vlan, mrvl_parse_pattern_vlan }, 2048 { pattern_vlan_ip, mrvl_parse_pattern_vlan_ip4 }, 2049 { pattern_vlan_ip_tcp, mrvl_parse_pattern_vlan_ip_tcp }, 2050 { pattern_vlan_ip_udp, mrvl_parse_pattern_vlan_ip_udp }, 2051 { pattern_vlan_ip6, mrvl_parse_pattern_vlan_ip6 }, 2052 { pattern_vlan_ip6_tcp, mrvl_parse_pattern_vlan_ip6_tcp }, 2053 { pattern_vlan_ip6_udp, mrvl_parse_pattern_vlan_ip6_udp }, 2054 { pattern_ip, mrvl_parse_pattern_ip4 }, 2055 { pattern_ip_tcp, mrvl_parse_pattern_ip4_tcp }, 2056 { pattern_ip_udp, mrvl_parse_pattern_ip4_udp }, 2057 { pattern_ip6, mrvl_parse_pattern_ip6 }, 2058 { pattern_ip6_tcp, mrvl_parse_pattern_ip6_tcp }, 2059 { pattern_ip6_udp, mrvl_parse_pattern_ip6_udp }, 2060 { pattern_tcp, mrvl_parse_pattern_tcp }, 2061 { pattern_udp, mrvl_parse_pattern_udp } 2062 }; 2063 2064 /** 2065 * Check whether provided pattern matches any of the supported ones. 2066 * 2067 * @param type_pattern Pointer to the pattern type. 2068 * @param item_pattern Pointer to the flow pattern. 2069 * @returns 1 in case of success, 0 value otherwise. 2070 */ 2071 static int 2072 mrvl_patterns_match(const enum rte_flow_item_type *type_pattern, 2073 const struct rte_flow_item *item_pattern) 2074 { 2075 const enum rte_flow_item_type *type = type_pattern; 2076 const struct rte_flow_item *item = item_pattern; 2077 2078 for (;;) { 2079 if (item->type == RTE_FLOW_ITEM_TYPE_VOID) { 2080 item++; 2081 continue; 2082 } 2083 2084 if (*type == RTE_FLOW_ITEM_TYPE_END || 2085 item->type == RTE_FLOW_ITEM_TYPE_END) 2086 break; 2087 2088 if (*type != item->type) 2089 break; 2090 2091 item++; 2092 type++; 2093 } 2094 2095 return *type == item->type; 2096 } 2097 2098 /** 2099 * Parse flow attribute. 2100 * 2101 * This will check whether the provided attribute's flags are supported. 2102 * 2103 * @param priv Unused 2104 * @param attr Pointer to the flow attribute. 2105 * @param flow Unused 2106 * @param error Pointer to the flow error. 2107 * @returns 0 in case of success, negative value otherwise. 2108 */ 2109 static int 2110 mrvl_flow_parse_attr(struct mrvl_priv *priv __rte_unused, 2111 const struct rte_flow_attr *attr, 2112 struct rte_flow *flow __rte_unused, 2113 struct rte_flow_error *error) 2114 { 2115 if (!attr) { 2116 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ATTR, 2117 NULL, "NULL attribute"); 2118 return -rte_errno; 2119 } 2120 2121 if (attr->group) { 2122 rte_flow_error_set(error, ENOTSUP, 2123 RTE_FLOW_ERROR_TYPE_ATTR_GROUP, NULL, 2124 "Groups are not supported"); 2125 return -rte_errno; 2126 } 2127 if (attr->priority) { 2128 rte_flow_error_set(error, ENOTSUP, 2129 RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, NULL, 2130 "Priorities are not supported"); 2131 return -rte_errno; 2132 } 2133 if (!attr->ingress) { 2134 rte_flow_error_set(error, ENOTSUP, 2135 RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, NULL, 2136 "Only ingress is supported"); 2137 return -rte_errno; 2138 } 2139 if (attr->egress) { 2140 rte_flow_error_set(error, ENOTSUP, 2141 RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, NULL, 2142 "Egress is not supported"); 2143 return -rte_errno; 2144 } 2145 if (attr->transfer) { 2146 rte_flow_error_set(error, ENOTSUP, 2147 RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER, NULL, 2148 "Transfer is not supported"); 2149 return -rte_errno; 2150 } 2151 2152 return 0; 2153 } 2154 2155 /** 2156 * Parse flow pattern. 2157 * 2158 * Specific classifier rule will be created as well. 2159 * 2160 * @param priv Unused 2161 * @param pattern Pointer to the flow pattern. 2162 * @param flow Pointer to the flow. 2163 * @param error Pointer to the flow error. 2164 * @returns 0 in case of success, negative value otherwise. 2165 */ 2166 static int 2167 mrvl_flow_parse_pattern(struct mrvl_priv *priv __rte_unused, 2168 const struct rte_flow_item pattern[], 2169 struct rte_flow *flow, 2170 struct rte_flow_error *error) 2171 { 2172 unsigned int i; 2173 int ret; 2174 2175 for (i = 0; i < RTE_DIM(mrvl_patterns); i++) { 2176 if (!mrvl_patterns_match(mrvl_patterns[i].pattern, pattern)) 2177 continue; 2178 2179 ret = mrvl_patterns[i].parse(pattern, flow, error); 2180 if (ret) 2181 mrvl_free_all_key_mask(&flow->rule); 2182 2183 return ret; 2184 } 2185 2186 rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, NULL, 2187 "Unsupported pattern"); 2188 2189 return -rte_errno; 2190 } 2191 2192 /** 2193 * Parse flow actions. 2194 * 2195 * @param priv Pointer to the port's private data. 2196 * @param actions Pointer the action table. 2197 * @param flow Pointer to the flow. 2198 * @param error Pointer to the flow error. 2199 * @returns 0 in case of success, negative value otherwise. 2200 */ 2201 static int 2202 mrvl_flow_parse_actions(struct mrvl_priv *priv, 2203 const struct rte_flow_action actions[], 2204 struct rte_flow *flow, 2205 struct rte_flow_error *error) 2206 { 2207 const struct rte_flow_action *action = actions; 2208 int specified = 0; 2209 2210 for (; action->type != RTE_FLOW_ACTION_TYPE_END; action++) { 2211 if (action->type == RTE_FLOW_ACTION_TYPE_VOID) 2212 continue; 2213 2214 if (action->type == RTE_FLOW_ACTION_TYPE_DROP) { 2215 flow->cos.ppio = priv->ppio; 2216 flow->cos.tc = 0; 2217 flow->action.type = PP2_CLS_TBL_ACT_DROP; 2218 flow->action.cos = &flow->cos; 2219 specified++; 2220 } else if (action->type == RTE_FLOW_ACTION_TYPE_QUEUE) { 2221 const struct rte_flow_action_queue *q = 2222 (const struct rte_flow_action_queue *) 2223 action->conf; 2224 2225 if (q->index > priv->nb_rx_queues) { 2226 rte_flow_error_set(error, EINVAL, 2227 RTE_FLOW_ERROR_TYPE_ACTION, 2228 NULL, 2229 "Queue index out of range"); 2230 return -rte_errno; 2231 } 2232 2233 if (priv->rxq_map[q->index].tc == MRVL_UNKNOWN_TC) { 2234 /* 2235 * Unknown TC mapping, mapping will not have 2236 * a correct queue. 2237 */ 2238 MRVL_LOG(ERR, 2239 "Unknown TC mapping for queue %hu eth%hhu", 2240 q->index, priv->ppio_id); 2241 2242 rte_flow_error_set(error, EFAULT, 2243 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, 2244 NULL, NULL); 2245 return -rte_errno; 2246 } 2247 2248 MRVL_LOG(DEBUG, 2249 "Action: Assign packets to queue %d, tc:%d, q:%d", 2250 q->index, priv->rxq_map[q->index].tc, 2251 priv->rxq_map[q->index].inq); 2252 2253 flow->cos.ppio = priv->ppio; 2254 flow->cos.tc = priv->rxq_map[q->index].tc; 2255 flow->action.type = PP2_CLS_TBL_ACT_DONE; 2256 flow->action.cos = &flow->cos; 2257 specified++; 2258 } else if (action->type == RTE_FLOW_ACTION_TYPE_METER) { 2259 const struct rte_flow_action_meter *meter; 2260 struct mrvl_mtr *mtr; 2261 2262 meter = action->conf; 2263 if (!meter) 2264 return -rte_flow_error_set(error, EINVAL, 2265 RTE_FLOW_ERROR_TYPE_ACTION, 2266 NULL, "Invalid meter\n"); 2267 2268 LIST_FOREACH(mtr, &priv->mtrs, next) 2269 if (mtr->mtr_id == meter->mtr_id) 2270 break; 2271 2272 if (!mtr) 2273 return -rte_flow_error_set(error, EINVAL, 2274 RTE_FLOW_ERROR_TYPE_ACTION, 2275 NULL, 2276 "Meter id does not exist\n"); 2277 2278 if (!mtr->shared && mtr->refcnt) 2279 return -rte_flow_error_set(error, EPERM, 2280 RTE_FLOW_ERROR_TYPE_ACTION, 2281 NULL, 2282 "Meter cannot be shared\n"); 2283 2284 /* 2285 * In case cos has already been set 2286 * do not modify it. 2287 */ 2288 if (!flow->cos.ppio) { 2289 flow->cos.ppio = priv->ppio; 2290 flow->cos.tc = 0; 2291 } 2292 2293 flow->action.type = PP2_CLS_TBL_ACT_DONE; 2294 flow->action.cos = &flow->cos; 2295 flow->action.plcr = mtr->enabled ? mtr->plcr : NULL; 2296 flow->mtr = mtr; 2297 mtr->refcnt++; 2298 specified++; 2299 } else { 2300 rte_flow_error_set(error, ENOTSUP, 2301 RTE_FLOW_ERROR_TYPE_ACTION, NULL, 2302 "Action not supported"); 2303 return -rte_errno; 2304 } 2305 } 2306 2307 if (!specified) { 2308 rte_flow_error_set(error, EINVAL, 2309 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 2310 "Action not specified"); 2311 return -rte_errno; 2312 } 2313 2314 return 0; 2315 } 2316 2317 /** 2318 * Parse flow attribute, pattern and actions. 2319 * 2320 * @param priv Pointer to the port's private data. 2321 * @param attr Pointer to the flow attribute. 2322 * @param pattern Pointer to the flow pattern. 2323 * @param actions Pointer to the flow actions. 2324 * @param flow Pointer to the flow. 2325 * @param error Pointer to the flow error. 2326 * @returns 0 on success, negative value otherwise. 2327 */ 2328 static int 2329 mrvl_flow_parse(struct mrvl_priv *priv, const struct rte_flow_attr *attr, 2330 const struct rte_flow_item pattern[], 2331 const struct rte_flow_action actions[], 2332 struct rte_flow *flow, 2333 struct rte_flow_error *error) 2334 { 2335 int ret; 2336 2337 ret = mrvl_flow_parse_attr(priv, attr, flow, error); 2338 if (ret) 2339 return ret; 2340 2341 ret = mrvl_flow_parse_pattern(priv, pattern, flow, error); 2342 if (ret) 2343 return ret; 2344 2345 return mrvl_flow_parse_actions(priv, actions, flow, error); 2346 } 2347 2348 /** 2349 * Get engine type for the given flow. 2350 * 2351 * @param field Pointer to the flow. 2352 * @returns The type of the engine. 2353 */ 2354 static inline enum pp2_cls_tbl_type 2355 mrvl_engine_type(const struct rte_flow *flow) 2356 { 2357 int i, size = 0; 2358 2359 for (i = 0; i < flow->rule.num_fields; i++) 2360 size += flow->rule.fields[i].size; 2361 2362 /* 2363 * For maskable engine type the key size must be up to 8 bytes. 2364 * For keys with size bigger than 8 bytes, engine type must 2365 * be set to exact match. 2366 */ 2367 if (size > 8) 2368 return PP2_CLS_TBL_EXACT_MATCH; 2369 2370 return PP2_CLS_TBL_MASKABLE; 2371 } 2372 2373 /** 2374 * Create classifier table. 2375 * 2376 * @param dev Pointer to the device. 2377 * @param flow Pointer to the very first flow. 2378 * @returns 0 in case of success, negative value otherwise. 2379 */ 2380 static int 2381 mrvl_create_cls_table(struct rte_eth_dev *dev, struct rte_flow *first_flow) 2382 { 2383 struct mrvl_priv *priv = dev->data->dev_private; 2384 struct pp2_cls_tbl_key *key = &priv->cls_tbl_params.key; 2385 int ret; 2386 2387 if (priv->cls_tbl) { 2388 pp2_cls_tbl_deinit(priv->cls_tbl); 2389 priv->cls_tbl = NULL; 2390 } 2391 2392 memset(&priv->cls_tbl_params, 0, sizeof(priv->cls_tbl_params)); 2393 2394 priv->cls_tbl_params.type = mrvl_engine_type(first_flow); 2395 MRVL_LOG(INFO, "Setting cls search engine type to %s", 2396 priv->cls_tbl_params.type == PP2_CLS_TBL_EXACT_MATCH ? 2397 "exact" : "maskable"); 2398 priv->cls_tbl_params.max_num_rules = MRVL_CLS_MAX_NUM_RULES; 2399 priv->cls_tbl_params.default_act.type = PP2_CLS_TBL_ACT_DONE; 2400 priv->cls_tbl_params.default_act.cos = &first_flow->cos; 2401 2402 if (first_flow->pattern & F_DMAC) { 2403 key->proto_field[key->num_fields].proto = MV_NET_PROTO_ETH; 2404 key->proto_field[key->num_fields].field.eth = MV_NET_ETH_F_DA; 2405 key->key_size += 6; 2406 key->num_fields += 1; 2407 } 2408 2409 if (first_flow->pattern & F_SMAC) { 2410 key->proto_field[key->num_fields].proto = MV_NET_PROTO_ETH; 2411 key->proto_field[key->num_fields].field.eth = MV_NET_ETH_F_SA; 2412 key->key_size += 6; 2413 key->num_fields += 1; 2414 } 2415 2416 if (first_flow->pattern & F_TYPE) { 2417 key->proto_field[key->num_fields].proto = MV_NET_PROTO_ETH; 2418 key->proto_field[key->num_fields].field.eth = MV_NET_ETH_F_TYPE; 2419 key->key_size += 2; 2420 key->num_fields += 1; 2421 } 2422 2423 if (first_flow->pattern & F_VLAN_ID) { 2424 key->proto_field[key->num_fields].proto = MV_NET_PROTO_VLAN; 2425 key->proto_field[key->num_fields].field.vlan = MV_NET_VLAN_F_ID; 2426 key->key_size += 2; 2427 key->num_fields += 1; 2428 } 2429 2430 if (first_flow->pattern & F_VLAN_PRI) { 2431 key->proto_field[key->num_fields].proto = MV_NET_PROTO_VLAN; 2432 key->proto_field[key->num_fields].field.vlan = 2433 MV_NET_VLAN_F_PRI; 2434 key->key_size += 1; 2435 key->num_fields += 1; 2436 } 2437 2438 if (first_flow->pattern & F_IP4_TOS) { 2439 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP4; 2440 key->proto_field[key->num_fields].field.ipv4 = 2441 MV_NET_IP4_F_DSCP; 2442 key->key_size += 1; 2443 key->num_fields += 1; 2444 } 2445 2446 if (first_flow->pattern & F_IP4_SIP) { 2447 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP4; 2448 key->proto_field[key->num_fields].field.ipv4 = MV_NET_IP4_F_SA; 2449 key->key_size += 4; 2450 key->num_fields += 1; 2451 } 2452 2453 if (first_flow->pattern & F_IP4_DIP) { 2454 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP4; 2455 key->proto_field[key->num_fields].field.ipv4 = MV_NET_IP4_F_DA; 2456 key->key_size += 4; 2457 key->num_fields += 1; 2458 } 2459 2460 if (first_flow->pattern & F_IP4_PROTO) { 2461 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP4; 2462 key->proto_field[key->num_fields].field.ipv4 = 2463 MV_NET_IP4_F_PROTO; 2464 key->key_size += 1; 2465 key->num_fields += 1; 2466 } 2467 2468 if (first_flow->pattern & F_IP6_SIP) { 2469 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP6; 2470 key->proto_field[key->num_fields].field.ipv6 = MV_NET_IP6_F_SA; 2471 key->key_size += 16; 2472 key->num_fields += 1; 2473 } 2474 2475 if (first_flow->pattern & F_IP6_DIP) { 2476 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP6; 2477 key->proto_field[key->num_fields].field.ipv6 = MV_NET_IP6_F_DA; 2478 key->key_size += 16; 2479 key->num_fields += 1; 2480 } 2481 2482 if (first_flow->pattern & F_IP6_FLOW) { 2483 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP6; 2484 key->proto_field[key->num_fields].field.ipv6 = 2485 MV_NET_IP6_F_FLOW; 2486 key->key_size += 3; 2487 key->num_fields += 1; 2488 } 2489 2490 if (first_flow->pattern & F_IP6_NEXT_HDR) { 2491 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP6; 2492 key->proto_field[key->num_fields].field.ipv6 = 2493 MV_NET_IP6_F_NEXT_HDR; 2494 key->key_size += 1; 2495 key->num_fields += 1; 2496 } 2497 2498 if (first_flow->pattern & F_TCP_SPORT) { 2499 key->proto_field[key->num_fields].proto = MV_NET_PROTO_TCP; 2500 key->proto_field[key->num_fields].field.tcp = MV_NET_TCP_F_SP; 2501 key->key_size += 2; 2502 key->num_fields += 1; 2503 } 2504 2505 if (first_flow->pattern & F_TCP_DPORT) { 2506 key->proto_field[key->num_fields].proto = MV_NET_PROTO_TCP; 2507 key->proto_field[key->num_fields].field.tcp = MV_NET_TCP_F_DP; 2508 key->key_size += 2; 2509 key->num_fields += 1; 2510 } 2511 2512 if (first_flow->pattern & F_UDP_SPORT) { 2513 key->proto_field[key->num_fields].proto = MV_NET_PROTO_UDP; 2514 key->proto_field[key->num_fields].field.tcp = MV_NET_TCP_F_SP; 2515 key->key_size += 2; 2516 key->num_fields += 1; 2517 } 2518 2519 if (first_flow->pattern & F_UDP_DPORT) { 2520 key->proto_field[key->num_fields].proto = MV_NET_PROTO_UDP; 2521 key->proto_field[key->num_fields].field.udp = MV_NET_TCP_F_DP; 2522 key->key_size += 2; 2523 key->num_fields += 1; 2524 } 2525 2526 ret = pp2_cls_tbl_init(&priv->cls_tbl_params, &priv->cls_tbl); 2527 if (!ret) 2528 priv->cls_tbl_pattern = first_flow->pattern; 2529 2530 return ret; 2531 } 2532 2533 /** 2534 * Check whether new flow can be added to the table 2535 * 2536 * @param priv Pointer to the port's private data. 2537 * @param flow Pointer to the new flow. 2538 * @return 1 in case flow can be added, 0 otherwise. 2539 */ 2540 static inline int 2541 mrvl_flow_can_be_added(struct mrvl_priv *priv, const struct rte_flow *flow) 2542 { 2543 return flow->pattern == priv->cls_tbl_pattern && 2544 mrvl_engine_type(flow) == priv->cls_tbl_params.type; 2545 } 2546 2547 /** 2548 * DPDK flow create callback called when flow is to be created. 2549 * 2550 * @param dev Pointer to the device. 2551 * @param attr Pointer to the flow attribute. 2552 * @param pattern Pointer to the flow pattern. 2553 * @param actions Pointer to the flow actions. 2554 * @param error Pointer to the flow error. 2555 * @returns Pointer to the created flow in case of success, NULL otherwise. 2556 */ 2557 static struct rte_flow * 2558 mrvl_flow_create(struct rte_eth_dev *dev, 2559 const struct rte_flow_attr *attr, 2560 const struct rte_flow_item pattern[], 2561 const struct rte_flow_action actions[], 2562 struct rte_flow_error *error) 2563 { 2564 struct mrvl_priv *priv = dev->data->dev_private; 2565 struct rte_flow *flow, *first; 2566 int ret; 2567 2568 if (!dev->data->dev_started) { 2569 rte_flow_error_set(error, EINVAL, 2570 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 2571 "Port must be started first\n"); 2572 return NULL; 2573 } 2574 2575 flow = rte_zmalloc_socket(NULL, sizeof(*flow), 0, rte_socket_id()); 2576 if (!flow) 2577 return NULL; 2578 2579 ret = mrvl_flow_parse(priv, attr, pattern, actions, flow, error); 2580 if (ret) 2581 goto out; 2582 2583 /* 2584 * Four cases here: 2585 * 2586 * 1. In case table does not exist - create one. 2587 * 2. In case table exists, is empty and new flow cannot be added 2588 * recreate table. 2589 * 3. In case table is not empty and new flow matches table format 2590 * add it. 2591 * 4. Otherwise flow cannot be added. 2592 */ 2593 first = LIST_FIRST(&priv->flows); 2594 if (!priv->cls_tbl) { 2595 ret = mrvl_create_cls_table(dev, flow); 2596 } else if (!first && !mrvl_flow_can_be_added(priv, flow)) { 2597 ret = mrvl_create_cls_table(dev, flow); 2598 } else if (mrvl_flow_can_be_added(priv, flow)) { 2599 ret = 0; 2600 } else { 2601 rte_flow_error_set(error, EINVAL, 2602 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 2603 "Pattern does not match cls table format\n"); 2604 goto out; 2605 } 2606 2607 if (ret) { 2608 rte_flow_error_set(error, EINVAL, 2609 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 2610 "Failed to create cls table\n"); 2611 goto out; 2612 } 2613 2614 ret = pp2_cls_tbl_add_rule(priv->cls_tbl, &flow->rule, &flow->action); 2615 if (ret) { 2616 rte_flow_error_set(error, EINVAL, 2617 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 2618 "Failed to add rule\n"); 2619 goto out; 2620 } 2621 2622 LIST_INSERT_HEAD(&priv->flows, flow, next); 2623 2624 return flow; 2625 out: 2626 rte_free(flow); 2627 return NULL; 2628 } 2629 2630 /** 2631 * Remove classifier rule associated with given flow. 2632 * 2633 * @param priv Pointer to the port's private data. 2634 * @param flow Pointer to the flow. 2635 * @param error Pointer to the flow error. 2636 * @returns 0 in case of success, negative value otherwise. 2637 */ 2638 static int 2639 mrvl_flow_remove(struct mrvl_priv *priv, struct rte_flow *flow, 2640 struct rte_flow_error *error) 2641 { 2642 int ret; 2643 2644 if (!priv->cls_tbl) { 2645 rte_flow_error_set(error, EINVAL, 2646 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 2647 "Classifier table not initialized"); 2648 return -rte_errno; 2649 } 2650 2651 ret = pp2_cls_tbl_remove_rule(priv->cls_tbl, &flow->rule); 2652 if (ret) { 2653 rte_flow_error_set(error, EINVAL, 2654 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 2655 "Failed to remove rule"); 2656 return -rte_errno; 2657 } 2658 2659 mrvl_free_all_key_mask(&flow->rule); 2660 2661 if (flow->mtr) { 2662 flow->mtr->refcnt--; 2663 flow->mtr = NULL; 2664 } 2665 2666 return 0; 2667 } 2668 2669 /** 2670 * DPDK flow destroy callback called when flow is to be removed. 2671 * 2672 * @param dev Pointer to the device. 2673 * @param flow Pointer to the flow. 2674 * @param error Pointer to the flow error. 2675 * @returns 0 in case of success, negative value otherwise. 2676 */ 2677 static int 2678 mrvl_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow, 2679 struct rte_flow_error *error) 2680 { 2681 struct mrvl_priv *priv = dev->data->dev_private; 2682 struct rte_flow *f; 2683 int ret; 2684 2685 LIST_FOREACH(f, &priv->flows, next) { 2686 if (f == flow) 2687 break; 2688 } 2689 2690 if (!flow) { 2691 rte_flow_error_set(error, EINVAL, 2692 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 2693 "Rule was not found"); 2694 return -rte_errno; 2695 } 2696 2697 LIST_REMOVE(f, next); 2698 2699 ret = mrvl_flow_remove(priv, flow, error); 2700 if (ret) 2701 return ret; 2702 2703 rte_free(flow); 2704 2705 return 0; 2706 } 2707 2708 /** 2709 * DPDK flow callback called to verify given attribute, pattern and actions. 2710 * 2711 * @param dev Pointer to the device. 2712 * @param attr Pointer to the flow attribute. 2713 * @param pattern Pointer to the flow pattern. 2714 * @param actions Pointer to the flow actions. 2715 * @param error Pointer to the flow error. 2716 * @returns 0 on success, negative value otherwise. 2717 */ 2718 static int 2719 mrvl_flow_validate(struct rte_eth_dev *dev, 2720 const struct rte_flow_attr *attr, 2721 const struct rte_flow_item pattern[], 2722 const struct rte_flow_action actions[], 2723 struct rte_flow_error *error) 2724 { 2725 static struct rte_flow *flow; 2726 2727 flow = mrvl_flow_create(dev, attr, pattern, actions, error); 2728 if (!flow) 2729 return -rte_errno; 2730 2731 mrvl_flow_destroy(dev, flow, error); 2732 2733 return 0; 2734 } 2735 2736 /** 2737 * DPDK flow flush callback called when flows are to be flushed. 2738 * 2739 * @param dev Pointer to the device. 2740 * @param error Pointer to the flow error. 2741 * @returns 0 in case of success, negative value otherwise. 2742 */ 2743 static int 2744 mrvl_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error) 2745 { 2746 struct mrvl_priv *priv = dev->data->dev_private; 2747 2748 while (!LIST_EMPTY(&priv->flows)) { 2749 struct rte_flow *flow = LIST_FIRST(&priv->flows); 2750 int ret = mrvl_flow_remove(priv, flow, error); 2751 if (ret) 2752 return ret; 2753 2754 LIST_REMOVE(flow, next); 2755 rte_free(flow); 2756 } 2757 2758 return 0; 2759 } 2760 2761 /** 2762 * DPDK flow isolate callback called to isolate port. 2763 * 2764 * @param dev Pointer to the device. 2765 * @param enable Pass 0/1 to disable/enable port isolation. 2766 * @param error Pointer to the flow error. 2767 * @returns 0 in case of success, negative value otherwise. 2768 */ 2769 static int 2770 mrvl_flow_isolate(struct rte_eth_dev *dev, int enable, 2771 struct rte_flow_error *error) 2772 { 2773 struct mrvl_priv *priv = dev->data->dev_private; 2774 2775 if (dev->data->dev_started) { 2776 rte_flow_error_set(error, EBUSY, 2777 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, 2778 NULL, "Port must be stopped first\n"); 2779 return -rte_errno; 2780 } 2781 2782 priv->isolated = enable; 2783 2784 return 0; 2785 } 2786 2787 const struct rte_flow_ops mrvl_flow_ops = { 2788 .validate = mrvl_flow_validate, 2789 .create = mrvl_flow_create, 2790 .destroy = mrvl_flow_destroy, 2791 .flush = mrvl_flow_flush, 2792 .isolate = mrvl_flow_isolate 2793 }; 2794 2795 /** 2796 * Initialize flow resources. 2797 * 2798 * @param dev Pointer to the device. 2799 */ 2800 void 2801 mrvl_flow_init(struct rte_eth_dev *dev) 2802 { 2803 struct mrvl_priv *priv = dev->data->dev_private; 2804 2805 LIST_INIT(&priv->flows); 2806 } 2807 2808 /** 2809 * Cleanup flow resources. 2810 * 2811 * @param dev Pointer to the device. 2812 */ 2813 void 2814 mrvl_flow_deinit(struct rte_eth_dev *dev) 2815 { 2816 struct mrvl_priv *priv = dev->data->dev_private; 2817 2818 mrvl_flow_flush(dev, NULL); 2819 2820 if (priv->cls_tbl) { 2821 pp2_cls_tbl_deinit(priv->cls_tbl); 2822 priv->cls_tbl = NULL; 2823 } 2824 } 2825