aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/core/cma.c170
1 files changed, 105 insertions, 65 deletions
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 9664131c4eeb..249944c2c537 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -870,107 +870,138 @@ static inline int cma_any_port(struct sockaddr *addr)
870 return !cma_port(addr); 870 return !cma_port(addr);
871} 871}
872 872
873static void cma_save_ib_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_id, 873static void cma_save_ib_info(struct sockaddr *src_addr,
874 struct sockaddr *dst_addr,
875 struct rdma_cm_id *listen_id,
874 struct ib_sa_path_rec *path) 876 struct ib_sa_path_rec *path)
875{ 877{
876 struct sockaddr_ib *listen_ib, *ib; 878 struct sockaddr_ib *listen_ib, *ib;
877 879
878 listen_ib = (struct sockaddr_ib *) &listen_id->route.addr.src_addr; 880 listen_ib = (struct sockaddr_ib *) &listen_id->route.addr.src_addr;
879 ib = (struct sockaddr_ib *) &id->route.addr.src_addr; 881 if (src_addr) {
880 ib->sib_family = listen_ib->sib_family; 882 ib = (struct sockaddr_ib *)src_addr;
881 if (path) { 883 ib->sib_family = AF_IB;
882 ib->sib_pkey = path->pkey; 884 if (path) {
883 ib->sib_flowinfo = path->flow_label; 885 ib->sib_pkey = path->pkey;
884 memcpy(&ib->sib_addr, &path->sgid, 16); 886 ib->sib_flowinfo = path->flow_label;
885 } else { 887 memcpy(&ib->sib_addr, &path->sgid, 16);
886 ib->sib_pkey = listen_ib->sib_pkey; 888 ib->sib_sid = path->service_id;
887 ib->sib_flowinfo = listen_ib->sib_flowinfo; 889 ib->sib_scope_id = 0;
888 ib->sib_addr = listen_ib->sib_addr; 890 } else {
889 } 891 ib->sib_pkey = listen_ib->sib_pkey;
890 ib->sib_sid = listen_ib->sib_sid; 892 ib->sib_flowinfo = listen_ib->sib_flowinfo;
891 ib->sib_sid_mask = cpu_to_be64(0xffffffffffffffffULL); 893 ib->sib_addr = listen_ib->sib_addr;
892 ib->sib_scope_id = listen_ib->sib_scope_id; 894 ib->sib_sid = listen_ib->sib_sid;
893 895 ib->sib_scope_id = listen_ib->sib_scope_id;
894 if (path) { 896 }
895 ib = (struct sockaddr_ib *) &id->route.addr.dst_addr; 897 ib->sib_sid_mask = cpu_to_be64(0xffffffffffffffffULL);
896 ib->sib_family = listen_ib->sib_family; 898 }
897 ib->sib_pkey = path->pkey; 899 if (dst_addr) {
898 ib->sib_flowinfo = path->flow_label; 900 ib = (struct sockaddr_ib *)dst_addr;
899 memcpy(&ib->sib_addr, &path->dgid, 16); 901 ib->sib_family = AF_IB;
902 if (path) {
903 ib->sib_pkey = path->pkey;
904 ib->sib_flowinfo = path->flow_label;
905 memcpy(&ib->sib_addr, &path->dgid, 16);
906 }
900 } 907 }
901} 908}
902 909
903static __be16 ss_get_port(const struct sockaddr_storage *ss) 910static void cma_save_ip4_info(struct sockaddr *src_addr,
904{ 911 struct sockaddr *dst_addr,
905 if (ss->ss_family == AF_INET) 912 struct cma_hdr *hdr,
906 return ((struct sockaddr_in *)ss)->sin_port; 913 __be16 local_port)
907 else if (ss->ss_family == AF_INET6)
908 return ((struct sockaddr_in6 *)ss)->sin6_port;
909 BUG();
910}
911
912static void cma_save_ip4_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_id,
913 struct cma_hdr *hdr)
914{ 914{
915 struct sockaddr_in *ip4; 915 struct sockaddr_in *ip4;
916 916
917 ip4 = (struct sockaddr_in *) &id->route.addr.src_addr; 917 if (src_addr) {
918 ip4->sin_family = AF_INET; 918 ip4 = (struct sockaddr_in *)src_addr;
919 ip4->sin_addr.s_addr = hdr->dst_addr.ip4.addr; 919 ip4->sin_family = AF_INET;
920 ip4->sin_port = ss_get_port(&listen_id->route.addr.src_addr); 920 ip4->sin_addr.s_addr = hdr->dst_addr.ip4.addr;
921 ip4->sin_port = local_port;
922 }
921 923
922 ip4 = (struct sockaddr_in *) &id->route.addr.dst_addr; 924 if (dst_addr) {
923 ip4->sin_family = AF_INET; 925 ip4 = (struct sockaddr_in *)dst_addr;
924 ip4->sin_addr.s_addr = hdr->src_addr.ip4.addr; 926 ip4->sin_family = AF_INET;
925 ip4->sin_port = hdr->port; 927 ip4->sin_addr.s_addr = hdr->src_addr.ip4.addr;
928 ip4->sin_port = hdr->port;
929 }
926} 930}
927 931
928static void cma_save_ip6_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_id, 932static void cma_save_ip6_info(struct sockaddr *src_addr,
929 struct cma_hdr *hdr) 933 struct sockaddr *dst_addr,
934 struct cma_hdr *hdr,
935 __be16 local_port)
930{ 936{
931 struct sockaddr_in6 *ip6; 937 struct sockaddr_in6 *ip6;
932 938
933 ip6 = (struct sockaddr_in6 *) &id->route.addr.src_addr; 939 if (src_addr) {
934 ip6->sin6_family = AF_INET6; 940 ip6 = (struct sockaddr_in6 *)src_addr;
935 ip6->sin6_addr = hdr->dst_addr.ip6; 941 ip6->sin6_family = AF_INET6;
936 ip6->sin6_port = ss_get_port(&listen_id->route.addr.src_addr); 942 ip6->sin6_addr = hdr->dst_addr.ip6;
943 ip6->sin6_port = local_port;
944 }
937 945
938 ip6 = (struct sockaddr_in6 *) &id->route.addr.dst_addr; 946 if (dst_addr) {
939 ip6->sin6_family = AF_INET6; 947 ip6 = (struct sockaddr_in6 *)dst_addr;
940 ip6->sin6_addr = hdr->src_addr.ip6; 948 ip6->sin6_family = AF_INET6;
941 ip6->sin6_port = hdr->port; 949 ip6->sin6_addr = hdr->src_addr.ip6;
950 ip6->sin6_port = hdr->port;
951 }
942} 952}
943 953
944static int cma_save_net_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_id, 954static u16 cma_port_from_service_id(__be64 service_id)
945 struct ib_cm_event *ib_event)
946{ 955{
947 struct cma_hdr *hdr; 956 return (u16)be64_to_cpu(service_id);
957}
948 958
949 if (listen_id->route.addr.src_addr.ss_family == AF_IB) { 959static int cma_save_ip_info(struct sockaddr *src_addr,
950 if (ib_event->event == IB_CM_REQ_RECEIVED) 960 struct sockaddr *dst_addr,
951 cma_save_ib_info(id, listen_id, ib_event->param.req_rcvd.primary_path); 961 struct ib_cm_event *ib_event,
952 else if (ib_event->event == IB_CM_SIDR_REQ_RECEIVED) 962 __be64 service_id)
953 cma_save_ib_info(id, listen_id, NULL); 963{
954 return 0; 964 struct cma_hdr *hdr;
955 } 965 __be16 port;
956 966
957 hdr = ib_event->private_data; 967 hdr = ib_event->private_data;
958 if (hdr->cma_version != CMA_VERSION) 968 if (hdr->cma_version != CMA_VERSION)
959 return -EINVAL; 969 return -EINVAL;
960 970
971 port = htons(cma_port_from_service_id(service_id));
972
961 switch (cma_get_ip_ver(hdr)) { 973 switch (cma_get_ip_ver(hdr)) {
962 case 4: 974 case 4:
963 cma_save_ip4_info(id, listen_id, hdr); 975 cma_save_ip4_info(src_addr, dst_addr, hdr, port);
964 break; 976 break;
965 case 6: 977 case 6:
966 cma_save_ip6_info(id, listen_id, hdr); 978 cma_save_ip6_info(src_addr, dst_addr, hdr, port);
967 break; 979 break;
968 default: 980 default:
969 return -EINVAL; 981 return -EINVAL;
970 } 982 }
983
971 return 0; 984 return 0;
972} 985}
973 986
987static int cma_save_net_info(struct sockaddr *src_addr,
988 struct sockaddr *dst_addr,
989 struct rdma_cm_id *listen_id,
990 struct ib_cm_event *ib_event,
991 sa_family_t sa_family, __be64 service_id)
992{
993 if (sa_family == AF_IB) {
994 if (ib_event->event == IB_CM_REQ_RECEIVED)
995 cma_save_ib_info(src_addr, dst_addr, listen_id,
996 ib_event->param.req_rcvd.primary_path);
997 else if (ib_event->event == IB_CM_SIDR_REQ_RECEIVED)
998 cma_save_ib_info(src_addr, dst_addr, listen_id, NULL);
999 return 0;
1000 }
1001
1002 return cma_save_ip_info(src_addr, dst_addr, ib_event, service_id);
1003}
1004
974static inline int cma_user_data_offset(struct rdma_id_private *id_priv) 1005static inline int cma_user_data_offset(struct rdma_id_private *id_priv)
975{ 1006{
976 return cma_family(id_priv) == AF_IB ? 0 : sizeof(struct cma_hdr); 1007 return cma_family(id_priv) == AF_IB ? 0 : sizeof(struct cma_hdr);
@@ -1221,6 +1252,9 @@ static struct rdma_id_private *cma_new_conn_id(struct rdma_cm_id *listen_id,
1221 struct rdma_id_private *id_priv; 1252 struct rdma_id_private *id_priv;
1222 struct rdma_cm_id *id; 1253 struct rdma_cm_id *id;
1223 struct rdma_route *rt; 1254 struct rdma_route *rt;
1255 const sa_family_t ss_family = listen_id->route.addr.src_addr.ss_family;
1256 const __be64 service_id =
1257 ib_event->param.req_rcvd.primary_path->service_id;
1224 int ret; 1258 int ret;
1225 1259
1226 id = rdma_create_id(listen_id->event_handler, listen_id->context, 1260 id = rdma_create_id(listen_id->event_handler, listen_id->context,
@@ -1229,7 +1263,9 @@ static struct rdma_id_private *cma_new_conn_id(struct rdma_cm_id *listen_id,
1229 return NULL; 1263 return NULL;
1230 1264
1231 id_priv = container_of(id, struct rdma_id_private, id); 1265 id_priv = container_of(id, struct rdma_id_private, id);
1232 if (cma_save_net_info(id, listen_id, ib_event)) 1266 if (cma_save_net_info((struct sockaddr *)&id->route.addr.src_addr,
1267 (struct sockaddr *)&id->route.addr.dst_addr,
1268 listen_id, ib_event, ss_family, service_id))
1233 goto err; 1269 goto err;
1234 1270
1235 rt = &id->route; 1271 rt = &id->route;
@@ -1267,6 +1303,7 @@ static struct rdma_id_private *cma_new_udp_id(struct rdma_cm_id *listen_id,
1267{ 1303{
1268 struct rdma_id_private *id_priv; 1304 struct rdma_id_private *id_priv;
1269 struct rdma_cm_id *id; 1305 struct rdma_cm_id *id;
1306 const sa_family_t ss_family = listen_id->route.addr.src_addr.ss_family;
1270 int ret; 1307 int ret;
1271 1308
1272 id = rdma_create_id(listen_id->event_handler, listen_id->context, 1309 id = rdma_create_id(listen_id->event_handler, listen_id->context,
@@ -1275,7 +1312,10 @@ static struct rdma_id_private *cma_new_udp_id(struct rdma_cm_id *listen_id,
1275 return NULL; 1312 return NULL;
1276 1313
1277 id_priv = container_of(id, struct rdma_id_private, id); 1314 id_priv = container_of(id, struct rdma_id_private, id);
1278 if (cma_save_net_info(id, listen_id, ib_event)) 1315 if (cma_save_net_info((struct sockaddr *)&id->route.addr.src_addr,
1316 (struct sockaddr *)&id->route.addr.dst_addr,
1317 listen_id, ib_event, ss_family,
1318 ib_event->param.sidr_req_rcvd.service_id))
1279 goto err; 1319 goto err;
1280 1320
1281 if (!cma_any_addr((struct sockaddr *) &id->route.addr.src_addr)) { 1321 if (!cma_any_addr((struct sockaddr *) &id->route.addr.src_addr)) {