Add a call similar to getaddrinfo for RDMA devices.

From: Sean Hefty <[email protected]>
---
 trunk/ulp/librdmacm/include/rdma/rdma_cma.h |   31 ++++
 trunk/ulp/librdmacm/src/Sources             |    3 
 trunk/ulp/librdmacm/src/addrinfo.cpp        |  211 +++++++++++++++++++++++++++
 trunk/ulp/librdmacm/src/cma_exports.src     |    2 
 4 files changed, 246 insertions(+), 1 deletions(-)
 create mode 100644 trunk/ulp/librdmacm/src/addrinfo.cpp

diff --git a/trunk/ulp/librdmacm/include/rdma/rdma_cma.h 
b/trunk/ulp/librdmacm/include/rdma/rdma_cma.h
index 294a75b..b4cda67 100644
--- a/trunk/ulp/librdmacm/include/rdma/rdma_cma.h
+++ b/trunk/ulp/librdmacm/include/rdma/rdma_cma.h
@@ -188,6 +188,26 @@ struct rdma_cm_event
        }       param;
 };
 
+#define RAI_PASSIVE            0x00000001
+
+struct rdma_addrinfo {
+       int                                             ai_flags;
+       int                                             ai_family;
+       int                                             ai_qp_type;
+       int                                             ai_port_space;
+       socklen_t                               ai_src_len;
+       socklen_t                               ai_dst_len;
+       struct sockaddr                 *ai_src_addr;
+       struct sockaddr                 *ai_dst_addr;
+       char                                    *ai_src_canonname;
+       char                                    *ai_dst_canonname;
+       size_t                                  ai_route_len;
+       void                                    *ai_route;
+       size_t                                  ai_connect_len;
+       void                                    *ai_connect;
+       struct rdma_addrinfo    *ai_next;
+};
+
 /**
  * rdma_create_event_channel - Open a channel used to report communication 
events.
  * Description:
@@ -639,6 +659,17 @@ int rdma_set_option(struct rdma_cm_id *id, int level, int 
optname,
 __declspec(dllexport)
 int rdma_migrate_id(struct rdma_cm_id *id, struct rdma_event_channel *channel);
 
+/**
+ * rdma_getaddrinfo - RDMA address and route resolution service.
+ */
+__declspec(dllexport)
+int rdma_getaddrinfo(char *node, char *service,
+                                        struct rdma_addrinfo *hints,
+                                        struct rdma_addrinfo **res);
+
+__declspec(dllexport)
+void rdma_freeaddrinfo(struct rdma_addrinfo *res);
+
 __declspec(dllexport)
 int rdmaw_wsa_errno(int wsa_err);
 
diff --git a/trunk/ulp/librdmacm/src/Sources b/trunk/ulp/librdmacm/src/Sources
index 6a8418a..4934f04 100644
--- a/trunk/ulp/librdmacm/src/Sources
+++ b/trunk/ulp/librdmacm/src/Sources
@@ -19,7 +19,8 @@ USE_MSVCRT = 1
 SOURCES =                      \
        cma.rc                  \
        cma_main.cpp    \
-       cma.cpp
+       cma.cpp                 \
+       addrinfo.cpp
 
 INCLUDES = ..\include;..\..\..\inc;..\..\..\inc\user;..\..\libibverbs\include;\
                   ..\..\..\inc\user\linux;
diff --git a/trunk/ulp/librdmacm/src/addrinfo.cpp 
b/trunk/ulp/librdmacm/src/addrinfo.cpp
new file mode 100644
index 0000000..b9642fe
--- /dev/null
+++ b/trunk/ulp/librdmacm/src/addrinfo.cpp
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2010 Intel Corporation.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <windows.h>
+#include <winsock2.h>
+
+#include "cma.h"
+#include <rdma/rdma_cma.h>
+#include <rdma/rdma_verbs.h>
+
+static void ucma_convert_to_ai(struct addrinfo *ai, struct rdma_addrinfo *rai)
+{
+       memset(ai, 0, sizeof *ai);
+       ai->ai_flags = rai->ai_flags;
+       ai->ai_family = rai->ai_family;
+
+       switch (rai->ai_qp_type) {
+       case IBV_QPT_RC:
+               ai->ai_socktype = SOCK_STREAM;
+               break;
+       case IBV_QPT_UD:
+               ai->ai_socktype = SOCK_DGRAM;
+               break;
+       }
+
+       switch (rai->ai_port_space) {
+       case RDMA_PS_TCP:
+               ai->ai_protocol = IPPROTO_TCP;
+               break;
+       case RDMA_PS_IPOIB:
+       case RDMA_PS_UDP:
+               ai->ai_protocol = IPPROTO_UDP;
+               break;
+       }
+
+       if (rai->ai_flags & RAI_PASSIVE) {
+               ai->ai_addrlen = rai->ai_src_len;
+               ai->ai_addr = rai->ai_src_addr;
+       } else {
+               ai->ai_addrlen = rai->ai_dst_len;
+               ai->ai_addr = rai->ai_dst_addr;
+       }
+       ai->ai_canonname = rai->ai_dst_canonname;
+       ai->ai_next = NULL;
+}
+
+static int ucma_convert_to_rai(struct rdma_addrinfo *rai, struct addrinfo *ai)
+{
+       struct sockaddr *addr;
+       char *canonname;
+
+       memset(rai, 0, sizeof *rai);
+       rai->ai_flags = ai->ai_flags;
+       rai->ai_family = ai->ai_family;
+
+       switch (ai->ai_socktype) {
+       case SOCK_STREAM:
+               rai->ai_qp_type = IBV_QPT_RC;
+               break;
+       case SOCK_DGRAM:
+               rai->ai_qp_type = IBV_QPT_UD;
+               break;
+       }
+
+       switch (ai->ai_protocol) {
+       case IPPROTO_TCP:
+               rai->ai_port_space = RDMA_PS_TCP;
+               break;
+       case IPPROTO_UDP:
+               rai->ai_port_space = RDMA_PS_UDP;
+               break;
+       }
+
+       addr = (struct sockaddr *) malloc(ai->ai_addrlen);
+       if (!addr)
+               return rdma_seterrno(ENOMEM);
+
+       canonname = (char *) (ai->ai_canonname ? 
malloc(strlen(ai->ai_canonname) + 1) : NULL);
+       if (canonname)
+               strcpy(canonname, ai->ai_canonname);
+
+       memcpy(addr, ai->ai_addr, ai->ai_addrlen);
+       if (ai->ai_flags & RAI_PASSIVE) {
+               rai->ai_src_addr = addr;
+               rai->ai_src_len = ai->ai_addrlen;
+               rai->ai_src_canonname = canonname;
+       } else {
+               rai->ai_dst_addr = addr;
+               rai->ai_dst_len = ai->ai_addrlen;
+               rai->ai_dst_canonname = canonname;
+       }
+
+       return 0;
+}
+
+__declspec(dllexport)
+int rdma_getaddrinfo(char *node, char *service,
+                                        struct rdma_addrinfo *hints,
+                                        struct rdma_addrinfo **res)
+{
+       struct rdma_addrinfo *rai;
+       struct addrinfo ai_hints;
+       struct addrinfo *ai;
+       int ret;
+
+       if (hints)
+               ucma_convert_to_ai(&ai_hints, hints);
+
+       ret = getaddrinfo(node, service, &ai_hints, &ai);
+       if (ret)
+               return ret;
+
+       rai = (struct rdma_addrinfo *) malloc(sizeof(*rai));
+       if (!rai) {
+               ret = rdma_seterrno(ENOMEM);
+               goto err1;
+       }
+
+       ret = ucma_convert_to_rai(rai, ai);
+       if (ret)
+               goto err2;
+
+       if (!rai->ai_src_len && hints && hints->ai_src_len) {
+               rai->ai_src_addr = (struct sockaddr *) calloc(1, 
hints->ai_src_len);
+               if (!rai->ai_src_addr) {
+                       ret = rdma_seterrno(ENOMEM);
+                       goto err2;
+               }
+               memcpy(rai->ai_src_addr, hints->ai_src_addr,
+                      hints->ai_src_len);
+               rai->ai_src_len = hints->ai_src_len;
+       }
+
+       // requires ib acm support --
+       //if (!(rai->ai_flags & RAI_PASSIVE))
+       //      ucma_ib_resolve(rai);
+
+       freeaddrinfo(ai);
+       *res = rai;
+       return 0;
+
+err2:
+       rdma_freeaddrinfo(rai);
+err1:
+       freeaddrinfo(ai);
+       return ret;
+}
+
+__declspec(dllexport)
+void rdma_freeaddrinfo(struct rdma_addrinfo *res)
+{
+       struct rdma_addrinfo *rai;
+
+       while (res) {
+               rai = res;
+               res = res->ai_next;
+
+               if (rai->ai_connect)
+                       free(rai->ai_connect);
+
+               if (rai->ai_route)
+                       free(rai->ai_route);
+
+               if (rai->ai_src_canonname)
+                       free(rai->ai_src_canonname);
+
+               if (rai->ai_dst_canonname)
+                       free(rai->ai_dst_canonname);
+
+               if (rai->ai_src_addr)
+                       free(rai->ai_src_addr);
+
+               if (rai->ai_dst_addr)
+                       free(rai->ai_dst_addr);
+
+               free(rai);
+       }
+}
diff --git a/trunk/ulp/librdmacm/src/cma_exports.src 
b/trunk/ulp/librdmacm/src/cma_exports.src
index a8fe8f3..8f370be 100644
--- a/trunk/ulp/librdmacm/src/cma_exports.src
+++ b/trunk/ulp/librdmacm/src/cma_exports.src
@@ -30,5 +30,7 @@ rdma_free_devices
 rdma_event_str
 rdma_set_option
 rdma_migrate_id
+rdma_getaddrinfo
+rdma_freeaddrinfo
 rdmaw_wsa_errno
 #endif

_______________________________________________
ofw mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/ofw

Reply via email to