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