RDMA/cma: Remove padding arrays by using struct sockaddr_storage

There are a few places where the RDMA CM code handles IPv6 by doing

struct sockaddr addr;
u8 pad[sizeof(struct sockaddr_in6) -
sizeof(struct sockaddr)];

This is fragile and ugly; handle this in a better way with just

struct sockaddr_storage addr;

[ Also roll in patch from Aleksey Senin <alekseys@voltaire.com> to
switch to struct sockaddr_storage and get rid of padding arrays in
struct rdma_addr. ]

Signed-off-by: Roland Dreier <rolandd@cisco.com>

+26 -33
+18 -19
drivers/infiniband/core/cma.c
··· 155 155 } multicast; 156 156 struct list_head list; 157 157 void *context; 158 - struct sockaddr addr; 159 - u8 pad[sizeof(struct sockaddr_in6) - 160 - sizeof(struct sockaddr)]; 158 + struct sockaddr_storage addr; 161 159 }; 162 160 163 161 struct cma_work { ··· 784 786 cma_cancel_route(id_priv); 785 787 break; 786 788 case CMA_LISTEN: 787 - if (cma_any_addr(&id_priv->id.route.addr.src_addr) && 788 - !id_priv->cma_dev) 789 + if (cma_any_addr((struct sockaddr *) &id_priv->id.route.addr.src_addr) 790 + && !id_priv->cma_dev) 789 791 cma_cancel_listens(id_priv); 790 792 break; 791 793 default: ··· 1024 1026 rt->path_rec[1] = *ib_event->param.req_rcvd.alternate_path; 1025 1027 1026 1028 ib_addr_set_dgid(&rt->addr.dev_addr, &rt->path_rec[0].dgid); 1027 - ret = rdma_translate_ip(&id->route.addr.src_addr, 1029 + ret = rdma_translate_ip((struct sockaddr *) &id->route.addr.src_addr, 1028 1030 &id->route.addr.dev_addr); 1029 1031 if (ret) 1030 1032 goto destroy_id; ··· 1062 1064 cma_save_net_info(&id->route.addr, &listen_id->route.addr, 1063 1065 ip_ver, port, src, dst); 1064 1066 1065 - ret = rdma_translate_ip(&id->route.addr.src_addr, 1067 + ret = rdma_translate_ip((struct sockaddr *) &id->route.addr.src_addr, 1066 1068 &id->route.addr.dev_addr); 1067 1069 if (ret) 1068 1070 goto err; ··· 1375 1377 if (IS_ERR(id_priv->cm_id.ib)) 1376 1378 return PTR_ERR(id_priv->cm_id.ib); 1377 1379 1378 - addr = &id_priv->id.route.addr.src_addr; 1380 + addr = (struct sockaddr *) &id_priv->id.route.addr.src_addr; 1379 1381 svc_id = cma_get_service_id(id_priv->id.ps, addr); 1380 1382 if (cma_any_addr(addr)) 1381 1383 ret = ib_cm_listen(id_priv->cm_id.ib, svc_id, 0, NULL); ··· 1441 1443 1442 1444 dev_id_priv->state = CMA_ADDR_BOUND; 1443 1445 memcpy(&id->route.addr.src_addr, &id_priv->id.route.addr.src_addr, 1444 - ip_addr_size(&id_priv->id.route.addr.src_addr)); 1446 + ip_addr_size((struct sockaddr *) &id_priv->id.route.addr.src_addr)); 1445 1447 1446 1448 cma_attach_to_dev(dev_id_priv, cma_dev); 1447 1449 list_add_tail(&dev_id_priv->listen_list, &id_priv->listen_list); ··· 1561 1563 path_rec.pkey = cpu_to_be16(ib_addr_get_pkey(&addr->dev_addr)); 1562 1564 path_rec.numb_path = 1; 1563 1565 path_rec.reversible = 1; 1564 - path_rec.service_id = cma_get_service_id(id_priv->id.ps, &addr->dst_addr); 1566 + path_rec.service_id = cma_get_service_id(id_priv->id.ps, 1567 + (struct sockaddr *) &addr->dst_addr); 1565 1568 1566 1569 comp_mask = IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID | 1567 1570 IB_SA_PATH_REC_PKEY | IB_SA_PATH_REC_NUMB_PATH | 1568 1571 IB_SA_PATH_REC_REVERSIBLE | IB_SA_PATH_REC_SERVICE_ID; 1569 1572 1570 - if (addr->src_addr.sa_family == AF_INET) { 1573 + if (addr->src_addr.ss_family == AF_INET) { 1571 1574 path_rec.qos_class = cpu_to_be16((u16) id_priv->tos); 1572 1575 comp_mask |= IB_SA_PATH_REC_QOS_CLASS; 1573 1576 } else { ··· 1847 1848 ib_addr_get_sgid(&id_priv->id.route.addr.dev_addr, &gid); 1848 1849 ib_addr_set_dgid(&id_priv->id.route.addr.dev_addr, &gid); 1849 1850 1850 - if (cma_zero_addr(&id_priv->id.route.addr.src_addr)) { 1851 + if (cma_zero_addr((struct sockaddr *) &id_priv->id.route.addr.src_addr)) { 1851 1852 src_in = (struct sockaddr_in *)&id_priv->id.route.addr.src_addr; 1852 1853 dst_in = (struct sockaddr_in *)&id_priv->id.route.addr.dst_addr; 1853 1854 src_in->sin_family = dst_in->sin_family; ··· 1896 1897 if (cma_any_addr(dst_addr)) 1897 1898 ret = cma_resolve_loopback(id_priv); 1898 1899 else 1899 - ret = rdma_resolve_ip(&addr_client, &id->route.addr.src_addr, 1900 + ret = rdma_resolve_ip(&addr_client, (struct sockaddr *) &id->route.addr.src_addr, 1900 1901 dst_addr, &id->route.addr.dev_addr, 1901 1902 timeout_ms, addr_handler, id_priv); 1902 1903 if (ret) ··· 2020 2021 * We don't support binding to any address if anyone is bound to 2021 2022 * a specific address on the same port. 2022 2023 */ 2023 - if (cma_any_addr(&id_priv->id.route.addr.src_addr)) 2024 + if (cma_any_addr((struct sockaddr *) &id_priv->id.route.addr.src_addr)) 2024 2025 return -EADDRNOTAVAIL; 2025 2026 2026 2027 hlist_for_each_entry(cur_id, node, &bind_list->owners, node) { 2027 - if (cma_any_addr(&cur_id->id.route.addr.src_addr)) 2028 + if (cma_any_addr((struct sockaddr *) &cur_id->id.route.addr.src_addr)) 2028 2029 return -EADDRNOTAVAIL; 2029 2030 2030 2031 cur_sin = (struct sockaddr_in *) &cur_id->id.route.addr.src_addr; ··· 2059 2060 } 2060 2061 2061 2062 mutex_lock(&lock); 2062 - if (cma_any_port(&id_priv->id.route.addr.src_addr)) 2063 + if (cma_any_port((struct sockaddr *) &id_priv->id.route.addr.src_addr)) 2063 2064 ret = cma_alloc_any_port(ps, id_priv); 2064 2065 else 2065 2066 ret = cma_use_port(ps, id_priv); ··· 2231 2232 2232 2233 req.path = route->path_rec; 2233 2234 req.service_id = cma_get_service_id(id_priv->id.ps, 2234 - &route->addr.dst_addr); 2235 + (struct sockaddr *) &route->addr.dst_addr); 2235 2236 req.timeout_ms = 1 << (CMA_CM_RESPONSE_TIMEOUT - 8); 2236 2237 req.max_cm_retries = CMA_MAX_CM_RETRIES; 2237 2238 ··· 2282 2283 req.alternate_path = &route->path_rec[1]; 2283 2284 2284 2285 req.service_id = cma_get_service_id(id_priv->id.ps, 2285 - &route->addr.dst_addr); 2286 + (struct sockaddr *) &route->addr.dst_addr); 2286 2287 req.qp_num = id_priv->qp_num; 2287 2288 req.qp_type = IB_QPT_RC; 2288 2289 req.starting_psn = id_priv->seq_num; ··· 2666 2667 if (ret) 2667 2668 return ret; 2668 2669 2669 - cma_set_mgid(id_priv, &mc->addr, &rec.mgid); 2670 + cma_set_mgid(id_priv, (struct sockaddr *) &mc->addr, &rec.mgid); 2670 2671 if (id_priv->id.ps == RDMA_PS_UDP) 2671 2672 rec.qkey = cpu_to_be32(RDMA_UDP_QKEY); 2672 2673 ib_addr_get_sgid(dev_addr, &rec.port_gid);
+6 -8
drivers/infiniband/core/ucma.c
··· 81 81 82 82 u64 uid; 83 83 struct list_head list; 84 - struct sockaddr addr; 85 - u8 pad[sizeof(struct sockaddr_in6) - 86 - sizeof(struct sockaddr)]; 84 + struct sockaddr_storage addr; 87 85 }; 88 86 89 87 struct ucma_event { ··· 601 603 return PTR_ERR(ctx); 602 604 603 605 memset(&resp, 0, sizeof resp); 604 - addr = &ctx->cm_id->route.addr.src_addr; 606 + addr = (struct sockaddr *) &ctx->cm_id->route.addr.src_addr; 605 607 memcpy(&resp.src_addr, addr, addr->sa_family == AF_INET ? 606 608 sizeof(struct sockaddr_in) : 607 609 sizeof(struct sockaddr_in6)); 608 - addr = &ctx->cm_id->route.addr.dst_addr; 610 + addr = (struct sockaddr *) &ctx->cm_id->route.addr.dst_addr; 609 611 memcpy(&resp.dst_addr, addr, addr->sa_family == AF_INET ? 610 612 sizeof(struct sockaddr_in) : 611 613 sizeof(struct sockaddr_in6)); ··· 911 913 912 914 mc->uid = cmd.uid; 913 915 memcpy(&mc->addr, &cmd.addr, sizeof cmd.addr); 914 - ret = rdma_join_multicast(ctx->cm_id, &mc->addr, mc); 916 + ret = rdma_join_multicast(ctx->cm_id, (struct sockaddr *) &mc->addr, mc); 915 917 if (ret) 916 918 goto err2; 917 919 ··· 927 929 return 0; 928 930 929 931 err3: 930 - rdma_leave_multicast(ctx->cm_id, &mc->addr); 932 + rdma_leave_multicast(ctx->cm_id, (struct sockaddr *) &mc->addr); 931 933 ucma_cleanup_mc_events(mc); 932 934 err2: 933 935 mutex_lock(&mut); ··· 973 975 goto out; 974 976 } 975 977 976 - rdma_leave_multicast(mc->ctx->cm_id, &mc->addr); 978 + rdma_leave_multicast(mc->ctx->cm_id, (struct sockaddr *) &mc->addr); 977 979 mutex_lock(&mc->ctx->file->mut); 978 980 ucma_cleanup_mc_events(mc); 979 981 list_del(&mc->list);
+2 -6
include/rdma/rdma_cm.h
··· 71 71 }; 72 72 73 73 struct rdma_addr { 74 - struct sockaddr src_addr; 75 - u8 src_pad[sizeof(struct sockaddr_in6) - 76 - sizeof(struct sockaddr)]; 77 - struct sockaddr dst_addr; 78 - u8 dst_pad[sizeof(struct sockaddr_in6) - 79 - sizeof(struct sockaddr)]; 74 + struct sockaddr_storage src_addr; 75 + struct sockaddr_storage dst_addr; 80 76 struct rdma_dev_addr dev_addr; 81 77 }; 82 78