Пример #1
0
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);
}
Пример #2
0
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);
}
Пример #3
0
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;
}