DAT_RETURN dapls_ns_lookup_v4( IN DAPL_IA *ia_ptr, IN struct sockaddr_in *addr, IN DAT_TIMEOUT timeout, OUT ib_gid_t *gid) { struct xarpreq ar; struct sockaddr_in *sin; uchar_t *mac; int s, retries = 0; (void) dapl_os_memzero(&ar, sizeof (ar)); sin = (struct sockaddr_in *)&ar.xarp_pa; sin->sin_family = AF_INET; sin->sin_addr.s_addr = addr->sin_addr.s_addr; ar.xarp_ha.sdl_family = AF_LINK; s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) { dapl_dbg_log(DAPL_DBG_TYPE_ERR, "ns_lookup_v4: socket: %s\n", strerror(errno)); return (DAT_INTERNAL_ERROR); } if (dapls_ns_subnet_match_v4(s, ia_ptr, addr) != 0) { (void) close(s); return (DAT_INVALID_ADDRESS); } again:; if (ioctl(s, SIOCGXARP, (caddr_t)&ar) < 0) { /* * if SIOCGXARP failed, we force the ARP * cache to be filled by connecting to the * destination IP address. */ if (retries <= NS_MAX_RETRIES && dapls_ns_resolve_addr(AF_INET, (struct sockaddr *)addr, timeout) == 0) { retries++; goto again; } dapl_dbg_log(DAPL_DBG_TYPE_ERR, "ns_lookup_v4: giving up\n"); (void) close(s); return (DAT_ERROR(DAT_INVALID_ADDRESS, DAT_INVALID_ADDRESS_UNREACHABLE)); } if ((ar.xarp_flags & ATF_COM) == 0 && ar.xarp_ha.sdl_type == IFT_IB && retries <= NS_MAX_RETRIES) { /* * we get here if arp resolution is still incomplete */ retries++; (void) sleep(1); goto again; } (void) close(s); mac = (uchar_t *)LLADDR(&ar.xarp_ha); if (ar.xarp_flags & ATF_COM && ar.xarp_ha.sdl_type == IFT_IB && ar.xarp_ha.sdl_alen >= sizeof (ipoib_mac_t)) { ib_gid_t tmp_gid; /* LINTED: E_BAD_PTR_CAST_ALIGN */ (void) dapl_os_memcpy(&tmp_gid, &((ipoib_mac_t *)mac)->ipoib_gidpref, sizeof (ib_gid_t)); /* * gids from the ARP table are in network order, convert * the gids from network order to host byte order */ gid->gid_prefix = BETOH_64(tmp_gid.gid_prefix); gid->gid_guid = BETOH_64(tmp_gid.gid_guid); } else { int i, len; len = ar.xarp_ha.sdl_alen; dapl_dbg_log(DAPL_DBG_TYPE_ERR, "ns_lookup_v4: failed, non IB address: " "len = %d, addr = 0x", len); if (len > 0) { for (i = 0; i < len; i++) { dapl_dbg_log(DAPL_DBG_TYPE_ERR, "%02x", (int)mac[i] & 0xff); } } else { dapl_dbg_log(DAPL_DBG_TYPE_ERR, "0"); } dapl_dbg_log(DAPL_DBG_TYPE_ERR, "\n"); return (DAT_INVALID_ADDRESS); } return (DAT_SUCCESS); }
DAT_RETURN dapls_ns_lookup_v6( IN DAPL_IA *ia_ptr, IN struct sockaddr_in6 *addr, IN DAT_TIMEOUT timeout, OUT ib_gid_t *gid) { struct lifreq lifr; uchar_t *mac; int s, retries = 0; s = socket(AF_INET6, SOCK_DGRAM, 0); if (s < 0) { dapl_dbg_log(DAPL_DBG_TYPE_ERR, "ns_lookup_v6: socket: %s\n", strerror(errno)); return (DAT_INTERNAL_ERROR); } if (dapls_ns_subnet_match_v6(s, ia_ptr, addr) != 0) { (void) close(s); return (DAT_INVALID_ADDRESS); } (void) dapl_os_memzero(&lifr, sizeof (lifr)); (void) dapl_os_memcpy(&lifr.lifr_nd.lnr_addr, addr, sizeof (*addr)); (void) dapl_os_strcpy(lifr.lifr_name, ia_ptr->hca_ptr->name); again:; if (ioctl(s, SIOCLIFGETND, (caddr_t)&lifr) < 0) { /* * if SIOCLIFGETND failed, we force the ND * cache to be filled by connecting to the * destination IP address. */ if (retries < NS_MAX_RETRIES && dapls_ns_send_packet_v6(s, addr) == 0 && dapls_ns_resolve_addr(AF_INET6, (struct sockaddr *)addr, timeout) == 0) { retries++; goto again; } dapl_dbg_log(DAPL_DBG_TYPE_ERR, "ns_lookup_v6: giving up\n"); (void) close(s); return (DAT_ERROR(DAT_INVALID_ADDRESS, DAT_INVALID_ADDRESS_UNREACHABLE)); } if (lifr.lifr_nd.lnr_hdw_len == 0 && retries <= NS_MAX_RETRIES) { /* * lnr_hdw_len == 0 means that the ND entry * is still incomplete. we need to retry the ioctl. */ retries++; (void) sleep(1); goto again; } (void) close(s); mac = (uchar_t *)lifr.lifr_nd.lnr_hdw_addr; if (lifr.lifr_nd.lnr_hdw_len >= sizeof (ipoib_mac_t)) { ib_gid_t tmp_gid; /* LINTED: E_BAD_PTR_CAST_ALIGN */ (void) dapl_os_memcpy(&tmp_gid, &((ipoib_mac_t *)mac)->ipoib_gidpref, sizeof (ib_gid_t)); /* * gids from the ND table are in network order, convert * the gids from network order to host byte order */ gid->gid_prefix = BETOH_64(tmp_gid.gid_prefix); gid->gid_guid = BETOH_64(tmp_gid.gid_guid); } else { int i, len; len = lifr.lifr_nd.lnr_hdw_len; dapl_dbg_log(DAPL_DBG_TYPE_ERR, "ns_lookup_v6: failed, non IB address: " "len = %d, addr = 0x", len); if (len > 0) { for (i = 0; i < len; i++) { dapl_dbg_log(DAPL_DBG_TYPE_ERR, "%02x", (int)mac[i] & 0xff); } } else { dapl_dbg_log(DAPL_DBG_TYPE_ERR, "0"); } dapl_dbg_log(DAPL_DBG_TYPE_ERR, "\n"); return (DAT_INVALID_ADDRESS); } return (DAT_SUCCESS); }
DAT_RETURN dapli_lmr_create_shared(IN DAPL_IA * ia, IN DAT_REGION_DESCRIPTION reg_desc, IN DAT_VLEN length, IN DAPL_PZ * pz, IN DAT_MEM_PRIV_FLAGS privileges, IN DAT_VA_TYPE va_type, OUT DAT_LMR_HANDLE * lmr_handle, OUT DAT_LMR_CONTEXT * lmr_context, OUT DAT_RMR_CONTEXT * rmr_context, OUT DAT_VLEN * registered_length, OUT DAT_VADDR * registered_address) { DAPL_LMR *lmr; DAT_RETURN dat_status; dat_status = DAT_SUCCESS; dapl_dbg_log(DAPL_DBG_TYPE_API, "dapl_lmr_create_shared_virtual (ia=%p len=%x pz=%p priv=%x)\n", ia, length, pz, privileges); lmr = dapl_lmr_alloc(ia, DAT_MEM_TYPE_LMR, reg_desc, length, /* length is meaningless */ (DAT_PZ_HANDLE) pz, privileges); if (NULL == lmr) { dat_status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, DAT_RESOURCE_MEMORY); goto bail; } /* * Added for the shared memory support - - - * Save the region description. We need to copy the shared * memory id because the region_desc only contains a pointer * to it. */ dapl_os_memcpy(&lmr->shmid, reg_desc.for_shared_memory.shared_memory_id, sizeof(lmr->shmid)); lmr->param.region_desc = reg_desc; lmr->param.length = length; lmr->param.mem_type = DAT_MEM_TYPE_SHARED_VIRTUAL; lmr->param.region_desc.for_shared_memory.shared_memory_id = &lmr->shmid; dat_status = dapls_ib_mr_register_shared(ia, lmr, privileges, va_type); if (dat_status != DAT_SUCCESS) { dapl_lmr_dealloc(lmr); dat_status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, DAT_RESOURCE_MEMORY_REGION); goto bail; } dapl_os_atomic_inc(&pz->pz_ref_count); *lmr_handle = (DAT_LMR_HANDLE) lmr; if (NULL != lmr_context) { *lmr_context = (DAT_LMR_CONTEXT) lmr->param.lmr_context; } if (NULL != rmr_context) { *rmr_context = (DAT_LMR_CONTEXT) lmr->param.rmr_context; } if (NULL != registered_length) { *registered_length = lmr->param.length; } if (NULL != registered_address) { *registered_address = (DAT_VADDR) (uintptr_t) lmr->param.region_desc.for_shared_memory.virtual_address; } bail: return dat_status; }