Set underlay QPN as part of flow rule when it's applicable. There is one root flow table in the NIC RX namespace and all the underlay QPs steer the traffic to this flow table. In order to prevent QP to get traffic which is not target to its underlay QP, we need to set the underlay QP number as part of the steering matching. Note: When multicast traffic is sent the QPN filtering is done by the firmware as some early step. Adding the QPN match on the flow table entry is wrong as by that time the target QPN holds the multicast address (e.g. FF(s)) and it won't match.
Unified · Split
| @@ -2125,7 +2125,7 @@ static int parse_flow_attr(struct mlx5_core_dev *mdev, u32 *match_c, · 2124 unmodified lines | ||
| 2125 | 2125 | * it won't fall into the multicast flow steering table and this rule |
| 2126 | 2126 | * could steal other multicast packets. |
| 2127 | 2127 | */ |
| 2128 | −static bool flow_is_multicast_only(struct ib_flow_attr *ib_attr) | |
| 2128 | +static bool flow_is_multicast_only(const struct ib_flow_attr *ib_attr) | |
| 2129 | 2129 | { |
| 2130 | 2130 | union ib_flow_spec *flow_spec; |
| 2131 | 2131 | |
| @@ -2337,10 +2337,31 @@ static struct mlx5_ib_flow_prio *get_flow_table(struct mlx5_ib_dev *dev, · 205 unmodified lines | ||
| 2337 | 2337 | return err ? ERR_PTR(err) : prio; |
| 2338 | 2338 | } |
| 2339 | 2339 | |
| 2340 | −static struct mlx5_ib_flow_handler *create_flow_rule(struct mlx5_ib_dev *dev, | |
| 2341 | − struct mlx5_ib_flow_prio *ft_prio, | |
| 2342 | − const struct ib_flow_attr *flow_attr, | |
| 2343 | − struct mlx5_flow_destination *dst) | |
| 2340 | +static void set_underlay_qp(struct mlx5_ib_dev *dev, | |
| 2341 | + struct mlx5_flow_spec *spec, | |
| 2342 | + u32 underlay_qpn) | |
| 2343 | +{ | |
| 2344 | + void *misc_params_c = MLX5_ADDR_OF(fte_match_param, | |
| 2345 | + spec->match_criteria, | |
| 2346 | + misc_parameters); | |
| 2347 | + void *misc_params_v = MLX5_ADDR_OF(fte_match_param, spec->match_value, | |
| 2348 | + misc_parameters); | |
| 2349 | + | |
| 2350 | + if (underlay_qpn && | |
| 2351 | + MLX5_CAP_FLOWTABLE_NIC_RX(dev->mdev, | |
| 2352 | + ft_field_support.bth_dst_qp)) { | |
| 2353 | + MLX5_SET(fte_match_set_misc, | |
| 2354 | + misc_params_v, bth_dst_qp, underlay_qpn); | |
| 2355 | + MLX5_SET(fte_match_set_misc, | |
| 2356 | + misc_params_c, bth_dst_qp, 0xffffff); | |
| 2357 | + } | |
| 2358 | +} | |
| 2359 | + | |
| 2360 | +static struct mlx5_ib_flow_handler *_create_flow_rule(struct mlx5_ib_dev *dev, | |
| 2361 | + struct mlx5_ib_flow_prio *ft_prio, | |
| 2362 | + const struct ib_flow_attr *flow_attr, | |
| 2363 | + struct mlx5_flow_destination *dst, | |
| 2364 | + u32 underlay_qpn) | |
| 2344 | 2365 | { |
| 2345 | 2366 | struct mlx5_flow_table *ft = ft_prio->flow_table; |
| 2346 | 2367 | struct mlx5_ib_flow_handler *handler; |
| @@ -2376,6 +2397,9 @@ static struct mlx5_ib_flow_handler *create_flow_rule(struct mlx5_ib_dev *dev, · 29 unmodified lines | ||
| 2376 | 2397 | ib_flow += ((union ib_flow_spec *)ib_flow)->size; |
| 2377 | 2398 | } |
| 2378 | 2399 | |
| 2400 | + if (!flow_is_multicast_only(flow_attr)) | |
| 2401 | + set_underlay_qp(dev, spec, underlay_qpn); | |
| 2402 | + | |
| 2379 | 2403 | spec->match_criteria_enable = get_match_criteria_enable(spec->match_criteria); |
| 2380 | 2404 | if (is_drop) { |
| 2381 | 2405 | flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP; |
| @@ -2415,6 +2439,14 @@ free: · 33 unmodified lines | ||
| 2415 | 2439 | return err ? ERR_PTR(err) : handler; |
| 2416 | 2440 | } |
| 2417 | 2441 | |
| 2442 | +static struct mlx5_ib_flow_handler *create_flow_rule(struct mlx5_ib_dev *dev, | |
| 2443 | + struct mlx5_ib_flow_prio *ft_prio, | |
| 2444 | + const struct ib_flow_attr *flow_attr, | |
| 2445 | + struct mlx5_flow_destination *dst) | |
| 2446 | +{ | |
| 2447 | + return _create_flow_rule(dev, ft_prio, flow_attr, dst, 0); | |
| 2448 | +} | |
| 2449 | + | |
| 2418 | 2450 | static struct mlx5_ib_flow_handler *create_dont_trap_rule(struct mlx5_ib_dev *dev, |
| 2419 | 2451 | struct mlx5_ib_flow_prio *ft_prio, |
| 2420 | 2452 | struct ib_flow_attr *flow_attr, |
| @@ -2551,6 +2583,7 @@ static struct ib_flow *mlx5_ib_create_flow(struct ib_qp *qp, · 130 unmodified lines | ||
| 2551 | 2583 | struct mlx5_ib_flow_prio *ft_prio_tx = NULL; |
| 2552 | 2584 | struct mlx5_ib_flow_prio *ft_prio; |
| 2553 | 2585 | int err; |
| 2586 | + int underlay_qpn; | |
| 2554 | 2587 | |
| 2555 | 2588 | if (flow_attr->priority > MLX5_IB_FLOW_LAST_PRIO) |
| 2556 | 2589 | return ERR_PTR(-ENOMEM); |
| @@ -2591,8 +2624,10 @@ static struct ib_flow *mlx5_ib_create_flow(struct ib_qp *qp, · 34 unmodified lines | ||
| 2591 | 2624 | handler = create_dont_trap_rule(dev, ft_prio, |
| 2592 | 2625 | flow_attr, dst); |
| 2593 | 2626 | } else { |
| 2594 | − handler = create_flow_rule(dev, ft_prio, flow_attr, | |
| 2595 | − dst); | |
| 2627 | + underlay_qpn = (mqp->flags & MLX5_IB_QP_UNDERLAY) ? | |
| 2628 | + mqp->underlay_qpn : 0; | |
| 2629 | + handler = _create_flow_rule(dev, ft_prio, flow_attr, | |
| 2630 | + dst, underlay_qpn); | |
| 2596 | 2631 | } |
| 2597 | 2632 | } else if (flow_attr->type == IB_FLOW_ATTR_ALL_DEFAULT || |
| 2598 | 2633 | flow_attr->type == IB_FLOW_ATTR_MC_DEFAULT) { |
| @@ -295,8 +295,10 @@ struct mlx5_ifc_flow_table_fields_supported_bits { · 294 unmodified lines | ||
| 295 | 295 | u8 inner_tcp_dport[0x1]; |
| 296 | 296 | u8 inner_tcp_flags[0x1]; |
| 297 | 297 | u8 reserved_at_37[0x9]; |
| 298 | + u8 reserved_at_40[0x1a]; | |
| 299 | + u8 bth_dst_qp[0x1]; | |
| 298 | 300 | |
| 299 | − u8 reserved_at_40[0x40]; | |
| 301 | + u8 reserved_at_5b[0x25]; | |
| 300 | 302 | }; |
| 301 | 303 | |
| 302 | 304 | struct mlx5_ifc_flow_table_prop_layout_bits { |
| @@ -432,7 +434,9 @@ struct mlx5_ifc_fte_match_set_misc_bits { · 129 unmodified lines | ||
| 432 | 434 | u8 reserved_at_100[0xc]; |
| 433 | 435 | u8 inner_ipv6_flow_label[0x14]; |
| 434 | 436 | |
| 435 | − u8 reserved_at_120[0xe0]; | |
| 437 | + u8 reserved_at_120[0x28]; | |
| 438 | + u8 bth_dst_qp[0x18]; | |
| 439 | + u8 reserved_at_160[0xa0]; | |
| 436 | 440 | }; |
| 437 | 441 | |
| 438 | 442 | struct mlx5_ifc_cmd_pas_bits { |