1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <strings.h> 28 29 #include <dapl.h> 30 #include <dapl_adapter_util.h> 31 #include <dapl_evd_util.h> 32 #include <dapl_cr_util.h> 33 #include <dapl_lmr_util.h> 34 #include <dapl_rmr_util.h> 35 #include <dapl_cookie.h> 36 #include <dapl_name_service.h> 37 #include <dapl_tavor_ibtf_impl.h> 38 39 /* Function prototypes */ 40 extern DAT_RETURN dapls_tavor_wrid_init(ib_qp_handle_t); 41 extern void dapls_tavor_wrid_cleanup(DAPL_EP *, ib_qp_handle_t); 42 43 int g_dapl_loopback_connection = 0; 44 45 /* 46 * dapls_ib_connect 47 * 48 * Initiate a connection with the passive listener on another node 49 * 50 * Input: 51 * ep_handle, 52 * remote_ia_address, 53 * remote_conn_qual, 54 * prd_size size of private data and structure 55 * prd_prt pointer to private data structure 56 * 57 * Output: 58 * none 59 * 60 * Returns: 61 * DAT_SUCCESS 62 * DAT_INSUFFICIENT_RESOURCES 63 * DAT_INVALID_PARAMETER 64 * 65 */ 66 67 DAT_RETURN 68 dapls_ib_connect(IN DAT_EP_HANDLE ep_handle, 69 IN DAT_IA_ADDRESS_PTR remote_ia_address, IN DAT_CONN_QUAL remote_conn_qual, 70 IN DAT_COUNT prd_size, IN DAPL_PRIVATE *prd_ptr, IN DAT_TIMEOUT timeout) 71 { 72 dapl_ep_connect_t args; 73 DAPL_EP *ep_p = (DAPL_EP *)ep_handle; 74 struct sockaddr *s; 75 char addr_buf[64]; 76 ib_gid_t dgid; 77 int retval; 78 struct sockaddr_in6 *v6addr; 79 struct sockaddr_in *v4addr; 80 dapl_ia_addr_t *sap; 81 82 s = (struct sockaddr *)remote_ia_address; 83 dapl_dbg_log(DAPL_DBG_TYPE_CM, 84 "dapls_ib_connect: ep 0x%p\n" 85 " addr %s, conn_qual %016llu, ep_hkey %016llx\n" 86 " prd_size %d, timeout 0x%x\n", 87 ep_p, dapls_inet_ntop(s, addr_buf, 64), remote_conn_qual, 88 ep_p->qp_handle->ep_hkey, prd_size, timeout); 89 if (ep_p->qp_handle == NULL) { 90 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 91 "dapls_ib_connect: ep 0x%p, addr %s, conn_qual %016llu, " 92 "qp_handle == NULL\n", ep_p, dapls_inet_ntop(s, 93 addr_buf, 64), remote_conn_qual); 94 return (DAT_INVALID_PARAMETER); 95 } 96 if (timeout == DAT_TIMEOUT_INFINITE) { 97 args.epc_timeout = 0; 98 } else { 99 args.epc_timeout = timeout; 100 } 101 /* resolve remote address to dgid */ 102 retval = dapls_ns_lookup_address(ep_p->header.owner_ia, 103 remote_ia_address, timeout, &dgid); 104 if (retval == DAT_SUCCESS) { 105 args.epc_dgid = dgid; 106 } else if ((retval & DAT_SUBTYPE_MASK) == 107 DAT_INVALID_ADDRESS_UNREACHABLE) { 108 /* let the kernel driver look up the dgid from ATS */ 109 args.epc_dgid.gid_guid = 0ULL; 110 args.epc_dgid.gid_prefix = 0ULL; 111 } else { 112 return (retval); 113 } 114 args.epc_sid = remote_conn_qual; 115 args.epc_hkey = ep_p->qp_handle->ep_hkey; 116 sap = (dapl_ia_addr_t *)&args.epc_raddr_sadata; 117 /* 118 * filled in the remote_ia_address for consistent though 119 * not necessary when dapls_ns_lookup_address has resolved the dgid 120 */ 121 switch (s->sa_family) { 122 case AF_INET: 123 /* LINTED: E_BAD_PTR_CAST_ALIGN */ 124 v4addr = (struct sockaddr_in *)s; 125 sap->iad_v4pad[0] = 0; 126 sap->iad_v4pad[1] = 0; 127 sap->iad_v4pad[2] = 0; 128 sap->iad_v4 = v4addr->sin_addr; 129 break; 130 case AF_INET6: 131 /* LINTED: E_BAD_PTR_CAST_ALIGN */ 132 v6addr = (struct sockaddr_in6 *)s; 133 sap->iad_v6 = v6addr->sin6_addr; 134 break; 135 } 136 137 /* establish the hello message */ 138 (void) dapl_os_memzero((void *)&prd_ptr->hello_msg, 139 sizeof (DAPL_HELLO_MSG)); 140 /* on ATS leave the msg blank to avoid confusion to 3rd parties */ 141 if ((args.epc_dgid.gid_guid | args.epc_dgid.gid_prefix)) { 142 prd_ptr->hello_msg.hi_checksum = DAPL_CHECKSUM; 143 prd_ptr->hello_msg.hi_clen = prd_size; 144 prd_ptr->hello_msg.hi_mid = 0; 145 prd_ptr->hello_msg.hi_vers = DAPL_HELLO_MSG_VERS; 146 147 /* fill in local address */ 148 s = (struct sockaddr *) 149 &ep_p->header.owner_ia->hca_ptr->hca_address; 150 prd_ptr->hello_msg.hi_ipv = (uint8_t)s->sa_family; 151 switch (s->sa_family) { 152 case AF_INET: 153 /* LINTED: E_BAD_PTR_CAST_ALIGN */ 154 v4addr = (struct sockaddr_in *)s; 155 prd_ptr->hello_msg.hi_port = v4addr->sin_port; 156 prd_ptr->hello_msg.hi_v4ipaddr = v4addr->sin_addr; 157 break; 158 case AF_INET6: 159 /* LINTED: E_BAD_PTR_CAST_ALIGN */ 160 v6addr = (struct sockaddr_in6 *)s; 161 prd_ptr->hello_msg.hi_port = v6addr->sin6_port; 162 prd_ptr->hello_msg.hi_v6ipaddr = v6addr->sin6_addr; 163 break; 164 default: 165 break; /* fall through */ 166 } 167 } 168 if (prd_size > 0) { 169 (void) dapl_os_memcpy((void *)&args.epc_priv[0], 170 (void *)prd_ptr, sizeof (DAPL_PRIVATE)); 171 } else { 172 (void) dapl_os_memcpy((void *) 173 &args.epc_priv[DAPL_CONSUMER_MAX_PRIVATE_DATA_SIZE], 174 (void *)&prd_ptr->hello_msg, sizeof (DAPL_HELLO_MSG)); 175 } 176 args.epc_priv_sz = sizeof (DAPL_PRIVATE); 177 178 retval = ioctl(ep_p->header.owner_ia->hca_ptr->ib_hca_handle->ia_fd, 179 DAPL_EP_CONNECT, &args); 180 if (retval != 0) { 181 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 182 "dapls_ib_connect: connect failed %s, retval %d\n\n", 183 strerror(errno), retval); 184 return (dapls_convert_error(errno, retval)); 185 } 186 187 dapl_dbg_log(DAPL_DBG_TYPE_CM, 188 "dapls_ib_connect: connected to %s\n\n", 189 dapls_inet_ntop(s, addr_buf, 64)); 190 return (DAT_SUCCESS); 191 } 192 193 /* 194 * dapls_ib_disconnect 195 * 196 * Disconnect an EP 197 * 198 * Input: 199 * ep_handle, 200 * disconnect_flags 201 * 202 * Output: 203 * none 204 * 205 * Returns: 206 * DAT_SUCCESS 207 * DAT_INSUFFICIENT_RESOURCES 208 * DAT_INVALID_PARAMETER 209 * 210 */ 211 /* ARGSUSED */ 212 DAT_RETURN 213 dapls_ib_disconnect(IN DAPL_EP *ep_ptr, 214 IN DAT_CLOSE_FLAGS close_flags) 215 { 216 dapl_ep_disconnect_t args; 217 struct sockaddr *s; 218 char addr_buf[64]; 219 int retval; 220 221 if (ep_ptr->qp_handle == NULL) { 222 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 223 "dapls_ib_disconnect: qp_handle == NULL\n"); 224 return (DAT_INVALID_PARAMETER); 225 } 226 args.epd_hkey = ep_ptr->qp_handle->ep_hkey; 227 228 retval = ioctl(ep_ptr->header.owner_ia->hca_ptr->ib_hca_handle->ia_fd, 229 DAPL_EP_DISCONNECT, &args); 230 /* no reason for disconnect to fail so transition the state */ 231 ep_ptr->qp_state = IBT_STATE_ERROR; 232 233 if (retval != 0) { 234 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 235 "dapls_ib_disconnect: disconnect failed %s\n", 236 strerror(errno)); 237 return (dapls_convert_error(errno, retval)); 238 } 239 s = (struct sockaddr *)ep_ptr->param.remote_ia_address_ptr; 240 dapl_dbg_log(DAPL_DBG_TYPE_CM, 241 "dapls_ib_disconnect: disconnected from %s, conn_qual %016llu\n", 242 dapls_inet_ntop(s, addr_buf, 64), ep_ptr->param.remote_port_qual); 243 return (DAT_SUCCESS); 244 } 245 246 247 /* 248 * dapls_ib_connected 249 * 250 * transition qp_state to IBT_STATE_RTS 251 * 252 */ 253 void 254 dapls_ib_connected(IN DAPL_EP *ep_ptr) 255 { 256 ep_ptr->qp_state = IBT_STATE_RTS; 257 } 258 259 260 /* 261 * dapls_ib_disconnect_clean 262 * 263 * transition qp_state to IBT_STATE_ERROR. 264 * abort connection if necessary. 265 * 266 * Input: 267 * ep_ptr DAPL_EP 268 * 269 * Output: 270 * none 271 * 272 * Returns: 273 * void 274 * 275 */ 276 /* ARGSUSED */ 277 void 278 dapls_ib_disconnect_clean(IN DAPL_EP *ep_ptr, IN DAT_BOOLEAN active, 279 IN const ib_cm_events_t ib_cm_event) 280 { 281 switch (ib_cm_event) { 282 case IB_CME_CONNECTED: 283 case IB_CME_CONNECTION_REQUEST_PENDING: 284 case IB_CME_CONNECTION_REQUEST_PENDING_PRIVATE_DATA: 285 (void) dapls_ib_disconnect(ep_ptr, DAT_CLOSE_ABRUPT_FLAG); 286 /* FALLTHROUGH */ 287 case IB_CME_DESTINATION_REJECT: 288 case IB_CME_DESTINATION_REJECT_PRIVATE_DATA: 289 case IB_CME_DESTINATION_UNREACHABLE: 290 case IB_CME_TOO_MANY_CONNECTION_REQUESTS: 291 case IB_CME_LOCAL_FAILURE: 292 case IB_CME_TIMED_OUT: 293 case IB_CME_DISCONNECTED_ON_LINK_DOWN: 294 ep_ptr->qp_state = IBT_STATE_ERROR; 295 } 296 } 297 298 299 /* 300 * dapls_ib_reinit_ep 301 * 302 * Move the QP to INIT state again. 303 * 304 * Input: 305 * ep_ptr DAPL_EP 306 * 307 * Output: 308 * none 309 * 310 * Returns: 311 * void 312 * 313 */ 314 void 315 dapls_ib_reinit_ep(IN DAPL_EP *ep_ptr) 316 { 317 dapl_ep_reinit_t reinit_args; 318 ib_hca_handle_t hca_hndl; 319 ib_qp_handle_t qp_p; 320 char addr_buf[64]; 321 int retval; 322 323 hca_hndl = ep_ptr->header.owner_ia->hca_ptr->ib_hca_handle; 324 qp_p = ep_ptr->qp_handle; 325 326 if (qp_p == NULL) { 327 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 328 "dapls_ib_reinit: qp_handle == NULL\n"); 329 return; 330 } 331 /* 332 * Do all the work request cleanup processing right away 333 * no one should really be doing any operation on this 334 * qp (we are not threadsafe)... 335 */ 336 dapls_tavor_wrid_cleanup(ep_ptr, qp_p); 337 338 reinit_args.epri_hkey = qp_p->ep_hkey; 339 if (ioctl(hca_hndl->ia_fd, DAPL_EP_REINIT, &reinit_args) != 0) { 340 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 341 "dapls_ib_reinit: reinit failed %s\n", 342 strerror(errno)); 343 return; 344 } 345 346 qp_p->qp_sq_lastwqeaddr = NULL; 347 qp_p->qp_rq_lastwqeaddr = NULL; 348 349 /* 350 * Setup data structure for work request processing 351 */ 352 retval = dapls_tavor_wrid_init(qp_p); 353 if (retval != DAT_SUCCESS) { 354 /* 355 * we failed to create data structures for work request 356 * processing. Lets unmap and leave, the qp will get 357 * cleaned when ep gets destroyed - the ep is unusable 358 * in this state. 359 */ 360 if (munmap((void *)qp_p->qp_addr, qp_p->qp_map_len) < 0) { 361 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 362 "qp_free: munmap failed(%d)\n", errno); 363 } 364 qp_p->qp_addr = NULL; 365 dapl_dbg_log(DAPL_DBG_TYPE_CM, 366 "dapls_ib_reinit: wrid_init failed %d\n", retval); 367 return; 368 } 369 370 /* we have a new ep and it is in the init state */ 371 ep_ptr->qp_state = IBT_STATE_INIT; 372 373 dapl_dbg_log(DAPL_DBG_TYPE_CM, 374 "dapls_ib_reinit: successful, ia_address %s, conn_qual %016llu\n", 375 dapls_inet_ntop((struct sockaddr *)ep_ptr->param. 376 remote_ia_address_ptr, addr_buf, 64), 377 ep_ptr->param.remote_port_qual); 378 } 379 380 381 /* 382 * dapl_ib_setup_conn_listener 383 * 384 * Have the CM set up a connection listener. 385 * 386 * Input: 387 * ibm_hca_handle HCA handle 388 * qp_handle QP handle 389 * 390 * Output: 391 * none 392 * 393 * Returns: 394 * DAT_SUCCESS 395 * DAT_INSUFFICIENT_RESOURCES 396 * DAT_INVALID_PARAMETER 397 * 398 */ 399 DAT_RETURN 400 dapls_ib_setup_conn_listener(IN DAPL_IA *ia_ptr, 401 IN DAT_UINT64 ServiceID, IN DAPL_SP *sp_ptr) 402 { 403 ib_hca_handle_t hca_hdl = ia_ptr->hca_ptr->ib_hca_handle; 404 struct dapls_ib_cm_srvc_handle *srvc_hdl; 405 dapl_service_register_t args; 406 struct sockaddr *s; 407 char addr_buf[64]; 408 DAPL_EVD *evd_p = (DAPL_EVD *)sp_ptr->evd_handle; 409 int retval; 410 411 if (hca_hdl == NULL) { 412 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 413 "setup_conn_listener: hca_handle == NULL\n"); 414 return (DAT_INVALID_PARAMETER); 415 } 416 if (evd_p == NULL) { 417 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 418 "setup_conn_listener: evd_p == NULL\n"); 419 return (DAT_INVALID_PARAMETER); 420 } 421 srvc_hdl = (struct dapls_ib_cm_srvc_handle *) 422 dapl_os_alloc(sizeof (*srvc_hdl)); 423 if (srvc_hdl == NULL) { 424 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 425 "setup_conn_listener: srvc_handle == NULL\n"); 426 return (DAT_INSUFFICIENT_RESOURCES); 427 } 428 429 args.sr_sid = ServiceID; 430 args.sr_evd_hkey = evd_p->ib_cq_handle->evd_hkey; 431 args.sr_sp_cookie = (uintptr_t)sp_ptr; 432 433 retval = ioctl(hca_hdl->ia_fd, DAPL_SERVICE_REGISTER, &args); 434 if (retval != 0) { 435 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 436 "setup_conn_listener: register failed %s\n", 437 strerror(errno)); 438 dapl_os_free(srvc_hdl, sizeof (*srvc_hdl)); 439 return (dapls_convert_error(errno, retval)); 440 } 441 srvc_hdl->sv_sp_hkey = args.sr_sp_hkey; 442 sp_ptr->cm_srvc_handle = srvc_hdl; 443 sp_ptr->conn_qual = args.sr_retsid; 444 445 s = (struct sockaddr *)&ia_ptr->hca_ptr->hca_address; 446 dapl_dbg_log(DAPL_DBG_TYPE_CM, 447 "setup_conn_listener: listening on ia_address %s, " 448 "conn_qual %016llu\n\n", dapls_inet_ntop(s, addr_buf, 64), 449 sp_ptr->conn_qual); 450 return (DAT_SUCCESS); 451 } 452 453 /* 454 * dapl_ib_remove_conn_listener 455 * 456 * Have the CM remove a connection listener. 457 * 458 * Input: 459 * ia_handle IA handle 460 * ServiceID IB Channel Service ID 461 * 462 * Output: 463 * none 464 * 465 * Returns: 466 * DAT_SUCCESS 467 * DAT_INVALID_PARAMETER 468 * 469 */ 470 DAT_RETURN 471 dapls_ib_remove_conn_listener(IN DAPL_IA *ia_ptr, IN DAPL_SP *sp_ptr) 472 { 473 ib_hca_handle_t hca_hdl = ia_ptr->hca_ptr->ib_hca_handle; 474 struct dapls_ib_cm_srvc_handle *srvc_hdl; 475 dapl_service_deregister_t args; 476 struct sockaddr *s; 477 char addr_buf[64]; 478 int retval; 479 480 if (hca_hdl == NULL) { 481 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 482 "remove_conn_listener: hca_handle == NULL\n"); 483 return (DAT_INVALID_PARAMETER); 484 } 485 srvc_hdl = (struct dapls_ib_cm_srvc_handle *)sp_ptr-> 486 cm_srvc_handle; 487 488 args.sdr_sp_hkey = srvc_hdl->sv_sp_hkey; 489 retval = ioctl(hca_hdl->ia_fd, DAPL_SERVICE_DEREGISTER, &args); 490 if (retval != 0) { 491 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 492 "remove_conn_listener: deregister failed %s\n", 493 strerror(errno)); 494 return (dapls_convert_error(errno, retval)); 495 } 496 dapl_os_free(srvc_hdl, sizeof (*srvc_hdl)); 497 sp_ptr->cm_srvc_handle = NULL; 498 499 s = (struct sockaddr *)&ia_ptr->hca_ptr->hca_address; 500 dapl_dbg_log(DAPL_DBG_TYPE_CM, 501 "remove_conn_listener: successful, ia_address %s, " 502 "conn_qual %016llu\n\n", dapls_inet_ntop(s, addr_buf, 64), 503 sp_ptr->conn_qual); 504 return (DAT_SUCCESS); 505 } 506 507 /* 508 * dapls_ib_reject_connection 509 * 510 * Perform necessary steps to reject a connection 511 * 512 * Input: 513 * cr_handle 514 * 515 * Output: 516 * none 517 * 518 * Returns: 519 * DAT_SUCCESS 520 * DAT_INSUFFICIENT_RESOURCES 521 * DAT_INVALID_PARAMETER 522 * 523 */ 524 DAT_RETURN 525 dapls_ib_reject_connection(IN ib_cm_handle_t cm_handle, 526 IN int reject_reason, IN DAPL_SP *sp_ptr) 527 { 528 dapl_cr_reject_t args; 529 int retval; 530 531 args.crr_reason = reject_reason; 532 args.crr_bkl_cookie = (uint64_t)cm_handle; 533 args.crr_sp_hkey = sp_ptr->cm_srvc_handle->sv_sp_hkey; 534 535 dapl_dbg_log(DAPL_DBG_TYPE_CM, 536 "dapls_ib_reject: fd %d, sp_hkey %016llx, bkl_index 0x%llx\n", 537 sp_ptr->header.owner_ia->hca_ptr->ib_hca_handle->ia_fd, 538 args.crr_sp_hkey, args.crr_bkl_cookie); 539 540 retval = ioctl(sp_ptr->header.owner_ia->hca_ptr->ib_hca_handle->ia_fd, 541 DAPL_CR_REJECT, &args); 542 if (retval != 0) { 543 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 544 "dapls_ib_reject: reject failed %s\n", 545 strerror(errno)); 546 return (dapls_convert_error(errno, retval)); 547 } 548 return (DAT_SUCCESS); 549 } 550 551 552 /* 553 * dapls_ib_accept_connection 554 * 555 * Perform necessary steps to accept a connection 556 * 557 * Input: 558 * cr_handle 559 * ep_handle 560 * private_data_size 561 * private_data 562 * 563 * Output: 564 * none 565 * 566 * Returns: 567 * DAT_SUCCESS 568 * DAT_INSUFFICIENT_RESOURCES 569 * DAT_INVALID_PARAMETER 570 * 571 */ 572 DAT_RETURN 573 dapls_ib_accept_connection(IN DAT_CR_HANDLE cr_handle, 574 IN DAT_EP_HANDLE ep_handle, IN DAPL_PRIVATE *prd_ptr) 575 { 576 DAPL_EP *ep_p = (DAPL_EP *)ep_handle; 577 DAPL_CR *cr_p = (DAPL_CR *)cr_handle; 578 dapl_cr_accept_t args; 579 int retval; 580 581 /* check if ep is valid */ 582 if (ep_p->qp_handle == NULL) { 583 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 584 "dapls_ib_accept: qp_handle == NULL\n"); 585 return (DAT_INVALID_PARAMETER); 586 } 587 588 dapl_dbg_log(DAPL_DBG_TYPE_CM, 589 "dapls_ib_accept: fd %d, sp_hkey %016llx, " 590 "bkl_index 0x%llx, ep_hkey %016llx\n", 591 cr_p->header.owner_ia->hca_ptr->ib_hca_handle->ia_fd, 592 cr_p->sp_ptr->cm_srvc_handle->sv_sp_hkey, 593 (uint64_t)cr_p->ib_cm_handle, ep_p->qp_handle->ep_hkey); 594 595 args.cra_bkl_cookie = (uint64_t)cr_p->ib_cm_handle; 596 args.cra_sp_hkey = cr_p->sp_ptr->cm_srvc_handle->sv_sp_hkey; 597 args.cra_ep_hkey = ep_p->qp_handle->ep_hkey; 598 599 args.cra_priv_sz = IB_MAX_REP_PDATA_SIZE; 600 bcopy(prd_ptr, args.cra_priv, IB_MAX_REP_PDATA_SIZE); 601 602 retval = ioctl(cr_p->header.owner_ia->hca_ptr->ib_hca_handle->ia_fd, 603 DAPL_CR_ACCEPT, &args); 604 if (retval != 0) { 605 ep_p->qp_state = IBT_STATE_ERROR; 606 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 607 "dapls_ib_accept: accept failed %s\n", 608 strerror(errno)); 609 return (dapls_convert_error(errno, retval)); 610 } 611 return (DAT_SUCCESS); 612 } 613 /* 614 * dapls_ib_cm_remote_addr 615 * 616 * Obtain the remote IP address given a connection 617 * 618 * Input: 619 * cr_handle 620 * private data structure handle (only for IBHOSTS_NAMING) 621 * 622 * Output: 623 * remote_ia_address: where to place the remote address 624 * 625 * Returns: 626 * DAT_SUCCESS 627 * DAT_INSUFFICIENT_RESOURCES 628 * DAT_INVALID_PARAMETER 629 * 630 */ 631 /* ARGSUSED */ 632 DAT_RETURN 633 dapls_ib_cm_remote_addr( 634 IN DAT_HANDLE dat_handle, 635 IN DAPL_PRIVATE *prd_ptr, 636 OUT DAT_SOCK_ADDR6 *remote_ia_address) 637 { 638 return (DAT_SUCCESS); 639 } 640 641 642 /* 643 * dapls_ib_handoff_connection 644 * 645 * handoff connection to a different qualifier 646 * 647 * Input: 648 * cr_ptr 649 * cr_handoff 650 * 651 * Output: 652 * none 653 * 654 * Returns: 655 * DAT_SUCCESS 656 * DAT_INSUFFICIENT_RESOURCES 657 * DAT_INVALID_PARAMETER 658 * 659 */ 660 DAT_RETURN 661 dapls_ib_handoff_connection(IN DAPL_CR *cr_ptr, IN DAT_CONN_QUAL cr_handoff) 662 { 663 dapl_cr_handoff_t args; 664 int retval; 665 666 dapl_dbg_log(DAPL_DBG_TYPE_CM, 667 "dapls_ib_handoff: fd %d, sp_hkey %016llx, " 668 "bkl_index 0x%llx conn_qual %llu\n", 669 cr_ptr->header.owner_ia->hca_ptr->ib_hca_handle->ia_fd, 670 cr_ptr->sp_ptr->cm_srvc_handle->sv_sp_hkey, 671 (uint64_t)cr_ptr->ib_cm_handle, cr_handoff); 672 673 args.crh_bkl_cookie = (uint64_t)cr_ptr->ib_cm_handle; 674 args.crh_sp_hkey = cr_ptr->sp_ptr->cm_srvc_handle->sv_sp_hkey; 675 args.crh_conn_qual = cr_handoff; 676 677 retval = ioctl(cr_ptr->header.owner_ia->hca_ptr->ib_hca_handle->ia_fd, 678 DAPL_CR_HANDOFF, &args); 679 if (retval != 0) { 680 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 681 "dapls_ib_handoff: failed %s\n", strerror(errno)); 682 return (dapls_convert_error(errno, retval)); 683 } 684 return (DAT_SUCCESS); 685 } 686