From patchwork Thu Feb 19 22:02:28 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Somnath Kotur X-Patchwork-Id: 5850291 Return-Path: X-Original-To: patchwork-linux-rdma@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id C7A52BF440 for ; Thu, 19 Feb 2015 05:37:43 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C68BF201F4 for ; Thu, 19 Feb 2015 05:37:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B816A200F4 for ; Thu, 19 Feb 2015 05:37:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751837AbbBSFhl (ORCPT ); Thu, 19 Feb 2015 00:37:41 -0500 Received: from cmexedge1.emulex.com ([138.239.224.99]:59793 "EHLO CMEXEDGE1.ext.emulex.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751659AbbBSFhk (ORCPT ); Thu, 19 Feb 2015 00:37:40 -0500 Received: from CMEXHTCAS2.ad.emulex.com (138.239.115.218) by CMEXEDGE1.ext.emulex.com (138.239.224.99) with Microsoft SMTP Server (TLS) id 14.3.174.1; Wed, 18 Feb 2015 21:37:41 -0800 Received: from codebrowse.emulex.com (10.192.207.129) by smtp.emulex.com (138.239.115.208) with Microsoft SMTP Server id 14.3.174.1; Wed, 18 Feb 2015 21:37:33 -0800 From: Somnath Kotur To: CC: , Somnath Kotur , Matan Barak Subject: [PATCH 13/30] IB/Core: Changes to the IB Core infrastructure for RoCEv2 support Date: Fri, 20 Feb 2015 03:32:28 +0530 X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1424383365-19337-1-git-send-email-somnath.kotur@emulex.com> References: <1424383365-19337-1-git-send-email-somnath.kotur@emulex.com> MIME-Version: 1.0 Message-ID: <097599e9-9e75-42e4-b92f-eb11823c5c29@CMEXHTCAS2.ad.emulex.com> Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org X-Spam-Status: No, score=-3.7 required=5.0 tests=BAYES_00, DATE_IN_FUTURE_12_24, RCVD_IN_DNSWL_HI,T_RP_MATCHES_RCVD,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 1. Choose sgid_index and type from all the matching entries in RDMA-CM based on hint from the IP stack. 2. Set hop_limit for the IP Packet based on above hint from IP stack 3. Define a RDMA_NETWORK enum type. Signed-off-by: Somnath Kotur Signed-off-by: Matan Barak --- drivers/infiniband/core/addr.c | 8 ++++ drivers/infiniband/core/cma.c | 10 +++++- drivers/infiniband/core/verbs.c | 70 +++++++++++++++++++++------------------ include/rdma/ib_addr.h | 1 + include/rdma/ib_verbs.h | 6 +++ 5 files changed, 62 insertions(+), 33 deletions(-) diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index 43af7f5..da24c0e 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -257,6 +257,9 @@ static int addr4_resolve(struct sockaddr_in *src_in, goto put; } + if (rt->rt_uses_gateway) + addr->network = RDMA_NETWORK_IPV4; + ret = dst_fetch_ha(&rt->dst, addr, &fl4.daddr); put: ip_rt_put(rt); @@ -271,6 +274,7 @@ static int addr6_resolve(struct sockaddr_in6 *src_in, { struct flowi6 fl6; struct dst_entry *dst; + struct rt6_info *rt; int ret; memset(&fl6, 0, sizeof fl6); @@ -282,6 +286,7 @@ static int addr6_resolve(struct sockaddr_in6 *src_in, if ((ret = dst->error)) goto put; + rt = (struct rt6_info *)dst; if (ipv6_addr_any(&fl6.saddr)) { ret = ipv6_dev_get_saddr(&init_net, ip6_dst_idev(dst)->dev, &fl6.daddr, 0, &fl6.saddr); @@ -305,6 +310,9 @@ static int addr6_resolve(struct sockaddr_in6 *src_in, goto put; } + if (rt->rt6i_flags & RTF_GATEWAY) + addr->network = RDMA_NETWORK_IPV6; + ret = dst_fetch_ha(dst, addr, &fl6.daddr); put: dst_release(dst); diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 237f2dd..50635fe 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -1952,6 +1952,7 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv) { struct rdma_route *route = &id_priv->id.route; struct rdma_addr *addr = &route->addr; + enum ib_gid_type network_gid_type; struct cma_work *work; int ret; struct net_device *ndev = NULL; @@ -1990,7 +1991,14 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv) rdma_ip2gid((struct sockaddr *)&id_priv->id.route.addr.dst_addr, &route->path_rec->dgid); - route->path_rec->hop_limit = 1; + /* Use the hint from IP Stack to select GID Type */ + network_gid_type = ib_network_to_gid_type(addr->dev_addr.network); + if (addr->dev_addr.network != RDMA_NETWORK_IB) { + route->path_rec->gid_type = network_gid_type; + route->path_rec->hop_limit = IPV6_DEFAULT_HOPLIMIT; + } else { + route->path_rec->hop_limit = 1; + } route->path_rec->reversible = 1; route->path_rec->pkey = cpu_to_be16(0xffff); route->path_rec->mtu_selector = IB_SA_EQ; diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index 0fdac14..5478c5d 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -219,37 +219,6 @@ static int ib_get_grh_header_version(const void *h) return 6; } -static int ib_get_dgid_sgid_by_grh(const void *h, - enum rdma_network_type net_type, - union ib_gid *dgid, union ib_gid *sgid) -{ - switch (net_type) { - case RDMA_NETWORK_IPV4: { - const struct iphdr *ip4h = (struct iphdr *)(h + 20); - - ipv6_addr_set_v4mapped(ip4h->daddr, (struct in6_addr *)dgid); - ipv6_addr_set_v4mapped(ip4h->saddr, (struct in6_addr *)sgid); - return 0; - } - case RDMA_NETWORK_IPV6: { - struct ipv6hdr *ip6h = (struct ipv6hdr *)h; - - memcpy(dgid, &ip6h->daddr, sizeof(*dgid)); - memcpy(sgid, &ip6h->saddr, sizeof(*sgid)); - return 0; - } - case RDMA_NETWORK_IB: { - struct ib_grh *grh = (struct ib_grh *)h; - - memcpy(dgid, &grh->dgid, sizeof(*dgid)); - memcpy(sgid, &grh->sgid, sizeof(*sgid)); - return 0; - } - } - - return -EINVAL; -} - static enum rdma_network_type ib_get_net_type_by_grh(struct ib_device *device, u8 port_num, const struct ib_grh *grh) @@ -305,6 +274,40 @@ static int get_sgid_index_from_eth(struct ib_device *device, u8 port_num, &context, gid_index); } +static int get_gids_from_grh(struct ib_grh *grh, enum rdma_network_type net_type, + union ib_gid *sgid, union ib_gid *dgid) +{ + union rdma_network_hdr *l3grh; + struct sockaddr_in src_in; + struct sockaddr_in dst_in; + __be32 src_saddr, dst_saddr; + + if (!sgid || !dgid) + return -EINVAL; + + if (net_type == RDMA_NETWORK_IPV4) { + l3grh = (union rdma_network_hdr *) + ((u8 *)grh + 20); + memcpy(&src_in.sin_addr.s_addr, + &l3grh->roce4grh.saddr, 4); + memcpy(&dst_in.sin_addr.s_addr, + &l3grh->roce4grh.daddr, 4); + src_saddr = src_in.sin_addr.s_addr; + dst_saddr = dst_in.sin_addr.s_addr; + ipv6_addr_set_v4mapped(src_saddr, + (struct in6_addr *)sgid); + ipv6_addr_set_v4mapped(dst_saddr, + (struct in6_addr *)dgid); + return 0; + } else if (net_type == RDMA_NETWORK_IPV6 || + net_type == RDMA_NETWORK_IB) { + *dgid = grh->dgid; + *sgid = grh->sgid; + return 0; + } else + return -EINVAL; +} + int ib_init_ah_from_wc(struct ib_device *device, u8 port_num, struct ib_wc *wc, struct ib_grh *grh, struct ib_ah_attr *ah_attr) { @@ -326,7 +329,7 @@ int ib_init_ah_from_wc(struct ib_device *device, u8 port_num, struct ib_wc *wc, net_type = ib_get_net_type_by_grh(device, port_num, grh); gid_type = ib_network_to_gid_type(net_type); } - ret = ib_get_dgid_sgid_by_grh(grh, net_type, &dgid, &sgid); + ret = get_gids_from_grh(grh, net_type, &sgid, &dgid); if (ret) return ret; @@ -1004,6 +1007,9 @@ int ib_resolve_eth_dmac(struct ib_qp *qp, rcu_read_unlock(); goto out; } + if (sgid_attr.gid_type == IB_GID_TYPE_ROCE_V2) + qp_attr->ah_attr.grh.hop_limit = + IPV6_DEFAULT_HOPLIMIT; dev_hold(sgid_attr.ndev); ifindex = sgid_attr.ndev->ifindex; diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h index 0dfaaa7..80afbf7 100644 --- a/include/rdma/ib_addr.h +++ b/include/rdma/ib_addr.h @@ -71,6 +71,7 @@ struct rdma_dev_addr { unsigned short dev_type; int bound_dev_if; enum rdma_transport_type transport; + enum rdma_network_type network; }; /** diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 01eaf32..fa541b9 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -51,6 +51,7 @@ #include #include #include +#include #include #include @@ -516,6 +517,11 @@ struct ib_grh { union ib_gid dgid; }; +union rdma_network_hdr { + struct ib_grh ibgrh; + struct iphdr roce4grh; +}; + enum { IB_MULTICAST_QPN = 0xffffff };