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 #define MRVL_VLAN_ID_MASK 0x0fff 24 #define MRVL_VLAN_PRI_MASK 0x7000 25 #define MRVL_IPV4_DSCP_MASK 0xfc 26 #define MRVL_IPV4_ADDR_MASK 0xffffffff 27 #define MRVL_IPV6_FLOW_MASK 0x0fffff 28 29 /** 30 * Allocate memory for classifier rule key and mask fields. 31 * 32 * @param field Pointer to the classifier rule. 33 * @returns 0 in case of success, negative value otherwise. 34 */ 35 static int 36 mrvl_alloc_key_mask(struct pp2_cls_rule_key_field *field) 37 { 38 unsigned int id = rte_socket_id(); 39 40 field->key = rte_zmalloc_socket(NULL, MRVL_CLS_STR_SIZE_MAX, 0, id); 41 if (!field->key) 42 goto out; 43 44 field->mask = rte_zmalloc_socket(NULL, MRVL_CLS_STR_SIZE_MAX, 0, id); 45 if (!field->mask) 46 goto out_mask; 47 48 return 0; 49 out_mask: 50 rte_free(field->key); 51 out: 52 field->key = NULL; 53 field->mask = NULL; 54 return -1; 55 } 56 57 /** 58 * Free memory allocated for classifier rule key and mask fields. 59 * 60 * @param field Pointer to the classifier rule. 61 */ 62 static void 63 mrvl_free_key_mask(struct pp2_cls_rule_key_field *field) 64 { 65 rte_free(field->key); 66 rte_free(field->mask); 67 field->key = NULL; 68 field->mask = NULL; 69 } 70 71 /** 72 * Free memory allocated for all classifier rule key and mask fields. 73 * 74 * @param rule Pointer to the classifier table rule. 75 */ 76 static void 77 mrvl_free_all_key_mask(struct pp2_cls_tbl_rule *rule) 78 { 79 int i; 80 81 for (i = 0; i < rule->num_fields; i++) 82 mrvl_free_key_mask(&rule->fields[i]); 83 rule->num_fields = 0; 84 } 85 86 /* 87 * Initialize rte flow item parsing. 88 * 89 * @param item Pointer to the flow item. 90 * @param spec_ptr Pointer to the specific item pointer. 91 * @param mask_ptr Pointer to the specific item's mask pointer. 92 * @def_mask Pointer to the default mask. 93 * @size Size of the flow item. 94 * @error Pointer to the rte flow error. 95 * @returns 0 in case of success, negative value otherwise. 96 */ 97 static int 98 mrvl_parse_init(const struct rte_flow_item *item, 99 const void **spec_ptr, 100 const void **mask_ptr, 101 const void *def_mask, 102 unsigned int size, 103 struct rte_flow_error *error) 104 { 105 const uint8_t *spec; 106 const uint8_t *mask; 107 const uint8_t *last; 108 uint8_t zeros[size]; 109 110 memset(zeros, 0, size); 111 112 if (item == NULL) { 113 rte_flow_error_set(error, EINVAL, 114 RTE_FLOW_ERROR_TYPE_ITEM, NULL, 115 "NULL item\n"); 116 return -rte_errno; 117 } 118 119 if ((item->last != NULL || item->mask != NULL) && item->spec == NULL) { 120 rte_flow_error_set(error, EINVAL, 121 RTE_FLOW_ERROR_TYPE_ITEM, item, 122 "Mask or last is set without spec\n"); 123 return -rte_errno; 124 } 125 126 /* 127 * If "mask" is not set, default mask is used, 128 * but if default mask is NULL, "mask" should be set. 129 */ 130 if (item->mask == NULL) { 131 if (def_mask == NULL) { 132 rte_flow_error_set(error, EINVAL, 133 RTE_FLOW_ERROR_TYPE_ITEM, NULL, 134 "Mask should be specified\n"); 135 return -rte_errno; 136 } 137 138 mask = (const uint8_t *)def_mask; 139 } else { 140 mask = (const uint8_t *)item->mask; 141 } 142 143 spec = (const uint8_t *)item->spec; 144 last = (const uint8_t *)item->last; 145 146 if (spec == NULL) { 147 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, 148 NULL, "Spec should be specified\n"); 149 return -rte_errno; 150 } 151 152 /* 153 * If field values in "last" are either 0 or equal to the corresponding 154 * values in "spec" then they are ignored. 155 */ 156 if (last != NULL && 157 !memcmp(last, zeros, size) && 158 memcmp(last, spec, size) != 0) { 159 rte_flow_error_set(error, ENOTSUP, 160 RTE_FLOW_ERROR_TYPE_ITEM, NULL, 161 "Ranging is not supported\n"); 162 return -rte_errno; 163 } 164 165 *spec_ptr = spec; 166 *mask_ptr = mask; 167 168 return 0; 169 } 170 171 /** 172 * Parse the eth flow item. 173 * 174 * This will create classifier rule that matches either destination or source 175 * mac. 176 * 177 * @param spec Pointer to the specific flow item. 178 * @param mask Pointer to the specific flow item's mask. 179 * @param parse_dst Parse either destination or source mac address. 180 * @param flow Pointer to the flow. 181 * @return 0 in case of success, negative error value otherwise. 182 */ 183 static int 184 mrvl_parse_mac(const struct rte_flow_item_eth *spec, 185 const struct rte_flow_item_eth *mask, 186 int parse_dst, struct rte_flow *flow) 187 { 188 struct pp2_cls_rule_key_field *key_field; 189 const uint8_t *k, *m; 190 191 if (parse_dst) { 192 k = spec->dst.addr_bytes; 193 m = mask->dst.addr_bytes; 194 195 flow->table_key.proto_field[flow->rule.num_fields].field.eth = 196 MV_NET_ETH_F_DA; 197 } else { 198 k = spec->src.addr_bytes; 199 m = mask->src.addr_bytes; 200 201 flow->table_key.proto_field[flow->rule.num_fields].field.eth = 202 MV_NET_ETH_F_SA; 203 } 204 205 key_field = &flow->rule.fields[flow->rule.num_fields]; 206 mrvl_alloc_key_mask(key_field); 207 key_field->size = 6; 208 209 snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, 210 RTE_ETHER_ADDR_PRT_FMT, 211 k[0], k[1], k[2], k[3], k[4], k[5]); 212 213 snprintf((char *)key_field->mask, MRVL_CLS_STR_SIZE_MAX, 214 RTE_ETHER_ADDR_PRT_FMT, 215 m[0], m[1], m[2], m[3], m[4], m[5]); 216 217 flow->table_key.proto_field[flow->rule.num_fields].proto = 218 MV_NET_PROTO_ETH; 219 flow->table_key.key_size += key_field->size; 220 221 flow->rule.num_fields += 1; 222 223 return 0; 224 } 225 226 /** 227 * Helper for parsing the eth flow item destination mac address. 228 * 229 * @param spec Pointer to the specific flow item. 230 * @param mask Pointer to the specific flow item's mask. 231 * @param flow Pointer to the flow. 232 * @return 0 in case of success, negative error value otherwise. 233 */ 234 static inline int 235 mrvl_parse_dmac(const struct rte_flow_item_eth *spec, 236 const struct rte_flow_item_eth *mask, 237 struct rte_flow *flow) 238 { 239 return mrvl_parse_mac(spec, mask, 1, flow); 240 } 241 242 /** 243 * Helper for parsing the eth flow item source mac address. 244 * 245 * @param spec Pointer to the specific flow item. 246 * @param mask Pointer to the specific flow item's mask. 247 * @param flow Pointer to the flow. 248 * @return 0 in case of success, negative error value otherwise. 249 */ 250 static inline int 251 mrvl_parse_smac(const struct rte_flow_item_eth *spec, 252 const struct rte_flow_item_eth *mask, 253 struct rte_flow *flow) 254 { 255 return mrvl_parse_mac(spec, mask, 0, flow); 256 } 257 258 /** 259 * Parse the ether type field of the eth flow item. 260 * 261 * @param spec Pointer to the specific flow item. 262 * @param mask Pointer to the specific flow item's mask. 263 * @param flow Pointer to the flow. 264 * @return 0 in case of success, negative error value otherwise. 265 */ 266 static int 267 mrvl_parse_type(const struct rte_flow_item_eth *spec, 268 const struct rte_flow_item_eth *mask __rte_unused, 269 struct rte_flow *flow) 270 { 271 struct pp2_cls_rule_key_field *key_field; 272 uint16_t k; 273 274 key_field = &flow->rule.fields[flow->rule.num_fields]; 275 mrvl_alloc_key_mask(key_field); 276 key_field->size = 2; 277 278 k = rte_be_to_cpu_16(spec->type); 279 snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k); 280 281 flow->table_key.proto_field[flow->rule.num_fields].proto = 282 MV_NET_PROTO_ETH; 283 flow->table_key.proto_field[flow->rule.num_fields].field.eth = 284 MV_NET_ETH_F_TYPE; 285 flow->table_key.key_size += key_field->size; 286 287 flow->rule.num_fields += 1; 288 289 return 0; 290 } 291 292 /** 293 * Parse the vid field of the vlan rte flow item. 294 * 295 * This will create classifier rule that matches vid. 296 * 297 * @param spec Pointer to the specific flow item. 298 * @param mask Pointer to the specific flow item's mask. 299 * @param flow Pointer to the flow. 300 * @return 0 in case of success, negative error value otherwise. 301 */ 302 static int 303 mrvl_parse_vlan_id(const struct rte_flow_item_vlan *spec, 304 const struct rte_flow_item_vlan *mask __rte_unused, 305 struct rte_flow *flow) 306 { 307 struct pp2_cls_rule_key_field *key_field; 308 uint16_t k; 309 310 key_field = &flow->rule.fields[flow->rule.num_fields]; 311 mrvl_alloc_key_mask(key_field); 312 key_field->size = 2; 313 314 k = rte_be_to_cpu_16(spec->tci) & MRVL_VLAN_ID_MASK; 315 snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k); 316 317 flow->table_key.proto_field[flow->rule.num_fields].proto = 318 MV_NET_PROTO_VLAN; 319 flow->table_key.proto_field[flow->rule.num_fields].field.vlan = 320 MV_NET_VLAN_F_ID; 321 flow->table_key.key_size += key_field->size; 322 323 flow->rule.num_fields += 1; 324 325 return 0; 326 } 327 328 /** 329 * Parse the pri field of the vlan rte flow item. 330 * 331 * This will create classifier rule that matches pri. 332 * 333 * @param spec Pointer to the specific flow item. 334 * @param mask Pointer to the specific flow item's mask. 335 * @param flow Pointer to the flow. 336 * @return 0 in case of success, negative error value otherwise. 337 */ 338 static int 339 mrvl_parse_vlan_pri(const struct rte_flow_item_vlan *spec, 340 const struct rte_flow_item_vlan *mask __rte_unused, 341 struct rte_flow *flow) 342 { 343 struct pp2_cls_rule_key_field *key_field; 344 uint16_t k; 345 346 key_field = &flow->rule.fields[flow->rule.num_fields]; 347 mrvl_alloc_key_mask(key_field); 348 key_field->size = 1; 349 350 k = (rte_be_to_cpu_16(spec->tci) & MRVL_VLAN_PRI_MASK) >> 13; 351 snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k); 352 353 flow->table_key.proto_field[flow->rule.num_fields].proto = 354 MV_NET_PROTO_VLAN; 355 flow->table_key.proto_field[flow->rule.num_fields].field.vlan = 356 MV_NET_VLAN_F_PRI; 357 flow->table_key.key_size += key_field->size; 358 359 flow->rule.num_fields += 1; 360 361 return 0; 362 } 363 364 /** 365 * Parse the dscp field of the ipv4 rte flow item. 366 * 367 * This will create classifier rule that matches dscp field. 368 * 369 * @param spec Pointer to the specific flow item. 370 * @param mask Pointer to the specific flow item's mask. 371 * @param flow Pointer to the flow. 372 * @return 0 in case of success, negative error value otherwise. 373 */ 374 static int 375 mrvl_parse_ip4_dscp(const struct rte_flow_item_ipv4 *spec, 376 const struct rte_flow_item_ipv4 *mask, 377 struct rte_flow *flow) 378 { 379 struct pp2_cls_rule_key_field *key_field; 380 uint8_t k, m; 381 382 key_field = &flow->rule.fields[flow->rule.num_fields]; 383 mrvl_alloc_key_mask(key_field); 384 key_field->size = 1; 385 386 k = (spec->hdr.type_of_service & MRVL_IPV4_DSCP_MASK) >> 2; 387 m = (mask->hdr.type_of_service & MRVL_IPV4_DSCP_MASK) >> 2; 388 snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k); 389 snprintf((char *)key_field->mask, MRVL_CLS_STR_SIZE_MAX, "%u", m); 390 391 flow->table_key.proto_field[flow->rule.num_fields].proto = 392 MV_NET_PROTO_IP4; 393 flow->table_key.proto_field[flow->rule.num_fields].field.ipv4 = 394 MV_NET_IP4_F_DSCP; 395 flow->table_key.key_size += key_field->size; 396 397 flow->rule.num_fields += 1; 398 399 return 0; 400 } 401 402 /** 403 * Parse either source or destination ip addresses of the ipv4 flow item. 404 * 405 * This will create classifier rule that matches either destination 406 * or source ip field. 407 * 408 * @param spec Pointer to the specific flow item. 409 * @param mask Pointer to the specific flow item's mask. 410 * @param parse_dst Parse either destination or source ip address. 411 * @param flow Pointer to the flow. 412 * @return 0 in case of success, negative error value otherwise. 413 */ 414 static int 415 mrvl_parse_ip4_addr(const struct rte_flow_item_ipv4 *spec, 416 const struct rte_flow_item_ipv4 *mask, 417 int parse_dst, struct rte_flow *flow) 418 { 419 struct pp2_cls_rule_key_field *key_field; 420 struct in_addr k; 421 uint32_t m; 422 423 memset(&k, 0, sizeof(k)); 424 if (parse_dst) { 425 k.s_addr = spec->hdr.dst_addr; 426 m = rte_be_to_cpu_32(mask->hdr.dst_addr); 427 428 flow->table_key.proto_field[flow->rule.num_fields].field.ipv4 = 429 MV_NET_IP4_F_DA; 430 } else { 431 k.s_addr = spec->hdr.src_addr; 432 m = rte_be_to_cpu_32(mask->hdr.src_addr); 433 434 flow->table_key.proto_field[flow->rule.num_fields].field.ipv4 = 435 MV_NET_IP4_F_SA; 436 } 437 438 key_field = &flow->rule.fields[flow->rule.num_fields]; 439 mrvl_alloc_key_mask(key_field); 440 key_field->size = 4; 441 442 inet_ntop(AF_INET, &k, (char *)key_field->key, MRVL_CLS_STR_SIZE_MAX); 443 snprintf((char *)key_field->mask, MRVL_CLS_STR_SIZE_MAX, "0x%x", m); 444 445 flow->table_key.proto_field[flow->rule.num_fields].proto = 446 MV_NET_PROTO_IP4; 447 flow->table_key.key_size += key_field->size; 448 449 flow->rule.num_fields += 1; 450 451 return 0; 452 } 453 454 /** 455 * Helper for parsing destination ip of the ipv4 flow item. 456 * 457 * @param spec Pointer to the specific flow item. 458 * @param mask Pointer to the specific flow item's mask. 459 * @param flow Pointer to the flow. 460 * @return 0 in case of success, negative error value otherwise. 461 */ 462 static inline int 463 mrvl_parse_ip4_dip(const struct rte_flow_item_ipv4 *spec, 464 const struct rte_flow_item_ipv4 *mask, 465 struct rte_flow *flow) 466 { 467 return mrvl_parse_ip4_addr(spec, mask, 1, flow); 468 } 469 470 /** 471 * Helper for parsing source ip of the ipv4 flow item. 472 * 473 * @param spec Pointer to the specific flow item. 474 * @param mask Pointer to the specific flow item's mask. 475 * @param flow Pointer to the flow. 476 * @return 0 in case of success, negative error value otherwise. 477 */ 478 static inline int 479 mrvl_parse_ip4_sip(const struct rte_flow_item_ipv4 *spec, 480 const struct rte_flow_item_ipv4 *mask, 481 struct rte_flow *flow) 482 { 483 return mrvl_parse_ip4_addr(spec, mask, 0, flow); 484 } 485 486 /** 487 * Parse the proto field of the ipv4 rte flow item. 488 * 489 * This will create classifier rule that matches proto field. 490 * 491 * @param spec Pointer to the specific flow item. 492 * @param mask Pointer to the specific flow item's mask. 493 * @param flow Pointer to the flow. 494 * @return 0 in case of success, negative error value otherwise. 495 */ 496 static int 497 mrvl_parse_ip4_proto(const struct rte_flow_item_ipv4 *spec, 498 const struct rte_flow_item_ipv4 *mask __rte_unused, 499 struct rte_flow *flow) 500 { 501 struct pp2_cls_rule_key_field *key_field; 502 uint8_t k = spec->hdr.next_proto_id; 503 504 key_field = &flow->rule.fields[flow->rule.num_fields]; 505 mrvl_alloc_key_mask(key_field); 506 key_field->size = 1; 507 508 snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k); 509 510 flow->table_key.proto_field[flow->rule.num_fields].proto = 511 MV_NET_PROTO_IP4; 512 flow->table_key.proto_field[flow->rule.num_fields].field.ipv4 = 513 MV_NET_IP4_F_PROTO; 514 flow->table_key.key_size += key_field->size; 515 516 flow->rule.num_fields += 1; 517 518 return 0; 519 } 520 521 /** 522 * Parse either source or destination ip addresses of the ipv6 rte flow item. 523 * 524 * This will create classifier rule that matches either destination 525 * or source ip field. 526 * 527 * @param spec Pointer to the specific flow item. 528 * @param mask Pointer to the specific flow item's mask. 529 * @param parse_dst Parse either destination or source ipv6 address. 530 * @param flow Pointer to the flow. 531 * @return 0 in case of success, negative error value otherwise. 532 */ 533 static int 534 mrvl_parse_ip6_addr(const struct rte_flow_item_ipv6 *spec, 535 const struct rte_flow_item_ipv6 *mask, 536 int parse_dst, struct rte_flow *flow) 537 { 538 struct pp2_cls_rule_key_field *key_field; 539 int size = sizeof(spec->hdr.dst_addr); 540 struct in6_addr k, m; 541 542 memset(&k, 0, sizeof(k)); 543 if (parse_dst) { 544 memcpy(k.s6_addr, spec->hdr.dst_addr, size); 545 memcpy(m.s6_addr, mask->hdr.dst_addr, size); 546 547 flow->table_key.proto_field[flow->rule.num_fields].field.ipv6 = 548 MV_NET_IP6_F_DA; 549 } else { 550 memcpy(k.s6_addr, spec->hdr.src_addr, size); 551 memcpy(m.s6_addr, mask->hdr.src_addr, size); 552 553 flow->table_key.proto_field[flow->rule.num_fields].field.ipv6 = 554 MV_NET_IP6_F_SA; 555 } 556 557 key_field = &flow->rule.fields[flow->rule.num_fields]; 558 mrvl_alloc_key_mask(key_field); 559 key_field->size = 16; 560 561 inet_ntop(AF_INET6, &k, (char *)key_field->key, MRVL_CLS_STR_SIZE_MAX); 562 inet_ntop(AF_INET6, &m, (char *)key_field->mask, MRVL_CLS_STR_SIZE_MAX); 563 564 flow->table_key.proto_field[flow->rule.num_fields].proto = 565 MV_NET_PROTO_IP6; 566 flow->table_key.key_size += key_field->size; 567 568 flow->rule.num_fields += 1; 569 570 return 0; 571 } 572 573 /** 574 * Helper for parsing destination ip of the ipv6 flow item. 575 * 576 * @param spec Pointer to the specific flow item. 577 * @param mask Pointer to the specific flow item's mask. 578 * @param flow Pointer to the flow. 579 * @return 0 in case of success, negative error value otherwise. 580 */ 581 static inline int 582 mrvl_parse_ip6_dip(const struct rte_flow_item_ipv6 *spec, 583 const struct rte_flow_item_ipv6 *mask, 584 struct rte_flow *flow) 585 { 586 return mrvl_parse_ip6_addr(spec, mask, 1, flow); 587 } 588 589 /** 590 * Helper for parsing source ip of the ipv6 flow item. 591 * 592 * @param spec Pointer to the specific flow item. 593 * @param mask Pointer to the specific flow item's mask. 594 * @param flow Pointer to the flow. 595 * @return 0 in case of success, negative error value otherwise. 596 */ 597 static inline int 598 mrvl_parse_ip6_sip(const struct rte_flow_item_ipv6 *spec, 599 const struct rte_flow_item_ipv6 *mask, 600 struct rte_flow *flow) 601 { 602 return mrvl_parse_ip6_addr(spec, mask, 0, flow); 603 } 604 605 /** 606 * Parse the flow label of the ipv6 flow item. 607 * 608 * This will create classifier rule that matches flow field. 609 * 610 * @param spec Pointer to the specific flow item. 611 * @param mask Pointer to the specific flow item's mask. 612 * @param flow Pointer to the flow. 613 * @return 0 in case of success, negative error value otherwise. 614 */ 615 static int 616 mrvl_parse_ip6_flow(const struct rte_flow_item_ipv6 *spec, 617 const struct rte_flow_item_ipv6 *mask, 618 struct rte_flow *flow) 619 { 620 struct pp2_cls_rule_key_field *key_field; 621 uint32_t k = rte_be_to_cpu_32(spec->hdr.vtc_flow) & MRVL_IPV6_FLOW_MASK, 622 m = rte_be_to_cpu_32(mask->hdr.vtc_flow) & MRVL_IPV6_FLOW_MASK; 623 624 key_field = &flow->rule.fields[flow->rule.num_fields]; 625 mrvl_alloc_key_mask(key_field); 626 key_field->size = 3; 627 628 snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k); 629 snprintf((char *)key_field->mask, MRVL_CLS_STR_SIZE_MAX, "%u", m); 630 631 flow->table_key.proto_field[flow->rule.num_fields].proto = 632 MV_NET_PROTO_IP6; 633 flow->table_key.proto_field[flow->rule.num_fields].field.ipv6 = 634 MV_NET_IP6_F_FLOW; 635 flow->table_key.key_size += key_field->size; 636 637 flow->rule.num_fields += 1; 638 639 return 0; 640 } 641 642 /** 643 * Parse the next header of the ipv6 flow item. 644 * 645 * This will create classifier rule that matches next header field. 646 * 647 * @param spec Pointer to the specific flow item. 648 * @param mask Pointer to the specific flow item's mask. 649 * @param flow Pointer to the flow. 650 * @return 0 in case of success, negative error value otherwise. 651 */ 652 static int 653 mrvl_parse_ip6_next_hdr(const struct rte_flow_item_ipv6 *spec, 654 const struct rte_flow_item_ipv6 *mask __rte_unused, 655 struct rte_flow *flow) 656 { 657 struct pp2_cls_rule_key_field *key_field; 658 uint8_t k = spec->hdr.proto; 659 660 key_field = &flow->rule.fields[flow->rule.num_fields]; 661 mrvl_alloc_key_mask(key_field); 662 key_field->size = 1; 663 664 snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k); 665 666 flow->table_key.proto_field[flow->rule.num_fields].proto = 667 MV_NET_PROTO_IP6; 668 flow->table_key.proto_field[flow->rule.num_fields].field.ipv6 = 669 MV_NET_IP6_F_NEXT_HDR; 670 flow->table_key.key_size += key_field->size; 671 672 flow->rule.num_fields += 1; 673 674 return 0; 675 } 676 677 /** 678 * Parse destination or source port of the tcp flow item. 679 * 680 * This will create classifier rule that matches either destination or 681 * source tcp port. 682 * 683 * @param spec Pointer to the specific flow item. 684 * @param mask Pointer to the specific flow item's mask. 685 * @param parse_dst Parse either destination or source port. 686 * @param flow Pointer to the flow. 687 * @return 0 in case of success, negative error value otherwise. 688 */ 689 static int 690 mrvl_parse_tcp_port(const struct rte_flow_item_tcp *spec, 691 const struct rte_flow_item_tcp *mask __rte_unused, 692 int parse_dst, struct rte_flow *flow) 693 { 694 struct pp2_cls_rule_key_field *key_field; 695 uint16_t k; 696 697 key_field = &flow->rule.fields[flow->rule.num_fields]; 698 mrvl_alloc_key_mask(key_field); 699 key_field->size = 2; 700 701 if (parse_dst) { 702 k = rte_be_to_cpu_16(spec->hdr.dst_port); 703 704 flow->table_key.proto_field[flow->rule.num_fields].field.tcp = 705 MV_NET_TCP_F_DP; 706 } else { 707 k = rte_be_to_cpu_16(spec->hdr.src_port); 708 709 flow->table_key.proto_field[flow->rule.num_fields].field.tcp = 710 MV_NET_TCP_F_SP; 711 } 712 713 snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k); 714 715 flow->table_key.proto_field[flow->rule.num_fields].proto = 716 MV_NET_PROTO_TCP; 717 flow->table_key.key_size += key_field->size; 718 719 flow->rule.num_fields += 1; 720 721 return 0; 722 } 723 724 /** 725 * Helper for parsing the tcp source port of the tcp flow item. 726 * 727 * @param spec Pointer to the specific flow item. 728 * @param mask Pointer to the specific flow item's mask. 729 * @param flow Pointer to the flow. 730 * @return 0 in case of success, negative error value otherwise. 731 */ 732 static inline int 733 mrvl_parse_tcp_sport(const struct rte_flow_item_tcp *spec, 734 const struct rte_flow_item_tcp *mask, 735 struct rte_flow *flow) 736 { 737 return mrvl_parse_tcp_port(spec, mask, 0, flow); 738 } 739 740 /** 741 * Helper for parsing the tcp destination port of the tcp flow item. 742 * 743 * @param spec Pointer to the specific flow item. 744 * @param mask Pointer to the specific flow item's mask. 745 * @param flow Pointer to the flow. 746 * @return 0 in case of success, negative error value otherwise. 747 */ 748 static inline int 749 mrvl_parse_tcp_dport(const struct rte_flow_item_tcp *spec, 750 const struct rte_flow_item_tcp *mask, 751 struct rte_flow *flow) 752 { 753 return mrvl_parse_tcp_port(spec, mask, 1, flow); 754 } 755 756 /** 757 * Parse destination or source port of the udp flow item. 758 * 759 * This will create classifier rule that matches either destination or 760 * source udp port. 761 * 762 * @param spec Pointer to the specific flow item. 763 * @param mask Pointer to the specific flow item's mask. 764 * @param parse_dst Parse either destination or source port. 765 * @param flow Pointer to the flow. 766 * @return 0 in case of success, negative error value otherwise. 767 */ 768 static int 769 mrvl_parse_udp_port(const struct rte_flow_item_udp *spec, 770 const struct rte_flow_item_udp *mask __rte_unused, 771 int parse_dst, struct rte_flow *flow) 772 { 773 struct pp2_cls_rule_key_field *key_field; 774 uint16_t k; 775 776 key_field = &flow->rule.fields[flow->rule.num_fields]; 777 mrvl_alloc_key_mask(key_field); 778 key_field->size = 2; 779 780 if (parse_dst) { 781 k = rte_be_to_cpu_16(spec->hdr.dst_port); 782 783 flow->table_key.proto_field[flow->rule.num_fields].field.udp = 784 MV_NET_UDP_F_DP; 785 } else { 786 k = rte_be_to_cpu_16(spec->hdr.src_port); 787 788 flow->table_key.proto_field[flow->rule.num_fields].field.udp = 789 MV_NET_UDP_F_SP; 790 } 791 792 snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k); 793 794 flow->table_key.proto_field[flow->rule.num_fields].proto = 795 MV_NET_PROTO_UDP; 796 flow->table_key.key_size += key_field->size; 797 798 flow->rule.num_fields += 1; 799 800 return 0; 801 } 802 803 /** 804 * Helper for parsing the udp source port of the udp flow item. 805 * 806 * @param spec Pointer to the specific flow item. 807 * @param mask Pointer to the specific flow item's mask. 808 * @param flow Pointer to the flow. 809 * @return 0 in case of success, negative error value otherwise. 810 */ 811 static inline int 812 mrvl_parse_udp_sport(const struct rte_flow_item_udp *spec, 813 const struct rte_flow_item_udp *mask, 814 struct rte_flow *flow) 815 { 816 return mrvl_parse_udp_port(spec, mask, 0, flow); 817 } 818 819 /** 820 * Helper for parsing the udp destination port of the udp flow item. 821 * 822 * @param spec Pointer to the specific flow item. 823 * @param mask Pointer to the specific flow item's mask. 824 * @param flow Pointer to the flow. 825 * @return 0 in case of success, negative error value otherwise. 826 */ 827 static inline int 828 mrvl_parse_udp_dport(const struct rte_flow_item_udp *spec, 829 const struct rte_flow_item_udp *mask, 830 struct rte_flow *flow) 831 { 832 return mrvl_parse_udp_port(spec, mask, 1, flow); 833 } 834 835 /** 836 * Parse eth flow item. 837 * 838 * @param item Pointer to the flow item. 839 * @param flow Pointer to the flow. 840 * @param error Pointer to the flow error. 841 * @returns 0 on success, negative value otherwise. 842 */ 843 static int 844 mrvl_parse_eth(const struct rte_flow_item *item, struct rte_flow *flow, 845 struct rte_flow_error *error) 846 { 847 const struct rte_flow_item_eth *spec = NULL, *mask = NULL; 848 struct rte_ether_addr zero; 849 int ret; 850 851 ret = mrvl_parse_init(item, (const void **)&spec, (const void **)&mask, 852 &rte_flow_item_eth_mask, 853 sizeof(struct rte_flow_item_eth), error); 854 if (ret) 855 return ret; 856 857 memset(&zero, 0, sizeof(zero)); 858 859 if (memcmp(&mask->dst, &zero, sizeof(mask->dst))) { 860 ret = mrvl_parse_dmac(spec, mask, flow); 861 if (ret) 862 goto out; 863 } 864 865 if (memcmp(&mask->src, &zero, sizeof(mask->src))) { 866 ret = mrvl_parse_smac(spec, mask, flow); 867 if (ret) 868 goto out; 869 } 870 871 if (mask->type) { 872 MRVL_LOG(WARNING, "eth type mask is ignored"); 873 ret = mrvl_parse_type(spec, mask, flow); 874 if (ret) 875 goto out; 876 } 877 878 return 0; 879 out: 880 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 881 "Reached maximum number of fields in cls tbl key\n"); 882 return -rte_errno; 883 } 884 885 /** 886 * Parse vlan flow item. 887 * 888 * @param item Pointer to the flow item. 889 * @param flow Pointer to the flow. 890 * @param error Pointer to the flow error. 891 * @returns 0 on success, negative value otherwise. 892 */ 893 static int 894 mrvl_parse_vlan(const struct rte_flow_item *item, 895 struct rte_flow *flow, 896 struct rte_flow_error *error) 897 { 898 const struct rte_flow_item_vlan *spec = NULL, *mask = NULL; 899 uint16_t m; 900 int ret, i; 901 902 ret = mrvl_parse_init(item, (const void **)&spec, (const void **)&mask, 903 &rte_flow_item_vlan_mask, 904 sizeof(struct rte_flow_item_vlan), error); 905 if (ret) 906 return ret; 907 908 m = rte_be_to_cpu_16(mask->tci); 909 if (m & MRVL_VLAN_ID_MASK) { 910 MRVL_LOG(WARNING, "vlan id mask is ignored"); 911 ret = mrvl_parse_vlan_id(spec, mask, flow); 912 if (ret) 913 goto out; 914 } 915 916 if (m & MRVL_VLAN_PRI_MASK) { 917 MRVL_LOG(WARNING, "vlan pri mask is ignored"); 918 ret = mrvl_parse_vlan_pri(spec, mask, flow); 919 if (ret) 920 goto out; 921 } 922 923 if (mask->inner_type) { 924 struct rte_flow_item_eth spec_eth = { 925 .type = spec->inner_type, 926 }; 927 struct rte_flow_item_eth mask_eth = { 928 .type = mask->inner_type, 929 }; 930 931 /* TPID is not supported so if ETH_TYPE was selected, 932 * error is return. else, classify eth-type with the tpid value 933 */ 934 for (i = 0; i < flow->rule.num_fields; i++) 935 if (flow->table_key.proto_field[i].proto == 936 MV_NET_PROTO_ETH && 937 flow->table_key.proto_field[i].field.eth == 938 MV_NET_ETH_F_TYPE) { 939 rte_flow_error_set(error, ENOTSUP, 940 RTE_FLOW_ERROR_TYPE_ITEM, 941 item, 942 "VLAN TPID matching is not supported"); 943 return -rte_errno; 944 } 945 946 MRVL_LOG(WARNING, "inner eth type mask is ignored"); 947 ret = mrvl_parse_type(&spec_eth, &mask_eth, flow); 948 if (ret) 949 goto out; 950 } 951 952 return 0; 953 out: 954 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 955 "Reached maximum number of fields in cls tbl key\n"); 956 return -rte_errno; 957 } 958 959 /** 960 * Parse ipv4 flow item. 961 * 962 * @param item Pointer to the flow item. 963 * @param flow Pointer to the flow. 964 * @param error Pointer to the flow error. 965 * @returns 0 on success, negative value otherwise. 966 */ 967 static int 968 mrvl_parse_ip4(const struct rte_flow_item *item, 969 struct rte_flow *flow, 970 struct rte_flow_error *error) 971 { 972 const struct rte_flow_item_ipv4 *spec = NULL, *mask = NULL; 973 int ret; 974 975 ret = mrvl_parse_init(item, (const void **)&spec, (const void **)&mask, 976 &rte_flow_item_ipv4_mask, 977 sizeof(struct rte_flow_item_ipv4), error); 978 if (ret) 979 return ret; 980 981 if (mask->hdr.version_ihl || 982 mask->hdr.total_length || 983 mask->hdr.packet_id || 984 mask->hdr.fragment_offset || 985 mask->hdr.time_to_live || 986 mask->hdr.hdr_checksum) { 987 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, 988 NULL, "Not supported by classifier\n"); 989 return -rte_errno; 990 } 991 992 if (mask->hdr.type_of_service & MRVL_IPV4_DSCP_MASK) { 993 ret = mrvl_parse_ip4_dscp(spec, mask, flow); 994 if (ret) 995 goto out; 996 } 997 998 if (mask->hdr.src_addr) { 999 ret = mrvl_parse_ip4_sip(spec, mask, flow); 1000 if (ret) 1001 goto out; 1002 } 1003 1004 if (mask->hdr.dst_addr) { 1005 ret = mrvl_parse_ip4_dip(spec, mask, flow); 1006 if (ret) 1007 goto out; 1008 } 1009 1010 if (mask->hdr.next_proto_id) { 1011 MRVL_LOG(WARNING, "next proto id mask is ignored"); 1012 ret = mrvl_parse_ip4_proto(spec, mask, flow); 1013 if (ret) 1014 goto out; 1015 } 1016 1017 return 0; 1018 out: 1019 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 1020 "Reached maximum number of fields in cls tbl key\n"); 1021 return -rte_errno; 1022 } 1023 1024 /** 1025 * Parse ipv6 flow item. 1026 * 1027 * @param item Pointer to the flow item. 1028 * @param flow Pointer to the flow. 1029 * @param error Pointer to the flow error. 1030 * @returns 0 on success, negative value otherwise. 1031 */ 1032 static int 1033 mrvl_parse_ip6(const struct rte_flow_item *item, 1034 struct rte_flow *flow, 1035 struct rte_flow_error *error) 1036 { 1037 const struct rte_flow_item_ipv6 *spec = NULL, *mask = NULL; 1038 struct rte_ipv6_hdr zero; 1039 uint32_t flow_mask; 1040 int ret; 1041 1042 ret = mrvl_parse_init(item, (const void **)&spec, 1043 (const void **)&mask, 1044 &rte_flow_item_ipv6_mask, 1045 sizeof(struct rte_flow_item_ipv6), 1046 error); 1047 if (ret) 1048 return ret; 1049 1050 memset(&zero, 0, sizeof(zero)); 1051 1052 if (mask->hdr.payload_len || 1053 mask->hdr.hop_limits) { 1054 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, 1055 NULL, "Not supported by classifier\n"); 1056 return -rte_errno; 1057 } 1058 1059 if (memcmp(mask->hdr.src_addr, 1060 zero.src_addr, sizeof(mask->hdr.src_addr))) { 1061 ret = mrvl_parse_ip6_sip(spec, mask, flow); 1062 if (ret) 1063 goto out; 1064 } 1065 1066 if (memcmp(mask->hdr.dst_addr, 1067 zero.dst_addr, sizeof(mask->hdr.dst_addr))) { 1068 ret = mrvl_parse_ip6_dip(spec, mask, flow); 1069 if (ret) 1070 goto out; 1071 } 1072 1073 flow_mask = rte_be_to_cpu_32(mask->hdr.vtc_flow) & MRVL_IPV6_FLOW_MASK; 1074 if (flow_mask) { 1075 ret = mrvl_parse_ip6_flow(spec, mask, flow); 1076 if (ret) 1077 goto out; 1078 } 1079 1080 if (mask->hdr.proto) { 1081 MRVL_LOG(WARNING, "next header mask is ignored"); 1082 ret = mrvl_parse_ip6_next_hdr(spec, mask, 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 tcp 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_tcp(const struct rte_flow_item *item, 1104 struct rte_flow *flow, 1105 struct rte_flow_error *error) 1106 { 1107 const struct rte_flow_item_tcp *spec = NULL, *mask = NULL; 1108 int ret; 1109 1110 ret = mrvl_parse_init(item, (const void **)&spec, (const void **)&mask, 1111 &rte_flow_item_tcp_mask, 1112 sizeof(struct rte_flow_item_tcp), error); 1113 if (ret) 1114 return ret; 1115 1116 if (mask->hdr.sent_seq || 1117 mask->hdr.recv_ack || 1118 mask->hdr.data_off || 1119 mask->hdr.tcp_flags || 1120 mask->hdr.rx_win || 1121 mask->hdr.cksum || 1122 mask->hdr.tcp_urp) { 1123 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, 1124 NULL, "Not supported by classifier\n"); 1125 return -rte_errno; 1126 } 1127 1128 if (mask->hdr.src_port) { 1129 MRVL_LOG(WARNING, "tcp sport mask is ignored"); 1130 ret = mrvl_parse_tcp_sport(spec, mask, flow); 1131 if (ret) 1132 goto out; 1133 } 1134 1135 if (mask->hdr.dst_port) { 1136 MRVL_LOG(WARNING, "tcp dport mask is ignored"); 1137 ret = mrvl_parse_tcp_dport(spec, mask, flow); 1138 if (ret) 1139 goto out; 1140 } 1141 1142 return 0; 1143 out: 1144 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 1145 "Reached maximum number of fields in cls tbl key\n"); 1146 return -rte_errno; 1147 } 1148 1149 /** 1150 * Parse udp flow item. 1151 * 1152 * @param item Pointer to the flow item. 1153 * @param flow Pointer to the flow. 1154 * @param error Pointer to the flow error. 1155 * @returns 0 on success, negative value otherwise. 1156 */ 1157 static int 1158 mrvl_parse_udp(const struct rte_flow_item *item, 1159 struct rte_flow *flow, 1160 struct rte_flow_error *error) 1161 { 1162 const struct rte_flow_item_udp *spec = NULL, *mask = NULL; 1163 int ret; 1164 1165 ret = mrvl_parse_init(item, (const void **)&spec, (const void **)&mask, 1166 &rte_flow_item_udp_mask, 1167 sizeof(struct rte_flow_item_udp), error); 1168 if (ret) 1169 return ret; 1170 1171 if (mask->hdr.dgram_len || 1172 mask->hdr.dgram_cksum) { 1173 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, 1174 NULL, "Not supported by classifier\n"); 1175 return -rte_errno; 1176 } 1177 1178 if (mask->hdr.src_port) { 1179 MRVL_LOG(WARNING, "udp sport mask is ignored"); 1180 ret = mrvl_parse_udp_sport(spec, mask, flow); 1181 if (ret) 1182 goto out; 1183 } 1184 1185 if (mask->hdr.dst_port) { 1186 MRVL_LOG(WARNING, "udp dport mask is ignored"); 1187 ret = mrvl_parse_udp_dport(spec, mask, flow); 1188 if (ret) 1189 goto out; 1190 } 1191 1192 return 0; 1193 out: 1194 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 1195 "Reached maximum number of fields in cls tbl key\n"); 1196 return -rte_errno; 1197 } 1198 1199 static int 1200 mrvl_string_to_hex_values(const uint8_t *input_string, 1201 uint8_t *hex_key, 1202 uint8_t *length) 1203 { 1204 char tmp_arr[3], tmp_string[MRVL_CLS_STR_SIZE_MAX], *string_iter; 1205 int i; 1206 1207 strcpy(tmp_string, (const char *)input_string); 1208 string_iter = tmp_string; 1209 1210 string_iter += 2; /* skip the '0x' */ 1211 *length = ((*length - 2) + 1) / 2; 1212 1213 for (i = 0; i < *length; i++) { 1214 strncpy(tmp_arr, string_iter, 2); 1215 tmp_arr[2] = '\0'; 1216 if (get_val_securely8(tmp_arr, 16, 1217 &hex_key[*length - 1 - i]) < 0) 1218 return -1; 1219 string_iter += 2; 1220 } 1221 1222 return 0; 1223 } 1224 1225 /** 1226 * Parse raw flow item. 1227 * 1228 * @param item Pointer to the flow item. 1229 * @param flow Pointer to the flow. 1230 * @param error Pointer to the flow error. 1231 * @returns 0 on success, negative value otherwise. 1232 */ 1233 static int 1234 mrvl_parse_raw(const struct rte_flow_item *item, 1235 struct rte_flow *flow, 1236 struct rte_flow_error *error) 1237 { 1238 const struct rte_flow_item_raw *spec = NULL, *mask = NULL; 1239 struct pp2_cls_rule_key_field *key_field; 1240 struct mv_net_udf *udf_params; 1241 uint8_t length; 1242 int ret; 1243 1244 ret = mrvl_parse_init(item, (const void **)&spec, (const void **)&mask, 1245 &rte_flow_item_raw_mask, 1246 sizeof(struct rte_flow_item_raw), error); 1247 if (ret) 1248 return ret; 1249 1250 if (!spec->pattern) { 1251 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC, 1252 NULL, "pattern pointer MUST be given\n"); 1253 return -rte_errno; 1254 } 1255 1256 /* Only hex string is supported; so, it must start with '0x' */ 1257 if (strncmp((const char *)spec->pattern, "0x", 2) != 0) { 1258 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC, 1259 NULL, "'pattern' string must start with '0x'\n"); 1260 return -rte_errno; 1261 } 1262 1263 if (mask->pattern && 1264 strncmp((const char *)mask->pattern, "0x", 2) != 0) { 1265 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC, 1266 NULL, "'mask-pattern' string must start with '0x'\n"); 1267 return -rte_errno; 1268 } 1269 1270 if (mask->search && spec->search) { 1271 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC, 1272 NULL, "'search' option must be '0'\n"); 1273 return -rte_errno; 1274 } 1275 1276 if (mask->offset && spec->offset != 0) { 1277 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC, 1278 NULL, "'offset' option must be '0'\n"); 1279 return -rte_errno; 1280 } 1281 1282 if (!mask->relative || !spec->relative) { 1283 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC, 1284 NULL, "'relative' option must be given and enabled\n"); 1285 return -rte_errno; 1286 } 1287 1288 length = spec->length & mask->length; 1289 if (!length) { 1290 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC, 1291 NULL, "'length' option must be given bigger than '0'\n"); 1292 return -rte_errno; 1293 } 1294 1295 key_field = &flow->rule.fields[flow->rule.num_fields]; 1296 mrvl_alloc_key_mask(key_field); 1297 1298 /* pattern and length refer to string bytes. we need to convert it to 1299 * values. 1300 */ 1301 key_field->size = length; 1302 ret = mrvl_string_to_hex_values(spec->pattern, key_field->key, 1303 &key_field->size); 1304 if (ret) { 1305 rte_flow_error_set(error, EINVAL, 1306 RTE_FLOW_ERROR_TYPE_ITEM_SPEC, 1307 NULL, 1308 "can't convert pattern from string to hex\n"); 1309 return -rte_errno; 1310 } 1311 if (mask->pattern) { 1312 ret = mrvl_string_to_hex_values(mask->pattern, key_field->mask, 1313 &length); 1314 if (ret) { 1315 rte_flow_error_set(error, EINVAL, 1316 RTE_FLOW_ERROR_TYPE_ITEM_SPEC, 1317 NULL, 1318 "can't convert mask-pattern from string to hex\n"); 1319 return -rte_errno; 1320 } 1321 } else { 1322 rte_free(key_field->mask); 1323 key_field->mask = NULL; 1324 } 1325 1326 flow->table_key.proto_field[flow->rule.num_fields].proto = 1327 MV_NET_UDF; 1328 udf_params = 1329 &flow->table_key.proto_field[flow->rule.num_fields].field.udf; 1330 udf_params->id = flow->next_udf_id++; 1331 udf_params->size = key_field->size; 1332 flow->table_key.key_size += key_field->size; 1333 1334 flow->rule.num_fields += 1; 1335 1336 return 0; 1337 } 1338 1339 /** 1340 * Structure used to map specific flow pattern to the pattern parse callback 1341 * which will iterate over each pattern item and extract relevant data. 1342 */ 1343 static const struct { 1344 const enum rte_flow_item_type pattern_type; 1345 int (*parse)(const struct rte_flow_item *pattern, 1346 struct rte_flow *flow, 1347 struct rte_flow_error *error); 1348 } mrvl_patterns[] = { 1349 { RTE_FLOW_ITEM_TYPE_ETH, mrvl_parse_eth }, 1350 { RTE_FLOW_ITEM_TYPE_VLAN, mrvl_parse_vlan }, 1351 { RTE_FLOW_ITEM_TYPE_IPV4, mrvl_parse_ip4 }, 1352 { RTE_FLOW_ITEM_TYPE_IPV6, mrvl_parse_ip6 }, 1353 { RTE_FLOW_ITEM_TYPE_TCP, mrvl_parse_tcp }, 1354 { RTE_FLOW_ITEM_TYPE_UDP, mrvl_parse_udp }, 1355 { RTE_FLOW_ITEM_TYPE_RAW, mrvl_parse_raw }, 1356 { RTE_FLOW_ITEM_TYPE_END, NULL } 1357 }; 1358 1359 /** 1360 * Parse flow attribute. 1361 * 1362 * This will check whether the provided attribute's flags are supported. 1363 * 1364 * @param priv Unused 1365 * @param attr Pointer to the flow attribute. 1366 * @param flow Unused 1367 * @param error Pointer to the flow error. 1368 * @returns 0 in case of success, negative value otherwise. 1369 */ 1370 static int 1371 mrvl_flow_parse_attr(struct mrvl_priv *priv __rte_unused, 1372 const struct rte_flow_attr *attr, 1373 struct rte_flow *flow __rte_unused, 1374 struct rte_flow_error *error) 1375 { 1376 if (!attr) { 1377 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ATTR, 1378 NULL, "NULL attribute"); 1379 return -rte_errno; 1380 } 1381 1382 if (attr->group) { 1383 rte_flow_error_set(error, ENOTSUP, 1384 RTE_FLOW_ERROR_TYPE_ATTR_GROUP, NULL, 1385 "Groups are not supported"); 1386 return -rte_errno; 1387 } 1388 if (attr->priority) { 1389 rte_flow_error_set(error, ENOTSUP, 1390 RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, NULL, 1391 "Priorities are not supported"); 1392 return -rte_errno; 1393 } 1394 if (!attr->ingress) { 1395 rte_flow_error_set(error, ENOTSUP, 1396 RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, NULL, 1397 "Only ingress is supported"); 1398 return -rte_errno; 1399 } 1400 if (attr->egress) { 1401 rte_flow_error_set(error, ENOTSUP, 1402 RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, NULL, 1403 "Egress is not supported"); 1404 return -rte_errno; 1405 } 1406 if (attr->transfer) { 1407 rte_flow_error_set(error, ENOTSUP, 1408 RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER, NULL, 1409 "Transfer is not supported"); 1410 return -rte_errno; 1411 } 1412 1413 return 0; 1414 } 1415 1416 /** 1417 * Parse flow pattern. 1418 * 1419 * Specific classifier rule will be created as well. 1420 * 1421 * @param priv Unused 1422 * @param pattern Pointer to the flow pattern. 1423 * @param flow Pointer to the flow. 1424 * @param error Pointer to the flow error. 1425 * @returns 0 in case of success, negative value otherwise. 1426 */ 1427 static int 1428 mrvl_flow_parse_pattern(struct mrvl_priv *priv __rte_unused, 1429 const struct rte_flow_item pattern[], 1430 struct rte_flow *flow, 1431 struct rte_flow_error *error) 1432 { 1433 unsigned int i, j; 1434 int ret; 1435 1436 for (i = 0; pattern[i].type != RTE_FLOW_ITEM_TYPE_END; i++) { 1437 if (pattern[i].type == RTE_FLOW_ITEM_TYPE_VOID) 1438 continue; 1439 for (j = 0; mrvl_patterns[j].pattern_type != 1440 RTE_FLOW_ITEM_TYPE_END; j++) { 1441 if (mrvl_patterns[j].pattern_type != pattern[i].type) 1442 continue; 1443 1444 if (flow->rule.num_fields >= 1445 PP2_CLS_TBL_MAX_NUM_FIELDS) { 1446 rte_flow_error_set(error, ENOSPC, 1447 RTE_FLOW_ERROR_TYPE_ITEM_NUM, 1448 NULL, 1449 "too many pattern (max %d)"); 1450 return -rte_errno; 1451 } 1452 1453 ret = mrvl_patterns[j].parse(&pattern[i], flow, error); 1454 if (ret) { 1455 mrvl_free_all_key_mask(&flow->rule); 1456 return ret; 1457 } 1458 break; 1459 } 1460 if (mrvl_patterns[j].pattern_type == RTE_FLOW_ITEM_TYPE_END) { 1461 rte_flow_error_set(error, ENOTSUP, 1462 RTE_FLOW_ERROR_TYPE_ITEM, NULL, 1463 "Unsupported pattern"); 1464 return -rte_errno; 1465 } 1466 } 1467 1468 flow->table_key.num_fields = flow->rule.num_fields; 1469 1470 return 0; 1471 } 1472 1473 /** 1474 * Parse flow actions. 1475 * 1476 * @param priv Pointer to the port's private data. 1477 * @param actions Pointer the action table. 1478 * @param flow Pointer to the flow. 1479 * @param error Pointer to the flow error. 1480 * @returns 0 in case of success, negative value otherwise. 1481 */ 1482 static int 1483 mrvl_flow_parse_actions(struct mrvl_priv *priv, 1484 const struct rte_flow_action actions[], 1485 struct rte_flow *flow, 1486 struct rte_flow_error *error) 1487 { 1488 const struct rte_flow_action *action = actions; 1489 int specified = 0; 1490 1491 for (; action->type != RTE_FLOW_ACTION_TYPE_END; action++) { 1492 if (action->type == RTE_FLOW_ACTION_TYPE_VOID) 1493 continue; 1494 1495 if (action->type == RTE_FLOW_ACTION_TYPE_DROP) { 1496 flow->cos.ppio = priv->ppio; 1497 flow->cos.tc = 0; 1498 flow->action.type = PP2_CLS_TBL_ACT_DROP; 1499 flow->action.cos = &flow->cos; 1500 specified++; 1501 } else if (action->type == RTE_FLOW_ACTION_TYPE_QUEUE) { 1502 const struct rte_flow_action_queue *q = 1503 (const struct rte_flow_action_queue *) 1504 action->conf; 1505 1506 if (q->index > priv->nb_rx_queues) { 1507 rte_flow_error_set(error, EINVAL, 1508 RTE_FLOW_ERROR_TYPE_ACTION, 1509 NULL, 1510 "Queue index out of range"); 1511 return -rte_errno; 1512 } 1513 1514 if (priv->rxq_map[q->index].tc == MRVL_UNKNOWN_TC) { 1515 /* 1516 * Unknown TC mapping, mapping will not have 1517 * a correct queue. 1518 */ 1519 MRVL_LOG(ERR, 1520 "Unknown TC mapping for queue %hu eth%hhu", 1521 q->index, priv->ppio_id); 1522 1523 rte_flow_error_set(error, EFAULT, 1524 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, 1525 NULL, NULL); 1526 return -rte_errno; 1527 } 1528 1529 MRVL_LOG(DEBUG, 1530 "Action: Assign packets to queue %d, tc:%d, q:%d", 1531 q->index, priv->rxq_map[q->index].tc, 1532 priv->rxq_map[q->index].inq); 1533 1534 flow->cos.ppio = priv->ppio; 1535 flow->cos.tc = priv->rxq_map[q->index].tc; 1536 flow->action.type = PP2_CLS_TBL_ACT_DONE; 1537 flow->action.cos = &flow->cos; 1538 specified++; 1539 } else if (action->type == RTE_FLOW_ACTION_TYPE_METER) { 1540 const struct rte_flow_action_meter *meter; 1541 struct mrvl_mtr *mtr; 1542 1543 meter = action->conf; 1544 if (!meter) 1545 return -rte_flow_error_set(error, EINVAL, 1546 RTE_FLOW_ERROR_TYPE_ACTION, 1547 NULL, "Invalid meter\n"); 1548 1549 LIST_FOREACH(mtr, &priv->mtrs, next) 1550 if (mtr->mtr_id == meter->mtr_id) 1551 break; 1552 1553 if (!mtr) 1554 return -rte_flow_error_set(error, EINVAL, 1555 RTE_FLOW_ERROR_TYPE_ACTION, 1556 NULL, 1557 "Meter id does not exist\n"); 1558 1559 if (!mtr->shared && mtr->refcnt) 1560 return -rte_flow_error_set(error, EPERM, 1561 RTE_FLOW_ERROR_TYPE_ACTION, 1562 NULL, 1563 "Meter cannot be shared\n"); 1564 1565 /* 1566 * In case cos has already been set 1567 * do not modify it. 1568 */ 1569 if (!flow->cos.ppio) { 1570 flow->cos.ppio = priv->ppio; 1571 flow->cos.tc = 0; 1572 } 1573 1574 flow->action.type = PP2_CLS_TBL_ACT_DONE; 1575 flow->action.cos = &flow->cos; 1576 flow->action.plcr = mtr->enabled ? mtr->plcr : NULL; 1577 flow->mtr = mtr; 1578 mtr->refcnt++; 1579 specified++; 1580 } else { 1581 rte_flow_error_set(error, ENOTSUP, 1582 RTE_FLOW_ERROR_TYPE_ACTION, NULL, 1583 "Action not supported"); 1584 return -rte_errno; 1585 } 1586 } 1587 1588 if (!specified) { 1589 rte_flow_error_set(error, EINVAL, 1590 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 1591 "Action not specified"); 1592 return -rte_errno; 1593 } 1594 1595 return 0; 1596 } 1597 1598 /** 1599 * Parse flow attribute, pattern and actions. 1600 * 1601 * @param priv Pointer to the port's private data. 1602 * @param attr Pointer to the flow attribute. 1603 * @param pattern Pointer to the flow pattern. 1604 * @param actions Pointer to the flow actions. 1605 * @param flow Pointer to the flow. 1606 * @param error Pointer to the flow error. 1607 * @returns 0 on success, negative value otherwise. 1608 */ 1609 static int 1610 mrvl_flow_parse(struct mrvl_priv *priv, const struct rte_flow_attr *attr, 1611 const struct rte_flow_item pattern[], 1612 const struct rte_flow_action actions[], 1613 struct rte_flow *flow, 1614 struct rte_flow_error *error) 1615 { 1616 int ret; 1617 1618 ret = mrvl_flow_parse_attr(priv, attr, flow, error); 1619 if (ret) 1620 return ret; 1621 1622 ret = mrvl_flow_parse_pattern(priv, pattern, flow, error); 1623 if (ret) 1624 return ret; 1625 1626 return mrvl_flow_parse_actions(priv, actions, flow, error); 1627 } 1628 1629 /** 1630 * Get engine type for the given flow. 1631 * 1632 * @param field Pointer to the flow. 1633 * @returns The type of the engine. 1634 */ 1635 static inline enum pp2_cls_tbl_type 1636 mrvl_engine_type(const struct rte_flow *flow) 1637 { 1638 int i, size = 0; 1639 1640 for (i = 0; i < flow->rule.num_fields; i++) 1641 size += flow->rule.fields[i].size; 1642 1643 /* 1644 * For maskable engine type the key size must be up to 8 bytes. 1645 * For keys with size bigger than 8 bytes, engine type must 1646 * be set to exact match. 1647 */ 1648 if (size > 8) 1649 return PP2_CLS_TBL_EXACT_MATCH; 1650 1651 return PP2_CLS_TBL_MASKABLE; 1652 } 1653 1654 /** 1655 * Create classifier table. 1656 * 1657 * @param dev Pointer to the device. 1658 * @param flow Pointer to the very first flow. 1659 * @returns 0 in case of success, negative value otherwise. 1660 */ 1661 static int 1662 mrvl_create_cls_table(struct rte_eth_dev *dev, struct rte_flow *first_flow) 1663 { 1664 struct mrvl_priv *priv = dev->data->dev_private; 1665 struct pp2_cls_tbl_key *key = &priv->cls_tbl_params.key; 1666 int ret; 1667 1668 if (priv->cls_tbl) { 1669 pp2_cls_tbl_deinit(priv->cls_tbl); 1670 priv->cls_tbl = NULL; 1671 } 1672 1673 memset(&priv->cls_tbl_params, 0, sizeof(priv->cls_tbl_params)); 1674 1675 priv->cls_tbl_params.type = mrvl_engine_type(first_flow); 1676 MRVL_LOG(INFO, "Setting cls search engine type to %s", 1677 priv->cls_tbl_params.type == PP2_CLS_TBL_EXACT_MATCH ? 1678 "exact" : "maskable"); 1679 priv->cls_tbl_params.max_num_rules = MRVL_CLS_MAX_NUM_RULES; 1680 priv->cls_tbl_params.default_act.type = PP2_CLS_TBL_ACT_DONE; 1681 priv->cls_tbl_params.default_act.cos = &first_flow->cos; 1682 memcpy(key, &first_flow->table_key, sizeof(struct pp2_cls_tbl_key)); 1683 1684 ret = pp2_cls_tbl_init(&priv->cls_tbl_params, &priv->cls_tbl); 1685 1686 return ret; 1687 } 1688 1689 /** 1690 * Check whether new flow can be added to the table 1691 * 1692 * @param priv Pointer to the port's private data. 1693 * @param flow Pointer to the new flow. 1694 * @return 1 in case flow can be added, 0 otherwise. 1695 */ 1696 static inline int 1697 mrvl_flow_can_be_added(struct mrvl_priv *priv, const struct rte_flow *flow) 1698 { 1699 int same = memcmp(&flow->table_key, &priv->cls_tbl_params.key, 1700 sizeof(struct pp2_cls_tbl_key)) == 0; 1701 1702 return same && mrvl_engine_type(flow) == priv->cls_tbl_params.type; 1703 } 1704 1705 /** 1706 * DPDK flow create callback called when flow is to be created. 1707 * 1708 * @param dev Pointer to the device. 1709 * @param attr Pointer to the flow attribute. 1710 * @param pattern Pointer to the flow pattern. 1711 * @param actions Pointer to the flow actions. 1712 * @param error Pointer to the flow error. 1713 * @returns Pointer to the created flow in case of success, NULL otherwise. 1714 */ 1715 static struct rte_flow * 1716 mrvl_flow_create(struct rte_eth_dev *dev, 1717 const struct rte_flow_attr *attr, 1718 const struct rte_flow_item pattern[], 1719 const struct rte_flow_action actions[], 1720 struct rte_flow_error *error) 1721 { 1722 struct mrvl_priv *priv = dev->data->dev_private; 1723 struct rte_flow *flow, *first; 1724 int ret; 1725 1726 if (!dev->data->dev_started) { 1727 rte_flow_error_set(error, EINVAL, 1728 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 1729 "Port must be started first\n"); 1730 return NULL; 1731 } 1732 1733 flow = rte_zmalloc_socket(NULL, sizeof(*flow), 0, rte_socket_id()); 1734 if (!flow) 1735 return NULL; 1736 1737 ret = mrvl_flow_parse(priv, attr, pattern, actions, flow, error); 1738 if (ret) 1739 goto out; 1740 1741 /* 1742 * Four cases here: 1743 * 1744 * 1. In case table does not exist - create one. 1745 * 2. In case table exists, is empty and new flow cannot be added 1746 * recreate table. 1747 * 3. In case table is not empty and new flow matches table format 1748 * add it. 1749 * 4. Otherwise flow cannot be added. 1750 */ 1751 first = LIST_FIRST(&priv->flows); 1752 if (!priv->cls_tbl) { 1753 ret = mrvl_create_cls_table(dev, flow); 1754 } else if (!first && !mrvl_flow_can_be_added(priv, flow)) { 1755 ret = mrvl_create_cls_table(dev, flow); 1756 } else if (mrvl_flow_can_be_added(priv, flow)) { 1757 ret = 0; 1758 } else { 1759 rte_flow_error_set(error, EINVAL, 1760 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 1761 "Pattern does not match cls table format\n"); 1762 goto out; 1763 } 1764 1765 if (ret) { 1766 rte_flow_error_set(error, EINVAL, 1767 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 1768 "Failed to create cls table\n"); 1769 goto out; 1770 } 1771 1772 ret = pp2_cls_tbl_add_rule(priv->cls_tbl, &flow->rule, &flow->action); 1773 if (ret) { 1774 rte_flow_error_set(error, EINVAL, 1775 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 1776 "Failed to add rule\n"); 1777 goto out; 1778 } 1779 1780 LIST_INSERT_HEAD(&priv->flows, flow, next); 1781 1782 return flow; 1783 out: 1784 rte_free(flow); 1785 return NULL; 1786 } 1787 1788 /** 1789 * Remove classifier rule associated with given flow. 1790 * 1791 * @param priv Pointer to the port's private data. 1792 * @param flow Pointer to the flow. 1793 * @param error Pointer to the flow error. 1794 * @returns 0 in case of success, negative value otherwise. 1795 */ 1796 static int 1797 mrvl_flow_remove(struct mrvl_priv *priv, struct rte_flow *flow, 1798 struct rte_flow_error *error) 1799 { 1800 int ret; 1801 1802 if (!priv->cls_tbl) { 1803 rte_flow_error_set(error, EINVAL, 1804 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 1805 "Classifier table not initialized"); 1806 return -rte_errno; 1807 } 1808 1809 ret = pp2_cls_tbl_remove_rule(priv->cls_tbl, &flow->rule); 1810 if (ret) { 1811 rte_flow_error_set(error, EINVAL, 1812 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 1813 "Failed to remove rule"); 1814 return -rte_errno; 1815 } 1816 1817 mrvl_free_all_key_mask(&flow->rule); 1818 1819 if (flow->mtr) { 1820 flow->mtr->refcnt--; 1821 flow->mtr = NULL; 1822 } 1823 1824 return 0; 1825 } 1826 1827 /** 1828 * DPDK flow destroy callback called when flow is to be removed. 1829 * 1830 * @param dev Pointer to the device. 1831 * @param flow Pointer to the flow. 1832 * @param error Pointer to the flow error. 1833 * @returns 0 in case of success, negative value otherwise. 1834 */ 1835 static int 1836 mrvl_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow, 1837 struct rte_flow_error *error) 1838 { 1839 struct mrvl_priv *priv = dev->data->dev_private; 1840 struct rte_flow *f; 1841 int ret; 1842 1843 LIST_FOREACH(f, &priv->flows, next) { 1844 if (f == flow) 1845 break; 1846 } 1847 1848 if (!flow) { 1849 rte_flow_error_set(error, EINVAL, 1850 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 1851 "Rule was not found"); 1852 return -rte_errno; 1853 } 1854 1855 LIST_REMOVE(f, next); 1856 1857 ret = mrvl_flow_remove(priv, flow, error); 1858 if (ret) 1859 return ret; 1860 1861 rte_free(flow); 1862 1863 return 0; 1864 } 1865 1866 /** 1867 * DPDK flow callback called to verify given attribute, pattern and actions. 1868 * 1869 * @param dev Pointer to the device. 1870 * @param attr Pointer to the flow attribute. 1871 * @param pattern Pointer to the flow pattern. 1872 * @param actions Pointer to the flow actions. 1873 * @param error Pointer to the flow error. 1874 * @returns 0 on success, negative value otherwise. 1875 */ 1876 static int 1877 mrvl_flow_validate(struct rte_eth_dev *dev, 1878 const struct rte_flow_attr *attr, 1879 const struct rte_flow_item pattern[], 1880 const struct rte_flow_action actions[], 1881 struct rte_flow_error *error) 1882 { 1883 static struct rte_flow *flow; 1884 1885 flow = mrvl_flow_create(dev, attr, pattern, actions, error); 1886 if (!flow) 1887 return -rte_errno; 1888 1889 mrvl_flow_destroy(dev, flow, error); 1890 1891 return 0; 1892 } 1893 1894 /** 1895 * DPDK flow flush callback called when flows are to be flushed. 1896 * 1897 * @param dev Pointer to the device. 1898 * @param error Pointer to the flow error. 1899 * @returns 0 in case of success, negative value otherwise. 1900 */ 1901 static int 1902 mrvl_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error) 1903 { 1904 struct mrvl_priv *priv = dev->data->dev_private; 1905 1906 while (!LIST_EMPTY(&priv->flows)) { 1907 struct rte_flow *flow = LIST_FIRST(&priv->flows); 1908 int ret = mrvl_flow_remove(priv, flow, error); 1909 if (ret) 1910 return ret; 1911 1912 LIST_REMOVE(flow, next); 1913 rte_free(flow); 1914 } 1915 1916 if (priv->cls_tbl) { 1917 pp2_cls_tbl_deinit(priv->cls_tbl); 1918 priv->cls_tbl = NULL; 1919 } 1920 1921 return 0; 1922 } 1923 1924 /** 1925 * DPDK flow isolate callback called to isolate port. 1926 * 1927 * @param dev Pointer to the device. 1928 * @param enable Pass 0/1 to disable/enable port isolation. 1929 * @param error Pointer to the flow error. 1930 * @returns 0 in case of success, negative value otherwise. 1931 */ 1932 static int 1933 mrvl_flow_isolate(struct rte_eth_dev *dev, int enable, 1934 struct rte_flow_error *error) 1935 { 1936 struct mrvl_priv *priv = dev->data->dev_private; 1937 1938 if (dev->data->dev_started) { 1939 rte_flow_error_set(error, EBUSY, 1940 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, 1941 NULL, "Port must be stopped first\n"); 1942 return -rte_errno; 1943 } 1944 1945 priv->isolated = enable; 1946 1947 return 0; 1948 } 1949 1950 const struct rte_flow_ops mrvl_flow_ops = { 1951 .validate = mrvl_flow_validate, 1952 .create = mrvl_flow_create, 1953 .destroy = mrvl_flow_destroy, 1954 .flush = mrvl_flow_flush, 1955 .isolate = mrvl_flow_isolate 1956 }; 1957 1958 /** 1959 * Initialize flow resources. 1960 * 1961 * @param dev Pointer to the device. 1962 */ 1963 void 1964 mrvl_flow_init(struct rte_eth_dev *dev) 1965 { 1966 struct mrvl_priv *priv = dev->data->dev_private; 1967 1968 LIST_INIT(&priv->flows); 1969 } 1970 1971 /** 1972 * Cleanup flow resources. 1973 * 1974 * @param dev Pointer to the device. 1975 */ 1976 void 1977 mrvl_flow_deinit(struct rte_eth_dev *dev) 1978 { 1979 mrvl_flow_flush(dev, NULL); 1980 } 1981