RDMA requires the user to allocate hardware resources before
establishing a connection.  To support this, the user must know
the source address that the connection will use to reach the
remote endpoint.  Modify rdma_getaddrinfo to determine an
appropriate source address based on the specified destination,
when a source address is not given.

Signed-off-by: Sean Hefty <sean.he...@intel.com>
---

 src/addrinfo.c |   60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 60 insertions(+), 0 deletions(-)

diff --git a/src/addrinfo.c b/src/addrinfo.c
index 15ae071..dfaf9d5 100644
--- a/src/addrinfo.c
+++ b/src/addrinfo.c
@@ -39,6 +39,7 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netdb.h>
+#include <unistd.h>
 
 #include "cma.h"
 #include <rdma/rdma_cma.h>
@@ -129,6 +130,48 @@ static int ucma_convert_to_rai(struct rdma_addrinfo *rai, 
struct addrinfo *ai)
        return 0;
 }
 
+static int ucma_resolve_src(struct rdma_addrinfo *rai)
+{
+       struct sockaddr *addr;
+       socklen_t len;
+       int ret, s;
+
+       s = socket(rai->ai_family, SOCK_DGRAM, IPPROTO_UDP);
+       if (s < 0)
+               return s;
+
+       ret = connect(s, rai->ai_dst_addr, rai->ai_dst_len);
+       if (ret)
+               goto err1;
+
+       addr = zalloc(rai->ai_dst_len);
+       if (!addr) {
+               ret = ERR(ENOMEM);
+               goto err1;
+       }
+
+       len = rai->ai_dst_len;
+       ret = getsockname(s, addr, &len);
+       if (ret)
+               goto err2;
+
+       if (addr->sa_family == AF_INET)
+               ((struct sockaddr_in *) addr)->sin_port = 0;
+       else
+               ((struct sockaddr_in6 *) addr)->sin6_port = 0;
+       rai->ai_src_addr = addr;
+       rai->ai_src_len = len;
+
+       close(s);
+       return 0;
+
+err2:
+       free(addr);
+err1:
+       close(s);
+       return ret;
+}
+
 int rdma_getaddrinfo(char *node, char *service,
                     struct rdma_addrinfo *hints,
                     struct rdma_addrinfo **res)
@@ -159,6 +202,23 @@ int rdma_getaddrinfo(char *node, char *service,
        if (ret)
                goto err2;
 
+       if (!rai->ai_src_len) {
+               if (hints && hints->ai_src_len) {
+                       rai->ai_src_addr = zalloc(hints->ai_src_len);
+                       if (!rai->ai_src_addr) {
+                               ret = ERR(ENOMEM);
+                               goto err2;
+                       }
+                       memcpy(rai->ai_src_addr, hints->ai_src_addr,
+                              hints->ai_src_len);
+                       rai->ai_src_len = hints->ai_src_len;
+               } else {
+                       ret = ucma_resolve_src(rai);
+                       if (ret)
+                               goto err2;
+               }
+       }
+
        freeaddrinfo(ai);
        *res = rai;
        return 0;



--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to