Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 17 Jul 2018 09:04:37 +0000 (UTC)
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r336369 - head/sys/ofed/drivers/infiniband/core
Message-ID:  <201807170904.w6H94bYX008079@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hselasky
Date: Tue Jul 17 09:04:36 2018
New Revision: 336369
URL: https://svnweb.freebsd.org/changeset/base/336369

Log:
  For multicast functions in ibcore, verify that LIDs are multicast LIDs.
  
  The Infiniband spec defines "A multicast address is defined by a
  MGID and a MLID" (section 10.5).
  
  Add check to verify that the MLID value is in the correct address
  range.
  
  RoCE Annex (A16.9.10/11) declares that during attach (detach) QP to a
  multicast group, if the QP is associated with a RoCE port, the
  multicast group MLID is unused and is ignored.
  
  During attach or detach multicast, when the QP is associated with a
  port, it is enough to check the port's link layer and validate the
  LID only if it is Infiniband. Otherwise, avoid validating the
  multicast LID.
  
  Linux commit:
  8561eae60ff9417a50fa1fb2b83ae950dc5c1e21
  5236333592244557a19694a51337df6ac018f0a7
  
  MFC after:		1 week
  Sponsored by:		Mellanox Technologies

Modified:
  head/sys/ofed/drivers/infiniband/core/ib_verbs.c

Modified: head/sys/ofed/drivers/infiniband/core/ib_verbs.c
==============================================================================
--- head/sys/ofed/drivers/infiniband/core/ib_verbs.c	Tue Jul 17 09:02:29 2018	(r336368)
+++ head/sys/ofed/drivers/infiniband/core/ib_verbs.c	Tue Jul 17 09:04:36 2018	(r336369)
@@ -1467,13 +1467,52 @@ EXPORT_SYMBOL(ib_dealloc_fmr);
 
 /* Multicast groups */
 
+static bool is_valid_mcast_lid(struct ib_qp *qp, u16 lid)
+{
+	struct ib_qp_init_attr init_attr = {};
+	struct ib_qp_attr attr = {};
+	int num_eth_ports = 0;
+	int port;
+
+	/* If QP state >= init, it is assigned to a port and we can check this
+	 * port only.
+	 */
+	if (!ib_query_qp(qp, &attr, IB_QP_STATE | IB_QP_PORT, &init_attr)) {
+		if (attr.qp_state >= IB_QPS_INIT) {
+			if (rdma_port_get_link_layer(qp->device, attr.port_num) !=
+			    IB_LINK_LAYER_INFINIBAND)
+				return true;
+			goto lid_check;
+		}
+	}
+
+	/* Can't get a quick answer, iterate over all ports */
+	for (port = 0; port < qp->device->phys_port_cnt; port++)
+		if (rdma_port_get_link_layer(qp->device, port) !=
+		    IB_LINK_LAYER_INFINIBAND)
+			num_eth_ports++;
+
+	/* If we have at lease one Ethernet port, RoCE annex declares that
+	 * multicast LID should be ignored. We can't tell at this step if the
+	 * QP belongs to an IB or Ethernet port.
+	 */
+	if (num_eth_ports)
+		return true;
+
+	/* If all the ports are IB, we can check according to IB spec. */
+lid_check:
+	return !(lid < be16_to_cpu(IB_MULTICAST_LID_BASE) ||
+		 lid == be16_to_cpu(IB_LID_PERMISSIVE));
+}
+
 int ib_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
 {
 	int ret;
 
 	if (!qp->device->attach_mcast)
 		return -ENOSYS;
-	if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD)
+	if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD ||
+	    !is_valid_mcast_lid(qp, lid))
 		return -EINVAL;
 
 	ret = qp->device->attach_mcast(qp, gid, lid);
@@ -1489,7 +1528,8 @@ int ib_detach_mcast(struct ib_qp *qp, union ib_gid *gi
 
 	if (!qp->device->detach_mcast)
 		return -ENOSYS;
-	if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD)
+	if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD ||
+	    !is_valid_mcast_lid(qp, lid))
 		return -EINVAL;
 
 	ret = qp->device->detach_mcast(qp, gid, lid);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201807170904.w6H94bYX008079>