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