RDMA/cma: Initialize the flow label of CM's route path record
authorMark Zhang <markz@mellanox.com>
Mon, 4 May 2020 05:19:34 +0000 (08:19 +0300)
committerJason Gunthorpe <jgg@mellanox.com>
Wed, 6 May 2020 19:51:44 +0000 (16:51 -0300)
If flow label is not set by the user or it's not IPv4, initialize it with
the cma src/dst based on the "Kernighan and Ritchie's hash function".

Link: https://lore.kernel.org/r/20200504051935.269708-5-leon@kernel.org
Signed-off-by: Mark Zhang <markz@mellanox.com>
Reviewed-by: Maor Gottlieb <maorg@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
drivers/infiniband/core/cma.c

index e8d99b71f44ac200421a222b72a09c29cd367f08..432eec472164e0d6056a2080962d06f54151f467 100644 (file)
@@ -2909,6 +2909,24 @@ static int iboe_tos_to_sl(struct net_device *ndev, int tos)
                return 0;
 }
 
+static __be32 cma_get_roce_udp_flow_label(struct rdma_id_private *id_priv)
+{
+       struct sockaddr_in6 *addr6;
+       u16 dport, sport;
+       u32 hash, fl;
+
+       addr6 = (struct sockaddr_in6 *)cma_src_addr(id_priv);
+       fl = be32_to_cpu(addr6->sin6_flowinfo) & IB_GRH_FLOWLABEL_MASK;
+       if ((cma_family(id_priv) != AF_INET6) || !fl) {
+               dport = be16_to_cpu(cma_port(cma_dst_addr(id_priv)));
+               sport = be16_to_cpu(cma_port(cma_src_addr(id_priv)));
+               hash = (u32)sport * 31 + dport;
+               fl = hash & IB_GRH_FLOWLABEL_MASK;
+       }
+
+       return cpu_to_be32(fl);
+}
+
 static int cma_resolve_iboe_route(struct rdma_id_private *id_priv)
 {
        struct rdma_route *route = &id_priv->id.route;
@@ -2975,6 +2993,11 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv)
                goto err2;
        }
 
+       if (rdma_protocol_roce_udp_encap(id_priv->id.device,
+                                        id_priv->id.port_num))
+               route->path_rec->flow_label =
+                       cma_get_roce_udp_flow_label(id_priv);
+
        cma_init_resolve_route_work(work, id_priv);
        queue_work(cma_wq, &work->work);