From 7f0fbf984a5140efb76f93fef1f35202c617249d Mon Sep 17 00:00:00 2001 From: Hal Rosenstock Date: Thu, 19 Jun 2014 11:54:11 -0400 Subject: [PATCH] rsocket: Add support for RDMA_ROUTE option in rgetsockopt Create as many ibv_path_data structs from the RDMA route ibv_sa_path_rec struct for the rsocket based on how many fit into the supplied buffer. Signed-off-by: Hal Rosenstock Signed-off-by: Sean Hefty --- src/rsocket.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/src/rsocket.c b/src/rsocket.c index 0e5635f0..947e678b 100644 --- a/src/rsocket.c +++ b/src/rsocket.c @@ -3500,11 +3500,38 @@ int rsetsockopt(int socket, int level, int optname, return ret; } +static void rs_convert_sa_path(struct ibv_sa_path_rec *sa_path, + struct ibv_path_data *path_data) +{ + uint32_t fl_hop; + + memset(path_data, 0, sizeof(*path_data)); + path_data->path.dgid = sa_path->dgid; + path_data->path.sgid = sa_path->sgid; + path_data->path.dlid = sa_path->dlid; + path_data->path.slid = sa_path->slid; + fl_hop = ntohl(sa_path->flow_label) << 8; + path_data->path.flowlabel_hoplimit = htonl(fl_hop) | sa_path->hop_limit; + path_data->path.tclass = sa_path->traffic_class; + path_data->path.reversible_numpath = sa_path->reversible << 7 | 1; + path_data->path.pkey = sa_path->pkey; + path_data->path.qosclass_sl = sa_path->sl; + path_data->path.mtu = sa_path->mtu | 2 << 6; /* exactly */ + path_data->path.rate = sa_path->rate | 2 << 6; + path_data->path.packetlifetime = sa_path->packet_life_time | 2 << 6; + path_data->flags= sa_path->preference; +} + int rgetsockopt(int socket, int level, int optname, void *optval, socklen_t *optlen) { struct rsocket *rs; + void *opt; + struct ibv_sa_path_rec *path_rec; + struct ibv_path_data path_data; + socklen_t len; int ret = 0; + int num_paths; rs = idm_lookup(&idm, socket); if (!rs) @@ -3597,6 +3624,36 @@ int rgetsockopt(int socket, int level, int optname, *((int *) optval) = rs->target_iomap_size; *optlen = sizeof(int); break; + case RDMA_ROUTE: + if (rs->optval) { + if (*optlen < rs->optlen) { + ret = EINVAL; + } else { + memcpy(rs->optval, optval, rs->optlen); + *optlen = rs->optlen; + } + } else { + if (*optlen < sizeof(path_data)) { + ret = EINVAL; + } else { + len = 0; + opt = optval; + path_rec = rs->cm_id->route.path_rec; + num_paths = 0; + while (len + sizeof(path_data) <= *optlen && + num_paths < rs->cm_id->route.num_paths) { + rs_convert_sa_path(path_rec, &path_data); + memcpy(opt, &path_data, sizeof(path_data)); + len += sizeof(path_data); + opt += sizeof(path_data); + path_rec++; + num_paths++; + } + *optlen = len; + ret = 0; + } + } + break; default: ret = ENOTSUP; break; -- 2.46.0