Provide support to specify a type of service for a communication
identifier.  A new function call is used when dealing with IPv4
addresses.  For IPv6 addresses, the ToS is specified through the
traffic class and flow label fields in the sockaddr_in6 structure.

Signed-off-by: Sean Hefty <[EMAIL PROTECTED]>
---
Minor compile fix-up added.  I incorrectly had the fix included with the
4th patch of this series, rather than with this one, where it belongs.
I removed the mistake from the 4th patch before it was posted.

 drivers/infiniband/core/cma.c |   37 +++++++++++++++++++++++++++++++------
 include/rdma/rdma_cm.h        |   14 ++++++++++++++
 2 files changed, 45 insertions(+), 6 deletions(-)

diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 32a0e66..216f5a8 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -138,6 +138,7 @@ struct rdma_id_private {
        u32                     qkey;
        u32                     qp_num;
        u8                      srq;
+       u8                      tos;
 };
 
 struct cma_multicast {
@@ -1474,6 +1475,15 @@ err:
 }
 EXPORT_SYMBOL(rdma_listen);
 
+void rdma_set_service_type(struct rdma_cm_id *id, int tos)
+{
+       struct rdma_id_private *id_priv;
+
+       id_priv = container_of(id, struct rdma_id_private, id);
+       id_priv->tos = (u8) tos;
+}
+EXPORT_SYMBOL(rdma_set_service_type);
+
 static void cma_query_handler(int status, struct ib_sa_path_rec *path_rec,
                              void *context)
 {
@@ -1500,6 +1510,8 @@ static int cma_query_ib_route(struct rdma_id_private 
*id_priv, int
timeout_ms,
 {
        struct rdma_dev_addr *addr = &id_priv->id.route.addr.dev_addr;
        struct ib_sa_path_rec path_rec;
+       ib_sa_comp_mask comp_mask;
+       struct sockaddr_in6 *sin6;
 
        memset(&path_rec, 0, sizeof path_rec);
        ib_addr_get_sgid(addr, &path_rec.sgid);
@@ -1508,13 +1520,26 @@ static int cma_query_ib_route(struct rdma_id_private 
*id_priv, int
timeout_ms,
        path_rec.numb_path = 1;
        path_rec.reversible = 1;
 
+       comp_mask = IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID |
+                   IB_SA_PATH_REC_PKEY | IB_SA_PATH_REC_NUMB_PATH |
+                   IB_SA_PATH_REC_REVERSIBLE;
+
+       if (id_priv->id.route.addr.src_addr.sa_family == AF_INET) {
+               path_rec.qos_class = cpu_to_be16((u16) id_priv->tos);
+               comp_mask |= IB_SA_PATH_REC_QOS_CLASS;
+       } else {
+               sin6 = (struct sockaddr_in6 *) &id_priv->id.route.addr.src_addr;
+               path_rec.flow_label = sin6->sin6_flowinfo;
+               path_rec.traffic_class = (u8) (be32_to_cpu(sin6->sin6_flowinfo) 
>> 20);
+               comp_mask |= IB_SA_PATH_REC_FLOW_LABEL |
+                            IB_SA_PATH_REC_TRAFFIC_CLASS;
+       }
+
        id_priv->query_id = ib_sa_path_rec_get(&sa_client, id_priv->id.device,
-                               id_priv->id.port_num, &path_rec,
-                               IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID |
-                               IB_SA_PATH_REC_PKEY | IB_SA_PATH_REC_NUMB_PATH |
-                               IB_SA_PATH_REC_REVERSIBLE,
-                               timeout_ms, GFP_KERNEL,
-                               cma_query_handler, work, &id_priv->query);
+                                              id_priv->id.port_num, &path_rec,
+                                              comp_mask, timeout_ms,
+                                              GFP_KERNEL, cma_query_handler,
+                                              work, &id_priv->query);
 
        return (id_priv->query_id < 0) ? id_priv->query_id : 0;
 }
diff --git a/include/rdma/rdma_cm.h b/include/rdma/rdma_cm.h
index 2d6a770..010f876 100644
--- a/include/rdma/rdma_cm.h
+++ b/include/rdma/rdma_cm.h
@@ -314,4 +314,18 @@ int rdma_join_multicast(struct rdma_cm_id *id, struct 
sockaddr *addr,
  */
 void rdma_leave_multicast(struct rdma_cm_id *id, struct sockaddr *addr);
 
+/**
+ * rdma_set_service_type - Set the type of service associated with a
+ *   connection identifier.
+ * @id: Communication identifier to associated with service type.
+ * @tos: Type of service.
+ *
+ * The type of service is interpretted as a differentiated service
+ * field (RFC 2474).  The service type should be specified before
+ * performing route resolution, as existing communication on the
+ * connection identifier may be unaffected.  The type of service
+ * requested may not be supported by the network to all destinations.
+ */
+void rdma_set_service_type(struct rdma_cm_id *id, int tos);
+
 #endif /* RDMA_CM_H */

_______________________________________________
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