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