Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 81e30880 authored by Yishai Hadas's avatar Yishai Hadas Committed by Doug Ledford
Browse files

IB/mlx5: Add multicast flow steering support for underlay QP



In order to add multicast flow steering support, there is need
to block the attaching of mcg flow for underlay QP, recognize
multicast IB_FLOW_SPEC_IPV4 based on its IP and enable
creating/destroying flow for IB layer.

Signed-off-by: default avatarYishai Hadas <yishaih@mellanox.com>
Reviewed-by: default avatarMaor Gottlieb <maorg@mellanox.com>
Signed-off-by: default avatarLeon Romanovsky <leon@kernel.org>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent c2e53b2c
Loading
Loading
Loading
Loading
+31 −12
Original line number Original line Diff line number Diff line
@@ -2102,23 +2102,34 @@ static int parse_flow_attr(struct mlx5_core_dev *mdev, u32 *match_c,
 */
 */
static bool flow_is_multicast_only(struct ib_flow_attr *ib_attr)
static bool flow_is_multicast_only(struct ib_flow_attr *ib_attr)
{
{
	struct ib_flow_spec_eth *eth_spec;
	union ib_flow_spec *flow_spec;


	if (ib_attr->type != IB_FLOW_ATTR_NORMAL ||
	if (ib_attr->type != IB_FLOW_ATTR_NORMAL ||
	    ib_attr->size < sizeof(struct ib_flow_attr) +
	    sizeof(struct ib_flow_spec_eth) ||
	    ib_attr->num_of_specs < 1)
	    ib_attr->num_of_specs < 1)
		return false;
		return false;


	eth_spec = (struct ib_flow_spec_eth *)(ib_attr + 1);
	flow_spec = (union ib_flow_spec *)(ib_attr + 1);
	if (eth_spec->type != IB_FLOW_SPEC_ETH ||
	if (flow_spec->type == IB_FLOW_SPEC_IPV4) {
	    eth_spec->size != sizeof(*eth_spec))
		struct ib_flow_spec_ipv4 *ipv4_spec;

		ipv4_spec = (struct ib_flow_spec_ipv4 *)flow_spec;
		if (ipv4_is_multicast(ipv4_spec->val.dst_ip))
			return true;

		return false;
		return false;
	}

	if (flow_spec->type == IB_FLOW_SPEC_ETH) {
		struct ib_flow_spec_eth *eth_spec;


		eth_spec = (struct ib_flow_spec_eth *)flow_spec;
		return is_multicast_ether_addr(eth_spec->mask.dst_mac) &&
		return is_multicast_ether_addr(eth_spec->mask.dst_mac) &&
		       is_multicast_ether_addr(eth_spec->val.dst_mac);
		       is_multicast_ether_addr(eth_spec->val.dst_mac);
	}
	}


	return false;
}

static bool is_valid_ethertype(struct mlx5_core_dev *mdev,
static bool is_valid_ethertype(struct mlx5_core_dev *mdev,
			       const struct ib_flow_attr *flow_attr,
			       const struct ib_flow_attr *flow_attr,
			       bool check_inner)
			       bool check_inner)
@@ -2594,8 +2605,14 @@ static struct ib_flow *mlx5_ib_create_flow(struct ib_qp *qp,
static int mlx5_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
static int mlx5_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
{
{
	struct mlx5_ib_dev *dev = to_mdev(ibqp->device);
	struct mlx5_ib_dev *dev = to_mdev(ibqp->device);
	struct mlx5_ib_qp *mqp = to_mqp(ibqp);
	int err;
	int err;


	if (mqp->flags & MLX5_IB_QP_UNDERLAY) {
		mlx5_ib_dbg(dev, "Attaching a multi cast group to underlay QP is not supported\n");
		return -EOPNOTSUPP;
	}

	err = mlx5_core_attach_mcg(dev->mdev, gid, ibqp->qp_num);
	err = mlx5_core_attach_mcg(dev->mdev, gid, ibqp->qp_num);
	if (err)
	if (err)
		mlx5_ib_warn(dev, "failed attaching QPN 0x%x, MGID %pI6\n",
		mlx5_ib_warn(dev, "failed attaching QPN 0x%x, MGID %pI6\n",
@@ -3941,18 +3958,20 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
			(1ull << IB_USER_VERBS_CMD_CLOSE_XRCD);
			(1ull << IB_USER_VERBS_CMD_CLOSE_XRCD);
	}
	}


	if (mlx5_ib_port_link_layer(&dev->ib_dev, 1) ==
	    IB_LINK_LAYER_ETHERNET) {
	dev->ib_dev.create_flow	= mlx5_ib_create_flow;
	dev->ib_dev.create_flow	= mlx5_ib_create_flow;
	dev->ib_dev.destroy_flow = mlx5_ib_destroy_flow;
	dev->ib_dev.destroy_flow = mlx5_ib_destroy_flow;
	dev->ib_dev.uverbs_ex_cmd_mask |=
			(1ull << IB_USER_VERBS_EX_CMD_CREATE_FLOW) |
			(1ull << IB_USER_VERBS_EX_CMD_DESTROY_FLOW);

	if (mlx5_ib_port_link_layer(&dev->ib_dev, 1) ==
	    IB_LINK_LAYER_ETHERNET) {
		dev->ib_dev.create_wq	 = mlx5_ib_create_wq;
		dev->ib_dev.create_wq	 = mlx5_ib_create_wq;
		dev->ib_dev.modify_wq	 = mlx5_ib_modify_wq;
		dev->ib_dev.modify_wq	 = mlx5_ib_modify_wq;
		dev->ib_dev.destroy_wq	 = mlx5_ib_destroy_wq;
		dev->ib_dev.destroy_wq	 = mlx5_ib_destroy_wq;
		dev->ib_dev.create_rwq_ind_table = mlx5_ib_create_rwq_ind_table;
		dev->ib_dev.create_rwq_ind_table = mlx5_ib_create_rwq_ind_table;
		dev->ib_dev.destroy_rwq_ind_table = mlx5_ib_destroy_rwq_ind_table;
		dev->ib_dev.destroy_rwq_ind_table = mlx5_ib_destroy_rwq_ind_table;
		dev->ib_dev.uverbs_ex_cmd_mask |=
		dev->ib_dev.uverbs_ex_cmd_mask |=
			(1ull << IB_USER_VERBS_EX_CMD_CREATE_FLOW) |
			(1ull << IB_USER_VERBS_EX_CMD_DESTROY_FLOW) |
			(1ull << IB_USER_VERBS_EX_CMD_CREATE_WQ) |
			(1ull << IB_USER_VERBS_EX_CMD_CREATE_WQ) |
			(1ull << IB_USER_VERBS_EX_CMD_MODIFY_WQ) |
			(1ull << IB_USER_VERBS_EX_CMD_MODIFY_WQ) |
			(1ull << IB_USER_VERBS_EX_CMD_DESTROY_WQ) |
			(1ull << IB_USER_VERBS_EX_CMD_DESTROY_WQ) |