aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorJason Gunthorpe <jgunthorpe@obsidianresearch.com>2015-04-20 16:01:11 -0400
committerDoug Ledford <dledford@redhat.com>2015-05-05 09:18:01 -0400
commit285214409a9e5fceba2215461b4682b6069d8e77 (patch)
tree438d9df8a3e9a5a37fa9843da83a61f81976e0e7 /drivers/infiniband
parent5ebe6afaf0057ac3eaeb98defd5456894b446d22 (diff)
RDMA/CMA: Canonize IPv4 on IPV6 sockets properly
When accepting a new IPv4 connect to an IPv6 socket, the CMA tries to canonize the address family to IPv4, but does not properly process the listening sockaddr to get the listening port, and does not properly set the address family of the canonized sockaddr. Fixes: e51060f08a61 ("IB: IP address based RDMA connection manager") Cc: <stable@vger.kernel.org> Reported-By: Yotam Kenneth <yotamke@mellanox.com> Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> Tested-by: Haggai Eran <haggaie@mellanox.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/core/cma.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index d570030d899c..06441a43c3aa 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -859,19 +859,27 @@ static void cma_save_ib_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_id
859 memcpy(&ib->sib_addr, &path->dgid, 16); 859 memcpy(&ib->sib_addr, &path->dgid, 16);
860} 860}
861 861
862static __be16 ss_get_port(const struct sockaddr_storage *ss)
863{
864 if (ss->ss_family == AF_INET)
865 return ((struct sockaddr_in *)ss)->sin_port;
866 else if (ss->ss_family == AF_INET6)
867 return ((struct sockaddr_in6 *)ss)->sin6_port;
868 BUG();
869}
870
862static void cma_save_ip4_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_id, 871static void cma_save_ip4_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_id,
863 struct cma_hdr *hdr) 872 struct cma_hdr *hdr)
864{ 873{
865 struct sockaddr_in *listen4, *ip4; 874 struct sockaddr_in *ip4;
866 875
867 listen4 = (struct sockaddr_in *) &listen_id->route.addr.src_addr;
868 ip4 = (struct sockaddr_in *) &id->route.addr.src_addr; 876 ip4 = (struct sockaddr_in *) &id->route.addr.src_addr;
869 ip4->sin_family = listen4->sin_family; 877 ip4->sin_family = AF_INET;
870 ip4->sin_addr.s_addr = hdr->dst_addr.ip4.addr; 878 ip4->sin_addr.s_addr = hdr->dst_addr.ip4.addr;
871 ip4->sin_port = listen4->sin_port; 879 ip4->sin_port = ss_get_port(&listen_id->route.addr.src_addr);
872 880
873 ip4 = (struct sockaddr_in *) &id->route.addr.dst_addr; 881 ip4 = (struct sockaddr_in *) &id->route.addr.dst_addr;
874 ip4->sin_family = listen4->sin_family; 882 ip4->sin_family = AF_INET;
875 ip4->sin_addr.s_addr = hdr->src_addr.ip4.addr; 883 ip4->sin_addr.s_addr = hdr->src_addr.ip4.addr;
876 ip4->sin_port = hdr->port; 884 ip4->sin_port = hdr->port;
877} 885}
@@ -879,16 +887,15 @@ static void cma_save_ip4_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_i
879static void cma_save_ip6_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_id, 887static void cma_save_ip6_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_id,
880 struct cma_hdr *hdr) 888 struct cma_hdr *hdr)
881{ 889{
882 struct sockaddr_in6 *listen6, *ip6; 890 struct sockaddr_in6 *ip6;
883 891
884 listen6 = (struct sockaddr_in6 *) &listen_id->route.addr.src_addr;
885 ip6 = (struct sockaddr_in6 *) &id->route.addr.src_addr; 892 ip6 = (struct sockaddr_in6 *) &id->route.addr.src_addr;
886 ip6->sin6_family = listen6->sin6_family; 893 ip6->sin6_family = AF_INET6;
887 ip6->sin6_addr = hdr->dst_addr.ip6; 894 ip6->sin6_addr = hdr->dst_addr.ip6;
888 ip6->sin6_port = listen6->sin6_port; 895 ip6->sin6_port = ss_get_port(&listen_id->route.addr.src_addr);
889 896
890 ip6 = (struct sockaddr_in6 *) &id->route.addr.dst_addr; 897 ip6 = (struct sockaddr_in6 *) &id->route.addr.dst_addr;
891 ip6->sin6_family = listen6->sin6_family; 898 ip6->sin6_family = AF_INET6;
892 ip6->sin6_addr = hdr->src_addr.ip6; 899 ip6->sin6_addr = hdr->src_addr.ip6;
893 ip6->sin6_port = hdr->port; 900 ip6->sin6_port = hdr->port;
894} 901}