1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright 2016 6WIND S.A. 3 * Copyright 2016 Mellanox Technologies, Ltd 4 */ 5 6 #include <netinet/in.h> 7 #include <sys/queue.h> 8 #include <stdalign.h> 9 #include <stdint.h> 10 #include <string.h> 11 12 /* Verbs header. */ 13 /* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */ 14 #ifdef PEDANTIC 15 #pragma GCC diagnostic ignored "-Wpedantic" 16 #endif 17 #include <infiniband/verbs.h> 18 #ifdef PEDANTIC 19 #pragma GCC diagnostic error "-Wpedantic" 20 #endif 21 22 #include <rte_common.h> 23 #include <rte_ether.h> 24 #include <rte_ethdev_driver.h> 25 #include <rte_flow.h> 26 #include <rte_flow_driver.h> 27 #include <rte_malloc.h> 28 #include <rte_ip.h> 29 30 #include "mlx5.h" 31 #include "mlx5_defs.h" 32 #include "mlx5_flow.h" 33 #include "mlx5_glue.h" 34 #include "mlx5_prm.h" 35 #include "mlx5_rxtx.h" 36 37 /* Dev ops structure defined in mlx5.c */ 38 extern const struct eth_dev_ops mlx5_dev_ops; 39 extern const struct eth_dev_ops mlx5_dev_ops_isolate; 40 41 /** Device flow drivers. */ 42 #ifdef HAVE_IBV_FLOW_DV_SUPPORT 43 extern const struct mlx5_flow_driver_ops mlx5_flow_dv_drv_ops; 44 #endif 45 extern const struct mlx5_flow_driver_ops mlx5_flow_verbs_drv_ops; 46 47 const struct mlx5_flow_driver_ops mlx5_flow_null_drv_ops; 48 49 const struct mlx5_flow_driver_ops *flow_drv_ops[] = { 50 [MLX5_FLOW_TYPE_MIN] = &mlx5_flow_null_drv_ops, 51 #ifdef HAVE_IBV_FLOW_DV_SUPPORT 52 [MLX5_FLOW_TYPE_DV] = &mlx5_flow_dv_drv_ops, 53 #endif 54 [MLX5_FLOW_TYPE_VERBS] = &mlx5_flow_verbs_drv_ops, 55 [MLX5_FLOW_TYPE_MAX] = &mlx5_flow_null_drv_ops 56 }; 57 58 enum mlx5_expansion { 59 MLX5_EXPANSION_ROOT, 60 MLX5_EXPANSION_ROOT_OUTER, 61 MLX5_EXPANSION_ROOT_ETH_VLAN, 62 MLX5_EXPANSION_ROOT_OUTER_ETH_VLAN, 63 MLX5_EXPANSION_OUTER_ETH, 64 MLX5_EXPANSION_OUTER_ETH_VLAN, 65 MLX5_EXPANSION_OUTER_VLAN, 66 MLX5_EXPANSION_OUTER_IPV4, 67 MLX5_EXPANSION_OUTER_IPV4_UDP, 68 MLX5_EXPANSION_OUTER_IPV4_TCP, 69 MLX5_EXPANSION_OUTER_IPV6, 70 MLX5_EXPANSION_OUTER_IPV6_UDP, 71 MLX5_EXPANSION_OUTER_IPV6_TCP, 72 MLX5_EXPANSION_VXLAN, 73 MLX5_EXPANSION_VXLAN_GPE, 74 MLX5_EXPANSION_GRE, 75 MLX5_EXPANSION_MPLS, 76 MLX5_EXPANSION_ETH, 77 MLX5_EXPANSION_ETH_VLAN, 78 MLX5_EXPANSION_VLAN, 79 MLX5_EXPANSION_IPV4, 80 MLX5_EXPANSION_IPV4_UDP, 81 MLX5_EXPANSION_IPV4_TCP, 82 MLX5_EXPANSION_IPV6, 83 MLX5_EXPANSION_IPV6_UDP, 84 MLX5_EXPANSION_IPV6_TCP, 85 }; 86 87 /** Supported expansion of items. */ 88 static const struct rte_flow_expand_node mlx5_support_expansion[] = { 89 [MLX5_EXPANSION_ROOT] = { 90 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_ETH, 91 MLX5_EXPANSION_IPV4, 92 MLX5_EXPANSION_IPV6), 93 .type = RTE_FLOW_ITEM_TYPE_END, 94 }, 95 [MLX5_EXPANSION_ROOT_OUTER] = { 96 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_OUTER_ETH, 97 MLX5_EXPANSION_OUTER_IPV4, 98 MLX5_EXPANSION_OUTER_IPV6), 99 .type = RTE_FLOW_ITEM_TYPE_END, 100 }, 101 [MLX5_EXPANSION_ROOT_ETH_VLAN] = { 102 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_ETH_VLAN), 103 .type = RTE_FLOW_ITEM_TYPE_END, 104 }, 105 [MLX5_EXPANSION_ROOT_OUTER_ETH_VLAN] = { 106 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_OUTER_ETH_VLAN), 107 .type = RTE_FLOW_ITEM_TYPE_END, 108 }, 109 [MLX5_EXPANSION_OUTER_ETH] = { 110 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_OUTER_IPV4, 111 MLX5_EXPANSION_OUTER_IPV6, 112 MLX5_EXPANSION_MPLS), 113 .type = RTE_FLOW_ITEM_TYPE_ETH, 114 .rss_types = 0, 115 }, 116 [MLX5_EXPANSION_OUTER_ETH_VLAN] = { 117 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_OUTER_VLAN), 118 .type = RTE_FLOW_ITEM_TYPE_ETH, 119 .rss_types = 0, 120 }, 121 [MLX5_EXPANSION_OUTER_VLAN] = { 122 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_OUTER_IPV4, 123 MLX5_EXPANSION_OUTER_IPV6), 124 .type = RTE_FLOW_ITEM_TYPE_VLAN, 125 }, 126 [MLX5_EXPANSION_OUTER_IPV4] = { 127 .next = RTE_FLOW_EXPAND_RSS_NEXT 128 (MLX5_EXPANSION_OUTER_IPV4_UDP, 129 MLX5_EXPANSION_OUTER_IPV4_TCP, 130 MLX5_EXPANSION_GRE), 131 .type = RTE_FLOW_ITEM_TYPE_IPV4, 132 .rss_types = ETH_RSS_IPV4 | ETH_RSS_FRAG_IPV4 | 133 ETH_RSS_NONFRAG_IPV4_OTHER, 134 }, 135 [MLX5_EXPANSION_OUTER_IPV4_UDP] = { 136 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_VXLAN, 137 MLX5_EXPANSION_VXLAN_GPE), 138 .type = RTE_FLOW_ITEM_TYPE_UDP, 139 .rss_types = ETH_RSS_NONFRAG_IPV4_UDP, 140 }, 141 [MLX5_EXPANSION_OUTER_IPV4_TCP] = { 142 .type = RTE_FLOW_ITEM_TYPE_TCP, 143 .rss_types = ETH_RSS_NONFRAG_IPV4_TCP, 144 }, 145 [MLX5_EXPANSION_OUTER_IPV6] = { 146 .next = RTE_FLOW_EXPAND_RSS_NEXT 147 (MLX5_EXPANSION_OUTER_IPV6_UDP, 148 MLX5_EXPANSION_OUTER_IPV6_TCP), 149 .type = RTE_FLOW_ITEM_TYPE_IPV6, 150 .rss_types = ETH_RSS_IPV6 | ETH_RSS_FRAG_IPV6 | 151 ETH_RSS_NONFRAG_IPV6_OTHER, 152 }, 153 [MLX5_EXPANSION_OUTER_IPV6_UDP] = { 154 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_VXLAN, 155 MLX5_EXPANSION_VXLAN_GPE), 156 .type = RTE_FLOW_ITEM_TYPE_UDP, 157 .rss_types = ETH_RSS_NONFRAG_IPV6_UDP, 158 }, 159 [MLX5_EXPANSION_OUTER_IPV6_TCP] = { 160 .type = RTE_FLOW_ITEM_TYPE_TCP, 161 .rss_types = ETH_RSS_NONFRAG_IPV6_TCP, 162 }, 163 [MLX5_EXPANSION_VXLAN] = { 164 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_ETH), 165 .type = RTE_FLOW_ITEM_TYPE_VXLAN, 166 }, 167 [MLX5_EXPANSION_VXLAN_GPE] = { 168 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_ETH, 169 MLX5_EXPANSION_IPV4, 170 MLX5_EXPANSION_IPV6), 171 .type = RTE_FLOW_ITEM_TYPE_VXLAN_GPE, 172 }, 173 [MLX5_EXPANSION_GRE] = { 174 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_IPV4), 175 .type = RTE_FLOW_ITEM_TYPE_GRE, 176 }, 177 [MLX5_EXPANSION_MPLS] = { 178 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_IPV4, 179 MLX5_EXPANSION_IPV6), 180 .type = RTE_FLOW_ITEM_TYPE_MPLS, 181 }, 182 [MLX5_EXPANSION_ETH] = { 183 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_IPV4, 184 MLX5_EXPANSION_IPV6), 185 .type = RTE_FLOW_ITEM_TYPE_ETH, 186 }, 187 [MLX5_EXPANSION_ETH_VLAN] = { 188 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_VLAN), 189 .type = RTE_FLOW_ITEM_TYPE_ETH, 190 }, 191 [MLX5_EXPANSION_VLAN] = { 192 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_IPV4, 193 MLX5_EXPANSION_IPV6), 194 .type = RTE_FLOW_ITEM_TYPE_VLAN, 195 }, 196 [MLX5_EXPANSION_IPV4] = { 197 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_IPV4_UDP, 198 MLX5_EXPANSION_IPV4_TCP), 199 .type = RTE_FLOW_ITEM_TYPE_IPV4, 200 .rss_types = ETH_RSS_IPV4 | ETH_RSS_FRAG_IPV4 | 201 ETH_RSS_NONFRAG_IPV4_OTHER, 202 }, 203 [MLX5_EXPANSION_IPV4_UDP] = { 204 .type = RTE_FLOW_ITEM_TYPE_UDP, 205 .rss_types = ETH_RSS_NONFRAG_IPV4_UDP, 206 }, 207 [MLX5_EXPANSION_IPV4_TCP] = { 208 .type = RTE_FLOW_ITEM_TYPE_TCP, 209 .rss_types = ETH_RSS_NONFRAG_IPV4_TCP, 210 }, 211 [MLX5_EXPANSION_IPV6] = { 212 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_IPV6_UDP, 213 MLX5_EXPANSION_IPV6_TCP), 214 .type = RTE_FLOW_ITEM_TYPE_IPV6, 215 .rss_types = ETH_RSS_IPV6 | ETH_RSS_FRAG_IPV6 | 216 ETH_RSS_NONFRAG_IPV6_OTHER, 217 }, 218 [MLX5_EXPANSION_IPV6_UDP] = { 219 .type = RTE_FLOW_ITEM_TYPE_UDP, 220 .rss_types = ETH_RSS_NONFRAG_IPV6_UDP, 221 }, 222 [MLX5_EXPANSION_IPV6_TCP] = { 223 .type = RTE_FLOW_ITEM_TYPE_TCP, 224 .rss_types = ETH_RSS_NONFRAG_IPV6_TCP, 225 }, 226 }; 227 228 static const struct rte_flow_ops mlx5_flow_ops = { 229 .validate = mlx5_flow_validate, 230 .create = mlx5_flow_create, 231 .destroy = mlx5_flow_destroy, 232 .flush = mlx5_flow_flush, 233 .isolate = mlx5_flow_isolate, 234 .query = mlx5_flow_query, 235 }; 236 237 /* Convert FDIR request to Generic flow. */ 238 struct mlx5_fdir { 239 struct rte_flow_attr attr; 240 struct rte_flow_item items[4]; 241 struct rte_flow_item_eth l2; 242 struct rte_flow_item_eth l2_mask; 243 union { 244 struct rte_flow_item_ipv4 ipv4; 245 struct rte_flow_item_ipv6 ipv6; 246 } l3; 247 union { 248 struct rte_flow_item_ipv4 ipv4; 249 struct rte_flow_item_ipv6 ipv6; 250 } l3_mask; 251 union { 252 struct rte_flow_item_udp udp; 253 struct rte_flow_item_tcp tcp; 254 } l4; 255 union { 256 struct rte_flow_item_udp udp; 257 struct rte_flow_item_tcp tcp; 258 } l4_mask; 259 struct rte_flow_action actions[2]; 260 struct rte_flow_action_queue queue; 261 }; 262 263 /* Map of Verbs to Flow priority with 8 Verbs priorities. */ 264 static const uint32_t priority_map_3[][MLX5_PRIORITY_MAP_MAX] = { 265 { 0, 1, 2 }, { 2, 3, 4 }, { 5, 6, 7 }, 266 }; 267 268 /* Map of Verbs to Flow priority with 16 Verbs priorities. */ 269 static const uint32_t priority_map_5[][MLX5_PRIORITY_MAP_MAX] = { 270 { 0, 1, 2 }, { 3, 4, 5 }, { 6, 7, 8 }, 271 { 9, 10, 11 }, { 12, 13, 14 }, 272 }; 273 274 /* Tunnel information. */ 275 struct mlx5_flow_tunnel_info { 276 uint64_t tunnel; /**< Tunnel bit (see MLX5_FLOW_*). */ 277 uint32_t ptype; /**< Tunnel Ptype (see RTE_PTYPE_*). */ 278 }; 279 280 static struct mlx5_flow_tunnel_info tunnels_info[] = { 281 { 282 .tunnel = MLX5_FLOW_LAYER_VXLAN, 283 .ptype = RTE_PTYPE_TUNNEL_VXLAN | RTE_PTYPE_L4_UDP, 284 }, 285 { 286 .tunnel = MLX5_FLOW_LAYER_VXLAN_GPE, 287 .ptype = RTE_PTYPE_TUNNEL_VXLAN_GPE | RTE_PTYPE_L4_UDP, 288 }, 289 { 290 .tunnel = MLX5_FLOW_LAYER_GRE, 291 .ptype = RTE_PTYPE_TUNNEL_GRE, 292 }, 293 { 294 .tunnel = MLX5_FLOW_LAYER_MPLS | MLX5_FLOW_LAYER_OUTER_L4_UDP, 295 .ptype = RTE_PTYPE_TUNNEL_MPLS_IN_UDP | RTE_PTYPE_L4_UDP, 296 }, 297 { 298 .tunnel = MLX5_FLOW_LAYER_MPLS, 299 .ptype = RTE_PTYPE_TUNNEL_MPLS_IN_GRE, 300 }, 301 }; 302 303 /** 304 * Discover the maximum number of priority available. 305 * 306 * @param[in] dev 307 * Pointer to the Ethernet device structure. 308 * 309 * @return 310 * number of supported flow priority on success, a negative errno 311 * value otherwise and rte_errno is set. 312 */ 313 int 314 mlx5_flow_discover_priorities(struct rte_eth_dev *dev) 315 { 316 struct mlx5_priv *priv = dev->data->dev_private; 317 struct { 318 struct ibv_flow_attr attr; 319 struct ibv_flow_spec_eth eth; 320 struct ibv_flow_spec_action_drop drop; 321 } flow_attr = { 322 .attr = { 323 .num_of_specs = 2, 324 .port = (uint8_t)priv->ibv_port, 325 }, 326 .eth = { 327 .type = IBV_FLOW_SPEC_ETH, 328 .size = sizeof(struct ibv_flow_spec_eth), 329 }, 330 .drop = { 331 .size = sizeof(struct ibv_flow_spec_action_drop), 332 .type = IBV_FLOW_SPEC_ACTION_DROP, 333 }, 334 }; 335 struct ibv_flow *flow; 336 struct mlx5_hrxq *drop = mlx5_hrxq_drop_new(dev); 337 uint16_t vprio[] = { 8, 16 }; 338 int i; 339 int priority = 0; 340 341 if (!drop) { 342 rte_errno = ENOTSUP; 343 return -rte_errno; 344 } 345 for (i = 0; i != RTE_DIM(vprio); i++) { 346 flow_attr.attr.priority = vprio[i] - 1; 347 flow = mlx5_glue->create_flow(drop->qp, &flow_attr.attr); 348 if (!flow) 349 break; 350 claim_zero(mlx5_glue->destroy_flow(flow)); 351 priority = vprio[i]; 352 } 353 mlx5_hrxq_drop_release(dev); 354 switch (priority) { 355 case 8: 356 priority = RTE_DIM(priority_map_3); 357 break; 358 case 16: 359 priority = RTE_DIM(priority_map_5); 360 break; 361 default: 362 rte_errno = ENOTSUP; 363 DRV_LOG(ERR, 364 "port %u verbs maximum priority: %d expected 8/16", 365 dev->data->port_id, priority); 366 return -rte_errno; 367 } 368 DRV_LOG(INFO, "port %u flow maximum priority: %d", 369 dev->data->port_id, priority); 370 return priority; 371 } 372 373 /** 374 * Adjust flow priority based on the highest layer and the request priority. 375 * 376 * @param[in] dev 377 * Pointer to the Ethernet device structure. 378 * @param[in] priority 379 * The rule base priority. 380 * @param[in] subpriority 381 * The priority based on the items. 382 * 383 * @return 384 * The new priority. 385 */ 386 uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority, 387 uint32_t subpriority) 388 { 389 uint32_t res = 0; 390 struct mlx5_priv *priv = dev->data->dev_private; 391 392 switch (priv->config.flow_prio) { 393 case RTE_DIM(priority_map_3): 394 res = priority_map_3[priority][subpriority]; 395 break; 396 case RTE_DIM(priority_map_5): 397 res = priority_map_5[priority][subpriority]; 398 break; 399 } 400 return res; 401 } 402 403 /** 404 * Verify the @p item specifications (spec, last, mask) are compatible with the 405 * NIC capabilities. 406 * 407 * @param[in] item 408 * Item specification. 409 * @param[in] mask 410 * @p item->mask or flow default bit-masks. 411 * @param[in] nic_mask 412 * Bit-masks covering supported fields by the NIC to compare with user mask. 413 * @param[in] size 414 * Bit-masks size in bytes. 415 * @param[out] error 416 * Pointer to error structure. 417 * 418 * @return 419 * 0 on success, a negative errno value otherwise and rte_errno is set. 420 */ 421 int 422 mlx5_flow_item_acceptable(const struct rte_flow_item *item, 423 const uint8_t *mask, 424 const uint8_t *nic_mask, 425 unsigned int size, 426 struct rte_flow_error *error) 427 { 428 unsigned int i; 429 430 assert(nic_mask); 431 for (i = 0; i < size; ++i) 432 if ((nic_mask[i] | mask[i]) != nic_mask[i]) 433 return rte_flow_error_set(error, ENOTSUP, 434 RTE_FLOW_ERROR_TYPE_ITEM, 435 item, 436 "mask enables non supported" 437 " bits"); 438 if (!item->spec && (item->mask || item->last)) 439 return rte_flow_error_set(error, EINVAL, 440 RTE_FLOW_ERROR_TYPE_ITEM, item, 441 "mask/last without a spec is not" 442 " supported"); 443 if (item->spec && item->last) { 444 uint8_t spec[size]; 445 uint8_t last[size]; 446 unsigned int i; 447 int ret; 448 449 for (i = 0; i < size; ++i) { 450 spec[i] = ((const uint8_t *)item->spec)[i] & mask[i]; 451 last[i] = ((const uint8_t *)item->last)[i] & mask[i]; 452 } 453 ret = memcmp(spec, last, size); 454 if (ret != 0) 455 return rte_flow_error_set(error, EINVAL, 456 RTE_FLOW_ERROR_TYPE_ITEM, 457 item, 458 "range is not valid"); 459 } 460 return 0; 461 } 462 463 /** 464 * Adjust the hash fields according to the @p flow information. 465 * 466 * @param[in] dev_flow. 467 * Pointer to the mlx5_flow. 468 * @param[in] tunnel 469 * 1 when the hash field is for a tunnel item. 470 * @param[in] layer_types 471 * ETH_RSS_* types. 472 * @param[in] hash_fields 473 * Item hash fields. 474 * 475 * @return 476 * The hash fileds that should be used. 477 */ 478 uint64_t 479 mlx5_flow_hashfields_adjust(struct mlx5_flow *dev_flow, 480 int tunnel __rte_unused, uint64_t layer_types, 481 uint64_t hash_fields) 482 { 483 struct rte_flow *flow = dev_flow->flow; 484 #ifdef HAVE_IBV_DEVICE_TUNNEL_SUPPORT 485 int rss_request_inner = flow->rss.level >= 2; 486 487 /* Check RSS hash level for tunnel. */ 488 if (tunnel && rss_request_inner) 489 hash_fields |= IBV_RX_HASH_INNER; 490 else if (tunnel || rss_request_inner) 491 return 0; 492 #endif 493 /* Check if requested layer matches RSS hash fields. */ 494 if (!(flow->rss.types & layer_types)) 495 return 0; 496 return hash_fields; 497 } 498 499 /** 500 * Lookup and set the ptype in the data Rx part. A single Ptype can be used, 501 * if several tunnel rules are used on this queue, the tunnel ptype will be 502 * cleared. 503 * 504 * @param rxq_ctrl 505 * Rx queue to update. 506 */ 507 static void 508 flow_rxq_tunnel_ptype_update(struct mlx5_rxq_ctrl *rxq_ctrl) 509 { 510 unsigned int i; 511 uint32_t tunnel_ptype = 0; 512 513 /* Look up for the ptype to use. */ 514 for (i = 0; i != MLX5_FLOW_TUNNEL; ++i) { 515 if (!rxq_ctrl->flow_tunnels_n[i]) 516 continue; 517 if (!tunnel_ptype) { 518 tunnel_ptype = tunnels_info[i].ptype; 519 } else { 520 tunnel_ptype = 0; 521 break; 522 } 523 } 524 rxq_ctrl->rxq.tunnel = tunnel_ptype; 525 } 526 527 /** 528 * Set the Rx queue flags (Mark/Flag and Tunnel Ptypes) according to the devive 529 * flow. 530 * 531 * @param[in] dev 532 * Pointer to the Ethernet device structure. 533 * @param[in] dev_flow 534 * Pointer to device flow structure. 535 */ 536 static void 537 flow_drv_rxq_flags_set(struct rte_eth_dev *dev, struct mlx5_flow *dev_flow) 538 { 539 struct mlx5_priv *priv = dev->data->dev_private; 540 struct rte_flow *flow = dev_flow->flow; 541 const int mark = !!(flow->actions & 542 (MLX5_FLOW_ACTION_FLAG | MLX5_FLOW_ACTION_MARK)); 543 const int tunnel = !!(dev_flow->layers & MLX5_FLOW_LAYER_TUNNEL); 544 unsigned int i; 545 546 for (i = 0; i != flow->rss.queue_num; ++i) { 547 int idx = (*flow->queue)[i]; 548 struct mlx5_rxq_ctrl *rxq_ctrl = 549 container_of((*priv->rxqs)[idx], 550 struct mlx5_rxq_ctrl, rxq); 551 552 if (mark) { 553 rxq_ctrl->rxq.mark = 1; 554 rxq_ctrl->flow_mark_n++; 555 } 556 if (tunnel) { 557 unsigned int j; 558 559 /* Increase the counter matching the flow. */ 560 for (j = 0; j != MLX5_FLOW_TUNNEL; ++j) { 561 if ((tunnels_info[j].tunnel & 562 dev_flow->layers) == 563 tunnels_info[j].tunnel) { 564 rxq_ctrl->flow_tunnels_n[j]++; 565 break; 566 } 567 } 568 flow_rxq_tunnel_ptype_update(rxq_ctrl); 569 } 570 } 571 } 572 573 /** 574 * Set the Rx queue flags (Mark/Flag and Tunnel Ptypes) for a flow 575 * 576 * @param[in] dev 577 * Pointer to the Ethernet device structure. 578 * @param[in] flow 579 * Pointer to flow structure. 580 */ 581 static void 582 flow_rxq_flags_set(struct rte_eth_dev *dev, struct rte_flow *flow) 583 { 584 struct mlx5_flow *dev_flow; 585 586 LIST_FOREACH(dev_flow, &flow->dev_flows, next) 587 flow_drv_rxq_flags_set(dev, dev_flow); 588 } 589 590 /** 591 * Clear the Rx queue flags (Mark/Flag and Tunnel Ptype) associated with the 592 * device flow if no other flow uses it with the same kind of request. 593 * 594 * @param dev 595 * Pointer to Ethernet device. 596 * @param[in] dev_flow 597 * Pointer to the device flow. 598 */ 599 static void 600 flow_drv_rxq_flags_trim(struct rte_eth_dev *dev, struct mlx5_flow *dev_flow) 601 { 602 struct mlx5_priv *priv = dev->data->dev_private; 603 struct rte_flow *flow = dev_flow->flow; 604 const int mark = !!(flow->actions & 605 (MLX5_FLOW_ACTION_FLAG | MLX5_FLOW_ACTION_MARK)); 606 const int tunnel = !!(dev_flow->layers & MLX5_FLOW_LAYER_TUNNEL); 607 unsigned int i; 608 609 assert(dev->data->dev_started); 610 for (i = 0; i != flow->rss.queue_num; ++i) { 611 int idx = (*flow->queue)[i]; 612 struct mlx5_rxq_ctrl *rxq_ctrl = 613 container_of((*priv->rxqs)[idx], 614 struct mlx5_rxq_ctrl, rxq); 615 616 if (mark) { 617 rxq_ctrl->flow_mark_n--; 618 rxq_ctrl->rxq.mark = !!rxq_ctrl->flow_mark_n; 619 } 620 if (tunnel) { 621 unsigned int j; 622 623 /* Decrease the counter matching the flow. */ 624 for (j = 0; j != MLX5_FLOW_TUNNEL; ++j) { 625 if ((tunnels_info[j].tunnel & 626 dev_flow->layers) == 627 tunnels_info[j].tunnel) { 628 rxq_ctrl->flow_tunnels_n[j]--; 629 break; 630 } 631 } 632 flow_rxq_tunnel_ptype_update(rxq_ctrl); 633 } 634 } 635 } 636 637 /** 638 * Clear the Rx queue flags (Mark/Flag and Tunnel Ptype) associated with the 639 * @p flow if no other flow uses it with the same kind of request. 640 * 641 * @param dev 642 * Pointer to Ethernet device. 643 * @param[in] flow 644 * Pointer to the flow. 645 */ 646 static void 647 flow_rxq_flags_trim(struct rte_eth_dev *dev, struct rte_flow *flow) 648 { 649 struct mlx5_flow *dev_flow; 650 651 LIST_FOREACH(dev_flow, &flow->dev_flows, next) 652 flow_drv_rxq_flags_trim(dev, dev_flow); 653 } 654 655 /** 656 * Clear the Mark/Flag and Tunnel ptype information in all Rx queues. 657 * 658 * @param dev 659 * Pointer to Ethernet device. 660 */ 661 static void 662 flow_rxq_flags_clear(struct rte_eth_dev *dev) 663 { 664 struct mlx5_priv *priv = dev->data->dev_private; 665 unsigned int i; 666 667 for (i = 0; i != priv->rxqs_n; ++i) { 668 struct mlx5_rxq_ctrl *rxq_ctrl; 669 unsigned int j; 670 671 if (!(*priv->rxqs)[i]) 672 continue; 673 rxq_ctrl = container_of((*priv->rxqs)[i], 674 struct mlx5_rxq_ctrl, rxq); 675 rxq_ctrl->flow_mark_n = 0; 676 rxq_ctrl->rxq.mark = 0; 677 for (j = 0; j != MLX5_FLOW_TUNNEL; ++j) 678 rxq_ctrl->flow_tunnels_n[j] = 0; 679 rxq_ctrl->rxq.tunnel = 0; 680 } 681 } 682 683 /* 684 * Validate the flag action. 685 * 686 * @param[in] action_flags 687 * Bit-fields that holds the actions detected until now. 688 * @param[in] attr 689 * Attributes of flow that includes this action. 690 * @param[out] error 691 * Pointer to error structure. 692 * 693 * @return 694 * 0 on success, a negative errno value otherwise and rte_errno is set. 695 */ 696 int 697 mlx5_flow_validate_action_flag(uint64_t action_flags, 698 const struct rte_flow_attr *attr, 699 struct rte_flow_error *error) 700 { 701 702 if (action_flags & MLX5_FLOW_ACTION_DROP) 703 return rte_flow_error_set(error, EINVAL, 704 RTE_FLOW_ERROR_TYPE_ACTION, NULL, 705 "can't drop and flag in same flow"); 706 if (action_flags & MLX5_FLOW_ACTION_MARK) 707 return rte_flow_error_set(error, EINVAL, 708 RTE_FLOW_ERROR_TYPE_ACTION, NULL, 709 "can't mark and flag in same flow"); 710 if (action_flags & MLX5_FLOW_ACTION_FLAG) 711 return rte_flow_error_set(error, EINVAL, 712 RTE_FLOW_ERROR_TYPE_ACTION, NULL, 713 "can't have 2 flag" 714 " actions in same flow"); 715 if (attr->egress) 716 return rte_flow_error_set(error, ENOTSUP, 717 RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, NULL, 718 "flag action not supported for " 719 "egress"); 720 return 0; 721 } 722 723 /* 724 * Validate the mark action. 725 * 726 * @param[in] action 727 * Pointer to the queue action. 728 * @param[in] action_flags 729 * Bit-fields that holds the actions detected until now. 730 * @param[in] attr 731 * Attributes of flow that includes this action. 732 * @param[out] error 733 * Pointer to error structure. 734 * 735 * @return 736 * 0 on success, a negative errno value otherwise and rte_errno is set. 737 */ 738 int 739 mlx5_flow_validate_action_mark(const struct rte_flow_action *action, 740 uint64_t action_flags, 741 const struct rte_flow_attr *attr, 742 struct rte_flow_error *error) 743 { 744 const struct rte_flow_action_mark *mark = action->conf; 745 746 if (!mark) 747 return rte_flow_error_set(error, EINVAL, 748 RTE_FLOW_ERROR_TYPE_ACTION, 749 action, 750 "configuration cannot be null"); 751 if (mark->id >= MLX5_FLOW_MARK_MAX) 752 return rte_flow_error_set(error, EINVAL, 753 RTE_FLOW_ERROR_TYPE_ACTION_CONF, 754 &mark->id, 755 "mark id must in 0 <= id < " 756 RTE_STR(MLX5_FLOW_MARK_MAX)); 757 if (action_flags & MLX5_FLOW_ACTION_DROP) 758 return rte_flow_error_set(error, EINVAL, 759 RTE_FLOW_ERROR_TYPE_ACTION, NULL, 760 "can't drop and mark in same flow"); 761 if (action_flags & MLX5_FLOW_ACTION_FLAG) 762 return rte_flow_error_set(error, EINVAL, 763 RTE_FLOW_ERROR_TYPE_ACTION, NULL, 764 "can't flag and mark in same flow"); 765 if (action_flags & MLX5_FLOW_ACTION_MARK) 766 return rte_flow_error_set(error, EINVAL, 767 RTE_FLOW_ERROR_TYPE_ACTION, NULL, 768 "can't have 2 mark actions in same" 769 " flow"); 770 if (attr->egress) 771 return rte_flow_error_set(error, ENOTSUP, 772 RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, NULL, 773 "mark action not supported for " 774 "egress"); 775 return 0; 776 } 777 778 /* 779 * Validate the drop action. 780 * 781 * @param[in] action_flags 782 * Bit-fields that holds the actions detected until now. 783 * @param[in] attr 784 * Attributes of flow that includes this action. 785 * @param[out] error 786 * Pointer to error structure. 787 * 788 * @return 789 * 0 on success, a negative errno value otherwise and rte_errno is set. 790 */ 791 int 792 mlx5_flow_validate_action_drop(uint64_t action_flags, 793 const struct rte_flow_attr *attr, 794 struct rte_flow_error *error) 795 { 796 if (action_flags & MLX5_FLOW_ACTION_FLAG) 797 return rte_flow_error_set(error, EINVAL, 798 RTE_FLOW_ERROR_TYPE_ACTION, NULL, 799 "can't drop and flag in same flow"); 800 if (action_flags & MLX5_FLOW_ACTION_MARK) 801 return rte_flow_error_set(error, EINVAL, 802 RTE_FLOW_ERROR_TYPE_ACTION, NULL, 803 "can't drop and mark in same flow"); 804 if (action_flags & MLX5_FLOW_FATE_ACTIONS) 805 return rte_flow_error_set(error, EINVAL, 806 RTE_FLOW_ERROR_TYPE_ACTION, NULL, 807 "can't have 2 fate actions in" 808 " same flow"); 809 if (attr->egress) 810 return rte_flow_error_set(error, ENOTSUP, 811 RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, NULL, 812 "drop action not supported for " 813 "egress"); 814 return 0; 815 } 816 817 /* 818 * Validate the queue action. 819 * 820 * @param[in] action 821 * Pointer to the queue action. 822 * @param[in] action_flags 823 * Bit-fields that holds the actions detected until now. 824 * @param[in] dev 825 * Pointer to the Ethernet device structure. 826 * @param[in] attr 827 * Attributes of flow that includes this action. 828 * @param[out] error 829 * Pointer to error structure. 830 * 831 * @return 832 * 0 on success, a negative errno value otherwise and rte_errno is set. 833 */ 834 int 835 mlx5_flow_validate_action_queue(const struct rte_flow_action *action, 836 uint64_t action_flags, 837 struct rte_eth_dev *dev, 838 const struct rte_flow_attr *attr, 839 struct rte_flow_error *error) 840 { 841 struct mlx5_priv *priv = dev->data->dev_private; 842 const struct rte_flow_action_queue *queue = action->conf; 843 844 if (action_flags & MLX5_FLOW_FATE_ACTIONS) 845 return rte_flow_error_set(error, EINVAL, 846 RTE_FLOW_ERROR_TYPE_ACTION, NULL, 847 "can't have 2 fate actions in" 848 " same flow"); 849 if (!priv->rxqs_n) 850 return rte_flow_error_set(error, EINVAL, 851 RTE_FLOW_ERROR_TYPE_ACTION_CONF, 852 NULL, "No Rx queues configured"); 853 if (queue->index >= priv->rxqs_n) 854 return rte_flow_error_set(error, EINVAL, 855 RTE_FLOW_ERROR_TYPE_ACTION_CONF, 856 &queue->index, 857 "queue index out of range"); 858 if (!(*priv->rxqs)[queue->index]) 859 return rte_flow_error_set(error, EINVAL, 860 RTE_FLOW_ERROR_TYPE_ACTION_CONF, 861 &queue->index, 862 "queue is not configured"); 863 if (attr->egress) 864 return rte_flow_error_set(error, ENOTSUP, 865 RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, NULL, 866 "queue action not supported for " 867 "egress"); 868 return 0; 869 } 870 871 /* 872 * Validate the rss action. 873 * 874 * @param[in] action 875 * Pointer to the queue action. 876 * @param[in] action_flags 877 * Bit-fields that holds the actions detected until now. 878 * @param[in] dev 879 * Pointer to the Ethernet device structure. 880 * @param[in] attr 881 * Attributes of flow that includes this action. 882 * @param[in] item_flags 883 * Items that were detected. 884 * @param[out] error 885 * Pointer to error structure. 886 * 887 * @return 888 * 0 on success, a negative errno value otherwise and rte_errno is set. 889 */ 890 int 891 mlx5_flow_validate_action_rss(const struct rte_flow_action *action, 892 uint64_t action_flags, 893 struct rte_eth_dev *dev, 894 const struct rte_flow_attr *attr, 895 uint64_t item_flags, 896 struct rte_flow_error *error) 897 { 898 struct mlx5_priv *priv = dev->data->dev_private; 899 const struct rte_flow_action_rss *rss = action->conf; 900 int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL); 901 unsigned int i; 902 903 if (action_flags & MLX5_FLOW_FATE_ACTIONS) 904 return rte_flow_error_set(error, EINVAL, 905 RTE_FLOW_ERROR_TYPE_ACTION, NULL, 906 "can't have 2 fate actions" 907 " in same flow"); 908 if (rss->func != RTE_ETH_HASH_FUNCTION_DEFAULT && 909 rss->func != RTE_ETH_HASH_FUNCTION_TOEPLITZ) 910 return rte_flow_error_set(error, ENOTSUP, 911 RTE_FLOW_ERROR_TYPE_ACTION_CONF, 912 &rss->func, 913 "RSS hash function not supported"); 914 #ifdef HAVE_IBV_DEVICE_TUNNEL_SUPPORT 915 if (rss->level > 2) 916 #else 917 if (rss->level > 1) 918 #endif 919 return rte_flow_error_set(error, ENOTSUP, 920 RTE_FLOW_ERROR_TYPE_ACTION_CONF, 921 &rss->level, 922 "tunnel RSS is not supported"); 923 /* allow RSS key_len 0 in case of NULL (default) RSS key. */ 924 if (rss->key_len == 0 && rss->key != NULL) 925 return rte_flow_error_set(error, ENOTSUP, 926 RTE_FLOW_ERROR_TYPE_ACTION_CONF, 927 &rss->key_len, 928 "RSS hash key length 0"); 929 if (rss->key_len > 0 && rss->key_len < MLX5_RSS_HASH_KEY_LEN) 930 return rte_flow_error_set(error, ENOTSUP, 931 RTE_FLOW_ERROR_TYPE_ACTION_CONF, 932 &rss->key_len, 933 "RSS hash key too small"); 934 if (rss->key_len > MLX5_RSS_HASH_KEY_LEN) 935 return rte_flow_error_set(error, ENOTSUP, 936 RTE_FLOW_ERROR_TYPE_ACTION_CONF, 937 &rss->key_len, 938 "RSS hash key too large"); 939 if (rss->queue_num > priv->config.ind_table_max_size) 940 return rte_flow_error_set(error, ENOTSUP, 941 RTE_FLOW_ERROR_TYPE_ACTION_CONF, 942 &rss->queue_num, 943 "number of queues too large"); 944 if (rss->types & MLX5_RSS_HF_MASK) 945 return rte_flow_error_set(error, ENOTSUP, 946 RTE_FLOW_ERROR_TYPE_ACTION_CONF, 947 &rss->types, 948 "some RSS protocols are not" 949 " supported"); 950 if (!priv->rxqs_n) 951 return rte_flow_error_set(error, EINVAL, 952 RTE_FLOW_ERROR_TYPE_ACTION_CONF, 953 NULL, "No Rx queues configured"); 954 if (!rss->queue_num) 955 return rte_flow_error_set(error, EINVAL, 956 RTE_FLOW_ERROR_TYPE_ACTION_CONF, 957 NULL, "No queues configured"); 958 for (i = 0; i != rss->queue_num; ++i) { 959 if (!(*priv->rxqs)[rss->queue[i]]) 960 return rte_flow_error_set 961 (error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION_CONF, 962 &rss->queue[i], "queue is not configured"); 963 } 964 if (attr->egress) 965 return rte_flow_error_set(error, ENOTSUP, 966 RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, NULL, 967 "rss action not supported for " 968 "egress"); 969 if (rss->level > 1 && !tunnel) 970 return rte_flow_error_set(error, EINVAL, 971 RTE_FLOW_ERROR_TYPE_ACTION_CONF, NULL, 972 "inner RSS is not supported for " 973 "non-tunnel flows"); 974 return 0; 975 } 976 977 /* 978 * Validate the count action. 979 * 980 * @param[in] dev 981 * Pointer to the Ethernet device structure. 982 * @param[in] attr 983 * Attributes of flow that includes this action. 984 * @param[out] error 985 * Pointer to error structure. 986 * 987 * @return 988 * 0 on success, a negative errno value otherwise and rte_errno is set. 989 */ 990 int 991 mlx5_flow_validate_action_count(struct rte_eth_dev *dev __rte_unused, 992 const struct rte_flow_attr *attr, 993 struct rte_flow_error *error) 994 { 995 if (attr->egress) 996 return rte_flow_error_set(error, ENOTSUP, 997 RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, NULL, 998 "count action not supported for " 999 "egress"); 1000 return 0; 1001 } 1002 1003 /** 1004 * Verify the @p attributes will be correctly understood by the NIC and store 1005 * them in the @p flow if everything is correct. 1006 * 1007 * @param[in] dev 1008 * Pointer to the Ethernet device structure. 1009 * @param[in] attributes 1010 * Pointer to flow attributes 1011 * @param[out] error 1012 * Pointer to error structure. 1013 * 1014 * @return 1015 * 0 on success, a negative errno value otherwise and rte_errno is set. 1016 */ 1017 int 1018 mlx5_flow_validate_attributes(struct rte_eth_dev *dev, 1019 const struct rte_flow_attr *attributes, 1020 struct rte_flow_error *error) 1021 { 1022 struct mlx5_priv *priv = dev->data->dev_private; 1023 uint32_t priority_max = priv->config.flow_prio - 1; 1024 1025 if (attributes->group) 1026 return rte_flow_error_set(error, ENOTSUP, 1027 RTE_FLOW_ERROR_TYPE_ATTR_GROUP, 1028 NULL, "groups is not supported"); 1029 if (attributes->priority != MLX5_FLOW_PRIO_RSVD && 1030 attributes->priority >= priority_max) 1031 return rte_flow_error_set(error, ENOTSUP, 1032 RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, 1033 NULL, "priority out of range"); 1034 if (attributes->egress) 1035 return rte_flow_error_set(error, ENOTSUP, 1036 RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, NULL, 1037 "egress is not supported"); 1038 if (attributes->transfer && !priv->config.dv_esw_en) 1039 return rte_flow_error_set(error, ENOTSUP, 1040 RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER, 1041 NULL, "transfer is not supported"); 1042 if (!attributes->ingress) 1043 return rte_flow_error_set(error, EINVAL, 1044 RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, 1045 NULL, 1046 "ingress attribute is mandatory"); 1047 return 0; 1048 } 1049 1050 /** 1051 * Validate Ethernet item. 1052 * 1053 * @param[in] item 1054 * Item specification. 1055 * @param[in] item_flags 1056 * Bit-fields that holds the items detected until now. 1057 * @param[out] error 1058 * Pointer to error structure. 1059 * 1060 * @return 1061 * 0 on success, a negative errno value otherwise and rte_errno is set. 1062 */ 1063 int 1064 mlx5_flow_validate_item_eth(const struct rte_flow_item *item, 1065 uint64_t item_flags, 1066 struct rte_flow_error *error) 1067 { 1068 const struct rte_flow_item_eth *mask = item->mask; 1069 const struct rte_flow_item_eth nic_mask = { 1070 .dst.addr_bytes = "\xff\xff\xff\xff\xff\xff", 1071 .src.addr_bytes = "\xff\xff\xff\xff\xff\xff", 1072 .type = RTE_BE16(0xffff), 1073 }; 1074 int ret; 1075 int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL); 1076 const uint64_t ethm = tunnel ? MLX5_FLOW_LAYER_INNER_L2 : 1077 MLX5_FLOW_LAYER_OUTER_L2; 1078 1079 if (item_flags & ethm) 1080 return rte_flow_error_set(error, ENOTSUP, 1081 RTE_FLOW_ERROR_TYPE_ITEM, item, 1082 "multiple L2 layers not supported"); 1083 if (!mask) 1084 mask = &rte_flow_item_eth_mask; 1085 ret = mlx5_flow_item_acceptable(item, (const uint8_t *)mask, 1086 (const uint8_t *)&nic_mask, 1087 sizeof(struct rte_flow_item_eth), 1088 error); 1089 return ret; 1090 } 1091 1092 /** 1093 * Validate VLAN item. 1094 * 1095 * @param[in] item 1096 * Item specification. 1097 * @param[in] item_flags 1098 * Bit-fields that holds the items detected until now. 1099 * @param[out] error 1100 * Pointer to error structure. 1101 * 1102 * @return 1103 * 0 on success, a negative errno value otherwise and rte_errno is set. 1104 */ 1105 int 1106 mlx5_flow_validate_item_vlan(const struct rte_flow_item *item, 1107 uint64_t item_flags, 1108 struct rte_flow_error *error) 1109 { 1110 const struct rte_flow_item_vlan *spec = item->spec; 1111 const struct rte_flow_item_vlan *mask = item->mask; 1112 const struct rte_flow_item_vlan nic_mask = { 1113 .tci = RTE_BE16(0x0fff), 1114 .inner_type = RTE_BE16(0xffff), 1115 }; 1116 uint16_t vlan_tag = 0; 1117 const int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL); 1118 int ret; 1119 const uint64_t l34m = tunnel ? (MLX5_FLOW_LAYER_INNER_L3 | 1120 MLX5_FLOW_LAYER_INNER_L4) : 1121 (MLX5_FLOW_LAYER_OUTER_L3 | 1122 MLX5_FLOW_LAYER_OUTER_L4); 1123 const uint64_t vlanm = tunnel ? MLX5_FLOW_LAYER_INNER_VLAN : 1124 MLX5_FLOW_LAYER_OUTER_VLAN; 1125 1126 if (item_flags & vlanm) 1127 return rte_flow_error_set(error, EINVAL, 1128 RTE_FLOW_ERROR_TYPE_ITEM, item, 1129 "multiple VLAN layers not supported"); 1130 else if ((item_flags & l34m) != 0) 1131 return rte_flow_error_set(error, EINVAL, 1132 RTE_FLOW_ERROR_TYPE_ITEM, item, 1133 "L2 layer cannot follow L3/L4 layer"); 1134 if (!mask) 1135 mask = &rte_flow_item_vlan_mask; 1136 ret = mlx5_flow_item_acceptable(item, (const uint8_t *)mask, 1137 (const uint8_t *)&nic_mask, 1138 sizeof(struct rte_flow_item_vlan), 1139 error); 1140 if (ret) 1141 return ret; 1142 if (spec) { 1143 vlan_tag = spec->tci; 1144 vlan_tag &= mask->tci; 1145 } 1146 /* 1147 * From verbs perspective an empty VLAN is equivalent 1148 * to a packet without VLAN layer. 1149 */ 1150 if (!vlan_tag) 1151 return rte_flow_error_set(error, EINVAL, 1152 RTE_FLOW_ERROR_TYPE_ITEM_SPEC, 1153 item->spec, 1154 "VLAN cannot be empty"); 1155 return 0; 1156 } 1157 1158 /** 1159 * Validate IPV4 item. 1160 * 1161 * @param[in] item 1162 * Item specification. 1163 * @param[in] item_flags 1164 * Bit-fields that holds the items detected until now. 1165 * @param[in] acc_mask 1166 * Acceptable mask, if NULL default internal default mask 1167 * will be used to check whether item fields are supported. 1168 * @param[out] error 1169 * Pointer to error structure. 1170 * 1171 * @return 1172 * 0 on success, a negative errno value otherwise and rte_errno is set. 1173 */ 1174 int 1175 mlx5_flow_validate_item_ipv4(const struct rte_flow_item *item, 1176 uint64_t item_flags, 1177 const struct rte_flow_item_ipv4 *acc_mask, 1178 struct rte_flow_error *error) 1179 { 1180 const struct rte_flow_item_ipv4 *mask = item->mask; 1181 const struct rte_flow_item_ipv4 nic_mask = { 1182 .hdr = { 1183 .src_addr = RTE_BE32(0xffffffff), 1184 .dst_addr = RTE_BE32(0xffffffff), 1185 .type_of_service = 0xff, 1186 .next_proto_id = 0xff, 1187 }, 1188 }; 1189 const int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL); 1190 const uint64_t l3m = tunnel ? MLX5_FLOW_LAYER_INNER_L3 : 1191 MLX5_FLOW_LAYER_OUTER_L3; 1192 const uint64_t l4m = tunnel ? MLX5_FLOW_LAYER_INNER_L4 : 1193 MLX5_FLOW_LAYER_OUTER_L4; 1194 int ret; 1195 1196 if (item_flags & l3m) 1197 return rte_flow_error_set(error, ENOTSUP, 1198 RTE_FLOW_ERROR_TYPE_ITEM, item, 1199 "multiple L3 layers not supported"); 1200 else if (item_flags & l4m) 1201 return rte_flow_error_set(error, EINVAL, 1202 RTE_FLOW_ERROR_TYPE_ITEM, item, 1203 "L3 cannot follow an L4 layer."); 1204 if (!mask) 1205 mask = &rte_flow_item_ipv4_mask; 1206 else if (mask->hdr.next_proto_id != 0 && 1207 mask->hdr.next_proto_id != 0xff) 1208 return rte_flow_error_set(error, EINVAL, 1209 RTE_FLOW_ERROR_TYPE_ITEM_MASK, mask, 1210 "partial mask is not supported" 1211 " for protocol"); 1212 ret = mlx5_flow_item_acceptable(item, (const uint8_t *)mask, 1213 acc_mask ? (const uint8_t *)acc_mask 1214 : (const uint8_t *)&nic_mask, 1215 sizeof(struct rte_flow_item_ipv4), 1216 error); 1217 if (ret < 0) 1218 return ret; 1219 return 0; 1220 } 1221 1222 /** 1223 * Validate IPV6 item. 1224 * 1225 * @param[in] item 1226 * Item specification. 1227 * @param[in] item_flags 1228 * Bit-fields that holds the items detected until now. 1229 * @param[in] acc_mask 1230 * Acceptable mask, if NULL default internal default mask 1231 * will be used to check whether item fields are supported. 1232 * @param[out] error 1233 * Pointer to error structure. 1234 * 1235 * @return 1236 * 0 on success, a negative errno value otherwise and rte_errno is set. 1237 */ 1238 int 1239 mlx5_flow_validate_item_ipv6(const struct rte_flow_item *item, 1240 uint64_t item_flags, 1241 const struct rte_flow_item_ipv6 *acc_mask, 1242 struct rte_flow_error *error) 1243 { 1244 const struct rte_flow_item_ipv6 *mask = item->mask; 1245 const struct rte_flow_item_ipv6 nic_mask = { 1246 .hdr = { 1247 .src_addr = 1248 "\xff\xff\xff\xff\xff\xff\xff\xff" 1249 "\xff\xff\xff\xff\xff\xff\xff\xff", 1250 .dst_addr = 1251 "\xff\xff\xff\xff\xff\xff\xff\xff" 1252 "\xff\xff\xff\xff\xff\xff\xff\xff", 1253 .vtc_flow = RTE_BE32(0xffffffff), 1254 .proto = 0xff, 1255 .hop_limits = 0xff, 1256 }, 1257 }; 1258 const int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL); 1259 const uint64_t l3m = tunnel ? MLX5_FLOW_LAYER_INNER_L3 : 1260 MLX5_FLOW_LAYER_OUTER_L3; 1261 const uint64_t l4m = tunnel ? MLX5_FLOW_LAYER_INNER_L4 : 1262 MLX5_FLOW_LAYER_OUTER_L4; 1263 int ret; 1264 1265 if (item_flags & l3m) 1266 return rte_flow_error_set(error, ENOTSUP, 1267 RTE_FLOW_ERROR_TYPE_ITEM, item, 1268 "multiple L3 layers not supported"); 1269 else if (item_flags & l4m) 1270 return rte_flow_error_set(error, EINVAL, 1271 RTE_FLOW_ERROR_TYPE_ITEM, item, 1272 "L3 cannot follow an L4 layer."); 1273 if (!mask) 1274 mask = &rte_flow_item_ipv6_mask; 1275 ret = mlx5_flow_item_acceptable(item, (const uint8_t *)mask, 1276 acc_mask ? (const uint8_t *)acc_mask 1277 : (const uint8_t *)&nic_mask, 1278 sizeof(struct rte_flow_item_ipv6), 1279 error); 1280 if (ret < 0) 1281 return ret; 1282 return 0; 1283 } 1284 1285 /** 1286 * Validate UDP item. 1287 * 1288 * @param[in] item 1289 * Item specification. 1290 * @param[in] item_flags 1291 * Bit-fields that holds the items detected until now. 1292 * @param[in] target_protocol 1293 * The next protocol in the previous item. 1294 * @param[in] flow_mask 1295 * mlx5 flow-specific (DV, verbs, etc.) supported header fields mask. 1296 * @param[out] error 1297 * Pointer to error structure. 1298 * 1299 * @return 1300 * 0 on success, a negative errno value otherwise and rte_errno is set. 1301 */ 1302 int 1303 mlx5_flow_validate_item_udp(const struct rte_flow_item *item, 1304 uint64_t item_flags, 1305 uint8_t target_protocol, 1306 struct rte_flow_error *error) 1307 { 1308 const struct rte_flow_item_udp *mask = item->mask; 1309 const int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL); 1310 const uint64_t l3m = tunnel ? MLX5_FLOW_LAYER_INNER_L3 : 1311 MLX5_FLOW_LAYER_OUTER_L3; 1312 const uint64_t l4m = tunnel ? MLX5_FLOW_LAYER_INNER_L4 : 1313 MLX5_FLOW_LAYER_OUTER_L4; 1314 int ret; 1315 1316 if (target_protocol != 0xff && target_protocol != IPPROTO_UDP) 1317 return rte_flow_error_set(error, EINVAL, 1318 RTE_FLOW_ERROR_TYPE_ITEM, item, 1319 "protocol filtering not compatible" 1320 " with UDP layer"); 1321 if (!(item_flags & l3m)) 1322 return rte_flow_error_set(error, EINVAL, 1323 RTE_FLOW_ERROR_TYPE_ITEM, item, 1324 "L3 is mandatory to filter on L4"); 1325 if (item_flags & l4m) 1326 return rte_flow_error_set(error, EINVAL, 1327 RTE_FLOW_ERROR_TYPE_ITEM, item, 1328 "multiple L4 layers not supported"); 1329 if (!mask) 1330 mask = &rte_flow_item_udp_mask; 1331 ret = mlx5_flow_item_acceptable 1332 (item, (const uint8_t *)mask, 1333 (const uint8_t *)&rte_flow_item_udp_mask, 1334 sizeof(struct rte_flow_item_udp), error); 1335 if (ret < 0) 1336 return ret; 1337 return 0; 1338 } 1339 1340 /** 1341 * Validate TCP item. 1342 * 1343 * @param[in] item 1344 * Item specification. 1345 * @param[in] item_flags 1346 * Bit-fields that holds the items detected until now. 1347 * @param[in] target_protocol 1348 * The next protocol in the previous item. 1349 * @param[out] error 1350 * Pointer to error structure. 1351 * 1352 * @return 1353 * 0 on success, a negative errno value otherwise and rte_errno is set. 1354 */ 1355 int 1356 mlx5_flow_validate_item_tcp(const struct rte_flow_item *item, 1357 uint64_t item_flags, 1358 uint8_t target_protocol, 1359 const struct rte_flow_item_tcp *flow_mask, 1360 struct rte_flow_error *error) 1361 { 1362 const struct rte_flow_item_tcp *mask = item->mask; 1363 const int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL); 1364 const uint64_t l3m = tunnel ? MLX5_FLOW_LAYER_INNER_L3 : 1365 MLX5_FLOW_LAYER_OUTER_L3; 1366 const uint64_t l4m = tunnel ? MLX5_FLOW_LAYER_INNER_L4 : 1367 MLX5_FLOW_LAYER_OUTER_L4; 1368 int ret; 1369 1370 assert(flow_mask); 1371 if (target_protocol != 0xff && target_protocol != IPPROTO_TCP) 1372 return rte_flow_error_set(error, EINVAL, 1373 RTE_FLOW_ERROR_TYPE_ITEM, item, 1374 "protocol filtering not compatible" 1375 " with TCP layer"); 1376 if (!(item_flags & l3m)) 1377 return rte_flow_error_set(error, EINVAL, 1378 RTE_FLOW_ERROR_TYPE_ITEM, item, 1379 "L3 is mandatory to filter on L4"); 1380 if (item_flags & l4m) 1381 return rte_flow_error_set(error, EINVAL, 1382 RTE_FLOW_ERROR_TYPE_ITEM, item, 1383 "multiple L4 layers not supported"); 1384 if (!mask) 1385 mask = &rte_flow_item_tcp_mask; 1386 ret = mlx5_flow_item_acceptable 1387 (item, (const uint8_t *)mask, 1388 (const uint8_t *)flow_mask, 1389 sizeof(struct rte_flow_item_tcp), error); 1390 if (ret < 0) 1391 return ret; 1392 return 0; 1393 } 1394 1395 /** 1396 * Validate VXLAN item. 1397 * 1398 * @param[in] item 1399 * Item specification. 1400 * @param[in] item_flags 1401 * Bit-fields that holds the items detected until now. 1402 * @param[in] target_protocol 1403 * The next protocol in the previous item. 1404 * @param[out] error 1405 * Pointer to error structure. 1406 * 1407 * @return 1408 * 0 on success, a negative errno value otherwise and rte_errno is set. 1409 */ 1410 int 1411 mlx5_flow_validate_item_vxlan(const struct rte_flow_item *item, 1412 uint64_t item_flags, 1413 struct rte_flow_error *error) 1414 { 1415 const struct rte_flow_item_vxlan *spec = item->spec; 1416 const struct rte_flow_item_vxlan *mask = item->mask; 1417 int ret; 1418 union vni { 1419 uint32_t vlan_id; 1420 uint8_t vni[4]; 1421 } id = { .vlan_id = 0, }; 1422 uint32_t vlan_id = 0; 1423 1424 1425 if (item_flags & MLX5_FLOW_LAYER_TUNNEL) 1426 return rte_flow_error_set(error, ENOTSUP, 1427 RTE_FLOW_ERROR_TYPE_ITEM, item, 1428 "multiple tunnel layers not" 1429 " supported"); 1430 /* 1431 * Verify only UDPv4 is present as defined in 1432 * https://tools.ietf.org/html/rfc7348 1433 */ 1434 if (!(item_flags & MLX5_FLOW_LAYER_OUTER_L4_UDP)) 1435 return rte_flow_error_set(error, EINVAL, 1436 RTE_FLOW_ERROR_TYPE_ITEM, item, 1437 "no outer UDP layer found"); 1438 if (!mask) 1439 mask = &rte_flow_item_vxlan_mask; 1440 ret = mlx5_flow_item_acceptable 1441 (item, (const uint8_t *)mask, 1442 (const uint8_t *)&rte_flow_item_vxlan_mask, 1443 sizeof(struct rte_flow_item_vxlan), 1444 error); 1445 if (ret < 0) 1446 return ret; 1447 if (spec) { 1448 memcpy(&id.vni[1], spec->vni, 3); 1449 vlan_id = id.vlan_id; 1450 memcpy(&id.vni[1], mask->vni, 3); 1451 vlan_id &= id.vlan_id; 1452 } 1453 /* 1454 * Tunnel id 0 is equivalent as not adding a VXLAN layer, if 1455 * only this layer is defined in the Verbs specification it is 1456 * interpreted as wildcard and all packets will match this 1457 * rule, if it follows a full stack layer (ex: eth / ipv4 / 1458 * udp), all packets matching the layers before will also 1459 * match this rule. To avoid such situation, VNI 0 is 1460 * currently refused. 1461 */ 1462 if (!vlan_id) 1463 return rte_flow_error_set(error, ENOTSUP, 1464 RTE_FLOW_ERROR_TYPE_ITEM, item, 1465 "VXLAN vni cannot be 0"); 1466 if (!(item_flags & MLX5_FLOW_LAYER_OUTER)) 1467 return rte_flow_error_set(error, ENOTSUP, 1468 RTE_FLOW_ERROR_TYPE_ITEM, item, 1469 "VXLAN tunnel must be fully defined"); 1470 return 0; 1471 } 1472 1473 /** 1474 * Validate VXLAN_GPE item. 1475 * 1476 * @param[in] item 1477 * Item specification. 1478 * @param[in] item_flags 1479 * Bit-fields that holds the items detected until now. 1480 * @param[in] priv 1481 * Pointer to the private data structure. 1482 * @param[in] target_protocol 1483 * The next protocol in the previous item. 1484 * @param[out] error 1485 * Pointer to error structure. 1486 * 1487 * @return 1488 * 0 on success, a negative errno value otherwise and rte_errno is set. 1489 */ 1490 int 1491 mlx5_flow_validate_item_vxlan_gpe(const struct rte_flow_item *item, 1492 uint64_t item_flags, 1493 struct rte_eth_dev *dev, 1494 struct rte_flow_error *error) 1495 { 1496 struct mlx5_priv *priv = dev->data->dev_private; 1497 const struct rte_flow_item_vxlan_gpe *spec = item->spec; 1498 const struct rte_flow_item_vxlan_gpe *mask = item->mask; 1499 int ret; 1500 union vni { 1501 uint32_t vlan_id; 1502 uint8_t vni[4]; 1503 } id = { .vlan_id = 0, }; 1504 uint32_t vlan_id = 0; 1505 1506 if (!priv->config.l3_vxlan_en) 1507 return rte_flow_error_set(error, ENOTSUP, 1508 RTE_FLOW_ERROR_TYPE_ITEM, item, 1509 "L3 VXLAN is not enabled by device" 1510 " parameter and/or not configured in" 1511 " firmware"); 1512 if (item_flags & MLX5_FLOW_LAYER_TUNNEL) 1513 return rte_flow_error_set(error, ENOTSUP, 1514 RTE_FLOW_ERROR_TYPE_ITEM, item, 1515 "multiple tunnel layers not" 1516 " supported"); 1517 /* 1518 * Verify only UDPv4 is present as defined in 1519 * https://tools.ietf.org/html/rfc7348 1520 */ 1521 if (!(item_flags & MLX5_FLOW_LAYER_OUTER_L4_UDP)) 1522 return rte_flow_error_set(error, EINVAL, 1523 RTE_FLOW_ERROR_TYPE_ITEM, item, 1524 "no outer UDP layer found"); 1525 if (!mask) 1526 mask = &rte_flow_item_vxlan_gpe_mask; 1527 ret = mlx5_flow_item_acceptable 1528 (item, (const uint8_t *)mask, 1529 (const uint8_t *)&rte_flow_item_vxlan_gpe_mask, 1530 sizeof(struct rte_flow_item_vxlan_gpe), 1531 error); 1532 if (ret < 0) 1533 return ret; 1534 if (spec) { 1535 if (spec->protocol) 1536 return rte_flow_error_set(error, ENOTSUP, 1537 RTE_FLOW_ERROR_TYPE_ITEM, 1538 item, 1539 "VxLAN-GPE protocol" 1540 " not supported"); 1541 memcpy(&id.vni[1], spec->vni, 3); 1542 vlan_id = id.vlan_id; 1543 memcpy(&id.vni[1], mask->vni, 3); 1544 vlan_id &= id.vlan_id; 1545 } 1546 /* 1547 * Tunnel id 0 is equivalent as not adding a VXLAN layer, if only this 1548 * layer is defined in the Verbs specification it is interpreted as 1549 * wildcard and all packets will match this rule, if it follows a full 1550 * stack layer (ex: eth / ipv4 / udp), all packets matching the layers 1551 * before will also match this rule. To avoid such situation, VNI 0 1552 * is currently refused. 1553 */ 1554 if (!vlan_id) 1555 return rte_flow_error_set(error, ENOTSUP, 1556 RTE_FLOW_ERROR_TYPE_ITEM, item, 1557 "VXLAN-GPE vni cannot be 0"); 1558 if (!(item_flags & MLX5_FLOW_LAYER_OUTER)) 1559 return rte_flow_error_set(error, ENOTSUP, 1560 RTE_FLOW_ERROR_TYPE_ITEM, item, 1561 "VXLAN-GPE tunnel must be fully" 1562 " defined"); 1563 return 0; 1564 } 1565 1566 /** 1567 * Validate GRE item. 1568 * 1569 * @param[in] item 1570 * Item specification. 1571 * @param[in] item_flags 1572 * Bit flags to mark detected items. 1573 * @param[in] target_protocol 1574 * The next protocol in the previous item. 1575 * @param[out] error 1576 * Pointer to error structure. 1577 * 1578 * @return 1579 * 0 on success, a negative errno value otherwise and rte_errno is set. 1580 */ 1581 int 1582 mlx5_flow_validate_item_gre(const struct rte_flow_item *item, 1583 uint64_t item_flags, 1584 uint8_t target_protocol, 1585 struct rte_flow_error *error) 1586 { 1587 const struct rte_flow_item_gre *spec __rte_unused = item->spec; 1588 const struct rte_flow_item_gre *mask = item->mask; 1589 int ret; 1590 1591 if (target_protocol != 0xff && target_protocol != IPPROTO_GRE) 1592 return rte_flow_error_set(error, EINVAL, 1593 RTE_FLOW_ERROR_TYPE_ITEM, item, 1594 "protocol filtering not compatible" 1595 " with this GRE layer"); 1596 if (item_flags & MLX5_FLOW_LAYER_TUNNEL) 1597 return rte_flow_error_set(error, ENOTSUP, 1598 RTE_FLOW_ERROR_TYPE_ITEM, item, 1599 "multiple tunnel layers not" 1600 " supported"); 1601 if (!(item_flags & MLX5_FLOW_LAYER_OUTER_L3)) 1602 return rte_flow_error_set(error, ENOTSUP, 1603 RTE_FLOW_ERROR_TYPE_ITEM, item, 1604 "L3 Layer is missing"); 1605 if (!mask) 1606 mask = &rte_flow_item_gre_mask; 1607 ret = mlx5_flow_item_acceptable 1608 (item, (const uint8_t *)mask, 1609 (const uint8_t *)&rte_flow_item_gre_mask, 1610 sizeof(struct rte_flow_item_gre), error); 1611 if (ret < 0) 1612 return ret; 1613 #ifndef HAVE_IBV_DEVICE_MPLS_SUPPORT 1614 if (spec && (spec->protocol & mask->protocol)) 1615 return rte_flow_error_set(error, ENOTSUP, 1616 RTE_FLOW_ERROR_TYPE_ITEM, item, 1617 "without MPLS support the" 1618 " specification cannot be used for" 1619 " filtering"); 1620 #endif 1621 return 0; 1622 } 1623 1624 /** 1625 * Validate MPLS item. 1626 * 1627 * @param[in] dev 1628 * Pointer to the rte_eth_dev structure. 1629 * @param[in] item 1630 * Item specification. 1631 * @param[in] item_flags 1632 * Bit-fields that holds the items detected until now. 1633 * @param[in] prev_layer 1634 * The protocol layer indicated in previous item. 1635 * @param[out] error 1636 * Pointer to error structure. 1637 * 1638 * @return 1639 * 0 on success, a negative errno value otherwise and rte_errno is set. 1640 */ 1641 int 1642 mlx5_flow_validate_item_mpls(struct rte_eth_dev *dev __rte_unused, 1643 const struct rte_flow_item *item __rte_unused, 1644 uint64_t item_flags __rte_unused, 1645 uint64_t prev_layer __rte_unused, 1646 struct rte_flow_error *error) 1647 { 1648 #ifdef HAVE_IBV_DEVICE_MPLS_SUPPORT 1649 const struct rte_flow_item_mpls *mask = item->mask; 1650 struct mlx5_priv *priv = dev->data->dev_private; 1651 int ret; 1652 1653 if (!priv->config.mpls_en) 1654 return rte_flow_error_set(error, ENOTSUP, 1655 RTE_FLOW_ERROR_TYPE_ITEM, item, 1656 "MPLS not supported or" 1657 " disabled in firmware" 1658 " configuration."); 1659 /* MPLS over IP, UDP, GRE is allowed */ 1660 if (!(prev_layer & (MLX5_FLOW_LAYER_OUTER_L3 | 1661 MLX5_FLOW_LAYER_OUTER_L4_UDP | 1662 MLX5_FLOW_LAYER_GRE))) 1663 return rte_flow_error_set(error, EINVAL, 1664 RTE_FLOW_ERROR_TYPE_ITEM, item, 1665 "protocol filtering not compatible" 1666 " with MPLS layer"); 1667 /* Multi-tunnel isn't allowed but MPLS over GRE is an exception. */ 1668 if ((item_flags & MLX5_FLOW_LAYER_TUNNEL) && 1669 !(item_flags & MLX5_FLOW_LAYER_GRE)) 1670 return rte_flow_error_set(error, ENOTSUP, 1671 RTE_FLOW_ERROR_TYPE_ITEM, item, 1672 "multiple tunnel layers not" 1673 " supported"); 1674 if (!mask) 1675 mask = &rte_flow_item_mpls_mask; 1676 ret = mlx5_flow_item_acceptable 1677 (item, (const uint8_t *)mask, 1678 (const uint8_t *)&rte_flow_item_mpls_mask, 1679 sizeof(struct rte_flow_item_mpls), error); 1680 if (ret < 0) 1681 return ret; 1682 return 0; 1683 #endif 1684 return rte_flow_error_set(error, ENOTSUP, 1685 RTE_FLOW_ERROR_TYPE_ITEM, item, 1686 "MPLS is not supported by Verbs, please" 1687 " update."); 1688 } 1689 1690 static int 1691 flow_null_validate(struct rte_eth_dev *dev __rte_unused, 1692 const struct rte_flow_attr *attr __rte_unused, 1693 const struct rte_flow_item items[] __rte_unused, 1694 const struct rte_flow_action actions[] __rte_unused, 1695 struct rte_flow_error *error) 1696 { 1697 return rte_flow_error_set(error, ENOTSUP, 1698 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, NULL); 1699 } 1700 1701 static struct mlx5_flow * 1702 flow_null_prepare(const struct rte_flow_attr *attr __rte_unused, 1703 const struct rte_flow_item items[] __rte_unused, 1704 const struct rte_flow_action actions[] __rte_unused, 1705 struct rte_flow_error *error) 1706 { 1707 rte_flow_error_set(error, ENOTSUP, 1708 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, NULL); 1709 return NULL; 1710 } 1711 1712 static int 1713 flow_null_translate(struct rte_eth_dev *dev __rte_unused, 1714 struct mlx5_flow *dev_flow __rte_unused, 1715 const struct rte_flow_attr *attr __rte_unused, 1716 const struct rte_flow_item items[] __rte_unused, 1717 const struct rte_flow_action actions[] __rte_unused, 1718 struct rte_flow_error *error) 1719 { 1720 return rte_flow_error_set(error, ENOTSUP, 1721 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, NULL); 1722 } 1723 1724 static int 1725 flow_null_apply(struct rte_eth_dev *dev __rte_unused, 1726 struct rte_flow *flow __rte_unused, 1727 struct rte_flow_error *error) 1728 { 1729 return rte_flow_error_set(error, ENOTSUP, 1730 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, NULL); 1731 } 1732 1733 static void 1734 flow_null_remove(struct rte_eth_dev *dev __rte_unused, 1735 struct rte_flow *flow __rte_unused) 1736 { 1737 } 1738 1739 static void 1740 flow_null_destroy(struct rte_eth_dev *dev __rte_unused, 1741 struct rte_flow *flow __rte_unused) 1742 { 1743 } 1744 1745 static int 1746 flow_null_query(struct rte_eth_dev *dev __rte_unused, 1747 struct rte_flow *flow __rte_unused, 1748 const struct rte_flow_action *actions __rte_unused, 1749 void *data __rte_unused, 1750 struct rte_flow_error *error) 1751 { 1752 return rte_flow_error_set(error, ENOTSUP, 1753 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, NULL); 1754 } 1755 1756 /* Void driver to protect from null pointer reference. */ 1757 const struct mlx5_flow_driver_ops mlx5_flow_null_drv_ops = { 1758 .validate = flow_null_validate, 1759 .prepare = flow_null_prepare, 1760 .translate = flow_null_translate, 1761 .apply = flow_null_apply, 1762 .remove = flow_null_remove, 1763 .destroy = flow_null_destroy, 1764 .query = flow_null_query, 1765 }; 1766 1767 /** 1768 * Select flow driver type according to flow attributes and device 1769 * configuration. 1770 * 1771 * @param[in] dev 1772 * Pointer to the dev structure. 1773 * @param[in] attr 1774 * Pointer to the flow attributes. 1775 * 1776 * @return 1777 * flow driver type, MLX5_FLOW_TYPE_MAX otherwise. 1778 */ 1779 static enum mlx5_flow_drv_type 1780 flow_get_drv_type(struct rte_eth_dev *dev, const struct rte_flow_attr *attr) 1781 { 1782 struct mlx5_priv *priv = dev->data->dev_private; 1783 enum mlx5_flow_drv_type type = MLX5_FLOW_TYPE_MAX; 1784 1785 if (attr->transfer && priv->config.dv_esw_en) 1786 type = MLX5_FLOW_TYPE_DV; 1787 if (!attr->transfer) 1788 type = priv->config.dv_flow_en ? MLX5_FLOW_TYPE_DV : 1789 MLX5_FLOW_TYPE_VERBS; 1790 return type; 1791 } 1792 1793 #define flow_get_drv_ops(type) flow_drv_ops[type] 1794 1795 /** 1796 * Flow driver validation API. This abstracts calling driver specific functions. 1797 * The type of flow driver is determined according to flow attributes. 1798 * 1799 * @param[in] dev 1800 * Pointer to the dev structure. 1801 * @param[in] attr 1802 * Pointer to the flow attributes. 1803 * @param[in] items 1804 * Pointer to the list of items. 1805 * @param[in] actions 1806 * Pointer to the list of actions. 1807 * @param[out] error 1808 * Pointer to the error structure. 1809 * 1810 * @return 1811 * 0 on success, a negative errno value otherwise and rte_errno is set. 1812 */ 1813 static inline int 1814 flow_drv_validate(struct rte_eth_dev *dev, 1815 const struct rte_flow_attr *attr, 1816 const struct rte_flow_item items[], 1817 const struct rte_flow_action actions[], 1818 struct rte_flow_error *error) 1819 { 1820 const struct mlx5_flow_driver_ops *fops; 1821 enum mlx5_flow_drv_type type = flow_get_drv_type(dev, attr); 1822 1823 fops = flow_get_drv_ops(type); 1824 return fops->validate(dev, attr, items, actions, error); 1825 } 1826 1827 /** 1828 * Flow driver preparation API. This abstracts calling driver specific 1829 * functions. Parent flow (rte_flow) should have driver type (drv_type). It 1830 * calculates the size of memory required for device flow, allocates the memory, 1831 * initializes the device flow and returns the pointer. 1832 * 1833 * @note 1834 * This function initializes device flow structure such as dv or verbs in 1835 * struct mlx5_flow. However, it is caller's responsibility to initialize the 1836 * rest. For example, adding returning device flow to flow->dev_flow list and 1837 * setting backward reference to the flow should be done out of this function. 1838 * layers field is not filled either. 1839 * 1840 * @param[in] attr 1841 * Pointer to the flow attributes. 1842 * @param[in] items 1843 * Pointer to the list of items. 1844 * @param[in] actions 1845 * Pointer to the list of actions. 1846 * @param[out] error 1847 * Pointer to the error structure. 1848 * 1849 * @return 1850 * Pointer to device flow on success, otherwise NULL and rte_errno is set. 1851 */ 1852 static inline struct mlx5_flow * 1853 flow_drv_prepare(const struct rte_flow *flow, 1854 const struct rte_flow_attr *attr, 1855 const struct rte_flow_item items[], 1856 const struct rte_flow_action actions[], 1857 struct rte_flow_error *error) 1858 { 1859 const struct mlx5_flow_driver_ops *fops; 1860 enum mlx5_flow_drv_type type = flow->drv_type; 1861 1862 assert(type > MLX5_FLOW_TYPE_MIN && type < MLX5_FLOW_TYPE_MAX); 1863 fops = flow_get_drv_ops(type); 1864 return fops->prepare(attr, items, actions, error); 1865 } 1866 1867 /** 1868 * Flow driver translation API. This abstracts calling driver specific 1869 * functions. Parent flow (rte_flow) should have driver type (drv_type). It 1870 * translates a generic flow into a driver flow. flow_drv_prepare() must 1871 * precede. 1872 * 1873 * @note 1874 * dev_flow->layers could be filled as a result of parsing during translation 1875 * if needed by flow_drv_apply(). dev_flow->flow->actions can also be filled 1876 * if necessary. As a flow can have multiple dev_flows by RSS flow expansion, 1877 * flow->actions could be overwritten even though all the expanded dev_flows 1878 * have the same actions. 1879 * 1880 * @param[in] dev 1881 * Pointer to the rte dev structure. 1882 * @param[in, out] dev_flow 1883 * Pointer to the mlx5 flow. 1884 * @param[in] attr 1885 * Pointer to the flow attributes. 1886 * @param[in] items 1887 * Pointer to the list of items. 1888 * @param[in] actions 1889 * Pointer to the list of actions. 1890 * @param[out] error 1891 * Pointer to the error structure. 1892 * 1893 * @return 1894 * 0 on success, a negative errno value otherwise and rte_errno is set. 1895 */ 1896 static inline int 1897 flow_drv_translate(struct rte_eth_dev *dev, struct mlx5_flow *dev_flow, 1898 const struct rte_flow_attr *attr, 1899 const struct rte_flow_item items[], 1900 const struct rte_flow_action actions[], 1901 struct rte_flow_error *error) 1902 { 1903 const struct mlx5_flow_driver_ops *fops; 1904 enum mlx5_flow_drv_type type = dev_flow->flow->drv_type; 1905 1906 assert(type > MLX5_FLOW_TYPE_MIN && type < MLX5_FLOW_TYPE_MAX); 1907 fops = flow_get_drv_ops(type); 1908 return fops->translate(dev, dev_flow, attr, items, actions, error); 1909 } 1910 1911 /** 1912 * Flow driver apply API. This abstracts calling driver specific functions. 1913 * Parent flow (rte_flow) should have driver type (drv_type). It applies 1914 * translated driver flows on to device. flow_drv_translate() must precede. 1915 * 1916 * @param[in] dev 1917 * Pointer to Ethernet device structure. 1918 * @param[in, out] flow 1919 * Pointer to flow structure. 1920 * @param[out] error 1921 * Pointer to error structure. 1922 * 1923 * @return 1924 * 0 on success, a negative errno value otherwise and rte_errno is set. 1925 */ 1926 static inline int 1927 flow_drv_apply(struct rte_eth_dev *dev, struct rte_flow *flow, 1928 struct rte_flow_error *error) 1929 { 1930 const struct mlx5_flow_driver_ops *fops; 1931 enum mlx5_flow_drv_type type = flow->drv_type; 1932 1933 assert(type > MLX5_FLOW_TYPE_MIN && type < MLX5_FLOW_TYPE_MAX); 1934 fops = flow_get_drv_ops(type); 1935 return fops->apply(dev, flow, error); 1936 } 1937 1938 /** 1939 * Flow driver remove API. This abstracts calling driver specific functions. 1940 * Parent flow (rte_flow) should have driver type (drv_type). It removes a flow 1941 * on device. All the resources of the flow should be freed by calling 1942 * flow_drv_destroy(). 1943 * 1944 * @param[in] dev 1945 * Pointer to Ethernet device. 1946 * @param[in, out] flow 1947 * Pointer to flow structure. 1948 */ 1949 static inline void 1950 flow_drv_remove(struct rte_eth_dev *dev, struct rte_flow *flow) 1951 { 1952 const struct mlx5_flow_driver_ops *fops; 1953 enum mlx5_flow_drv_type type = flow->drv_type; 1954 1955 assert(type > MLX5_FLOW_TYPE_MIN && type < MLX5_FLOW_TYPE_MAX); 1956 fops = flow_get_drv_ops(type); 1957 fops->remove(dev, flow); 1958 } 1959 1960 /** 1961 * Flow driver destroy API. This abstracts calling driver specific functions. 1962 * Parent flow (rte_flow) should have driver type (drv_type). It removes a flow 1963 * on device and releases resources of the flow. 1964 * 1965 * @param[in] dev 1966 * Pointer to Ethernet device. 1967 * @param[in, out] flow 1968 * Pointer to flow structure. 1969 */ 1970 static inline void 1971 flow_drv_destroy(struct rte_eth_dev *dev, struct rte_flow *flow) 1972 { 1973 const struct mlx5_flow_driver_ops *fops; 1974 enum mlx5_flow_drv_type type = flow->drv_type; 1975 1976 assert(type > MLX5_FLOW_TYPE_MIN && type < MLX5_FLOW_TYPE_MAX); 1977 fops = flow_get_drv_ops(type); 1978 fops->destroy(dev, flow); 1979 } 1980 1981 /** 1982 * Validate a flow supported by the NIC. 1983 * 1984 * @see rte_flow_validate() 1985 * @see rte_flow_ops 1986 */ 1987 int 1988 mlx5_flow_validate(struct rte_eth_dev *dev, 1989 const struct rte_flow_attr *attr, 1990 const struct rte_flow_item items[], 1991 const struct rte_flow_action actions[], 1992 struct rte_flow_error *error) 1993 { 1994 int ret; 1995 1996 ret = flow_drv_validate(dev, attr, items, actions, error); 1997 if (ret < 0) 1998 return ret; 1999 return 0; 2000 } 2001 2002 /** 2003 * Get RSS action from the action list. 2004 * 2005 * @param[in] actions 2006 * Pointer to the list of actions. 2007 * 2008 * @return 2009 * Pointer to the RSS action if exist, else return NULL. 2010 */ 2011 static const struct rte_flow_action_rss* 2012 flow_get_rss_action(const struct rte_flow_action actions[]) 2013 { 2014 for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) { 2015 switch (actions->type) { 2016 case RTE_FLOW_ACTION_TYPE_RSS: 2017 return (const struct rte_flow_action_rss *) 2018 actions->conf; 2019 default: 2020 break; 2021 } 2022 } 2023 return NULL; 2024 } 2025 2026 static unsigned int 2027 find_graph_root(const struct rte_flow_item pattern[], uint32_t rss_level) 2028 { 2029 const struct rte_flow_item *item; 2030 unsigned int has_vlan = 0; 2031 2032 for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) { 2033 if (item->type == RTE_FLOW_ITEM_TYPE_VLAN) { 2034 has_vlan = 1; 2035 break; 2036 } 2037 } 2038 if (has_vlan) 2039 return rss_level < 2 ? MLX5_EXPANSION_ROOT_ETH_VLAN : 2040 MLX5_EXPANSION_ROOT_OUTER_ETH_VLAN; 2041 return rss_level < 2 ? MLX5_EXPANSION_ROOT : 2042 MLX5_EXPANSION_ROOT_OUTER; 2043 } 2044 2045 /** 2046 * Create a flow and add it to @p list. 2047 * 2048 * @param dev 2049 * Pointer to Ethernet device. 2050 * @param list 2051 * Pointer to a TAILQ flow list. 2052 * @param[in] attr 2053 * Flow rule attributes. 2054 * @param[in] items 2055 * Pattern specification (list terminated by the END pattern item). 2056 * @param[in] actions 2057 * Associated actions (list terminated by the END action). 2058 * @param[out] error 2059 * Perform verbose error reporting if not NULL. 2060 * 2061 * @return 2062 * A flow on success, NULL otherwise and rte_errno is set. 2063 */ 2064 static struct rte_flow * 2065 flow_list_create(struct rte_eth_dev *dev, struct mlx5_flows *list, 2066 const struct rte_flow_attr *attr, 2067 const struct rte_flow_item items[], 2068 const struct rte_flow_action actions[], 2069 struct rte_flow_error *error) 2070 { 2071 struct rte_flow *flow = NULL; 2072 struct mlx5_flow *dev_flow; 2073 const struct rte_flow_action_rss *rss; 2074 union { 2075 struct rte_flow_expand_rss buf; 2076 uint8_t buffer[2048]; 2077 } expand_buffer; 2078 struct rte_flow_expand_rss *buf = &expand_buffer.buf; 2079 int ret; 2080 uint32_t i; 2081 uint32_t flow_size; 2082 2083 ret = flow_drv_validate(dev, attr, items, actions, error); 2084 if (ret < 0) 2085 return NULL; 2086 flow_size = sizeof(struct rte_flow); 2087 rss = flow_get_rss_action(actions); 2088 if (rss) 2089 flow_size += RTE_ALIGN_CEIL(rss->queue_num * sizeof(uint16_t), 2090 sizeof(void *)); 2091 else 2092 flow_size += RTE_ALIGN_CEIL(sizeof(uint16_t), sizeof(void *)); 2093 flow = rte_calloc(__func__, 1, flow_size, 0); 2094 if (!flow) { 2095 rte_errno = ENOMEM; 2096 return NULL; 2097 } 2098 flow->drv_type = flow_get_drv_type(dev, attr); 2099 flow->ingress = attr->ingress; 2100 flow->transfer = attr->transfer; 2101 assert(flow->drv_type > MLX5_FLOW_TYPE_MIN && 2102 flow->drv_type < MLX5_FLOW_TYPE_MAX); 2103 flow->queue = (void *)(flow + 1); 2104 LIST_INIT(&flow->dev_flows); 2105 if (rss && rss->types) { 2106 unsigned int graph_root; 2107 2108 graph_root = find_graph_root(items, rss->level); 2109 ret = rte_flow_expand_rss(buf, sizeof(expand_buffer.buffer), 2110 items, rss->types, 2111 mlx5_support_expansion, 2112 graph_root); 2113 assert(ret > 0 && 2114 (unsigned int)ret < sizeof(expand_buffer.buffer)); 2115 } else { 2116 buf->entries = 1; 2117 buf->entry[0].pattern = (void *)(uintptr_t)items; 2118 } 2119 for (i = 0; i < buf->entries; ++i) { 2120 dev_flow = flow_drv_prepare(flow, attr, buf->entry[i].pattern, 2121 actions, error); 2122 if (!dev_flow) 2123 goto error; 2124 dev_flow->flow = flow; 2125 LIST_INSERT_HEAD(&flow->dev_flows, dev_flow, next); 2126 ret = flow_drv_translate(dev, dev_flow, attr, 2127 buf->entry[i].pattern, 2128 actions, error); 2129 if (ret < 0) 2130 goto error; 2131 } 2132 if (dev->data->dev_started) { 2133 ret = flow_drv_apply(dev, flow, error); 2134 if (ret < 0) 2135 goto error; 2136 } 2137 TAILQ_INSERT_TAIL(list, flow, next); 2138 flow_rxq_flags_set(dev, flow); 2139 return flow; 2140 error: 2141 ret = rte_errno; /* Save rte_errno before cleanup. */ 2142 assert(flow); 2143 flow_drv_destroy(dev, flow); 2144 rte_free(flow); 2145 rte_errno = ret; /* Restore rte_errno. */ 2146 return NULL; 2147 } 2148 2149 /** 2150 * Create a flow. 2151 * 2152 * @see rte_flow_create() 2153 * @see rte_flow_ops 2154 */ 2155 struct rte_flow * 2156 mlx5_flow_create(struct rte_eth_dev *dev, 2157 const struct rte_flow_attr *attr, 2158 const struct rte_flow_item items[], 2159 const struct rte_flow_action actions[], 2160 struct rte_flow_error *error) 2161 { 2162 struct mlx5_priv *priv = dev->data->dev_private; 2163 2164 return flow_list_create(dev, &priv->flows, 2165 attr, items, actions, error); 2166 } 2167 2168 /** 2169 * Destroy a flow in a list. 2170 * 2171 * @param dev 2172 * Pointer to Ethernet device. 2173 * @param list 2174 * Pointer to a TAILQ flow list. 2175 * @param[in] flow 2176 * Flow to destroy. 2177 */ 2178 static void 2179 flow_list_destroy(struct rte_eth_dev *dev, struct mlx5_flows *list, 2180 struct rte_flow *flow) 2181 { 2182 /* 2183 * Update RX queue flags only if port is started, otherwise it is 2184 * already clean. 2185 */ 2186 if (dev->data->dev_started) 2187 flow_rxq_flags_trim(dev, flow); 2188 flow_drv_destroy(dev, flow); 2189 TAILQ_REMOVE(list, flow, next); 2190 rte_free(flow->fdir); 2191 rte_free(flow); 2192 } 2193 2194 /** 2195 * Destroy all flows. 2196 * 2197 * @param dev 2198 * Pointer to Ethernet device. 2199 * @param list 2200 * Pointer to a TAILQ flow list. 2201 */ 2202 void 2203 mlx5_flow_list_flush(struct rte_eth_dev *dev, struct mlx5_flows *list) 2204 { 2205 while (!TAILQ_EMPTY(list)) { 2206 struct rte_flow *flow; 2207 2208 flow = TAILQ_FIRST(list); 2209 flow_list_destroy(dev, list, flow); 2210 } 2211 } 2212 2213 /** 2214 * Remove all flows. 2215 * 2216 * @param dev 2217 * Pointer to Ethernet device. 2218 * @param list 2219 * Pointer to a TAILQ flow list. 2220 */ 2221 void 2222 mlx5_flow_stop(struct rte_eth_dev *dev, struct mlx5_flows *list) 2223 { 2224 struct rte_flow *flow; 2225 2226 TAILQ_FOREACH_REVERSE(flow, list, mlx5_flows, next) 2227 flow_drv_remove(dev, flow); 2228 flow_rxq_flags_clear(dev); 2229 } 2230 2231 /** 2232 * Add all flows. 2233 * 2234 * @param dev 2235 * Pointer to Ethernet device. 2236 * @param list 2237 * Pointer to a TAILQ flow list. 2238 * 2239 * @return 2240 * 0 on success, a negative errno value otherwise and rte_errno is set. 2241 */ 2242 int 2243 mlx5_flow_start(struct rte_eth_dev *dev, struct mlx5_flows *list) 2244 { 2245 struct rte_flow *flow; 2246 struct rte_flow_error error; 2247 int ret = 0; 2248 2249 TAILQ_FOREACH(flow, list, next) { 2250 ret = flow_drv_apply(dev, flow, &error); 2251 if (ret < 0) 2252 goto error; 2253 flow_rxq_flags_set(dev, flow); 2254 } 2255 return 0; 2256 error: 2257 ret = rte_errno; /* Save rte_errno before cleanup. */ 2258 mlx5_flow_stop(dev, list); 2259 rte_errno = ret; /* Restore rte_errno. */ 2260 return -rte_errno; 2261 } 2262 2263 /** 2264 * Verify the flow list is empty 2265 * 2266 * @param dev 2267 * Pointer to Ethernet device. 2268 * 2269 * @return the number of flows not released. 2270 */ 2271 int 2272 mlx5_flow_verify(struct rte_eth_dev *dev) 2273 { 2274 struct mlx5_priv *priv = dev->data->dev_private; 2275 struct rte_flow *flow; 2276 int ret = 0; 2277 2278 TAILQ_FOREACH(flow, &priv->flows, next) { 2279 DRV_LOG(DEBUG, "port %u flow %p still referenced", 2280 dev->data->port_id, (void *)flow); 2281 ++ret; 2282 } 2283 return ret; 2284 } 2285 2286 /** 2287 * Enable a control flow configured from the control plane. 2288 * 2289 * @param dev 2290 * Pointer to Ethernet device. 2291 * @param eth_spec 2292 * An Ethernet flow spec to apply. 2293 * @param eth_mask 2294 * An Ethernet flow mask to apply. 2295 * @param vlan_spec 2296 * A VLAN flow spec to apply. 2297 * @param vlan_mask 2298 * A VLAN flow mask to apply. 2299 * 2300 * @return 2301 * 0 on success, a negative errno value otherwise and rte_errno is set. 2302 */ 2303 int 2304 mlx5_ctrl_flow_vlan(struct rte_eth_dev *dev, 2305 struct rte_flow_item_eth *eth_spec, 2306 struct rte_flow_item_eth *eth_mask, 2307 struct rte_flow_item_vlan *vlan_spec, 2308 struct rte_flow_item_vlan *vlan_mask) 2309 { 2310 struct mlx5_priv *priv = dev->data->dev_private; 2311 const struct rte_flow_attr attr = { 2312 .ingress = 1, 2313 .priority = MLX5_FLOW_PRIO_RSVD, 2314 }; 2315 struct rte_flow_item items[] = { 2316 { 2317 .type = RTE_FLOW_ITEM_TYPE_ETH, 2318 .spec = eth_spec, 2319 .last = NULL, 2320 .mask = eth_mask, 2321 }, 2322 { 2323 .type = (vlan_spec) ? RTE_FLOW_ITEM_TYPE_VLAN : 2324 RTE_FLOW_ITEM_TYPE_END, 2325 .spec = vlan_spec, 2326 .last = NULL, 2327 .mask = vlan_mask, 2328 }, 2329 { 2330 .type = RTE_FLOW_ITEM_TYPE_END, 2331 }, 2332 }; 2333 uint16_t queue[priv->reta_idx_n]; 2334 struct rte_flow_action_rss action_rss = { 2335 .func = RTE_ETH_HASH_FUNCTION_DEFAULT, 2336 .level = 0, 2337 .types = priv->rss_conf.rss_hf, 2338 .key_len = priv->rss_conf.rss_key_len, 2339 .queue_num = priv->reta_idx_n, 2340 .key = priv->rss_conf.rss_key, 2341 .queue = queue, 2342 }; 2343 struct rte_flow_action actions[] = { 2344 { 2345 .type = RTE_FLOW_ACTION_TYPE_RSS, 2346 .conf = &action_rss, 2347 }, 2348 { 2349 .type = RTE_FLOW_ACTION_TYPE_END, 2350 }, 2351 }; 2352 struct rte_flow *flow; 2353 struct rte_flow_error error; 2354 unsigned int i; 2355 2356 if (!priv->reta_idx_n || !priv->rxqs_n) { 2357 return 0; 2358 } 2359 for (i = 0; i != priv->reta_idx_n; ++i) 2360 queue[i] = (*priv->reta_idx)[i]; 2361 flow = flow_list_create(dev, &priv->ctrl_flows, 2362 &attr, items, actions, &error); 2363 if (!flow) 2364 return -rte_errno; 2365 return 0; 2366 } 2367 2368 /** 2369 * Enable a flow control configured from the control plane. 2370 * 2371 * @param dev 2372 * Pointer to Ethernet device. 2373 * @param eth_spec 2374 * An Ethernet flow spec to apply. 2375 * @param eth_mask 2376 * An Ethernet flow mask to apply. 2377 * 2378 * @return 2379 * 0 on success, a negative errno value otherwise and rte_errno is set. 2380 */ 2381 int 2382 mlx5_ctrl_flow(struct rte_eth_dev *dev, 2383 struct rte_flow_item_eth *eth_spec, 2384 struct rte_flow_item_eth *eth_mask) 2385 { 2386 return mlx5_ctrl_flow_vlan(dev, eth_spec, eth_mask, NULL, NULL); 2387 } 2388 2389 /** 2390 * Destroy a flow. 2391 * 2392 * @see rte_flow_destroy() 2393 * @see rte_flow_ops 2394 */ 2395 int 2396 mlx5_flow_destroy(struct rte_eth_dev *dev, 2397 struct rte_flow *flow, 2398 struct rte_flow_error *error __rte_unused) 2399 { 2400 struct mlx5_priv *priv = dev->data->dev_private; 2401 2402 flow_list_destroy(dev, &priv->flows, flow); 2403 return 0; 2404 } 2405 2406 /** 2407 * Destroy all flows. 2408 * 2409 * @see rte_flow_flush() 2410 * @see rte_flow_ops 2411 */ 2412 int 2413 mlx5_flow_flush(struct rte_eth_dev *dev, 2414 struct rte_flow_error *error __rte_unused) 2415 { 2416 struct mlx5_priv *priv = dev->data->dev_private; 2417 2418 mlx5_flow_list_flush(dev, &priv->flows); 2419 return 0; 2420 } 2421 2422 /** 2423 * Isolated mode. 2424 * 2425 * @see rte_flow_isolate() 2426 * @see rte_flow_ops 2427 */ 2428 int 2429 mlx5_flow_isolate(struct rte_eth_dev *dev, 2430 int enable, 2431 struct rte_flow_error *error) 2432 { 2433 struct mlx5_priv *priv = dev->data->dev_private; 2434 2435 if (dev->data->dev_started) { 2436 rte_flow_error_set(error, EBUSY, 2437 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, 2438 NULL, 2439 "port must be stopped first"); 2440 return -rte_errno; 2441 } 2442 priv->isolated = !!enable; 2443 if (enable) 2444 dev->dev_ops = &mlx5_dev_ops_isolate; 2445 else 2446 dev->dev_ops = &mlx5_dev_ops; 2447 return 0; 2448 } 2449 2450 /** 2451 * Query a flow. 2452 * 2453 * @see rte_flow_query() 2454 * @see rte_flow_ops 2455 */ 2456 static int 2457 flow_drv_query(struct rte_eth_dev *dev, 2458 struct rte_flow *flow, 2459 const struct rte_flow_action *actions, 2460 void *data, 2461 struct rte_flow_error *error) 2462 { 2463 const struct mlx5_flow_driver_ops *fops; 2464 enum mlx5_flow_drv_type ftype = flow->drv_type; 2465 2466 assert(ftype > MLX5_FLOW_TYPE_MIN && ftype < MLX5_FLOW_TYPE_MAX); 2467 fops = flow_get_drv_ops(ftype); 2468 2469 return fops->query(dev, flow, actions, data, error); 2470 } 2471 2472 /** 2473 * Query a flow. 2474 * 2475 * @see rte_flow_query() 2476 * @see rte_flow_ops 2477 */ 2478 int 2479 mlx5_flow_query(struct rte_eth_dev *dev, 2480 struct rte_flow *flow, 2481 const struct rte_flow_action *actions, 2482 void *data, 2483 struct rte_flow_error *error) 2484 { 2485 int ret; 2486 2487 ret = flow_drv_query(dev, flow, actions, data, error); 2488 if (ret < 0) 2489 return ret; 2490 return 0; 2491 } 2492 2493 /** 2494 * Convert a flow director filter to a generic flow. 2495 * 2496 * @param dev 2497 * Pointer to Ethernet device. 2498 * @param fdir_filter 2499 * Flow director filter to add. 2500 * @param attributes 2501 * Generic flow parameters structure. 2502 * 2503 * @return 2504 * 0 on success, a negative errno value otherwise and rte_errno is set. 2505 */ 2506 static int 2507 flow_fdir_filter_convert(struct rte_eth_dev *dev, 2508 const struct rte_eth_fdir_filter *fdir_filter, 2509 struct mlx5_fdir *attributes) 2510 { 2511 struct mlx5_priv *priv = dev->data->dev_private; 2512 const struct rte_eth_fdir_input *input = &fdir_filter->input; 2513 const struct rte_eth_fdir_masks *mask = 2514 &dev->data->dev_conf.fdir_conf.mask; 2515 2516 /* Validate queue number. */ 2517 if (fdir_filter->action.rx_queue >= priv->rxqs_n) { 2518 DRV_LOG(ERR, "port %u invalid queue number %d", 2519 dev->data->port_id, fdir_filter->action.rx_queue); 2520 rte_errno = EINVAL; 2521 return -rte_errno; 2522 } 2523 attributes->attr.ingress = 1; 2524 attributes->items[0] = (struct rte_flow_item) { 2525 .type = RTE_FLOW_ITEM_TYPE_ETH, 2526 .spec = &attributes->l2, 2527 .mask = &attributes->l2_mask, 2528 }; 2529 switch (fdir_filter->action.behavior) { 2530 case RTE_ETH_FDIR_ACCEPT: 2531 attributes->actions[0] = (struct rte_flow_action){ 2532 .type = RTE_FLOW_ACTION_TYPE_QUEUE, 2533 .conf = &attributes->queue, 2534 }; 2535 break; 2536 case RTE_ETH_FDIR_REJECT: 2537 attributes->actions[0] = (struct rte_flow_action){ 2538 .type = RTE_FLOW_ACTION_TYPE_DROP, 2539 }; 2540 break; 2541 default: 2542 DRV_LOG(ERR, "port %u invalid behavior %d", 2543 dev->data->port_id, 2544 fdir_filter->action.behavior); 2545 rte_errno = ENOTSUP; 2546 return -rte_errno; 2547 } 2548 attributes->queue.index = fdir_filter->action.rx_queue; 2549 /* Handle L3. */ 2550 switch (fdir_filter->input.flow_type) { 2551 case RTE_ETH_FLOW_NONFRAG_IPV4_UDP: 2552 case RTE_ETH_FLOW_NONFRAG_IPV4_TCP: 2553 case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER: 2554 attributes->l3.ipv4.hdr = (struct rte_ipv4_hdr){ 2555 .src_addr = input->flow.ip4_flow.src_ip, 2556 .dst_addr = input->flow.ip4_flow.dst_ip, 2557 .time_to_live = input->flow.ip4_flow.ttl, 2558 .type_of_service = input->flow.ip4_flow.tos, 2559 }; 2560 attributes->l3_mask.ipv4.hdr = (struct rte_ipv4_hdr){ 2561 .src_addr = mask->ipv4_mask.src_ip, 2562 .dst_addr = mask->ipv4_mask.dst_ip, 2563 .time_to_live = mask->ipv4_mask.ttl, 2564 .type_of_service = mask->ipv4_mask.tos, 2565 .next_proto_id = mask->ipv4_mask.proto, 2566 }; 2567 attributes->items[1] = (struct rte_flow_item){ 2568 .type = RTE_FLOW_ITEM_TYPE_IPV4, 2569 .spec = &attributes->l3, 2570 .mask = &attributes->l3_mask, 2571 }; 2572 break; 2573 case RTE_ETH_FLOW_NONFRAG_IPV6_UDP: 2574 case RTE_ETH_FLOW_NONFRAG_IPV6_TCP: 2575 case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER: 2576 attributes->l3.ipv6.hdr = (struct rte_ipv6_hdr){ 2577 .hop_limits = input->flow.ipv6_flow.hop_limits, 2578 .proto = input->flow.ipv6_flow.proto, 2579 }; 2580 2581 memcpy(attributes->l3.ipv6.hdr.src_addr, 2582 input->flow.ipv6_flow.src_ip, 2583 RTE_DIM(attributes->l3.ipv6.hdr.src_addr)); 2584 memcpy(attributes->l3.ipv6.hdr.dst_addr, 2585 input->flow.ipv6_flow.dst_ip, 2586 RTE_DIM(attributes->l3.ipv6.hdr.src_addr)); 2587 memcpy(attributes->l3_mask.ipv6.hdr.src_addr, 2588 mask->ipv6_mask.src_ip, 2589 RTE_DIM(attributes->l3_mask.ipv6.hdr.src_addr)); 2590 memcpy(attributes->l3_mask.ipv6.hdr.dst_addr, 2591 mask->ipv6_mask.dst_ip, 2592 RTE_DIM(attributes->l3_mask.ipv6.hdr.src_addr)); 2593 attributes->items[1] = (struct rte_flow_item){ 2594 .type = RTE_FLOW_ITEM_TYPE_IPV6, 2595 .spec = &attributes->l3, 2596 .mask = &attributes->l3_mask, 2597 }; 2598 break; 2599 default: 2600 DRV_LOG(ERR, "port %u invalid flow type%d", 2601 dev->data->port_id, fdir_filter->input.flow_type); 2602 rte_errno = ENOTSUP; 2603 return -rte_errno; 2604 } 2605 /* Handle L4. */ 2606 switch (fdir_filter->input.flow_type) { 2607 case RTE_ETH_FLOW_NONFRAG_IPV4_UDP: 2608 attributes->l4.udp.hdr = (struct rte_udp_hdr){ 2609 .src_port = input->flow.udp4_flow.src_port, 2610 .dst_port = input->flow.udp4_flow.dst_port, 2611 }; 2612 attributes->l4_mask.udp.hdr = (struct rte_udp_hdr){ 2613 .src_port = mask->src_port_mask, 2614 .dst_port = mask->dst_port_mask, 2615 }; 2616 attributes->items[2] = (struct rte_flow_item){ 2617 .type = RTE_FLOW_ITEM_TYPE_UDP, 2618 .spec = &attributes->l4, 2619 .mask = &attributes->l4_mask, 2620 }; 2621 break; 2622 case RTE_ETH_FLOW_NONFRAG_IPV4_TCP: 2623 attributes->l4.tcp.hdr = (struct rte_tcp_hdr){ 2624 .src_port = input->flow.tcp4_flow.src_port, 2625 .dst_port = input->flow.tcp4_flow.dst_port, 2626 }; 2627 attributes->l4_mask.tcp.hdr = (struct rte_tcp_hdr){ 2628 .src_port = mask->src_port_mask, 2629 .dst_port = mask->dst_port_mask, 2630 }; 2631 attributes->items[2] = (struct rte_flow_item){ 2632 .type = RTE_FLOW_ITEM_TYPE_TCP, 2633 .spec = &attributes->l4, 2634 .mask = &attributes->l4_mask, 2635 }; 2636 break; 2637 case RTE_ETH_FLOW_NONFRAG_IPV6_UDP: 2638 attributes->l4.udp.hdr = (struct rte_udp_hdr){ 2639 .src_port = input->flow.udp6_flow.src_port, 2640 .dst_port = input->flow.udp6_flow.dst_port, 2641 }; 2642 attributes->l4_mask.udp.hdr = (struct rte_udp_hdr){ 2643 .src_port = mask->src_port_mask, 2644 .dst_port = mask->dst_port_mask, 2645 }; 2646 attributes->items[2] = (struct rte_flow_item){ 2647 .type = RTE_FLOW_ITEM_TYPE_UDP, 2648 .spec = &attributes->l4, 2649 .mask = &attributes->l4_mask, 2650 }; 2651 break; 2652 case RTE_ETH_FLOW_NONFRAG_IPV6_TCP: 2653 attributes->l4.tcp.hdr = (struct rte_tcp_hdr){ 2654 .src_port = input->flow.tcp6_flow.src_port, 2655 .dst_port = input->flow.tcp6_flow.dst_port, 2656 }; 2657 attributes->l4_mask.tcp.hdr = (struct rte_tcp_hdr){ 2658 .src_port = mask->src_port_mask, 2659 .dst_port = mask->dst_port_mask, 2660 }; 2661 attributes->items[2] = (struct rte_flow_item){ 2662 .type = RTE_FLOW_ITEM_TYPE_TCP, 2663 .spec = &attributes->l4, 2664 .mask = &attributes->l4_mask, 2665 }; 2666 break; 2667 case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER: 2668 case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER: 2669 break; 2670 default: 2671 DRV_LOG(ERR, "port %u invalid flow type%d", 2672 dev->data->port_id, fdir_filter->input.flow_type); 2673 rte_errno = ENOTSUP; 2674 return -rte_errno; 2675 } 2676 return 0; 2677 } 2678 2679 #define FLOW_FDIR_CMP(f1, f2, fld) \ 2680 memcmp(&(f1)->fld, &(f2)->fld, sizeof(f1->fld)) 2681 2682 /** 2683 * Compare two FDIR flows. If items and actions are identical, the two flows are 2684 * regarded as same. 2685 * 2686 * @param dev 2687 * Pointer to Ethernet device. 2688 * @param f1 2689 * FDIR flow to compare. 2690 * @param f2 2691 * FDIR flow to compare. 2692 * 2693 * @return 2694 * Zero on match, 1 otherwise. 2695 */ 2696 static int 2697 flow_fdir_cmp(const struct mlx5_fdir *f1, const struct mlx5_fdir *f2) 2698 { 2699 if (FLOW_FDIR_CMP(f1, f2, attr) || 2700 FLOW_FDIR_CMP(f1, f2, l2) || 2701 FLOW_FDIR_CMP(f1, f2, l2_mask) || 2702 FLOW_FDIR_CMP(f1, f2, l3) || 2703 FLOW_FDIR_CMP(f1, f2, l3_mask) || 2704 FLOW_FDIR_CMP(f1, f2, l4) || 2705 FLOW_FDIR_CMP(f1, f2, l4_mask) || 2706 FLOW_FDIR_CMP(f1, f2, actions[0].type)) 2707 return 1; 2708 if (f1->actions[0].type == RTE_FLOW_ACTION_TYPE_QUEUE && 2709 FLOW_FDIR_CMP(f1, f2, queue)) 2710 return 1; 2711 return 0; 2712 } 2713 2714 /** 2715 * Search device flow list to find out a matched FDIR flow. 2716 * 2717 * @param dev 2718 * Pointer to Ethernet device. 2719 * @param fdir_flow 2720 * FDIR flow to lookup. 2721 * 2722 * @return 2723 * Pointer of flow if found, NULL otherwise. 2724 */ 2725 static struct rte_flow * 2726 flow_fdir_filter_lookup(struct rte_eth_dev *dev, struct mlx5_fdir *fdir_flow) 2727 { 2728 struct mlx5_priv *priv = dev->data->dev_private; 2729 struct rte_flow *flow = NULL; 2730 2731 assert(fdir_flow); 2732 TAILQ_FOREACH(flow, &priv->flows, next) { 2733 if (flow->fdir && !flow_fdir_cmp(flow->fdir, fdir_flow)) { 2734 DRV_LOG(DEBUG, "port %u found FDIR flow %p", 2735 dev->data->port_id, (void *)flow); 2736 break; 2737 } 2738 } 2739 return flow; 2740 } 2741 2742 /** 2743 * Add new flow director filter and store it in list. 2744 * 2745 * @param dev 2746 * Pointer to Ethernet device. 2747 * @param fdir_filter 2748 * Flow director filter to add. 2749 * 2750 * @return 2751 * 0 on success, a negative errno value otherwise and rte_errno is set. 2752 */ 2753 static int 2754 flow_fdir_filter_add(struct rte_eth_dev *dev, 2755 const struct rte_eth_fdir_filter *fdir_filter) 2756 { 2757 struct mlx5_priv *priv = dev->data->dev_private; 2758 struct mlx5_fdir *fdir_flow; 2759 struct rte_flow *flow; 2760 int ret; 2761 2762 fdir_flow = rte_zmalloc(__func__, sizeof(*fdir_flow), 0); 2763 if (!fdir_flow) { 2764 rte_errno = ENOMEM; 2765 return -rte_errno; 2766 } 2767 ret = flow_fdir_filter_convert(dev, fdir_filter, fdir_flow); 2768 if (ret) 2769 goto error; 2770 flow = flow_fdir_filter_lookup(dev, fdir_flow); 2771 if (flow) { 2772 rte_errno = EEXIST; 2773 goto error; 2774 } 2775 flow = flow_list_create(dev, &priv->flows, &fdir_flow->attr, 2776 fdir_flow->items, fdir_flow->actions, NULL); 2777 if (!flow) 2778 goto error; 2779 assert(!flow->fdir); 2780 flow->fdir = fdir_flow; 2781 DRV_LOG(DEBUG, "port %u created FDIR flow %p", 2782 dev->data->port_id, (void *)flow); 2783 return 0; 2784 error: 2785 rte_free(fdir_flow); 2786 return -rte_errno; 2787 } 2788 2789 /** 2790 * Delete specific filter. 2791 * 2792 * @param dev 2793 * Pointer to Ethernet device. 2794 * @param fdir_filter 2795 * Filter to be deleted. 2796 * 2797 * @return 2798 * 0 on success, a negative errno value otherwise and rte_errno is set. 2799 */ 2800 static int 2801 flow_fdir_filter_delete(struct rte_eth_dev *dev, 2802 const struct rte_eth_fdir_filter *fdir_filter) 2803 { 2804 struct mlx5_priv *priv = dev->data->dev_private; 2805 struct rte_flow *flow; 2806 struct mlx5_fdir fdir_flow = { 2807 .attr.group = 0, 2808 }; 2809 int ret; 2810 2811 ret = flow_fdir_filter_convert(dev, fdir_filter, &fdir_flow); 2812 if (ret) 2813 return -rte_errno; 2814 flow = flow_fdir_filter_lookup(dev, &fdir_flow); 2815 if (!flow) { 2816 rte_errno = ENOENT; 2817 return -rte_errno; 2818 } 2819 flow_list_destroy(dev, &priv->flows, flow); 2820 DRV_LOG(DEBUG, "port %u deleted FDIR flow %p", 2821 dev->data->port_id, (void *)flow); 2822 return 0; 2823 } 2824 2825 /** 2826 * Update queue for specific filter. 2827 * 2828 * @param dev 2829 * Pointer to Ethernet device. 2830 * @param fdir_filter 2831 * Filter to be updated. 2832 * 2833 * @return 2834 * 0 on success, a negative errno value otherwise and rte_errno is set. 2835 */ 2836 static int 2837 flow_fdir_filter_update(struct rte_eth_dev *dev, 2838 const struct rte_eth_fdir_filter *fdir_filter) 2839 { 2840 int ret; 2841 2842 ret = flow_fdir_filter_delete(dev, fdir_filter); 2843 if (ret) 2844 return ret; 2845 return flow_fdir_filter_add(dev, fdir_filter); 2846 } 2847 2848 /** 2849 * Flush all filters. 2850 * 2851 * @param dev 2852 * Pointer to Ethernet device. 2853 */ 2854 static void 2855 flow_fdir_filter_flush(struct rte_eth_dev *dev) 2856 { 2857 struct mlx5_priv *priv = dev->data->dev_private; 2858 2859 mlx5_flow_list_flush(dev, &priv->flows); 2860 } 2861 2862 /** 2863 * Get flow director information. 2864 * 2865 * @param dev 2866 * Pointer to Ethernet device. 2867 * @param[out] fdir_info 2868 * Resulting flow director information. 2869 */ 2870 static void 2871 flow_fdir_info_get(struct rte_eth_dev *dev, struct rte_eth_fdir_info *fdir_info) 2872 { 2873 struct rte_eth_fdir_masks *mask = 2874 &dev->data->dev_conf.fdir_conf.mask; 2875 2876 fdir_info->mode = dev->data->dev_conf.fdir_conf.mode; 2877 fdir_info->guarant_spc = 0; 2878 rte_memcpy(&fdir_info->mask, mask, sizeof(fdir_info->mask)); 2879 fdir_info->max_flexpayload = 0; 2880 fdir_info->flow_types_mask[0] = 0; 2881 fdir_info->flex_payload_unit = 0; 2882 fdir_info->max_flex_payload_segment_num = 0; 2883 fdir_info->flex_payload_limit = 0; 2884 memset(&fdir_info->flex_conf, 0, sizeof(fdir_info->flex_conf)); 2885 } 2886 2887 /** 2888 * Deal with flow director operations. 2889 * 2890 * @param dev 2891 * Pointer to Ethernet device. 2892 * @param filter_op 2893 * Operation to perform. 2894 * @param arg 2895 * Pointer to operation-specific structure. 2896 * 2897 * @return 2898 * 0 on success, a negative errno value otherwise and rte_errno is set. 2899 */ 2900 static int 2901 flow_fdir_ctrl_func(struct rte_eth_dev *dev, enum rte_filter_op filter_op, 2902 void *arg) 2903 { 2904 enum rte_fdir_mode fdir_mode = 2905 dev->data->dev_conf.fdir_conf.mode; 2906 2907 if (filter_op == RTE_ETH_FILTER_NOP) 2908 return 0; 2909 if (fdir_mode != RTE_FDIR_MODE_PERFECT && 2910 fdir_mode != RTE_FDIR_MODE_PERFECT_MAC_VLAN) { 2911 DRV_LOG(ERR, "port %u flow director mode %d not supported", 2912 dev->data->port_id, fdir_mode); 2913 rte_errno = EINVAL; 2914 return -rte_errno; 2915 } 2916 switch (filter_op) { 2917 case RTE_ETH_FILTER_ADD: 2918 return flow_fdir_filter_add(dev, arg); 2919 case RTE_ETH_FILTER_UPDATE: 2920 return flow_fdir_filter_update(dev, arg); 2921 case RTE_ETH_FILTER_DELETE: 2922 return flow_fdir_filter_delete(dev, arg); 2923 case RTE_ETH_FILTER_FLUSH: 2924 flow_fdir_filter_flush(dev); 2925 break; 2926 case RTE_ETH_FILTER_INFO: 2927 flow_fdir_info_get(dev, arg); 2928 break; 2929 default: 2930 DRV_LOG(DEBUG, "port %u unknown operation %u", 2931 dev->data->port_id, filter_op); 2932 rte_errno = EINVAL; 2933 return -rte_errno; 2934 } 2935 return 0; 2936 } 2937 2938 /** 2939 * Manage filter operations. 2940 * 2941 * @param dev 2942 * Pointer to Ethernet device structure. 2943 * @param filter_type 2944 * Filter type. 2945 * @param filter_op 2946 * Operation to perform. 2947 * @param arg 2948 * Pointer to operation-specific structure. 2949 * 2950 * @return 2951 * 0 on success, a negative errno value otherwise and rte_errno is set. 2952 */ 2953 int 2954 mlx5_dev_filter_ctrl(struct rte_eth_dev *dev, 2955 enum rte_filter_type filter_type, 2956 enum rte_filter_op filter_op, 2957 void *arg) 2958 { 2959 switch (filter_type) { 2960 case RTE_ETH_FILTER_GENERIC: 2961 if (filter_op != RTE_ETH_FILTER_GET) { 2962 rte_errno = EINVAL; 2963 return -rte_errno; 2964 } 2965 *(const void **)arg = &mlx5_flow_ops; 2966 return 0; 2967 case RTE_ETH_FILTER_FDIR: 2968 return flow_fdir_ctrl_func(dev, filter_op, arg); 2969 default: 2970 DRV_LOG(ERR, "port %u filter type (%d) not supported", 2971 dev->data->port_id, filter_type); 2972 rte_errno = ENOTSUP; 2973 return -rte_errno; 2974 } 2975 return 0; 2976 } 2977