[ofw] [PATCH] DAPL v2.0: SCM: getifaddrs modfications for better out of the box experience

Davis, Arlin R arlin.r.davis at intel.com
Thu Oct 3 16:02:28 PDT 2013


socket cm will now walk list of interfaces and ignore loopback
and ignore IB devices, unless the IB netdev is the only device.
Works better in a heterogeneous environment with a mix of net device.
Tested with br0, mic0, and mic0:ib netdev mixes.
Overriding with DAPL_SCM_NETDEV still works as is.

Signed-off-by: Patrick Mccormick <patrick.m.mccormick at intel.com>
Signed-off-by: Arlin Davis <arlin.r.davis at intel.com>
---
 dapl/openib_common/util.c |   70 +++++++++++++++++++++++---------------------
 1 files changed, 37 insertions(+), 33 deletions(-)

diff --git a/dapl/openib_common/util.c b/dapl/openib_common/util.c
index 8b97263..20fb8b2 100644
--- a/dapl/openib_common/util.c
+++ b/dapl/openib_common/util.c
@@ -28,6 +28,7 @@
 #include "dapl_osd.h"
 
 #include <stdlib.h>
+#include <ifaddrs.h>
 
 int g_dapl_loopback_connection = 0;
 
@@ -148,7 +149,6 @@ int getipaddr_netdev(char *name, char *addr, int addr_len)
 
 	/* Fill in the structure */
 	snprintf(ifr.ifr_name, IFNAMSIZ, "%s", name);
-	ifr.ifr_hwaddr.sa_family = ARPHRD_INFINIBAND;
 
 	/* Create a socket fd */
 	skfd = socket(PF_INET, SOCK_STREAM, 0);
@@ -178,51 +178,54 @@ int getipaddr_netdev(char *name, char *addr, int addr_len)
 	return ret;
 }
 
-DAT_RETURN getlocalipaddr(char *addr, int addr_len)
+/* IPv4 only, use IB if netdev set or it's the only interface */
+DAT_RETURN getlocalipaddr (char *addr, int addr_len)
 {
-	struct sockaddr_in *sin;
-	int ret, skfd, i;
+	struct ifaddrs *ifap, *ifa;
+	int ret, found=0, ib_ok=0;
 	char *netdev = getenv("DAPL_SCM_NETDEV");
-	struct ifreq ifr[10];
-	struct ifconf ifc;
 
-	/* use provided netdev instead of default hostname */
 	if (netdev != NULL) {
 		ret = getipaddr_netdev(netdev, addr, addr_len);
 		if (ret) {
-			dapl_log(DAPL_DBG_TYPE_ERR,
-				 " getlocalipaddr: NETDEV = %s"
-				 " but not configured on system? ERR = %s\n",
-				 netdev, strerror(ret));
-			return dapl_convert_errno(ret, "getlocalipaddr");
-		} else
+			dapl_log(DAPL_DBG_TYPE_ERR, " ERR: NETDEV = %s"
+				 " but not configured on system?\n", netdev);
+			return dapl_convert_errno(errno, "getlocalipaddr");
+		} else {
+			dapl_log(DAPL_DBG_TYPE_UTIL," my_addr %s NETDEV = %s\n",
+				 inet_ntoa(((struct sockaddr_in *)addr)->sin_addr),
+				 netdev);
 			return DAT_SUCCESS;
+		}
 	}
 
-	if (addr_len < sizeof(*sin))
-		return DAT_INTERNAL_ERROR;
-
-	memset(&ifc,0,sizeof(ifc));
-	ifc.ifc_buf = (char *)ifr;
-	ifc.ifc_len = sizeof(ifr);
-
-	skfd = socket(PF_INET, SOCK_STREAM, 0);
-	ret = ioctl(skfd, SIOCGIFCONF, &ifc);
-	if (ret)
-		goto bail;
+	if ((ret = getifaddrs (&ifap)))
+		return dapl_convert_errno(errno, "getifaddrs");
 
-	/* first non-loopback interface in list */
-	for (i=0; i < ifc.ifc_len/sizeof(struct ifreq); i++) {
-		if (strcmp(ifr[i].ifr_name, "lo"))
-			break;
+retry:
+	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+		if (ifa->ifa_addr->sa_family == AF_INET) {
+			if (!found && !(ifa->ifa_flags & IFF_LOOPBACK) &&
+			    ((!ib_ok && dapl_os_pstrcmp("ib", ifa->ifa_name)) ||
+			     (ib_ok && !dapl_os_pstrcmp("ib", ifa->ifa_name)))) {
+				memcpy(addr, ifa->ifa_addr, sizeof(struct sockaddr_in));
+				found++;
+			}
+			dapl_log(DAPL_DBG_TYPE_UTIL,
+				 " getifaddrs: %s -> %s\n", ifa->ifa_name,
+				 inet_ntoa(((struct sockaddr_in *)ifa->ifa_addr)->sin_addr));
+		}
+	}
+	if (!found && !ib_ok) {
+		ib_ok = 1;
+		goto retry;
 	}
-	memcpy(addr, &ifr[i].ifr_addr, sizeof(struct sockaddr_in));
+	dapl_log(DAPL_DBG_TYPE_UTIL," my_addr %s\n",
+		 inet_ntoa(((struct sockaddr_in *)addr)->sin_addr));
 
-bail:
-	close(skfd);
-	return dapl_convert_errno(ret, "getlocalipaddr");
+	freeifaddrs(ifap);
+	return (found ? DAT_SUCCESS:DAT_INVALID_ADDRESS);
 }
-
 #endif
 
 enum ibv_mtu dapl_ib_mtu(int mtu)
@@ -811,3 +814,4 @@ ib_cm_events_t dapls_ib_get_cm_event(IN DAT_EVENT_NUMBER dat_event_num)
 	}
 	return ib_cm_event;
 }
+
-- 
1.7.3





More information about the ofw mailing list