@@ -78,7 +78,8 @@ enum {
RDMA_SQSIZE,
RDMA_RQSIZE,
RDMA_INLINE,
- RDMA_IOMAPSIZE
+ RDMA_IOMAPSIZE,
+ RDMA_ROUTE
};
int rsetsockopt(int socket, int level, int optname,
@@ -329,6 +329,8 @@ struct rsocket {
long fd_flags;
uint64_t so_opts;
uint64_t ipv6_opts;
+ void *optval;
+ size_t optlen;
int state;
int cq_armed;
int retries;
@@ -1243,13 +1245,26 @@ resolve_addr:
rs->retries = 0;
resolve_route:
to = 1000 << rs->retries++;
- ret = rdma_resolve_route(rs->cm_id, to);
- if (!ret)
- goto do_connect;
+ if (rs->optval) {
+ ret = rdma_set_option(rs->cm_id, RDMA_OPTION_IB,
+ RDMA_OPTION_IB_PATH, rs->optval,
+ rs->optlen);
+ free(rs->optval);
+ rs->optval = NULL;
+ if (!ret) {
+ rs->state = rs_resolving_route;
+ goto resolving_route;
+ }
+ } else {
+ ret = rdma_resolve_route(rs->cm_id, to);
+ if (!ret)
+ goto do_connect;
+ }
if (errno == EAGAIN || errno == EWOULDBLOCK)
rs->state = rs_resolving_route;
break;
case rs_resolving_route:
+resolving_route:
ret = ucma_complete(rs->cm_id);
if (ret) {
if (errno == ETIMEDOUT && rs->retries <= RS_CONN_RETRIES)
@@ -3312,6 +3327,15 @@ int rsetsockopt(int socket, int level, int optname,
rs->target_iomap_size = (uint16_t) rs_scale_to_value(
(uint8_t) rs_value_to_scale(*(int *) optval, 8), 8);
break;
+ case RDMA_ROUTE:
+ if ((rs->optval = calloc(optlen, 1))) {
+ memcpy(rs->optval, optval, optlen);
+ rs->optlen = optlen;
+ ret = 0;
+ } else {
+ ret = ERR(ENOMEM);
+ }
+ break;
default:
break;
}