From 53534445d649812061b1849b1a77a3499ba0cdd0 Mon Sep 17 00:00:00 2001 From: Arlin Davis Date: Tue, 1 Oct 2013 15:40:17 -0700 Subject: [PATCH] SCM: getifaddrs modfications for better out of the box experience 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 heterogenous 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 Signed-off-by: Arlin Davis --- dapl/openib_common/util.c | 70 +++++++++++++++++++++------------------ 1 file 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 +#include 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; } + -- 2.46.0