1 /* SPDX-License-Identifier: BSD-3-Clause 2 * 3 * Copyright(c) 2019-2021 Xilinx, Inc. 4 * Copyright(c) 2017-2019 Solarflare Communications Inc. 5 * 6 * This software was jointly developed between OKTET Labs (under contract 7 * for Solarflare) and Solarflare Communications, Inc. 8 */ 9 10 #include <rte_byteorder.h> 11 #include <rte_tailq.h> 12 #include <rte_common.h> 13 #include <ethdev_driver.h> 14 #include <rte_ether.h> 15 #include <rte_flow.h> 16 #include <rte_flow_driver.h> 17 18 #include "efx.h" 19 20 #include "sfc.h" 21 #include "sfc_debug.h" 22 #include "sfc_rx.h" 23 #include "sfc_filter.h" 24 #include "sfc_flow.h" 25 #include "sfc_log.h" 26 #include "sfc_dp_rx.h" 27 #include "sfc_mae_counter.h" 28 29 struct sfc_flow_ops_by_spec { 30 sfc_flow_parse_cb_t *parse; 31 sfc_flow_verify_cb_t *verify; 32 sfc_flow_cleanup_cb_t *cleanup; 33 sfc_flow_insert_cb_t *insert; 34 sfc_flow_remove_cb_t *remove; 35 }; 36 37 static sfc_flow_parse_cb_t sfc_flow_parse_rte_to_filter; 38 static sfc_flow_parse_cb_t sfc_flow_parse_rte_to_mae; 39 static sfc_flow_insert_cb_t sfc_flow_filter_insert; 40 static sfc_flow_remove_cb_t sfc_flow_filter_remove; 41 42 static const struct sfc_flow_ops_by_spec sfc_flow_ops_filter = { 43 .parse = sfc_flow_parse_rte_to_filter, 44 .verify = NULL, 45 .cleanup = NULL, 46 .insert = sfc_flow_filter_insert, 47 .remove = sfc_flow_filter_remove, 48 }; 49 50 static const struct sfc_flow_ops_by_spec sfc_flow_ops_mae = { 51 .parse = sfc_flow_parse_rte_to_mae, 52 .verify = sfc_mae_flow_verify, 53 .cleanup = sfc_mae_flow_cleanup, 54 .insert = sfc_mae_flow_insert, 55 .remove = sfc_mae_flow_remove, 56 }; 57 58 static const struct sfc_flow_ops_by_spec * 59 sfc_flow_get_ops_by_spec(struct rte_flow *flow) 60 { 61 struct sfc_flow_spec *spec = &flow->spec; 62 const struct sfc_flow_ops_by_spec *ops = NULL; 63 64 switch (spec->type) { 65 case SFC_FLOW_SPEC_FILTER: 66 ops = &sfc_flow_ops_filter; 67 break; 68 case SFC_FLOW_SPEC_MAE: 69 ops = &sfc_flow_ops_mae; 70 break; 71 default: 72 SFC_ASSERT(false); 73 break; 74 } 75 76 return ops; 77 } 78 79 /* 80 * Currently, filter-based (VNIC) flow API is implemented in such a manner 81 * that each flow rule is converted to one or more hardware filters. 82 * All elements of flow rule (attributes, pattern items, actions) 83 * correspond to one or more fields in the efx_filter_spec_s structure 84 * that is responsible for the hardware filter. 85 * If some required field is unset in the flow rule, then a handful 86 * of filter copies will be created to cover all possible values 87 * of such a field. 88 */ 89 90 static sfc_flow_item_parse sfc_flow_parse_void; 91 static sfc_flow_item_parse sfc_flow_parse_eth; 92 static sfc_flow_item_parse sfc_flow_parse_vlan; 93 static sfc_flow_item_parse sfc_flow_parse_ipv4; 94 static sfc_flow_item_parse sfc_flow_parse_ipv6; 95 static sfc_flow_item_parse sfc_flow_parse_tcp; 96 static sfc_flow_item_parse sfc_flow_parse_udp; 97 static sfc_flow_item_parse sfc_flow_parse_vxlan; 98 static sfc_flow_item_parse sfc_flow_parse_geneve; 99 static sfc_flow_item_parse sfc_flow_parse_nvgre; 100 static sfc_flow_item_parse sfc_flow_parse_pppoex; 101 102 typedef int (sfc_flow_spec_set_vals)(struct sfc_flow_spec *spec, 103 unsigned int filters_count_for_one_val, 104 struct rte_flow_error *error); 105 106 typedef boolean_t (sfc_flow_spec_check)(efx_filter_match_flags_t match, 107 efx_filter_spec_t *spec, 108 struct sfc_filter *filter); 109 110 struct sfc_flow_copy_flag { 111 /* EFX filter specification match flag */ 112 efx_filter_match_flags_t flag; 113 /* Number of values of corresponding field */ 114 unsigned int vals_count; 115 /* Function to set values in specifications */ 116 sfc_flow_spec_set_vals *set_vals; 117 /* 118 * Function to check that the specification is suitable 119 * for adding this match flag 120 */ 121 sfc_flow_spec_check *spec_check; 122 }; 123 124 static sfc_flow_spec_set_vals sfc_flow_set_unknown_dst_flags; 125 static sfc_flow_spec_check sfc_flow_check_unknown_dst_flags; 126 static sfc_flow_spec_set_vals sfc_flow_set_ethertypes; 127 static sfc_flow_spec_set_vals sfc_flow_set_ifrm_unknown_dst_flags; 128 static sfc_flow_spec_check sfc_flow_check_ifrm_unknown_dst_flags; 129 static sfc_flow_spec_set_vals sfc_flow_set_outer_vid_flag; 130 static sfc_flow_spec_check sfc_flow_check_outer_vid_flag; 131 132 static boolean_t 133 sfc_flow_is_zero(const uint8_t *buf, unsigned int size) 134 { 135 uint8_t sum = 0; 136 unsigned int i; 137 138 for (i = 0; i < size; i++) 139 sum |= buf[i]; 140 141 return (sum == 0) ? B_TRUE : B_FALSE; 142 } 143 144 /* 145 * Validate item and prepare structures spec and mask for parsing 146 */ 147 int 148 sfc_flow_parse_init(const struct rte_flow_item *item, 149 const void **spec_ptr, 150 const void **mask_ptr, 151 const void *supp_mask, 152 const void *def_mask, 153 unsigned int size, 154 struct rte_flow_error *error) 155 { 156 const uint8_t *spec; 157 const uint8_t *mask; 158 const uint8_t *last; 159 uint8_t supp; 160 unsigned int i; 161 162 if (item == NULL) { 163 rte_flow_error_set(error, EINVAL, 164 RTE_FLOW_ERROR_TYPE_ITEM, NULL, 165 "NULL item"); 166 return -rte_errno; 167 } 168 169 if ((item->last != NULL || item->mask != NULL) && item->spec == NULL) { 170 rte_flow_error_set(error, EINVAL, 171 RTE_FLOW_ERROR_TYPE_ITEM, item, 172 "Mask or last is set without spec"); 173 return -rte_errno; 174 } 175 176 /* 177 * If "mask" is not set, default mask is used, 178 * but if default mask is NULL, "mask" should be set 179 */ 180 if (item->mask == NULL) { 181 if (def_mask == NULL) { 182 rte_flow_error_set(error, EINVAL, 183 RTE_FLOW_ERROR_TYPE_ITEM, NULL, 184 "Mask should be specified"); 185 return -rte_errno; 186 } 187 188 mask = def_mask; 189 } else { 190 mask = item->mask; 191 } 192 193 spec = item->spec; 194 last = item->last; 195 196 if (spec == NULL) 197 goto exit; 198 199 /* 200 * If field values in "last" are either 0 or equal to the corresponding 201 * values in "spec" then they are ignored 202 */ 203 if (last != NULL && 204 !sfc_flow_is_zero(last, size) && 205 memcmp(last, spec, size) != 0) { 206 rte_flow_error_set(error, ENOTSUP, 207 RTE_FLOW_ERROR_TYPE_ITEM, item, 208 "Ranging is not supported"); 209 return -rte_errno; 210 } 211 212 if (supp_mask == NULL) { 213 rte_flow_error_set(error, EINVAL, 214 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 215 "Supported mask for item should be specified"); 216 return -rte_errno; 217 } 218 219 /* Check that mask does not ask for more match than supp_mask */ 220 for (i = 0; i < size; i++) { 221 supp = ((const uint8_t *)supp_mask)[i]; 222 223 if (~supp & mask[i]) { 224 rte_flow_error_set(error, ENOTSUP, 225 RTE_FLOW_ERROR_TYPE_ITEM, item, 226 "Item's field is not supported"); 227 return -rte_errno; 228 } 229 } 230 231 exit: 232 *spec_ptr = spec; 233 *mask_ptr = mask; 234 return 0; 235 } 236 237 /* 238 * Protocol parsers. 239 * Masking is not supported, so masks in items should be either 240 * full or empty (zeroed) and set only for supported fields which 241 * are specified in the supp_mask. 242 */ 243 244 static int 245 sfc_flow_parse_void(__rte_unused const struct rte_flow_item *item, 246 __rte_unused struct sfc_flow_parse_ctx *parse_ctx, 247 __rte_unused struct rte_flow_error *error) 248 { 249 return 0; 250 } 251 252 /** 253 * Convert Ethernet item to EFX filter specification. 254 * 255 * @param item[in] 256 * Item specification. Outer frame specification may only comprise 257 * source/destination addresses and Ethertype field. 258 * Inner frame specification may contain destination address only. 259 * There is support for individual/group mask as well as for empty and full. 260 * If the mask is NULL, default mask will be used. Ranging is not supported. 261 * @param efx_spec[in, out] 262 * EFX filter specification to update. 263 * @param[out] error 264 * Perform verbose error reporting if not NULL. 265 */ 266 static int 267 sfc_flow_parse_eth(const struct rte_flow_item *item, 268 struct sfc_flow_parse_ctx *parse_ctx, 269 struct rte_flow_error *error) 270 { 271 int rc; 272 efx_filter_spec_t *efx_spec = parse_ctx->filter; 273 const struct rte_flow_item_eth *spec = NULL; 274 const struct rte_flow_item_eth *mask = NULL; 275 const struct rte_flow_item_eth supp_mask = { 276 .dst.addr_bytes = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, 277 .src.addr_bytes = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, 278 .type = 0xffff, 279 }; 280 const struct rte_flow_item_eth ifrm_supp_mask = { 281 .dst.addr_bytes = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, 282 }; 283 const uint8_t ig_mask[EFX_MAC_ADDR_LEN] = { 284 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 285 }; 286 const struct rte_flow_item_eth *supp_mask_p; 287 const struct rte_flow_item_eth *def_mask_p; 288 uint8_t *loc_mac = NULL; 289 boolean_t is_ifrm = (efx_spec->efs_encap_type != 290 EFX_TUNNEL_PROTOCOL_NONE); 291 292 if (is_ifrm) { 293 supp_mask_p = &ifrm_supp_mask; 294 def_mask_p = &ifrm_supp_mask; 295 loc_mac = efx_spec->efs_ifrm_loc_mac; 296 } else { 297 supp_mask_p = &supp_mask; 298 def_mask_p = &rte_flow_item_eth_mask; 299 loc_mac = efx_spec->efs_loc_mac; 300 } 301 302 rc = sfc_flow_parse_init(item, 303 (const void **)&spec, 304 (const void **)&mask, 305 supp_mask_p, def_mask_p, 306 sizeof(struct rte_flow_item_eth), 307 error); 308 if (rc != 0) 309 return rc; 310 311 /* If "spec" is not set, could be any Ethernet */ 312 if (spec == NULL) 313 return 0; 314 315 if (rte_is_same_ether_addr(&mask->dst, &supp_mask.dst)) { 316 efx_spec->efs_match_flags |= is_ifrm ? 317 EFX_FILTER_MATCH_IFRM_LOC_MAC : 318 EFX_FILTER_MATCH_LOC_MAC; 319 rte_memcpy(loc_mac, spec->dst.addr_bytes, 320 EFX_MAC_ADDR_LEN); 321 } else if (memcmp(mask->dst.addr_bytes, ig_mask, 322 EFX_MAC_ADDR_LEN) == 0) { 323 if (rte_is_unicast_ether_addr(&spec->dst)) 324 efx_spec->efs_match_flags |= is_ifrm ? 325 EFX_FILTER_MATCH_IFRM_UNKNOWN_UCAST_DST : 326 EFX_FILTER_MATCH_UNKNOWN_UCAST_DST; 327 else 328 efx_spec->efs_match_flags |= is_ifrm ? 329 EFX_FILTER_MATCH_IFRM_UNKNOWN_MCAST_DST : 330 EFX_FILTER_MATCH_UNKNOWN_MCAST_DST; 331 } else if (!rte_is_zero_ether_addr(&mask->dst)) { 332 goto fail_bad_mask; 333 } 334 335 /* 336 * ifrm_supp_mask ensures that the source address and 337 * ethertype masks are equal to zero in inner frame, 338 * so these fields are filled in only for the outer frame 339 */ 340 if (rte_is_same_ether_addr(&mask->src, &supp_mask.src)) { 341 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_REM_MAC; 342 rte_memcpy(efx_spec->efs_rem_mac, spec->src.addr_bytes, 343 EFX_MAC_ADDR_LEN); 344 } else if (!rte_is_zero_ether_addr(&mask->src)) { 345 goto fail_bad_mask; 346 } 347 348 /* 349 * Ether type is in big-endian byte order in item and 350 * in little-endian in efx_spec, so byte swap is used 351 */ 352 if (mask->type == supp_mask.type) { 353 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_ETHER_TYPE; 354 efx_spec->efs_ether_type = rte_bswap16(spec->type); 355 } else if (mask->type != 0) { 356 goto fail_bad_mask; 357 } 358 359 return 0; 360 361 fail_bad_mask: 362 rte_flow_error_set(error, EINVAL, 363 RTE_FLOW_ERROR_TYPE_ITEM, item, 364 "Bad mask in the ETH pattern item"); 365 return -rte_errno; 366 } 367 368 /** 369 * Convert VLAN item to EFX filter specification. 370 * 371 * @param item[in] 372 * Item specification. Only VID field is supported. 373 * The mask can not be NULL. Ranging is not supported. 374 * @param efx_spec[in, out] 375 * EFX filter specification to update. 376 * @param[out] error 377 * Perform verbose error reporting if not NULL. 378 */ 379 static int 380 sfc_flow_parse_vlan(const struct rte_flow_item *item, 381 struct sfc_flow_parse_ctx *parse_ctx, 382 struct rte_flow_error *error) 383 { 384 int rc; 385 uint16_t vid; 386 efx_filter_spec_t *efx_spec = parse_ctx->filter; 387 const struct rte_flow_item_vlan *spec = NULL; 388 const struct rte_flow_item_vlan *mask = NULL; 389 const struct rte_flow_item_vlan supp_mask = { 390 .tci = rte_cpu_to_be_16(ETH_VLAN_ID_MAX), 391 .inner_type = RTE_BE16(0xffff), 392 }; 393 394 rc = sfc_flow_parse_init(item, 395 (const void **)&spec, 396 (const void **)&mask, 397 &supp_mask, 398 NULL, 399 sizeof(struct rte_flow_item_vlan), 400 error); 401 if (rc != 0) 402 return rc; 403 404 /* 405 * VID is in big-endian byte order in item and 406 * in little-endian in efx_spec, so byte swap is used. 407 * If two VLAN items are included, the first matches 408 * the outer tag and the next matches the inner tag. 409 */ 410 if (mask->tci == supp_mask.tci) { 411 /* Apply mask to keep VID only */ 412 vid = rte_bswap16(spec->tci & mask->tci); 413 414 if (!(efx_spec->efs_match_flags & 415 EFX_FILTER_MATCH_OUTER_VID)) { 416 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_OUTER_VID; 417 efx_spec->efs_outer_vid = vid; 418 } else if (!(efx_spec->efs_match_flags & 419 EFX_FILTER_MATCH_INNER_VID)) { 420 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_INNER_VID; 421 efx_spec->efs_inner_vid = vid; 422 } else { 423 rte_flow_error_set(error, EINVAL, 424 RTE_FLOW_ERROR_TYPE_ITEM, item, 425 "More than two VLAN items"); 426 return -rte_errno; 427 } 428 } else { 429 rte_flow_error_set(error, EINVAL, 430 RTE_FLOW_ERROR_TYPE_ITEM, item, 431 "VLAN ID in TCI match is required"); 432 return -rte_errno; 433 } 434 435 if (efx_spec->efs_match_flags & EFX_FILTER_MATCH_ETHER_TYPE) { 436 rte_flow_error_set(error, EINVAL, 437 RTE_FLOW_ERROR_TYPE_ITEM, item, 438 "VLAN TPID matching is not supported"); 439 return -rte_errno; 440 } 441 if (mask->inner_type == supp_mask.inner_type) { 442 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_ETHER_TYPE; 443 efx_spec->efs_ether_type = rte_bswap16(spec->inner_type); 444 } else if (mask->inner_type) { 445 rte_flow_error_set(error, EINVAL, 446 RTE_FLOW_ERROR_TYPE_ITEM, item, 447 "Bad mask for VLAN inner_type"); 448 return -rte_errno; 449 } 450 451 return 0; 452 } 453 454 /** 455 * Convert IPv4 item to EFX filter specification. 456 * 457 * @param item[in] 458 * Item specification. Only source and destination addresses and 459 * protocol fields are supported. If the mask is NULL, default 460 * mask will be used. Ranging is not supported. 461 * @param efx_spec[in, out] 462 * EFX filter specification to update. 463 * @param[out] error 464 * Perform verbose error reporting if not NULL. 465 */ 466 static int 467 sfc_flow_parse_ipv4(const struct rte_flow_item *item, 468 struct sfc_flow_parse_ctx *parse_ctx, 469 struct rte_flow_error *error) 470 { 471 int rc; 472 efx_filter_spec_t *efx_spec = parse_ctx->filter; 473 const struct rte_flow_item_ipv4 *spec = NULL; 474 const struct rte_flow_item_ipv4 *mask = NULL; 475 const uint16_t ether_type_ipv4 = rte_cpu_to_le_16(EFX_ETHER_TYPE_IPV4); 476 const struct rte_flow_item_ipv4 supp_mask = { 477 .hdr = { 478 .src_addr = 0xffffffff, 479 .dst_addr = 0xffffffff, 480 .next_proto_id = 0xff, 481 } 482 }; 483 484 rc = sfc_flow_parse_init(item, 485 (const void **)&spec, 486 (const void **)&mask, 487 &supp_mask, 488 &rte_flow_item_ipv4_mask, 489 sizeof(struct rte_flow_item_ipv4), 490 error); 491 if (rc != 0) 492 return rc; 493 494 /* 495 * Filtering by IPv4 source and destination addresses requires 496 * the appropriate ETHER_TYPE in hardware filters 497 */ 498 if (!(efx_spec->efs_match_flags & EFX_FILTER_MATCH_ETHER_TYPE)) { 499 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_ETHER_TYPE; 500 efx_spec->efs_ether_type = ether_type_ipv4; 501 } else if (efx_spec->efs_ether_type != ether_type_ipv4) { 502 rte_flow_error_set(error, EINVAL, 503 RTE_FLOW_ERROR_TYPE_ITEM, item, 504 "Ethertype in pattern with IPV4 item should be appropriate"); 505 return -rte_errno; 506 } 507 508 if (spec == NULL) 509 return 0; 510 511 /* 512 * IPv4 addresses are in big-endian byte order in item and in 513 * efx_spec 514 */ 515 if (mask->hdr.src_addr == supp_mask.hdr.src_addr) { 516 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_REM_HOST; 517 efx_spec->efs_rem_host.eo_u32[0] = spec->hdr.src_addr; 518 } else if (mask->hdr.src_addr != 0) { 519 goto fail_bad_mask; 520 } 521 522 if (mask->hdr.dst_addr == supp_mask.hdr.dst_addr) { 523 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_LOC_HOST; 524 efx_spec->efs_loc_host.eo_u32[0] = spec->hdr.dst_addr; 525 } else if (mask->hdr.dst_addr != 0) { 526 goto fail_bad_mask; 527 } 528 529 if (mask->hdr.next_proto_id == supp_mask.hdr.next_proto_id) { 530 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_IP_PROTO; 531 efx_spec->efs_ip_proto = spec->hdr.next_proto_id; 532 } else if (mask->hdr.next_proto_id != 0) { 533 goto fail_bad_mask; 534 } 535 536 return 0; 537 538 fail_bad_mask: 539 rte_flow_error_set(error, EINVAL, 540 RTE_FLOW_ERROR_TYPE_ITEM, item, 541 "Bad mask in the IPV4 pattern item"); 542 return -rte_errno; 543 } 544 545 /** 546 * Convert IPv6 item to EFX filter specification. 547 * 548 * @param item[in] 549 * Item specification. Only source and destination addresses and 550 * next header fields are supported. If the mask is NULL, default 551 * mask will be used. Ranging is not supported. 552 * @param efx_spec[in, out] 553 * EFX filter specification to update. 554 * @param[out] error 555 * Perform verbose error reporting if not NULL. 556 */ 557 static int 558 sfc_flow_parse_ipv6(const struct rte_flow_item *item, 559 struct sfc_flow_parse_ctx *parse_ctx, 560 struct rte_flow_error *error) 561 { 562 int rc; 563 efx_filter_spec_t *efx_spec = parse_ctx->filter; 564 const struct rte_flow_item_ipv6 *spec = NULL; 565 const struct rte_flow_item_ipv6 *mask = NULL; 566 const uint16_t ether_type_ipv6 = rte_cpu_to_le_16(EFX_ETHER_TYPE_IPV6); 567 const struct rte_flow_item_ipv6 supp_mask = { 568 .hdr = { 569 .src_addr = { 0xff, 0xff, 0xff, 0xff, 570 0xff, 0xff, 0xff, 0xff, 571 0xff, 0xff, 0xff, 0xff, 572 0xff, 0xff, 0xff, 0xff }, 573 .dst_addr = { 0xff, 0xff, 0xff, 0xff, 574 0xff, 0xff, 0xff, 0xff, 575 0xff, 0xff, 0xff, 0xff, 576 0xff, 0xff, 0xff, 0xff }, 577 .proto = 0xff, 578 } 579 }; 580 581 rc = sfc_flow_parse_init(item, 582 (const void **)&spec, 583 (const void **)&mask, 584 &supp_mask, 585 &rte_flow_item_ipv6_mask, 586 sizeof(struct rte_flow_item_ipv6), 587 error); 588 if (rc != 0) 589 return rc; 590 591 /* 592 * Filtering by IPv6 source and destination addresses requires 593 * the appropriate ETHER_TYPE in hardware filters 594 */ 595 if (!(efx_spec->efs_match_flags & EFX_FILTER_MATCH_ETHER_TYPE)) { 596 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_ETHER_TYPE; 597 efx_spec->efs_ether_type = ether_type_ipv6; 598 } else if (efx_spec->efs_ether_type != ether_type_ipv6) { 599 rte_flow_error_set(error, EINVAL, 600 RTE_FLOW_ERROR_TYPE_ITEM, item, 601 "Ethertype in pattern with IPV6 item should be appropriate"); 602 return -rte_errno; 603 } 604 605 if (spec == NULL) 606 return 0; 607 608 /* 609 * IPv6 addresses are in big-endian byte order in item and in 610 * efx_spec 611 */ 612 if (memcmp(mask->hdr.src_addr, supp_mask.hdr.src_addr, 613 sizeof(mask->hdr.src_addr)) == 0) { 614 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_REM_HOST; 615 616 RTE_BUILD_BUG_ON(sizeof(efx_spec->efs_rem_host) != 617 sizeof(spec->hdr.src_addr)); 618 rte_memcpy(&efx_spec->efs_rem_host, spec->hdr.src_addr, 619 sizeof(efx_spec->efs_rem_host)); 620 } else if (!sfc_flow_is_zero(mask->hdr.src_addr, 621 sizeof(mask->hdr.src_addr))) { 622 goto fail_bad_mask; 623 } 624 625 if (memcmp(mask->hdr.dst_addr, supp_mask.hdr.dst_addr, 626 sizeof(mask->hdr.dst_addr)) == 0) { 627 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_LOC_HOST; 628 629 RTE_BUILD_BUG_ON(sizeof(efx_spec->efs_loc_host) != 630 sizeof(spec->hdr.dst_addr)); 631 rte_memcpy(&efx_spec->efs_loc_host, spec->hdr.dst_addr, 632 sizeof(efx_spec->efs_loc_host)); 633 } else if (!sfc_flow_is_zero(mask->hdr.dst_addr, 634 sizeof(mask->hdr.dst_addr))) { 635 goto fail_bad_mask; 636 } 637 638 if (mask->hdr.proto == supp_mask.hdr.proto) { 639 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_IP_PROTO; 640 efx_spec->efs_ip_proto = spec->hdr.proto; 641 } else if (mask->hdr.proto != 0) { 642 goto fail_bad_mask; 643 } 644 645 return 0; 646 647 fail_bad_mask: 648 rte_flow_error_set(error, EINVAL, 649 RTE_FLOW_ERROR_TYPE_ITEM, item, 650 "Bad mask in the IPV6 pattern item"); 651 return -rte_errno; 652 } 653 654 /** 655 * Convert TCP item to EFX filter specification. 656 * 657 * @param item[in] 658 * Item specification. Only source and destination ports fields 659 * are supported. If the mask is NULL, default mask will be used. 660 * Ranging is not supported. 661 * @param efx_spec[in, out] 662 * EFX filter specification to update. 663 * @param[out] error 664 * Perform verbose error reporting if not NULL. 665 */ 666 static int 667 sfc_flow_parse_tcp(const struct rte_flow_item *item, 668 struct sfc_flow_parse_ctx *parse_ctx, 669 struct rte_flow_error *error) 670 { 671 int rc; 672 efx_filter_spec_t *efx_spec = parse_ctx->filter; 673 const struct rte_flow_item_tcp *spec = NULL; 674 const struct rte_flow_item_tcp *mask = NULL; 675 const struct rte_flow_item_tcp supp_mask = { 676 .hdr = { 677 .src_port = 0xffff, 678 .dst_port = 0xffff, 679 } 680 }; 681 682 rc = sfc_flow_parse_init(item, 683 (const void **)&spec, 684 (const void **)&mask, 685 &supp_mask, 686 &rte_flow_item_tcp_mask, 687 sizeof(struct rte_flow_item_tcp), 688 error); 689 if (rc != 0) 690 return rc; 691 692 /* 693 * Filtering by TCP source and destination ports requires 694 * the appropriate IP_PROTO in hardware filters 695 */ 696 if (!(efx_spec->efs_match_flags & EFX_FILTER_MATCH_IP_PROTO)) { 697 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_IP_PROTO; 698 efx_spec->efs_ip_proto = EFX_IPPROTO_TCP; 699 } else if (efx_spec->efs_ip_proto != EFX_IPPROTO_TCP) { 700 rte_flow_error_set(error, EINVAL, 701 RTE_FLOW_ERROR_TYPE_ITEM, item, 702 "IP proto in pattern with TCP item should be appropriate"); 703 return -rte_errno; 704 } 705 706 if (spec == NULL) 707 return 0; 708 709 /* 710 * Source and destination ports are in big-endian byte order in item and 711 * in little-endian in efx_spec, so byte swap is used 712 */ 713 if (mask->hdr.src_port == supp_mask.hdr.src_port) { 714 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_REM_PORT; 715 efx_spec->efs_rem_port = rte_bswap16(spec->hdr.src_port); 716 } else if (mask->hdr.src_port != 0) { 717 goto fail_bad_mask; 718 } 719 720 if (mask->hdr.dst_port == supp_mask.hdr.dst_port) { 721 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_LOC_PORT; 722 efx_spec->efs_loc_port = rte_bswap16(spec->hdr.dst_port); 723 } else if (mask->hdr.dst_port != 0) { 724 goto fail_bad_mask; 725 } 726 727 return 0; 728 729 fail_bad_mask: 730 rte_flow_error_set(error, EINVAL, 731 RTE_FLOW_ERROR_TYPE_ITEM, item, 732 "Bad mask in the TCP pattern item"); 733 return -rte_errno; 734 } 735 736 /** 737 * Convert UDP item to EFX filter specification. 738 * 739 * @param item[in] 740 * Item specification. Only source and destination ports fields 741 * are supported. If the mask is NULL, default mask will be used. 742 * Ranging is not supported. 743 * @param efx_spec[in, out] 744 * EFX filter specification to update. 745 * @param[out] error 746 * Perform verbose error reporting if not NULL. 747 */ 748 static int 749 sfc_flow_parse_udp(const struct rte_flow_item *item, 750 struct sfc_flow_parse_ctx *parse_ctx, 751 struct rte_flow_error *error) 752 { 753 int rc; 754 efx_filter_spec_t *efx_spec = parse_ctx->filter; 755 const struct rte_flow_item_udp *spec = NULL; 756 const struct rte_flow_item_udp *mask = NULL; 757 const struct rte_flow_item_udp supp_mask = { 758 .hdr = { 759 .src_port = 0xffff, 760 .dst_port = 0xffff, 761 } 762 }; 763 764 rc = sfc_flow_parse_init(item, 765 (const void **)&spec, 766 (const void **)&mask, 767 &supp_mask, 768 &rte_flow_item_udp_mask, 769 sizeof(struct rte_flow_item_udp), 770 error); 771 if (rc != 0) 772 return rc; 773 774 /* 775 * Filtering by UDP source and destination ports requires 776 * the appropriate IP_PROTO in hardware filters 777 */ 778 if (!(efx_spec->efs_match_flags & EFX_FILTER_MATCH_IP_PROTO)) { 779 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_IP_PROTO; 780 efx_spec->efs_ip_proto = EFX_IPPROTO_UDP; 781 } else if (efx_spec->efs_ip_proto != EFX_IPPROTO_UDP) { 782 rte_flow_error_set(error, EINVAL, 783 RTE_FLOW_ERROR_TYPE_ITEM, item, 784 "IP proto in pattern with UDP item should be appropriate"); 785 return -rte_errno; 786 } 787 788 if (spec == NULL) 789 return 0; 790 791 /* 792 * Source and destination ports are in big-endian byte order in item and 793 * in little-endian in efx_spec, so byte swap is used 794 */ 795 if (mask->hdr.src_port == supp_mask.hdr.src_port) { 796 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_REM_PORT; 797 efx_spec->efs_rem_port = rte_bswap16(spec->hdr.src_port); 798 } else if (mask->hdr.src_port != 0) { 799 goto fail_bad_mask; 800 } 801 802 if (mask->hdr.dst_port == supp_mask.hdr.dst_port) { 803 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_LOC_PORT; 804 efx_spec->efs_loc_port = rte_bswap16(spec->hdr.dst_port); 805 } else if (mask->hdr.dst_port != 0) { 806 goto fail_bad_mask; 807 } 808 809 return 0; 810 811 fail_bad_mask: 812 rte_flow_error_set(error, EINVAL, 813 RTE_FLOW_ERROR_TYPE_ITEM, item, 814 "Bad mask in the UDP pattern item"); 815 return -rte_errno; 816 } 817 818 /* 819 * Filters for encapsulated packets match based on the EtherType and IP 820 * protocol in the outer frame. 821 */ 822 static int 823 sfc_flow_set_match_flags_for_encap_pkts(const struct rte_flow_item *item, 824 efx_filter_spec_t *efx_spec, 825 uint8_t ip_proto, 826 struct rte_flow_error *error) 827 { 828 if (!(efx_spec->efs_match_flags & EFX_FILTER_MATCH_IP_PROTO)) { 829 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_IP_PROTO; 830 efx_spec->efs_ip_proto = ip_proto; 831 } else if (efx_spec->efs_ip_proto != ip_proto) { 832 switch (ip_proto) { 833 case EFX_IPPROTO_UDP: 834 rte_flow_error_set(error, EINVAL, 835 RTE_FLOW_ERROR_TYPE_ITEM, item, 836 "Outer IP header protocol must be UDP " 837 "in VxLAN/GENEVE pattern"); 838 return -rte_errno; 839 840 case EFX_IPPROTO_GRE: 841 rte_flow_error_set(error, EINVAL, 842 RTE_FLOW_ERROR_TYPE_ITEM, item, 843 "Outer IP header protocol must be GRE " 844 "in NVGRE pattern"); 845 return -rte_errno; 846 847 default: 848 rte_flow_error_set(error, EINVAL, 849 RTE_FLOW_ERROR_TYPE_ITEM, item, 850 "Only VxLAN/GENEVE/NVGRE tunneling patterns " 851 "are supported"); 852 return -rte_errno; 853 } 854 } 855 856 if (efx_spec->efs_match_flags & EFX_FILTER_MATCH_ETHER_TYPE && 857 efx_spec->efs_ether_type != EFX_ETHER_TYPE_IPV4 && 858 efx_spec->efs_ether_type != EFX_ETHER_TYPE_IPV6) { 859 rte_flow_error_set(error, EINVAL, 860 RTE_FLOW_ERROR_TYPE_ITEM, item, 861 "Outer frame EtherType in pattern with tunneling " 862 "must be IPv4 or IPv6"); 863 return -rte_errno; 864 } 865 866 return 0; 867 } 868 869 static int 870 sfc_flow_set_efx_spec_vni_or_vsid(efx_filter_spec_t *efx_spec, 871 const uint8_t *vni_or_vsid_val, 872 const uint8_t *vni_or_vsid_mask, 873 const struct rte_flow_item *item, 874 struct rte_flow_error *error) 875 { 876 const uint8_t vni_or_vsid_full_mask[EFX_VNI_OR_VSID_LEN] = { 877 0xff, 0xff, 0xff 878 }; 879 880 if (memcmp(vni_or_vsid_mask, vni_or_vsid_full_mask, 881 EFX_VNI_OR_VSID_LEN) == 0) { 882 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_VNI_OR_VSID; 883 rte_memcpy(efx_spec->efs_vni_or_vsid, vni_or_vsid_val, 884 EFX_VNI_OR_VSID_LEN); 885 } else if (!sfc_flow_is_zero(vni_or_vsid_mask, EFX_VNI_OR_VSID_LEN)) { 886 rte_flow_error_set(error, EINVAL, 887 RTE_FLOW_ERROR_TYPE_ITEM, item, 888 "Unsupported VNI/VSID mask"); 889 return -rte_errno; 890 } 891 892 return 0; 893 } 894 895 /** 896 * Convert VXLAN item to EFX filter specification. 897 * 898 * @param item[in] 899 * Item specification. Only VXLAN network identifier field is supported. 900 * If the mask is NULL, default mask will be used. 901 * Ranging is not supported. 902 * @param efx_spec[in, out] 903 * EFX filter specification to update. 904 * @param[out] error 905 * Perform verbose error reporting if not NULL. 906 */ 907 static int 908 sfc_flow_parse_vxlan(const struct rte_flow_item *item, 909 struct sfc_flow_parse_ctx *parse_ctx, 910 struct rte_flow_error *error) 911 { 912 int rc; 913 efx_filter_spec_t *efx_spec = parse_ctx->filter; 914 const struct rte_flow_item_vxlan *spec = NULL; 915 const struct rte_flow_item_vxlan *mask = NULL; 916 const struct rte_flow_item_vxlan supp_mask = { 917 .vni = { 0xff, 0xff, 0xff } 918 }; 919 920 rc = sfc_flow_parse_init(item, 921 (const void **)&spec, 922 (const void **)&mask, 923 &supp_mask, 924 &rte_flow_item_vxlan_mask, 925 sizeof(struct rte_flow_item_vxlan), 926 error); 927 if (rc != 0) 928 return rc; 929 930 rc = sfc_flow_set_match_flags_for_encap_pkts(item, efx_spec, 931 EFX_IPPROTO_UDP, error); 932 if (rc != 0) 933 return rc; 934 935 efx_spec->efs_encap_type = EFX_TUNNEL_PROTOCOL_VXLAN; 936 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_ENCAP_TYPE; 937 938 if (spec == NULL) 939 return 0; 940 941 rc = sfc_flow_set_efx_spec_vni_or_vsid(efx_spec, spec->vni, 942 mask->vni, item, error); 943 944 return rc; 945 } 946 947 /** 948 * Convert GENEVE item to EFX filter specification. 949 * 950 * @param item[in] 951 * Item specification. Only Virtual Network Identifier and protocol type 952 * fields are supported. But protocol type can be only Ethernet (0x6558). 953 * If the mask is NULL, default mask will be used. 954 * Ranging is not supported. 955 * @param efx_spec[in, out] 956 * EFX filter specification to update. 957 * @param[out] error 958 * Perform verbose error reporting if not NULL. 959 */ 960 static int 961 sfc_flow_parse_geneve(const struct rte_flow_item *item, 962 struct sfc_flow_parse_ctx *parse_ctx, 963 struct rte_flow_error *error) 964 { 965 int rc; 966 efx_filter_spec_t *efx_spec = parse_ctx->filter; 967 const struct rte_flow_item_geneve *spec = NULL; 968 const struct rte_flow_item_geneve *mask = NULL; 969 const struct rte_flow_item_geneve supp_mask = { 970 .protocol = RTE_BE16(0xffff), 971 .vni = { 0xff, 0xff, 0xff } 972 }; 973 974 rc = sfc_flow_parse_init(item, 975 (const void **)&spec, 976 (const void **)&mask, 977 &supp_mask, 978 &rte_flow_item_geneve_mask, 979 sizeof(struct rte_flow_item_geneve), 980 error); 981 if (rc != 0) 982 return rc; 983 984 rc = sfc_flow_set_match_flags_for_encap_pkts(item, efx_spec, 985 EFX_IPPROTO_UDP, error); 986 if (rc != 0) 987 return rc; 988 989 efx_spec->efs_encap_type = EFX_TUNNEL_PROTOCOL_GENEVE; 990 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_ENCAP_TYPE; 991 992 if (spec == NULL) 993 return 0; 994 995 if (mask->protocol == supp_mask.protocol) { 996 if (spec->protocol != rte_cpu_to_be_16(RTE_ETHER_TYPE_TEB)) { 997 rte_flow_error_set(error, EINVAL, 998 RTE_FLOW_ERROR_TYPE_ITEM, item, 999 "GENEVE encap. protocol must be Ethernet " 1000 "(0x6558) in the GENEVE pattern item"); 1001 return -rte_errno; 1002 } 1003 } else if (mask->protocol != 0) { 1004 rte_flow_error_set(error, EINVAL, 1005 RTE_FLOW_ERROR_TYPE_ITEM, item, 1006 "Unsupported mask for GENEVE encap. protocol"); 1007 return -rte_errno; 1008 } 1009 1010 rc = sfc_flow_set_efx_spec_vni_or_vsid(efx_spec, spec->vni, 1011 mask->vni, item, error); 1012 1013 return rc; 1014 } 1015 1016 /** 1017 * Convert NVGRE item to EFX filter specification. 1018 * 1019 * @param item[in] 1020 * Item specification. Only virtual subnet ID field is supported. 1021 * If the mask is NULL, default mask will be used. 1022 * Ranging is not supported. 1023 * @param efx_spec[in, out] 1024 * EFX filter specification to update. 1025 * @param[out] error 1026 * Perform verbose error reporting if not NULL. 1027 */ 1028 static int 1029 sfc_flow_parse_nvgre(const struct rte_flow_item *item, 1030 struct sfc_flow_parse_ctx *parse_ctx, 1031 struct rte_flow_error *error) 1032 { 1033 int rc; 1034 efx_filter_spec_t *efx_spec = parse_ctx->filter; 1035 const struct rte_flow_item_nvgre *spec = NULL; 1036 const struct rte_flow_item_nvgre *mask = NULL; 1037 const struct rte_flow_item_nvgre supp_mask = { 1038 .tni = { 0xff, 0xff, 0xff } 1039 }; 1040 1041 rc = sfc_flow_parse_init(item, 1042 (const void **)&spec, 1043 (const void **)&mask, 1044 &supp_mask, 1045 &rte_flow_item_nvgre_mask, 1046 sizeof(struct rte_flow_item_nvgre), 1047 error); 1048 if (rc != 0) 1049 return rc; 1050 1051 rc = sfc_flow_set_match_flags_for_encap_pkts(item, efx_spec, 1052 EFX_IPPROTO_GRE, error); 1053 if (rc != 0) 1054 return rc; 1055 1056 efx_spec->efs_encap_type = EFX_TUNNEL_PROTOCOL_NVGRE; 1057 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_ENCAP_TYPE; 1058 1059 if (spec == NULL) 1060 return 0; 1061 1062 rc = sfc_flow_set_efx_spec_vni_or_vsid(efx_spec, spec->tni, 1063 mask->tni, item, error); 1064 1065 return rc; 1066 } 1067 1068 /** 1069 * Convert PPPoEx item to EFX filter specification. 1070 * 1071 * @param item[in] 1072 * Item specification. 1073 * Matching on PPPoEx fields is not supported. 1074 * This item can only be used to set or validate the EtherType filter. 1075 * Only zero masks are allowed. 1076 * Ranging is not supported. 1077 * @param efx_spec[in, out] 1078 * EFX filter specification to update. 1079 * @param[out] error 1080 * Perform verbose error reporting if not NULL. 1081 */ 1082 static int 1083 sfc_flow_parse_pppoex(const struct rte_flow_item *item, 1084 struct sfc_flow_parse_ctx *parse_ctx, 1085 struct rte_flow_error *error) 1086 { 1087 efx_filter_spec_t *efx_spec = parse_ctx->filter; 1088 const struct rte_flow_item_pppoe *spec = NULL; 1089 const struct rte_flow_item_pppoe *mask = NULL; 1090 const struct rte_flow_item_pppoe supp_mask = {}; 1091 const struct rte_flow_item_pppoe def_mask = {}; 1092 uint16_t ether_type; 1093 int rc; 1094 1095 rc = sfc_flow_parse_init(item, 1096 (const void **)&spec, 1097 (const void **)&mask, 1098 &supp_mask, 1099 &def_mask, 1100 sizeof(struct rte_flow_item_pppoe), 1101 error); 1102 if (rc != 0) 1103 return rc; 1104 1105 if (item->type == RTE_FLOW_ITEM_TYPE_PPPOED) 1106 ether_type = RTE_ETHER_TYPE_PPPOE_DISCOVERY; 1107 else 1108 ether_type = RTE_ETHER_TYPE_PPPOE_SESSION; 1109 1110 if ((efx_spec->efs_match_flags & EFX_FILTER_MATCH_ETHER_TYPE) != 0) { 1111 if (efx_spec->efs_ether_type != ether_type) { 1112 rte_flow_error_set(error, EINVAL, 1113 RTE_FLOW_ERROR_TYPE_ITEM, item, 1114 "Invalid EtherType for a PPPoE flow item"); 1115 return -rte_errno; 1116 } 1117 } else { 1118 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_ETHER_TYPE; 1119 efx_spec->efs_ether_type = ether_type; 1120 } 1121 1122 return 0; 1123 } 1124 1125 static const struct sfc_flow_item sfc_flow_items[] = { 1126 { 1127 .type = RTE_FLOW_ITEM_TYPE_VOID, 1128 .prev_layer = SFC_FLOW_ITEM_ANY_LAYER, 1129 .layer = SFC_FLOW_ITEM_ANY_LAYER, 1130 .ctx_type = SFC_FLOW_PARSE_CTX_FILTER, 1131 .parse = sfc_flow_parse_void, 1132 }, 1133 { 1134 .type = RTE_FLOW_ITEM_TYPE_ETH, 1135 .prev_layer = SFC_FLOW_ITEM_START_LAYER, 1136 .layer = SFC_FLOW_ITEM_L2, 1137 .ctx_type = SFC_FLOW_PARSE_CTX_FILTER, 1138 .parse = sfc_flow_parse_eth, 1139 }, 1140 { 1141 .type = RTE_FLOW_ITEM_TYPE_VLAN, 1142 .prev_layer = SFC_FLOW_ITEM_L2, 1143 .layer = SFC_FLOW_ITEM_L2, 1144 .ctx_type = SFC_FLOW_PARSE_CTX_FILTER, 1145 .parse = sfc_flow_parse_vlan, 1146 }, 1147 { 1148 .type = RTE_FLOW_ITEM_TYPE_PPPOED, 1149 .prev_layer = SFC_FLOW_ITEM_L2, 1150 .layer = SFC_FLOW_ITEM_L2, 1151 .ctx_type = SFC_FLOW_PARSE_CTX_FILTER, 1152 .parse = sfc_flow_parse_pppoex, 1153 }, 1154 { 1155 .type = RTE_FLOW_ITEM_TYPE_PPPOES, 1156 .prev_layer = SFC_FLOW_ITEM_L2, 1157 .layer = SFC_FLOW_ITEM_L2, 1158 .ctx_type = SFC_FLOW_PARSE_CTX_FILTER, 1159 .parse = sfc_flow_parse_pppoex, 1160 }, 1161 { 1162 .type = RTE_FLOW_ITEM_TYPE_IPV4, 1163 .prev_layer = SFC_FLOW_ITEM_L2, 1164 .layer = SFC_FLOW_ITEM_L3, 1165 .ctx_type = SFC_FLOW_PARSE_CTX_FILTER, 1166 .parse = sfc_flow_parse_ipv4, 1167 }, 1168 { 1169 .type = RTE_FLOW_ITEM_TYPE_IPV6, 1170 .prev_layer = SFC_FLOW_ITEM_L2, 1171 .layer = SFC_FLOW_ITEM_L3, 1172 .ctx_type = SFC_FLOW_PARSE_CTX_FILTER, 1173 .parse = sfc_flow_parse_ipv6, 1174 }, 1175 { 1176 .type = RTE_FLOW_ITEM_TYPE_TCP, 1177 .prev_layer = SFC_FLOW_ITEM_L3, 1178 .layer = SFC_FLOW_ITEM_L4, 1179 .ctx_type = SFC_FLOW_PARSE_CTX_FILTER, 1180 .parse = sfc_flow_parse_tcp, 1181 }, 1182 { 1183 .type = RTE_FLOW_ITEM_TYPE_UDP, 1184 .prev_layer = SFC_FLOW_ITEM_L3, 1185 .layer = SFC_FLOW_ITEM_L4, 1186 .ctx_type = SFC_FLOW_PARSE_CTX_FILTER, 1187 .parse = sfc_flow_parse_udp, 1188 }, 1189 { 1190 .type = RTE_FLOW_ITEM_TYPE_VXLAN, 1191 .prev_layer = SFC_FLOW_ITEM_L4, 1192 .layer = SFC_FLOW_ITEM_START_LAYER, 1193 .ctx_type = SFC_FLOW_PARSE_CTX_FILTER, 1194 .parse = sfc_flow_parse_vxlan, 1195 }, 1196 { 1197 .type = RTE_FLOW_ITEM_TYPE_GENEVE, 1198 .prev_layer = SFC_FLOW_ITEM_L4, 1199 .layer = SFC_FLOW_ITEM_START_LAYER, 1200 .ctx_type = SFC_FLOW_PARSE_CTX_FILTER, 1201 .parse = sfc_flow_parse_geneve, 1202 }, 1203 { 1204 .type = RTE_FLOW_ITEM_TYPE_NVGRE, 1205 .prev_layer = SFC_FLOW_ITEM_L3, 1206 .layer = SFC_FLOW_ITEM_START_LAYER, 1207 .ctx_type = SFC_FLOW_PARSE_CTX_FILTER, 1208 .parse = sfc_flow_parse_nvgre, 1209 }, 1210 }; 1211 1212 /* 1213 * Protocol-independent flow API support 1214 */ 1215 static int 1216 sfc_flow_parse_attr(struct sfc_adapter *sa, 1217 const struct rte_flow_attr *attr, 1218 struct rte_flow *flow, 1219 struct rte_flow_error *error) 1220 { 1221 struct sfc_flow_spec *spec = &flow->spec; 1222 struct sfc_flow_spec_filter *spec_filter = &spec->filter; 1223 struct sfc_flow_spec_mae *spec_mae = &spec->mae; 1224 struct sfc_mae *mae = &sa->mae; 1225 1226 if (attr == NULL) { 1227 rte_flow_error_set(error, EINVAL, 1228 RTE_FLOW_ERROR_TYPE_ATTR, NULL, 1229 "NULL attribute"); 1230 return -rte_errno; 1231 } 1232 if (attr->group != 0) { 1233 rte_flow_error_set(error, ENOTSUP, 1234 RTE_FLOW_ERROR_TYPE_ATTR_GROUP, attr, 1235 "Groups are not supported"); 1236 return -rte_errno; 1237 } 1238 if (attr->egress != 0) { 1239 rte_flow_error_set(error, ENOTSUP, 1240 RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, attr, 1241 "Egress is not supported"); 1242 return -rte_errno; 1243 } 1244 if (attr->ingress == 0) { 1245 rte_flow_error_set(error, ENOTSUP, 1246 RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, attr, 1247 "Ingress is compulsory"); 1248 return -rte_errno; 1249 } 1250 if (attr->transfer == 0) { 1251 if (attr->priority != 0) { 1252 rte_flow_error_set(error, ENOTSUP, 1253 RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, 1254 attr, "Priorities are unsupported"); 1255 return -rte_errno; 1256 } 1257 spec->type = SFC_FLOW_SPEC_FILTER; 1258 spec_filter->template.efs_flags |= EFX_FILTER_FLAG_RX; 1259 spec_filter->template.efs_rss_context = EFX_RSS_CONTEXT_DEFAULT; 1260 spec_filter->template.efs_priority = EFX_FILTER_PRI_MANUAL; 1261 } else { 1262 if (mae->status != SFC_MAE_STATUS_SUPPORTED) { 1263 rte_flow_error_set(error, ENOTSUP, 1264 RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER, 1265 attr, "Transfer is not supported"); 1266 return -rte_errno; 1267 } 1268 if (attr->priority > mae->nb_action_rule_prios_max) { 1269 rte_flow_error_set(error, ENOTSUP, 1270 RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, 1271 attr, "Unsupported priority level"); 1272 return -rte_errno; 1273 } 1274 spec->type = SFC_FLOW_SPEC_MAE; 1275 spec_mae->priority = attr->priority; 1276 spec_mae->match_spec = NULL; 1277 spec_mae->action_set = NULL; 1278 spec_mae->rule_id.id = EFX_MAE_RSRC_ID_INVALID; 1279 } 1280 1281 return 0; 1282 } 1283 1284 /* Get item from array sfc_flow_items */ 1285 static const struct sfc_flow_item * 1286 sfc_flow_get_item(const struct sfc_flow_item *items, 1287 unsigned int nb_items, 1288 enum rte_flow_item_type type) 1289 { 1290 unsigned int i; 1291 1292 for (i = 0; i < nb_items; i++) 1293 if (items[i].type == type) 1294 return &items[i]; 1295 1296 return NULL; 1297 } 1298 1299 int 1300 sfc_flow_parse_pattern(const struct sfc_flow_item *flow_items, 1301 unsigned int nb_flow_items, 1302 const struct rte_flow_item pattern[], 1303 struct sfc_flow_parse_ctx *parse_ctx, 1304 struct rte_flow_error *error) 1305 { 1306 int rc; 1307 unsigned int prev_layer = SFC_FLOW_ITEM_ANY_LAYER; 1308 boolean_t is_ifrm = B_FALSE; 1309 const struct sfc_flow_item *item; 1310 1311 if (pattern == NULL) { 1312 rte_flow_error_set(error, EINVAL, 1313 RTE_FLOW_ERROR_TYPE_ITEM_NUM, NULL, 1314 "NULL pattern"); 1315 return -rte_errno; 1316 } 1317 1318 for (; pattern->type != RTE_FLOW_ITEM_TYPE_END; pattern++) { 1319 item = sfc_flow_get_item(flow_items, nb_flow_items, 1320 pattern->type); 1321 if (item == NULL) { 1322 rte_flow_error_set(error, ENOTSUP, 1323 RTE_FLOW_ERROR_TYPE_ITEM, pattern, 1324 "Unsupported pattern item"); 1325 return -rte_errno; 1326 } 1327 1328 /* 1329 * Omitting one or several protocol layers at the beginning 1330 * of pattern is supported 1331 */ 1332 if (item->prev_layer != SFC_FLOW_ITEM_ANY_LAYER && 1333 prev_layer != SFC_FLOW_ITEM_ANY_LAYER && 1334 item->prev_layer != prev_layer) { 1335 rte_flow_error_set(error, ENOTSUP, 1336 RTE_FLOW_ERROR_TYPE_ITEM, pattern, 1337 "Unexpected sequence of pattern items"); 1338 return -rte_errno; 1339 } 1340 1341 /* 1342 * Allow only VOID and ETH pattern items in the inner frame. 1343 * Also check that there is only one tunneling protocol. 1344 */ 1345 switch (item->type) { 1346 case RTE_FLOW_ITEM_TYPE_VOID: 1347 case RTE_FLOW_ITEM_TYPE_ETH: 1348 break; 1349 1350 case RTE_FLOW_ITEM_TYPE_VXLAN: 1351 case RTE_FLOW_ITEM_TYPE_GENEVE: 1352 case RTE_FLOW_ITEM_TYPE_NVGRE: 1353 if (is_ifrm) { 1354 rte_flow_error_set(error, EINVAL, 1355 RTE_FLOW_ERROR_TYPE_ITEM, 1356 pattern, 1357 "More than one tunneling protocol"); 1358 return -rte_errno; 1359 } 1360 is_ifrm = B_TRUE; 1361 break; 1362 1363 default: 1364 if (parse_ctx->type == SFC_FLOW_PARSE_CTX_FILTER && 1365 is_ifrm) { 1366 rte_flow_error_set(error, EINVAL, 1367 RTE_FLOW_ERROR_TYPE_ITEM, 1368 pattern, 1369 "There is an unsupported pattern item " 1370 "in the inner frame"); 1371 return -rte_errno; 1372 } 1373 break; 1374 } 1375 1376 if (parse_ctx->type != item->ctx_type) { 1377 rte_flow_error_set(error, EINVAL, 1378 RTE_FLOW_ERROR_TYPE_ITEM, pattern, 1379 "Parse context type mismatch"); 1380 return -rte_errno; 1381 } 1382 1383 rc = item->parse(pattern, parse_ctx, error); 1384 if (rc != 0) 1385 return rc; 1386 1387 if (item->layer != SFC_FLOW_ITEM_ANY_LAYER) 1388 prev_layer = item->layer; 1389 } 1390 1391 return 0; 1392 } 1393 1394 static int 1395 sfc_flow_parse_queue(struct sfc_adapter *sa, 1396 const struct rte_flow_action_queue *queue, 1397 struct rte_flow *flow) 1398 { 1399 struct sfc_flow_spec *spec = &flow->spec; 1400 struct sfc_flow_spec_filter *spec_filter = &spec->filter; 1401 struct sfc_rxq *rxq; 1402 struct sfc_rxq_info *rxq_info; 1403 1404 if (queue->index >= sfc_sa2shared(sa)->ethdev_rxq_count) 1405 return -EINVAL; 1406 1407 rxq = sfc_rxq_ctrl_by_ethdev_qid(sa, queue->index); 1408 spec_filter->template.efs_dmaq_id = (uint16_t)rxq->hw_index; 1409 1410 rxq_info = &sfc_sa2shared(sa)->rxq_info[queue->index]; 1411 spec_filter->rss_hash_required = !!(rxq_info->rxq_flags & 1412 SFC_RXQ_FLAG_RSS_HASH); 1413 1414 return 0; 1415 } 1416 1417 static int 1418 sfc_flow_parse_rss(struct sfc_adapter *sa, 1419 const struct rte_flow_action_rss *action_rss, 1420 struct rte_flow *flow) 1421 { 1422 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); 1423 struct sfc_rss *rss = &sas->rss; 1424 sfc_ethdev_qid_t ethdev_qid; 1425 struct sfc_rxq *rxq; 1426 unsigned int rxq_hw_index_min; 1427 unsigned int rxq_hw_index_max; 1428 efx_rx_hash_type_t efx_hash_types; 1429 const uint8_t *rss_key; 1430 struct sfc_flow_spec *spec = &flow->spec; 1431 struct sfc_flow_spec_filter *spec_filter = &spec->filter; 1432 struct sfc_flow_rss *sfc_rss_conf = &spec_filter->rss_conf; 1433 unsigned int i; 1434 1435 if (action_rss->queue_num == 0) 1436 return -EINVAL; 1437 1438 ethdev_qid = sfc_sa2shared(sa)->ethdev_rxq_count - 1; 1439 rxq = sfc_rxq_ctrl_by_ethdev_qid(sa, ethdev_qid); 1440 rxq_hw_index_min = rxq->hw_index; 1441 rxq_hw_index_max = 0; 1442 1443 for (i = 0; i < action_rss->queue_num; ++i) { 1444 ethdev_qid = action_rss->queue[i]; 1445 1446 if ((unsigned int)ethdev_qid >= 1447 sfc_sa2shared(sa)->ethdev_rxq_count) 1448 return -EINVAL; 1449 1450 rxq = sfc_rxq_ctrl_by_ethdev_qid(sa, ethdev_qid); 1451 1452 if (rxq->hw_index < rxq_hw_index_min) 1453 rxq_hw_index_min = rxq->hw_index; 1454 1455 if (rxq->hw_index > rxq_hw_index_max) 1456 rxq_hw_index_max = rxq->hw_index; 1457 } 1458 1459 switch (action_rss->func) { 1460 case RTE_ETH_HASH_FUNCTION_DEFAULT: 1461 case RTE_ETH_HASH_FUNCTION_TOEPLITZ: 1462 break; 1463 default: 1464 return -EINVAL; 1465 } 1466 1467 if (action_rss->level) 1468 return -EINVAL; 1469 1470 /* 1471 * Dummy RSS action with only one queue and no specific settings 1472 * for hash types and key does not require dedicated RSS context 1473 * and may be simplified to single queue action. 1474 */ 1475 if (action_rss->queue_num == 1 && action_rss->types == 0 && 1476 action_rss->key_len == 0) { 1477 spec_filter->template.efs_dmaq_id = rxq_hw_index_min; 1478 return 0; 1479 } 1480 1481 if (action_rss->types) { 1482 int rc; 1483 1484 rc = sfc_rx_hf_rte_to_efx(sa, action_rss->types, 1485 &efx_hash_types); 1486 if (rc != 0) 1487 return -rc; 1488 } else { 1489 unsigned int i; 1490 1491 efx_hash_types = 0; 1492 for (i = 0; i < rss->hf_map_nb_entries; ++i) 1493 efx_hash_types |= rss->hf_map[i].efx; 1494 } 1495 1496 if (action_rss->key_len) { 1497 if (action_rss->key_len != sizeof(rss->key)) 1498 return -EINVAL; 1499 1500 rss_key = action_rss->key; 1501 } else { 1502 rss_key = rss->key; 1503 } 1504 1505 spec_filter->rss = B_TRUE; 1506 1507 sfc_rss_conf->rxq_hw_index_min = rxq_hw_index_min; 1508 sfc_rss_conf->rxq_hw_index_max = rxq_hw_index_max; 1509 sfc_rss_conf->rss_hash_types = efx_hash_types; 1510 rte_memcpy(sfc_rss_conf->rss_key, rss_key, sizeof(rss->key)); 1511 1512 for (i = 0; i < RTE_DIM(sfc_rss_conf->rss_tbl); ++i) { 1513 unsigned int nb_queues = action_rss->queue_num; 1514 struct sfc_rxq *rxq; 1515 1516 ethdev_qid = action_rss->queue[i % nb_queues]; 1517 rxq = sfc_rxq_ctrl_by_ethdev_qid(sa, ethdev_qid); 1518 sfc_rss_conf->rss_tbl[i] = rxq->hw_index - rxq_hw_index_min; 1519 } 1520 1521 return 0; 1522 } 1523 1524 static int 1525 sfc_flow_spec_flush(struct sfc_adapter *sa, struct sfc_flow_spec *spec, 1526 unsigned int filters_count) 1527 { 1528 struct sfc_flow_spec_filter *spec_filter = &spec->filter; 1529 unsigned int i; 1530 int ret = 0; 1531 1532 for (i = 0; i < filters_count; i++) { 1533 int rc; 1534 1535 rc = efx_filter_remove(sa->nic, &spec_filter->filters[i]); 1536 if (ret == 0 && rc != 0) { 1537 sfc_err(sa, "failed to remove filter specification " 1538 "(rc = %d)", rc); 1539 ret = rc; 1540 } 1541 } 1542 1543 return ret; 1544 } 1545 1546 static int 1547 sfc_flow_spec_insert(struct sfc_adapter *sa, struct sfc_flow_spec *spec) 1548 { 1549 struct sfc_flow_spec_filter *spec_filter = &spec->filter; 1550 unsigned int i; 1551 int rc = 0; 1552 1553 for (i = 0; i < spec_filter->count; i++) { 1554 rc = efx_filter_insert(sa->nic, &spec_filter->filters[i]); 1555 if (rc != 0) { 1556 sfc_flow_spec_flush(sa, spec, i); 1557 break; 1558 } 1559 } 1560 1561 return rc; 1562 } 1563 1564 static int 1565 sfc_flow_spec_remove(struct sfc_adapter *sa, struct sfc_flow_spec *spec) 1566 { 1567 struct sfc_flow_spec_filter *spec_filter = &spec->filter; 1568 1569 return sfc_flow_spec_flush(sa, spec, spec_filter->count); 1570 } 1571 1572 static int 1573 sfc_flow_filter_insert(struct sfc_adapter *sa, 1574 struct rte_flow *flow) 1575 { 1576 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); 1577 struct sfc_rss *rss = &sas->rss; 1578 struct sfc_flow_spec_filter *spec_filter = &flow->spec.filter; 1579 struct sfc_flow_rss *flow_rss = &spec_filter->rss_conf; 1580 uint32_t efs_rss_context = EFX_RSS_CONTEXT_DEFAULT; 1581 boolean_t create_context; 1582 unsigned int i; 1583 int rc = 0; 1584 1585 create_context = spec_filter->rss || (spec_filter->rss_hash_required && 1586 rss->dummy_rss_context == EFX_RSS_CONTEXT_DEFAULT); 1587 1588 if (create_context) { 1589 unsigned int rss_spread; 1590 unsigned int rss_hash_types; 1591 uint8_t *rss_key; 1592 1593 if (spec_filter->rss) { 1594 rss_spread = MIN(flow_rss->rxq_hw_index_max - 1595 flow_rss->rxq_hw_index_min + 1, 1596 EFX_MAXRSS); 1597 rss_hash_types = flow_rss->rss_hash_types; 1598 rss_key = flow_rss->rss_key; 1599 } else { 1600 /* 1601 * Initialize dummy RSS context parameters to have 1602 * valid RSS hash. Use default RSS hash function and 1603 * key. 1604 */ 1605 rss_spread = 1; 1606 rss_hash_types = rss->hash_types; 1607 rss_key = rss->key; 1608 } 1609 1610 rc = efx_rx_scale_context_alloc(sa->nic, 1611 EFX_RX_SCALE_EXCLUSIVE, 1612 rss_spread, 1613 &efs_rss_context); 1614 if (rc != 0) 1615 goto fail_scale_context_alloc; 1616 1617 rc = efx_rx_scale_mode_set(sa->nic, efs_rss_context, 1618 rss->hash_alg, 1619 rss_hash_types, B_TRUE); 1620 if (rc != 0) 1621 goto fail_scale_mode_set; 1622 1623 rc = efx_rx_scale_key_set(sa->nic, efs_rss_context, 1624 rss_key, sizeof(rss->key)); 1625 if (rc != 0) 1626 goto fail_scale_key_set; 1627 } else { 1628 efs_rss_context = rss->dummy_rss_context; 1629 } 1630 1631 if (spec_filter->rss || spec_filter->rss_hash_required) { 1632 /* 1633 * At this point, fully elaborated filter specifications 1634 * have been produced from the template. To make sure that 1635 * RSS behaviour is consistent between them, set the same 1636 * RSS context value everywhere. 1637 */ 1638 for (i = 0; i < spec_filter->count; i++) { 1639 efx_filter_spec_t *spec = &spec_filter->filters[i]; 1640 1641 spec->efs_rss_context = efs_rss_context; 1642 spec->efs_flags |= EFX_FILTER_FLAG_RX_RSS; 1643 if (spec_filter->rss) 1644 spec->efs_dmaq_id = flow_rss->rxq_hw_index_min; 1645 } 1646 } 1647 1648 rc = sfc_flow_spec_insert(sa, &flow->spec); 1649 if (rc != 0) 1650 goto fail_filter_insert; 1651 1652 if (create_context) { 1653 unsigned int dummy_tbl[RTE_DIM(flow_rss->rss_tbl)] = {0}; 1654 unsigned int *tbl; 1655 1656 tbl = spec_filter->rss ? flow_rss->rss_tbl : dummy_tbl; 1657 1658 /* 1659 * Scale table is set after filter insertion because 1660 * the table entries are relative to the base RxQ ID 1661 * and the latter is submitted to the HW by means of 1662 * inserting a filter, so by the time of the request 1663 * the HW knows all the information needed to verify 1664 * the table entries, and the operation will succeed 1665 */ 1666 rc = efx_rx_scale_tbl_set(sa->nic, efs_rss_context, 1667 tbl, RTE_DIM(flow_rss->rss_tbl)); 1668 if (rc != 0) 1669 goto fail_scale_tbl_set; 1670 1671 /* Remember created dummy RSS context */ 1672 if (!spec_filter->rss) 1673 rss->dummy_rss_context = efs_rss_context; 1674 } 1675 1676 return 0; 1677 1678 fail_scale_tbl_set: 1679 sfc_flow_spec_remove(sa, &flow->spec); 1680 1681 fail_filter_insert: 1682 fail_scale_key_set: 1683 fail_scale_mode_set: 1684 if (create_context) 1685 efx_rx_scale_context_free(sa->nic, efs_rss_context); 1686 1687 fail_scale_context_alloc: 1688 return rc; 1689 } 1690 1691 static int 1692 sfc_flow_filter_remove(struct sfc_adapter *sa, 1693 struct rte_flow *flow) 1694 { 1695 struct sfc_flow_spec_filter *spec_filter = &flow->spec.filter; 1696 int rc = 0; 1697 1698 rc = sfc_flow_spec_remove(sa, &flow->spec); 1699 if (rc != 0) 1700 return rc; 1701 1702 if (spec_filter->rss) { 1703 /* 1704 * All specifications for a given flow rule have the same RSS 1705 * context, so that RSS context value is taken from the first 1706 * filter specification 1707 */ 1708 efx_filter_spec_t *spec = &spec_filter->filters[0]; 1709 1710 rc = efx_rx_scale_context_free(sa->nic, spec->efs_rss_context); 1711 } 1712 1713 return rc; 1714 } 1715 1716 static int 1717 sfc_flow_parse_mark(struct sfc_adapter *sa, 1718 const struct rte_flow_action_mark *mark, 1719 struct rte_flow *flow) 1720 { 1721 struct sfc_flow_spec *spec = &flow->spec; 1722 struct sfc_flow_spec_filter *spec_filter = &spec->filter; 1723 const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic); 1724 1725 if (mark == NULL || mark->id > encp->enc_filter_action_mark_max) 1726 return EINVAL; 1727 1728 spec_filter->template.efs_flags |= EFX_FILTER_FLAG_ACTION_MARK; 1729 spec_filter->template.efs_mark = mark->id; 1730 1731 return 0; 1732 } 1733 1734 static int 1735 sfc_flow_parse_actions(struct sfc_adapter *sa, 1736 const struct rte_flow_action actions[], 1737 struct rte_flow *flow, 1738 struct rte_flow_error *error) 1739 { 1740 int rc; 1741 struct sfc_flow_spec *spec = &flow->spec; 1742 struct sfc_flow_spec_filter *spec_filter = &spec->filter; 1743 const unsigned int dp_rx_features = sa->priv.dp_rx->features; 1744 uint32_t actions_set = 0; 1745 const uint32_t fate_actions_mask = (1UL << RTE_FLOW_ACTION_TYPE_QUEUE) | 1746 (1UL << RTE_FLOW_ACTION_TYPE_RSS) | 1747 (1UL << RTE_FLOW_ACTION_TYPE_DROP); 1748 const uint32_t mark_actions_mask = (1UL << RTE_FLOW_ACTION_TYPE_MARK) | 1749 (1UL << RTE_FLOW_ACTION_TYPE_FLAG); 1750 1751 if (actions == NULL) { 1752 rte_flow_error_set(error, EINVAL, 1753 RTE_FLOW_ERROR_TYPE_ACTION_NUM, NULL, 1754 "NULL actions"); 1755 return -rte_errno; 1756 } 1757 1758 for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) { 1759 switch (actions->type) { 1760 case RTE_FLOW_ACTION_TYPE_VOID: 1761 SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_VOID, 1762 actions_set); 1763 break; 1764 1765 case RTE_FLOW_ACTION_TYPE_QUEUE: 1766 SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_QUEUE, 1767 actions_set); 1768 if ((actions_set & fate_actions_mask) != 0) 1769 goto fail_fate_actions; 1770 1771 rc = sfc_flow_parse_queue(sa, actions->conf, flow); 1772 if (rc != 0) { 1773 rte_flow_error_set(error, EINVAL, 1774 RTE_FLOW_ERROR_TYPE_ACTION, actions, 1775 "Bad QUEUE action"); 1776 return -rte_errno; 1777 } 1778 break; 1779 1780 case RTE_FLOW_ACTION_TYPE_RSS: 1781 SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_RSS, 1782 actions_set); 1783 if ((actions_set & fate_actions_mask) != 0) 1784 goto fail_fate_actions; 1785 1786 rc = sfc_flow_parse_rss(sa, actions->conf, flow); 1787 if (rc != 0) { 1788 rte_flow_error_set(error, -rc, 1789 RTE_FLOW_ERROR_TYPE_ACTION, actions, 1790 "Bad RSS action"); 1791 return -rte_errno; 1792 } 1793 break; 1794 1795 case RTE_FLOW_ACTION_TYPE_DROP: 1796 SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_DROP, 1797 actions_set); 1798 if ((actions_set & fate_actions_mask) != 0) 1799 goto fail_fate_actions; 1800 1801 spec_filter->template.efs_dmaq_id = 1802 EFX_FILTER_SPEC_RX_DMAQ_ID_DROP; 1803 break; 1804 1805 case RTE_FLOW_ACTION_TYPE_FLAG: 1806 SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_FLAG, 1807 actions_set); 1808 if ((actions_set & mark_actions_mask) != 0) 1809 goto fail_actions_overlap; 1810 1811 if ((dp_rx_features & SFC_DP_RX_FEAT_FLOW_FLAG) == 0) { 1812 rte_flow_error_set(error, ENOTSUP, 1813 RTE_FLOW_ERROR_TYPE_ACTION, NULL, 1814 "FLAG action is not supported on the current Rx datapath"); 1815 return -rte_errno; 1816 } 1817 1818 spec_filter->template.efs_flags |= 1819 EFX_FILTER_FLAG_ACTION_FLAG; 1820 break; 1821 1822 case RTE_FLOW_ACTION_TYPE_MARK: 1823 SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_MARK, 1824 actions_set); 1825 if ((actions_set & mark_actions_mask) != 0) 1826 goto fail_actions_overlap; 1827 1828 if ((dp_rx_features & SFC_DP_RX_FEAT_FLOW_MARK) == 0) { 1829 rte_flow_error_set(error, ENOTSUP, 1830 RTE_FLOW_ERROR_TYPE_ACTION, NULL, 1831 "MARK action is not supported on the current Rx datapath"); 1832 return -rte_errno; 1833 } 1834 1835 rc = sfc_flow_parse_mark(sa, actions->conf, flow); 1836 if (rc != 0) { 1837 rte_flow_error_set(error, rc, 1838 RTE_FLOW_ERROR_TYPE_ACTION, actions, 1839 "Bad MARK action"); 1840 return -rte_errno; 1841 } 1842 break; 1843 1844 default: 1845 rte_flow_error_set(error, ENOTSUP, 1846 RTE_FLOW_ERROR_TYPE_ACTION, actions, 1847 "Action is not supported"); 1848 return -rte_errno; 1849 } 1850 1851 actions_set |= (1UL << actions->type); 1852 } 1853 1854 /* When fate is unknown, drop traffic. */ 1855 if ((actions_set & fate_actions_mask) == 0) { 1856 spec_filter->template.efs_dmaq_id = 1857 EFX_FILTER_SPEC_RX_DMAQ_ID_DROP; 1858 } 1859 1860 return 0; 1861 1862 fail_fate_actions: 1863 rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, actions, 1864 "Cannot combine several fate-deciding actions, " 1865 "choose between QUEUE, RSS or DROP"); 1866 return -rte_errno; 1867 1868 fail_actions_overlap: 1869 rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, actions, 1870 "Overlapping actions are not supported"); 1871 return -rte_errno; 1872 } 1873 1874 /** 1875 * Set the EFX_FILTER_MATCH_UNKNOWN_UCAST_DST 1876 * and EFX_FILTER_MATCH_UNKNOWN_MCAST_DST match flags in the same 1877 * specifications after copying. 1878 * 1879 * @param spec[in, out] 1880 * SFC flow specification to update. 1881 * @param filters_count_for_one_val[in] 1882 * How many specifications should have the same match flag, what is the 1883 * number of specifications before copying. 1884 * @param error[out] 1885 * Perform verbose error reporting if not NULL. 1886 */ 1887 static int 1888 sfc_flow_set_unknown_dst_flags(struct sfc_flow_spec *spec, 1889 unsigned int filters_count_for_one_val, 1890 struct rte_flow_error *error) 1891 { 1892 unsigned int i; 1893 struct sfc_flow_spec_filter *spec_filter = &spec->filter; 1894 static const efx_filter_match_flags_t vals[] = { 1895 EFX_FILTER_MATCH_UNKNOWN_UCAST_DST, 1896 EFX_FILTER_MATCH_UNKNOWN_MCAST_DST 1897 }; 1898 1899 if (filters_count_for_one_val * RTE_DIM(vals) != spec_filter->count) { 1900 rte_flow_error_set(error, EINVAL, 1901 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 1902 "Number of specifications is incorrect while copying " 1903 "by unknown destination flags"); 1904 return -rte_errno; 1905 } 1906 1907 for (i = 0; i < spec_filter->count; i++) { 1908 /* The check above ensures that divisor can't be zero here */ 1909 spec_filter->filters[i].efs_match_flags |= 1910 vals[i / filters_count_for_one_val]; 1911 } 1912 1913 return 0; 1914 } 1915 1916 /** 1917 * Check that the following conditions are met: 1918 * - the list of supported filters has a filter 1919 * with EFX_FILTER_MATCH_UNKNOWN_MCAST_DST flag instead of 1920 * EFX_FILTER_MATCH_UNKNOWN_UCAST_DST, since this filter will also 1921 * be inserted. 1922 * 1923 * @param match[in] 1924 * The match flags of filter. 1925 * @param spec[in] 1926 * Specification to be supplemented. 1927 * @param filter[in] 1928 * SFC filter with list of supported filters. 1929 */ 1930 static boolean_t 1931 sfc_flow_check_unknown_dst_flags(efx_filter_match_flags_t match, 1932 __rte_unused efx_filter_spec_t *spec, 1933 struct sfc_filter *filter) 1934 { 1935 unsigned int i; 1936 efx_filter_match_flags_t match_mcast_dst; 1937 1938 match_mcast_dst = 1939 (match & ~EFX_FILTER_MATCH_UNKNOWN_UCAST_DST) | 1940 EFX_FILTER_MATCH_UNKNOWN_MCAST_DST; 1941 for (i = 0; i < filter->supported_match_num; i++) { 1942 if (match_mcast_dst == filter->supported_match[i]) 1943 return B_TRUE; 1944 } 1945 1946 return B_FALSE; 1947 } 1948 1949 /** 1950 * Set the EFX_FILTER_MATCH_ETHER_TYPE match flag and EFX_ETHER_TYPE_IPV4 and 1951 * EFX_ETHER_TYPE_IPV6 values of the corresponding field in the same 1952 * specifications after copying. 1953 * 1954 * @param spec[in, out] 1955 * SFC flow specification to update. 1956 * @param filters_count_for_one_val[in] 1957 * How many specifications should have the same EtherType value, what is the 1958 * number of specifications before copying. 1959 * @param error[out] 1960 * Perform verbose error reporting if not NULL. 1961 */ 1962 static int 1963 sfc_flow_set_ethertypes(struct sfc_flow_spec *spec, 1964 unsigned int filters_count_for_one_val, 1965 struct rte_flow_error *error) 1966 { 1967 unsigned int i; 1968 struct sfc_flow_spec_filter *spec_filter = &spec->filter; 1969 static const uint16_t vals[] = { 1970 EFX_ETHER_TYPE_IPV4, EFX_ETHER_TYPE_IPV6 1971 }; 1972 1973 if (filters_count_for_one_val * RTE_DIM(vals) != spec_filter->count) { 1974 rte_flow_error_set(error, EINVAL, 1975 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 1976 "Number of specifications is incorrect " 1977 "while copying by Ethertype"); 1978 return -rte_errno; 1979 } 1980 1981 for (i = 0; i < spec_filter->count; i++) { 1982 spec_filter->filters[i].efs_match_flags |= 1983 EFX_FILTER_MATCH_ETHER_TYPE; 1984 1985 /* 1986 * The check above ensures that 1987 * filters_count_for_one_val is not 0 1988 */ 1989 spec_filter->filters[i].efs_ether_type = 1990 vals[i / filters_count_for_one_val]; 1991 } 1992 1993 return 0; 1994 } 1995 1996 /** 1997 * Set the EFX_FILTER_MATCH_OUTER_VID match flag with value 0 1998 * in the same specifications after copying. 1999 * 2000 * @param spec[in, out] 2001 * SFC flow specification to update. 2002 * @param filters_count_for_one_val[in] 2003 * How many specifications should have the same match flag, what is the 2004 * number of specifications before copying. 2005 * @param error[out] 2006 * Perform verbose error reporting if not NULL. 2007 */ 2008 static int 2009 sfc_flow_set_outer_vid_flag(struct sfc_flow_spec *spec, 2010 unsigned int filters_count_for_one_val, 2011 struct rte_flow_error *error) 2012 { 2013 struct sfc_flow_spec_filter *spec_filter = &spec->filter; 2014 unsigned int i; 2015 2016 if (filters_count_for_one_val != spec_filter->count) { 2017 rte_flow_error_set(error, EINVAL, 2018 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 2019 "Number of specifications is incorrect " 2020 "while copying by outer VLAN ID"); 2021 return -rte_errno; 2022 } 2023 2024 for (i = 0; i < spec_filter->count; i++) { 2025 spec_filter->filters[i].efs_match_flags |= 2026 EFX_FILTER_MATCH_OUTER_VID; 2027 2028 spec_filter->filters[i].efs_outer_vid = 0; 2029 } 2030 2031 return 0; 2032 } 2033 2034 /** 2035 * Set the EFX_FILTER_MATCH_IFRM_UNKNOWN_UCAST_DST and 2036 * EFX_FILTER_MATCH_IFRM_UNKNOWN_MCAST_DST match flags in the same 2037 * specifications after copying. 2038 * 2039 * @param spec[in, out] 2040 * SFC flow specification to update. 2041 * @param filters_count_for_one_val[in] 2042 * How many specifications should have the same match flag, what is the 2043 * number of specifications before copying. 2044 * @param error[out] 2045 * Perform verbose error reporting if not NULL. 2046 */ 2047 static int 2048 sfc_flow_set_ifrm_unknown_dst_flags(struct sfc_flow_spec *spec, 2049 unsigned int filters_count_for_one_val, 2050 struct rte_flow_error *error) 2051 { 2052 unsigned int i; 2053 struct sfc_flow_spec_filter *spec_filter = &spec->filter; 2054 static const efx_filter_match_flags_t vals[] = { 2055 EFX_FILTER_MATCH_IFRM_UNKNOWN_UCAST_DST, 2056 EFX_FILTER_MATCH_IFRM_UNKNOWN_MCAST_DST 2057 }; 2058 2059 if (filters_count_for_one_val * RTE_DIM(vals) != spec_filter->count) { 2060 rte_flow_error_set(error, EINVAL, 2061 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 2062 "Number of specifications is incorrect while copying " 2063 "by inner frame unknown destination flags"); 2064 return -rte_errno; 2065 } 2066 2067 for (i = 0; i < spec_filter->count; i++) { 2068 /* The check above ensures that divisor can't be zero here */ 2069 spec_filter->filters[i].efs_match_flags |= 2070 vals[i / filters_count_for_one_val]; 2071 } 2072 2073 return 0; 2074 } 2075 2076 /** 2077 * Check that the following conditions are met: 2078 * - the specification corresponds to a filter for encapsulated traffic 2079 * - the list of supported filters has a filter 2080 * with EFX_FILTER_MATCH_IFRM_UNKNOWN_MCAST_DST flag instead of 2081 * EFX_FILTER_MATCH_IFRM_UNKNOWN_UCAST_DST, since this filter will also 2082 * be inserted. 2083 * 2084 * @param match[in] 2085 * The match flags of filter. 2086 * @param spec[in] 2087 * Specification to be supplemented. 2088 * @param filter[in] 2089 * SFC filter with list of supported filters. 2090 */ 2091 static boolean_t 2092 sfc_flow_check_ifrm_unknown_dst_flags(efx_filter_match_flags_t match, 2093 efx_filter_spec_t *spec, 2094 struct sfc_filter *filter) 2095 { 2096 unsigned int i; 2097 efx_tunnel_protocol_t encap_type = spec->efs_encap_type; 2098 efx_filter_match_flags_t match_mcast_dst; 2099 2100 if (encap_type == EFX_TUNNEL_PROTOCOL_NONE) 2101 return B_FALSE; 2102 2103 match_mcast_dst = 2104 (match & ~EFX_FILTER_MATCH_IFRM_UNKNOWN_UCAST_DST) | 2105 EFX_FILTER_MATCH_IFRM_UNKNOWN_MCAST_DST; 2106 for (i = 0; i < filter->supported_match_num; i++) { 2107 if (match_mcast_dst == filter->supported_match[i]) 2108 return B_TRUE; 2109 } 2110 2111 return B_FALSE; 2112 } 2113 2114 /** 2115 * Check that the list of supported filters has a filter that differs 2116 * from @p match in that it has no flag EFX_FILTER_MATCH_OUTER_VID 2117 * in this case that filter will be used and the flag 2118 * EFX_FILTER_MATCH_OUTER_VID is not needed. 2119 * 2120 * @param match[in] 2121 * The match flags of filter. 2122 * @param spec[in] 2123 * Specification to be supplemented. 2124 * @param filter[in] 2125 * SFC filter with list of supported filters. 2126 */ 2127 static boolean_t 2128 sfc_flow_check_outer_vid_flag(efx_filter_match_flags_t match, 2129 __rte_unused efx_filter_spec_t *spec, 2130 struct sfc_filter *filter) 2131 { 2132 unsigned int i; 2133 efx_filter_match_flags_t match_without_vid = 2134 match & ~EFX_FILTER_MATCH_OUTER_VID; 2135 2136 for (i = 0; i < filter->supported_match_num; i++) { 2137 if (match_without_vid == filter->supported_match[i]) 2138 return B_FALSE; 2139 } 2140 2141 return B_TRUE; 2142 } 2143 2144 /* 2145 * Match flags that can be automatically added to filters. 2146 * Selecting the last minimum when searching for the copy flag ensures that the 2147 * EFX_FILTER_MATCH_UNKNOWN_UCAST_DST flag has a higher priority than 2148 * EFX_FILTER_MATCH_ETHER_TYPE. This is because the filter 2149 * EFX_FILTER_MATCH_UNKNOWN_UCAST_DST is at the end of the list of supported 2150 * filters. 2151 */ 2152 static const struct sfc_flow_copy_flag sfc_flow_copy_flags[] = { 2153 { 2154 .flag = EFX_FILTER_MATCH_UNKNOWN_UCAST_DST, 2155 .vals_count = 2, 2156 .set_vals = sfc_flow_set_unknown_dst_flags, 2157 .spec_check = sfc_flow_check_unknown_dst_flags, 2158 }, 2159 { 2160 .flag = EFX_FILTER_MATCH_ETHER_TYPE, 2161 .vals_count = 2, 2162 .set_vals = sfc_flow_set_ethertypes, 2163 .spec_check = NULL, 2164 }, 2165 { 2166 .flag = EFX_FILTER_MATCH_IFRM_UNKNOWN_UCAST_DST, 2167 .vals_count = 2, 2168 .set_vals = sfc_flow_set_ifrm_unknown_dst_flags, 2169 .spec_check = sfc_flow_check_ifrm_unknown_dst_flags, 2170 }, 2171 { 2172 .flag = EFX_FILTER_MATCH_OUTER_VID, 2173 .vals_count = 1, 2174 .set_vals = sfc_flow_set_outer_vid_flag, 2175 .spec_check = sfc_flow_check_outer_vid_flag, 2176 }, 2177 }; 2178 2179 /* Get item from array sfc_flow_copy_flags */ 2180 static const struct sfc_flow_copy_flag * 2181 sfc_flow_get_copy_flag(efx_filter_match_flags_t flag) 2182 { 2183 unsigned int i; 2184 2185 for (i = 0; i < RTE_DIM(sfc_flow_copy_flags); i++) { 2186 if (sfc_flow_copy_flags[i].flag == flag) 2187 return &sfc_flow_copy_flags[i]; 2188 } 2189 2190 return NULL; 2191 } 2192 2193 /** 2194 * Make copies of the specifications, set match flag and values 2195 * of the field that corresponds to it. 2196 * 2197 * @param spec[in, out] 2198 * SFC flow specification to update. 2199 * @param flag[in] 2200 * The match flag to add. 2201 * @param error[out] 2202 * Perform verbose error reporting if not NULL. 2203 */ 2204 static int 2205 sfc_flow_spec_add_match_flag(struct sfc_flow_spec *spec, 2206 efx_filter_match_flags_t flag, 2207 struct rte_flow_error *error) 2208 { 2209 unsigned int i; 2210 unsigned int new_filters_count; 2211 unsigned int filters_count_for_one_val; 2212 const struct sfc_flow_copy_flag *copy_flag; 2213 struct sfc_flow_spec_filter *spec_filter = &spec->filter; 2214 int rc; 2215 2216 copy_flag = sfc_flow_get_copy_flag(flag); 2217 if (copy_flag == NULL) { 2218 rte_flow_error_set(error, ENOTSUP, 2219 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 2220 "Unsupported spec field for copying"); 2221 return -rte_errno; 2222 } 2223 2224 new_filters_count = spec_filter->count * copy_flag->vals_count; 2225 if (new_filters_count > SF_FLOW_SPEC_NB_FILTERS_MAX) { 2226 rte_flow_error_set(error, EINVAL, 2227 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 2228 "Too much EFX specifications in the flow rule"); 2229 return -rte_errno; 2230 } 2231 2232 /* Copy filters specifications */ 2233 for (i = spec_filter->count; i < new_filters_count; i++) { 2234 spec_filter->filters[i] = 2235 spec_filter->filters[i - spec_filter->count]; 2236 } 2237 2238 filters_count_for_one_val = spec_filter->count; 2239 spec_filter->count = new_filters_count; 2240 2241 rc = copy_flag->set_vals(spec, filters_count_for_one_val, error); 2242 if (rc != 0) 2243 return rc; 2244 2245 return 0; 2246 } 2247 2248 /** 2249 * Check that the given set of match flags missing in the original filter spec 2250 * could be covered by adding spec copies which specify the corresponding 2251 * flags and packet field values to match. 2252 * 2253 * @param miss_flags[in] 2254 * Flags that are missing until the supported filter. 2255 * @param spec[in] 2256 * Specification to be supplemented. 2257 * @param filter[in] 2258 * SFC filter. 2259 * 2260 * @return 2261 * Number of specifications after copy or 0, if the flags can not be added. 2262 */ 2263 static unsigned int 2264 sfc_flow_check_missing_flags(efx_filter_match_flags_t miss_flags, 2265 efx_filter_spec_t *spec, 2266 struct sfc_filter *filter) 2267 { 2268 unsigned int i; 2269 efx_filter_match_flags_t copy_flags = 0; 2270 efx_filter_match_flags_t flag; 2271 efx_filter_match_flags_t match = spec->efs_match_flags | miss_flags; 2272 sfc_flow_spec_check *check; 2273 unsigned int multiplier = 1; 2274 2275 for (i = 0; i < RTE_DIM(sfc_flow_copy_flags); i++) { 2276 flag = sfc_flow_copy_flags[i].flag; 2277 check = sfc_flow_copy_flags[i].spec_check; 2278 if ((flag & miss_flags) == flag) { 2279 if (check != NULL && (!check(match, spec, filter))) 2280 continue; 2281 2282 copy_flags |= flag; 2283 multiplier *= sfc_flow_copy_flags[i].vals_count; 2284 } 2285 } 2286 2287 if (copy_flags == miss_flags) 2288 return multiplier; 2289 2290 return 0; 2291 } 2292 2293 /** 2294 * Attempt to supplement the specification template to the minimally 2295 * supported set of match flags. To do this, it is necessary to copy 2296 * the specifications, filling them with the values of fields that 2297 * correspond to the missing flags. 2298 * The necessary and sufficient filter is built from the fewest number 2299 * of copies which could be made to cover the minimally required set 2300 * of flags. 2301 * 2302 * @param sa[in] 2303 * SFC adapter. 2304 * @param spec[in, out] 2305 * SFC flow specification to update. 2306 * @param error[out] 2307 * Perform verbose error reporting if not NULL. 2308 */ 2309 static int 2310 sfc_flow_spec_filters_complete(struct sfc_adapter *sa, 2311 struct sfc_flow_spec *spec, 2312 struct rte_flow_error *error) 2313 { 2314 struct sfc_flow_spec_filter *spec_filter = &spec->filter; 2315 struct sfc_filter *filter = &sa->filter; 2316 efx_filter_match_flags_t miss_flags; 2317 efx_filter_match_flags_t min_miss_flags = 0; 2318 efx_filter_match_flags_t match; 2319 unsigned int min_multiplier = UINT_MAX; 2320 unsigned int multiplier; 2321 unsigned int i; 2322 int rc; 2323 2324 match = spec_filter->template.efs_match_flags; 2325 for (i = 0; i < filter->supported_match_num; i++) { 2326 if ((match & filter->supported_match[i]) == match) { 2327 miss_flags = filter->supported_match[i] & (~match); 2328 multiplier = sfc_flow_check_missing_flags(miss_flags, 2329 &spec_filter->template, filter); 2330 if (multiplier > 0) { 2331 if (multiplier <= min_multiplier) { 2332 min_multiplier = multiplier; 2333 min_miss_flags = miss_flags; 2334 } 2335 } 2336 } 2337 } 2338 2339 if (min_multiplier == UINT_MAX) { 2340 rte_flow_error_set(error, ENOTSUP, 2341 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 2342 "The flow rule pattern is unsupported"); 2343 return -rte_errno; 2344 } 2345 2346 for (i = 0; i < RTE_DIM(sfc_flow_copy_flags); i++) { 2347 efx_filter_match_flags_t flag = sfc_flow_copy_flags[i].flag; 2348 2349 if ((flag & min_miss_flags) == flag) { 2350 rc = sfc_flow_spec_add_match_flag(spec, flag, error); 2351 if (rc != 0) 2352 return rc; 2353 } 2354 } 2355 2356 return 0; 2357 } 2358 2359 /** 2360 * Check that set of match flags is referred to by a filter. Filter is 2361 * described by match flags with the ability to add OUTER_VID and INNER_VID 2362 * flags. 2363 * 2364 * @param match_flags[in] 2365 * Set of match flags. 2366 * @param flags_pattern[in] 2367 * Pattern of filter match flags. 2368 */ 2369 static boolean_t 2370 sfc_flow_is_match_with_vids(efx_filter_match_flags_t match_flags, 2371 efx_filter_match_flags_t flags_pattern) 2372 { 2373 if ((match_flags & flags_pattern) != flags_pattern) 2374 return B_FALSE; 2375 2376 switch (match_flags & ~flags_pattern) { 2377 case 0: 2378 case EFX_FILTER_MATCH_OUTER_VID: 2379 case EFX_FILTER_MATCH_OUTER_VID | EFX_FILTER_MATCH_INNER_VID: 2380 return B_TRUE; 2381 default: 2382 return B_FALSE; 2383 } 2384 } 2385 2386 /** 2387 * Check whether the spec maps to a hardware filter which is known to be 2388 * ineffective despite being valid. 2389 * 2390 * @param filter[in] 2391 * SFC filter with list of supported filters. 2392 * @param spec[in] 2393 * SFC flow specification. 2394 */ 2395 static boolean_t 2396 sfc_flow_is_match_flags_exception(struct sfc_filter *filter, 2397 struct sfc_flow_spec *spec) 2398 { 2399 unsigned int i; 2400 uint16_t ether_type; 2401 uint8_t ip_proto; 2402 efx_filter_match_flags_t match_flags; 2403 struct sfc_flow_spec_filter *spec_filter = &spec->filter; 2404 2405 for (i = 0; i < spec_filter->count; i++) { 2406 match_flags = spec_filter->filters[i].efs_match_flags; 2407 2408 if (sfc_flow_is_match_with_vids(match_flags, 2409 EFX_FILTER_MATCH_ETHER_TYPE) || 2410 sfc_flow_is_match_with_vids(match_flags, 2411 EFX_FILTER_MATCH_ETHER_TYPE | 2412 EFX_FILTER_MATCH_LOC_MAC)) { 2413 ether_type = spec_filter->filters[i].efs_ether_type; 2414 if (filter->supports_ip_proto_or_addr_filter && 2415 (ether_type == EFX_ETHER_TYPE_IPV4 || 2416 ether_type == EFX_ETHER_TYPE_IPV6)) 2417 return B_TRUE; 2418 } else if (sfc_flow_is_match_with_vids(match_flags, 2419 EFX_FILTER_MATCH_ETHER_TYPE | 2420 EFX_FILTER_MATCH_IP_PROTO) || 2421 sfc_flow_is_match_with_vids(match_flags, 2422 EFX_FILTER_MATCH_ETHER_TYPE | 2423 EFX_FILTER_MATCH_IP_PROTO | 2424 EFX_FILTER_MATCH_LOC_MAC)) { 2425 ip_proto = spec_filter->filters[i].efs_ip_proto; 2426 if (filter->supports_rem_or_local_port_filter && 2427 (ip_proto == EFX_IPPROTO_TCP || 2428 ip_proto == EFX_IPPROTO_UDP)) 2429 return B_TRUE; 2430 } 2431 } 2432 2433 return B_FALSE; 2434 } 2435 2436 static int 2437 sfc_flow_validate_match_flags(struct sfc_adapter *sa, 2438 struct rte_flow *flow, 2439 struct rte_flow_error *error) 2440 { 2441 struct sfc_flow_spec *spec = &flow->spec; 2442 struct sfc_flow_spec_filter *spec_filter = &spec->filter; 2443 efx_filter_spec_t *spec_tmpl = &spec_filter->template; 2444 efx_filter_match_flags_t match_flags = spec_tmpl->efs_match_flags; 2445 int rc; 2446 2447 /* Initialize the first filter spec with template */ 2448 spec_filter->filters[0] = *spec_tmpl; 2449 spec_filter->count = 1; 2450 2451 if (!sfc_filter_is_match_supported(sa, match_flags)) { 2452 rc = sfc_flow_spec_filters_complete(sa, &flow->spec, error); 2453 if (rc != 0) 2454 return rc; 2455 } 2456 2457 if (sfc_flow_is_match_flags_exception(&sa->filter, &flow->spec)) { 2458 rte_flow_error_set(error, ENOTSUP, 2459 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 2460 "The flow rule pattern is unsupported"); 2461 return -rte_errno; 2462 } 2463 2464 return 0; 2465 } 2466 2467 static int 2468 sfc_flow_parse_rte_to_filter(struct rte_eth_dev *dev, 2469 const struct rte_flow_item pattern[], 2470 const struct rte_flow_action actions[], 2471 struct rte_flow *flow, 2472 struct rte_flow_error *error) 2473 { 2474 struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev); 2475 struct sfc_flow_spec *spec = &flow->spec; 2476 struct sfc_flow_spec_filter *spec_filter = &spec->filter; 2477 struct sfc_flow_parse_ctx ctx; 2478 int rc; 2479 2480 ctx.type = SFC_FLOW_PARSE_CTX_FILTER; 2481 ctx.filter = &spec_filter->template; 2482 2483 rc = sfc_flow_parse_pattern(sfc_flow_items, RTE_DIM(sfc_flow_items), 2484 pattern, &ctx, error); 2485 if (rc != 0) 2486 goto fail_bad_value; 2487 2488 rc = sfc_flow_parse_actions(sa, actions, flow, error); 2489 if (rc != 0) 2490 goto fail_bad_value; 2491 2492 rc = sfc_flow_validate_match_flags(sa, flow, error); 2493 if (rc != 0) 2494 goto fail_bad_value; 2495 2496 return 0; 2497 2498 fail_bad_value: 2499 return rc; 2500 } 2501 2502 static int 2503 sfc_flow_parse_rte_to_mae(struct rte_eth_dev *dev, 2504 const struct rte_flow_item pattern[], 2505 const struct rte_flow_action actions[], 2506 struct rte_flow *flow, 2507 struct rte_flow_error *error) 2508 { 2509 struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev); 2510 struct sfc_flow_spec *spec = &flow->spec; 2511 struct sfc_flow_spec_mae *spec_mae = &spec->mae; 2512 int rc; 2513 2514 rc = sfc_mae_rule_parse_pattern(sa, pattern, spec_mae, error); 2515 if (rc != 0) 2516 return rc; 2517 2518 rc = sfc_mae_rule_parse_actions(sa, actions, spec_mae, error); 2519 if (rc != 0) 2520 return rc; 2521 2522 return 0; 2523 } 2524 2525 static int 2526 sfc_flow_parse(struct rte_eth_dev *dev, 2527 const struct rte_flow_attr *attr, 2528 const struct rte_flow_item pattern[], 2529 const struct rte_flow_action actions[], 2530 struct rte_flow *flow, 2531 struct rte_flow_error *error) 2532 { 2533 struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev); 2534 const struct sfc_flow_ops_by_spec *ops; 2535 int rc; 2536 2537 rc = sfc_flow_parse_attr(sa, attr, flow, error); 2538 if (rc != 0) 2539 return rc; 2540 2541 ops = sfc_flow_get_ops_by_spec(flow); 2542 if (ops == NULL || ops->parse == NULL) { 2543 rte_flow_error_set(error, ENOTSUP, 2544 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 2545 "No backend to handle this flow"); 2546 return -rte_errno; 2547 } 2548 2549 return ops->parse(dev, pattern, actions, flow, error); 2550 } 2551 2552 static struct rte_flow * 2553 sfc_flow_zmalloc(struct rte_flow_error *error) 2554 { 2555 struct rte_flow *flow; 2556 2557 flow = rte_zmalloc("sfc_rte_flow", sizeof(*flow), 0); 2558 if (flow == NULL) { 2559 rte_flow_error_set(error, ENOMEM, 2560 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 2561 "Failed to allocate memory"); 2562 } 2563 2564 return flow; 2565 } 2566 2567 static void 2568 sfc_flow_free(struct sfc_adapter *sa, struct rte_flow *flow) 2569 { 2570 const struct sfc_flow_ops_by_spec *ops; 2571 2572 ops = sfc_flow_get_ops_by_spec(flow); 2573 if (ops != NULL && ops->cleanup != NULL) 2574 ops->cleanup(sa, flow); 2575 2576 rte_free(flow); 2577 } 2578 2579 static int 2580 sfc_flow_insert(struct sfc_adapter *sa, struct rte_flow *flow, 2581 struct rte_flow_error *error) 2582 { 2583 const struct sfc_flow_ops_by_spec *ops; 2584 int rc; 2585 2586 ops = sfc_flow_get_ops_by_spec(flow); 2587 if (ops == NULL || ops->insert == NULL) { 2588 rte_flow_error_set(error, ENOTSUP, 2589 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 2590 "No backend to handle this flow"); 2591 return rte_errno; 2592 } 2593 2594 rc = ops->insert(sa, flow); 2595 if (rc != 0) { 2596 rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, 2597 NULL, "Failed to insert the flow rule"); 2598 } 2599 2600 return rc; 2601 } 2602 2603 static int 2604 sfc_flow_remove(struct sfc_adapter *sa, struct rte_flow *flow, 2605 struct rte_flow_error *error) 2606 { 2607 const struct sfc_flow_ops_by_spec *ops; 2608 int rc; 2609 2610 ops = sfc_flow_get_ops_by_spec(flow); 2611 if (ops == NULL || ops->remove == NULL) { 2612 rte_flow_error_set(error, ENOTSUP, 2613 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 2614 "No backend to handle this flow"); 2615 return rte_errno; 2616 } 2617 2618 rc = ops->remove(sa, flow); 2619 if (rc != 0) { 2620 rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, 2621 NULL, "Failed to remove the flow rule"); 2622 } 2623 2624 return rc; 2625 } 2626 2627 static int 2628 sfc_flow_verify(struct sfc_adapter *sa, struct rte_flow *flow, 2629 struct rte_flow_error *error) 2630 { 2631 const struct sfc_flow_ops_by_spec *ops; 2632 int rc = 0; 2633 2634 ops = sfc_flow_get_ops_by_spec(flow); 2635 if (ops == NULL) { 2636 rte_flow_error_set(error, ENOTSUP, 2637 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 2638 "No backend to handle this flow"); 2639 return -rte_errno; 2640 } 2641 2642 if (ops->verify != NULL) { 2643 SFC_ASSERT(sfc_adapter_is_locked(sa)); 2644 rc = ops->verify(sa, flow); 2645 } 2646 2647 if (rc != 0) { 2648 rte_flow_error_set(error, rc, 2649 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 2650 "Failed to verify flow validity with FW"); 2651 return -rte_errno; 2652 } 2653 2654 return 0; 2655 } 2656 2657 static int 2658 sfc_flow_validate(struct rte_eth_dev *dev, 2659 const struct rte_flow_attr *attr, 2660 const struct rte_flow_item pattern[], 2661 const struct rte_flow_action actions[], 2662 struct rte_flow_error *error) 2663 { 2664 struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev); 2665 struct rte_flow *flow; 2666 int rc; 2667 2668 flow = sfc_flow_zmalloc(error); 2669 if (flow == NULL) 2670 return -rte_errno; 2671 2672 sfc_adapter_lock(sa); 2673 2674 rc = sfc_flow_parse(dev, attr, pattern, actions, flow, error); 2675 if (rc == 0) 2676 rc = sfc_flow_verify(sa, flow, error); 2677 2678 sfc_flow_free(sa, flow); 2679 2680 sfc_adapter_unlock(sa); 2681 2682 return rc; 2683 } 2684 2685 static struct rte_flow * 2686 sfc_flow_create(struct rte_eth_dev *dev, 2687 const struct rte_flow_attr *attr, 2688 const struct rte_flow_item pattern[], 2689 const struct rte_flow_action actions[], 2690 struct rte_flow_error *error) 2691 { 2692 struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev); 2693 struct rte_flow *flow = NULL; 2694 int rc; 2695 2696 flow = sfc_flow_zmalloc(error); 2697 if (flow == NULL) 2698 goto fail_no_mem; 2699 2700 sfc_adapter_lock(sa); 2701 2702 rc = sfc_flow_parse(dev, attr, pattern, actions, flow, error); 2703 if (rc != 0) 2704 goto fail_bad_value; 2705 2706 TAILQ_INSERT_TAIL(&sa->flow_list, flow, entries); 2707 2708 if (sa->state == SFC_ADAPTER_STARTED) { 2709 rc = sfc_flow_insert(sa, flow, error); 2710 if (rc != 0) 2711 goto fail_flow_insert; 2712 } 2713 2714 sfc_adapter_unlock(sa); 2715 2716 return flow; 2717 2718 fail_flow_insert: 2719 TAILQ_REMOVE(&sa->flow_list, flow, entries); 2720 2721 fail_bad_value: 2722 sfc_flow_free(sa, flow); 2723 sfc_adapter_unlock(sa); 2724 2725 fail_no_mem: 2726 return NULL; 2727 } 2728 2729 static int 2730 sfc_flow_destroy(struct rte_eth_dev *dev, 2731 struct rte_flow *flow, 2732 struct rte_flow_error *error) 2733 { 2734 struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev); 2735 struct rte_flow *flow_ptr; 2736 int rc = EINVAL; 2737 2738 sfc_adapter_lock(sa); 2739 2740 TAILQ_FOREACH(flow_ptr, &sa->flow_list, entries) { 2741 if (flow_ptr == flow) 2742 rc = 0; 2743 } 2744 if (rc != 0) { 2745 rte_flow_error_set(error, rc, 2746 RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 2747 "Failed to find flow rule to destroy"); 2748 goto fail_bad_value; 2749 } 2750 2751 if (sa->state == SFC_ADAPTER_STARTED) 2752 rc = sfc_flow_remove(sa, flow, error); 2753 2754 TAILQ_REMOVE(&sa->flow_list, flow, entries); 2755 sfc_flow_free(sa, flow); 2756 2757 fail_bad_value: 2758 sfc_adapter_unlock(sa); 2759 2760 return -rc; 2761 } 2762 2763 static int 2764 sfc_flow_flush(struct rte_eth_dev *dev, 2765 struct rte_flow_error *error) 2766 { 2767 struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev); 2768 struct rte_flow *flow; 2769 int ret = 0; 2770 2771 sfc_adapter_lock(sa); 2772 2773 while ((flow = TAILQ_FIRST(&sa->flow_list)) != NULL) { 2774 if (sa->state == SFC_ADAPTER_STARTED) { 2775 int rc; 2776 2777 rc = sfc_flow_remove(sa, flow, error); 2778 if (rc != 0) 2779 ret = rc; 2780 } 2781 2782 TAILQ_REMOVE(&sa->flow_list, flow, entries); 2783 sfc_flow_free(sa, flow); 2784 } 2785 2786 sfc_adapter_unlock(sa); 2787 2788 return -ret; 2789 } 2790 2791 static int 2792 sfc_flow_isolate(struct rte_eth_dev *dev, int enable, 2793 struct rte_flow_error *error) 2794 { 2795 struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev); 2796 int ret = 0; 2797 2798 sfc_adapter_lock(sa); 2799 if (sa->state != SFC_ADAPTER_INITIALIZED) { 2800 rte_flow_error_set(error, EBUSY, 2801 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, 2802 NULL, "please close the port first"); 2803 ret = -rte_errno; 2804 } else { 2805 sfc_sa2shared(sa)->isolated = (enable) ? B_TRUE : B_FALSE; 2806 } 2807 sfc_adapter_unlock(sa); 2808 2809 return ret; 2810 } 2811 2812 const struct rte_flow_ops sfc_flow_ops = { 2813 .validate = sfc_flow_validate, 2814 .create = sfc_flow_create, 2815 .destroy = sfc_flow_destroy, 2816 .flush = sfc_flow_flush, 2817 .query = NULL, 2818 .isolate = sfc_flow_isolate, 2819 }; 2820 2821 void 2822 sfc_flow_init(struct sfc_adapter *sa) 2823 { 2824 SFC_ASSERT(sfc_adapter_is_locked(sa)); 2825 2826 TAILQ_INIT(&sa->flow_list); 2827 } 2828 2829 void 2830 sfc_flow_fini(struct sfc_adapter *sa) 2831 { 2832 struct rte_flow *flow; 2833 2834 SFC_ASSERT(sfc_adapter_is_locked(sa)); 2835 2836 while ((flow = TAILQ_FIRST(&sa->flow_list)) != NULL) { 2837 TAILQ_REMOVE(&sa->flow_list, flow, entries); 2838 sfc_flow_free(sa, flow); 2839 } 2840 } 2841 2842 void 2843 sfc_flow_stop(struct sfc_adapter *sa) 2844 { 2845 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); 2846 struct sfc_rss *rss = &sas->rss; 2847 struct rte_flow *flow; 2848 2849 SFC_ASSERT(sfc_adapter_is_locked(sa)); 2850 2851 TAILQ_FOREACH(flow, &sa->flow_list, entries) 2852 sfc_flow_remove(sa, flow, NULL); 2853 2854 if (rss->dummy_rss_context != EFX_RSS_CONTEXT_DEFAULT) { 2855 efx_rx_scale_context_free(sa->nic, rss->dummy_rss_context); 2856 rss->dummy_rss_context = EFX_RSS_CONTEXT_DEFAULT; 2857 } 2858 2859 /* 2860 * MAE counter service is not stopped on flow rule remove to avoid 2861 * extra work. Make sure that it is stopped here. 2862 */ 2863 sfc_mae_counter_stop(sa); 2864 } 2865 2866 int 2867 sfc_flow_start(struct sfc_adapter *sa) 2868 { 2869 struct rte_flow *flow; 2870 int rc = 0; 2871 2872 sfc_log_init(sa, "entry"); 2873 2874 SFC_ASSERT(sfc_adapter_is_locked(sa)); 2875 2876 TAILQ_FOREACH(flow, &sa->flow_list, entries) { 2877 rc = sfc_flow_insert(sa, flow, NULL); 2878 if (rc != 0) 2879 goto fail_bad_flow; 2880 } 2881 2882 sfc_log_init(sa, "done"); 2883 2884 fail_bad_flow: 2885 return rc; 2886 } 2887