Commit c5c4e40e authored by Don Hiatt's avatar Don Hiatt Committed by Jason Gunthorpe

IB/CM: Change sgid to IB GID when handling CM request

ULPs do not understand OPA GIDs and will reject CM requests
if the sgid does not match the local_gid. In order to
fix this behavior we convert the OPA GID back to an IB GID.
Reviewed-by: default avatarIra Weiny <ira.weiny@intel.com>
Signed-off-by: default avatarDon Hiatt <don.hiatt@intel.com>
Signed-off-by: default avatarDennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent 3cafad43
...@@ -1560,6 +1560,37 @@ static u16 cm_get_bth_pkey(struct cm_work *work) ...@@ -1560,6 +1560,37 @@ static u16 cm_get_bth_pkey(struct cm_work *work)
return pkey; return pkey;
} }
/**
* Convert OPA SGID to IB SGID
* ULPs (such as IPoIB) do not understand OPA GIDs and will
* reject them as the local_gid will not match the sgid. Therefore,
* change the pathrec's SGID to an IB SGID.
*
* @work: Work completion
* @path: Path record
*/
static void cm_opa_to_ib_sgid(struct cm_work *work,
struct sa_path_rec *path)
{
struct ib_device *dev = work->port->cm_dev->ib_device;
struct ib_gid_attr gid_attr;
u8 port_num = work->port->port_num;
if (rdma_cap_opa_ah(dev, port_num) &&
(ib_is_opa_gid(&path->sgid))) {
union ib_gid sgid;
if (ib_get_cached_gid(dev, port_num, 0,
&sgid, &gid_attr)) {
dev_warn(&dev->dev,
"Error updating sgid in CM request\n");
return;
}
path->sgid = sgid;
}
}
static void cm_format_req_event(struct cm_work *work, static void cm_format_req_event(struct cm_work *work,
struct cm_id_private *cm_id_priv, struct cm_id_private *cm_id_priv,
struct ib_cm_id *listen_id) struct ib_cm_id *listen_id)
...@@ -1573,10 +1604,13 @@ static void cm_format_req_event(struct cm_work *work, ...@@ -1573,10 +1604,13 @@ static void cm_format_req_event(struct cm_work *work,
param->bth_pkey = cm_get_bth_pkey(work); param->bth_pkey = cm_get_bth_pkey(work);
param->port = cm_id_priv->av.port->port_num; param->port = cm_id_priv->av.port->port_num;
param->primary_path = &work->path[0]; param->primary_path = &work->path[0];
if (cm_req_has_alt_path(req_msg)) cm_opa_to_ib_sgid(work, param->primary_path);
if (cm_req_has_alt_path(req_msg)) {
param->alternate_path = &work->path[1]; param->alternate_path = &work->path[1];
else cm_opa_to_ib_sgid(work, param->alternate_path);
} else {
param->alternate_path = NULL; param->alternate_path = NULL;
}
param->remote_ca_guid = req_msg->local_ca_guid; param->remote_ca_guid = req_msg->local_ca_guid;
param->remote_qkey = be32_to_cpu(req_msg->local_qkey); param->remote_qkey = be32_to_cpu(req_msg->local_qkey);
param->remote_qpn = be32_to_cpu(cm_req_get_local_qpn(req_msg)); param->remote_qpn = be32_to_cpu(cm_req_get_local_qpn(req_msg));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment