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