IB/cm: Use the source GID index type
authorMatan Barak <matanb@mellanox.com>
Wed, 23 Dec 2015 12:56:48 +0000 (14:56 +0200)
committerDoug Ledford <dledford@redhat.com>
Wed, 23 Dec 2015 15:35:10 +0000 (10:35 -0500)
Previosuly, cm and cma modules supported only IB and RoCE v1 GID type.
In order to support multiple GID types, the gid_type is passed to
cm_init_av_by_path and stored in the path record.

The rdma cm client would use a default GID type that will be saved in
rdma_id_private.

Signed-off-by: Matan Barak <matanb@mellanox.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/core/cm.c
drivers/infiniband/core/cma.c

index d93b82fbc25b953b14bd8703e3da9bd4984a3e80..d883a322fc655827d1514429f4c0e36c2c09abab 100644 (file)
@@ -364,7 +364,7 @@ static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av)
        read_lock_irqsave(&cm.device_lock, flags);
        list_for_each_entry(cm_dev, &cm.device_list, list) {
                if (!ib_find_cached_gid(cm_dev->ib_device, &path->sgid,
-                                       IB_GID_TYPE_IB, ndev, &p, NULL)) {
+                                       path->gid_type, ndev, &p, NULL)) {
                        port = cm_dev->port[p-1];
                        break;
                }
@@ -1600,6 +1600,8 @@ static int cm_req_handler(struct cm_work *work)
        struct ib_cm_id *cm_id;
        struct cm_id_private *cm_id_priv, *listen_cm_id_priv;
        struct cm_req_msg *req_msg;
+       union ib_gid gid;
+       struct ib_gid_attr gid_attr;
        int ret;
 
        req_msg = (struct cm_req_msg *)work->mad_recv_wc->recv_buf.mad;
@@ -1639,11 +1641,24 @@ static int cm_req_handler(struct cm_work *work)
        cm_format_paths_from_req(req_msg, &work->path[0], &work->path[1]);
 
        memcpy(work->path[0].dmac, cm_id_priv->av.ah_attr.dmac, ETH_ALEN);
-       ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av);
+       ret = ib_get_cached_gid(work->port->cm_dev->ib_device,
+                               work->port->port_num,
+                               cm_id_priv->av.ah_attr.grh.sgid_index,
+                               &gid, &gid_attr);
+       if (!ret) {
+               if (gid_attr.ndev)
+                       dev_put(gid_attr.ndev);
+               work->path[0].gid_type = gid_attr.gid_type;
+               ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av);
+       }
        if (ret) {
-               ib_get_cached_gid(work->port->cm_dev->ib_device,
-                                 work->port->port_num, 0, &work->path[0].sgid,
-                                 NULL);
+               int err = ib_get_cached_gid(work->port->cm_dev->ib_device,
+                                           work->port->port_num, 0,
+                                           &work->path[0].sgid,
+                                           &gid_attr);
+               if (!err && gid_attr.ndev)
+                       dev_put(gid_attr.ndev);
+               work->path[0].gid_type = gid_attr.gid_type;
                ib_send_cm_rej(cm_id, IB_CM_REJ_INVALID_GID,
                               &work->path[0].sgid, sizeof work->path[0].sgid,
                               NULL, 0);
index 2637ebfd17848b211e40383be73542f9fb00f83f..446323a9d38fb620643bc624a4ff4887739d96be 100644 (file)
@@ -228,6 +228,7 @@ struct rdma_id_private {
        u8                      tos;
        u8                      reuseaddr;
        u8                      afonly;
+       enum ib_gid_type        gid_type;
 };
 
 struct cma_multicast {
@@ -2314,6 +2315,7 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv)
                ndev = dev_get_by_index(&init_net, addr->dev_addr.bound_dev_if);
                route->path_rec->net = &init_net;
                route->path_rec->ifindex = addr->dev_addr.bound_dev_if;
+               route->path_rec->gid_type = id_priv->gid_type;
        }
        if (!ndev) {
                ret = -ENODEV;