Paths with hop_limit > 1 indicate that the connection will be routed
between IB subnets.  To support routed connections, the ib_cm requires
two paths: one from the active side to the active side router, and
a second from the passive side to the passive side router.

Modify the ib_cm interface to support multiple paths, and format the
CM REQ message with the correct passive side information.

Signed-off-by: Sean Hefty <[EMAIL PROTECTED]>
---

 drivers/infiniband/core/cm.c |   50 ++++++++++++++++++++++++------------------
 include/rdma/ib_cm.h         |    5 ++++
 2 files changed, 33 insertions(+), 22 deletions(-)

diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index 842cd0b..1e2010e 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -877,6 +877,8 @@ static void cm_format_req(struct cm_req_msg *req_msg,
                          struct cm_id_private *cm_id_priv,
                          struct ib_cm_req_param *param)
 {
+       struct ib_sa_path_rec *pri_path, *alt_path;
+
        cm_format_mad_hdr(&req_msg->hdr, CM_REQ_ATTR_ID,
                          cm_form_tid(cm_id_priv, CM_MSG_SEQUENCE_REQ));
 
@@ -900,33 +902,37 @@ static void cm_format_req(struct cm_req_msg *req_msg,
        cm_req_set_max_cm_retries(req_msg, param->max_cm_retries);
        cm_req_set_srq(req_msg, param->srq);
 
-       req_msg->primary_local_lid = param->primary_path->slid;
-       req_msg->primary_remote_lid = param->primary_path->dlid;
-       req_msg->primary_local_gid = param->primary_path->sgid;
-       req_msg->primary_remote_gid = param->primary_path->dgid;
-       cm_req_set_primary_flow_label(req_msg, param->primary_path->flow_label);
-       cm_req_set_primary_packet_rate(req_msg, param->primary_path->rate);
-       req_msg->primary_traffic_class = param->primary_path->traffic_class;
-       req_msg->primary_hop_limit = param->primary_path->hop_limit;
-       cm_req_set_primary_sl(req_msg, param->primary_path->sl);
-       cm_req_set_primary_subnet_local(req_msg, 1); /* local only... */
+       pri_path = (param->primary_path->hop_limit <= 1) ?
+                   param->primary_path : &param->primary_path[1];
+       req_msg->primary_local_lid = pri_path->slid;
+       req_msg->primary_remote_lid = pri_path->dlid;
+       req_msg->primary_local_gid = pri_path->sgid;
+       req_msg->primary_remote_gid = pri_path->dgid;
+       cm_req_set_primary_flow_label(req_msg, pri_path->flow_label);
+       cm_req_set_primary_packet_rate(req_msg, pri_path->rate);
+       req_msg->primary_traffic_class = pri_path->traffic_class;
+       req_msg->primary_hop_limit = pri_path->hop_limit;
+       cm_req_set_primary_sl(req_msg, pri_path->sl);
+       cm_req_set_primary_subnet_local(req_msg, (pri_path->hop_limit <= 1));
        cm_req_set_primary_local_ack_timeout(req_msg,
-               min(31, param->primary_path->packet_life_time + 1));
+               min(31, pri_path->packet_life_time + 1));
 
        if (param->alternate_path) {
-               req_msg->alt_local_lid = param->alternate_path->slid;
-               req_msg->alt_remote_lid = param->alternate_path->dlid;
-               req_msg->alt_local_gid = param->alternate_path->sgid;
-               req_msg->alt_remote_gid = param->alternate_path->dgid;
+               alt_path = (param->alternate_path->hop_limit <= 1) ?
+                           param->alternate_path : &param->alternate_path[1];
+               req_msg->alt_local_lid = alt_path->slid;
+               req_msg->alt_remote_lid = alt_path->dlid;
+               req_msg->alt_local_gid = alt_path->sgid;
+               req_msg->alt_remote_gid = alt_path->dgid;
                cm_req_set_alt_flow_label(req_msg,
-                                         param->alternate_path->flow_label);
-               cm_req_set_alt_packet_rate(req_msg, 
param->alternate_path->rate);
-               req_msg->alt_traffic_class = 
param->alternate_path->traffic_class;
-               req_msg->alt_hop_limit = param->alternate_path->hop_limit;
-               cm_req_set_alt_sl(req_msg, param->alternate_path->sl);
-               cm_req_set_alt_subnet_local(req_msg, 1); /* local only... */
+                                         alt_path->flow_label);
+               cm_req_set_alt_packet_rate(req_msg, alt_path->rate);
+               req_msg->alt_traffic_class = alt_path->traffic_class;
+               req_msg->alt_hop_limit = alt_path->hop_limit;
+               cm_req_set_alt_sl(req_msg, alt_path->sl);
+               cm_req_set_alt_subnet_local(req_msg, (alt_path->hop_limit <= 
1));
                cm_req_set_alt_local_ack_timeout(req_msg,
-                       min(31, param->alternate_path->packet_life_time + 1));
+                       min(31, alt_path->packet_life_time + 1));
        }
 
        if (param->private_data && param->private_data_len)
diff --git a/include/rdma/ib_cm.h b/include/rdma/ib_cm.h
index 5c07017..f715ba5 100644
--- a/include/rdma/ib_cm.h
+++ b/include/rdma/ib_cm.h
@@ -347,6 +347,11 @@ struct ib_cm_compare_data {
 int ib_cm_listen(struct ib_cm_id *cm_id, __be64 service_id, __be64 
service_mask,
                 struct ib_cm_compare_data *compare_data);
 
+/*
+ * If hop_limit > 1 or reversible = 0, then primary/alternate path fields
+ * point to an array of paths.  The first path is relative to the active
+ * side, and the second path is relative to the passive side.
+ */
 struct ib_cm_req_param {
        struct ib_sa_path_rec   *primary_path;
        struct ib_sa_path_rec   *alternate_path;

_______________________________________________
general mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to