rdsib_cm.c revision c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright (c) 2005 SilverStorm Technologies, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* OpenIB.org BSD license below:
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* provided with the distribution.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
/*
* Sun elects to include this software in Sun product
* under the OpenIB BSD license.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* This file contains CM related work:
*
* Service registration/deregistration
* Path lookup
* CM connection callbacks
* CM active and passive connection establishment
* Connection failover
*/
/*
* Handle an incoming CM REQ
*/
/* ARGSUSED */
static ibt_cm_status_t
{
int ret;
/*
* CM private data brings IP information
* Private data received is a stream of bytes and may not be properly
* aligned. So, bcopy the data onto the stack before accessing it.
*/
sizeof (rds_cm_private_data_t));
return (IBT_CM_REJECT);
}
return (IBT_CM_REJECT);
}
return (IBT_CM_REJECT);
}
/* user_buffer_size should be same on all nodes */
"UserBufferSize Mismatch, this node: %d remote node: %d",
return (IBT_CM_REJECT);
}
/*
* RDS needs more time to process a failover REQ so send an MRA.
* Otherwise, the remote may retry the REQ and fail the connection.
*/
}
/* Is there a session to the destination node? */
/*
* currently there is no session to the destination
* remote ip in the private data is the local ip and vice
* versa
*/
/* Check the list anyway. */
/*
* The only way this can fail is due to lack
* of kernel resources
*/
return (IBT_CM_REJECT);
}
}
}
/* catch peer-to-peer case as soon as possible */
/* Check possible peer-to-peer case here */
"handling", sp);
/* this node is active so reject this request */
return (IBT_CM_REJECT);
} else {
/* this node is passive, change the session */
}
}
}
switch (sp->session_state) {
"RDS_SESSION_STATE_ERROR", sp);
/* FALLTHRU */
case RDS_SESSION_STATE_ERROR:
/* move the session to init state */
if (ret != 0) {
"RDS_SESSION_STATE_FAILED", sp);
return (IBT_CM_REJECT);
} else {
"RDS_SESSION_STATE_INIT", sp);
}
} else {
}
break;
case RDS_SESSION_STATE_FAILED:
case RDS_SESSION_STATE_FINI:
/*
* Initialize both channels, we accept this connection
* only if both channels are initialized
*/
"RDS_SESSION_STATE_CREATED", sp);
if (ret != 0) {
/* Seems like there are not enough resources */
"RDS_SESSION_STATE_FAILED", sp);
return (IBT_CM_REJECT);
}
"RDS_SESSION_STATE_INIT", sp);
/* FALLTHRU */
case RDS_SESSION_STATE_INIT:
} else {
}
break;
default:
return (IBT_CM_REJECT);
}
if (cmp.cmp_failover) {
RDS_DPRINTF2("rds_handle_cm_req",
}
/*
* Peer to peer connection. There is an active
* connection pending on this ep. The one with
* greater port guid becomes active and the
* other becomes passive.
*/
/* this node is active so reject this request */
return (IBT_CM_REJECT);
} else {
/*
* This session is not the active end, change it
* to passive end.
*/
}
} else {
}
/* continue with accepting the connection request for this channel */
return (IBT_CM_REJECT);
}
/* pre-post recv buffers in the RQ */
rds_post_recv_buf((void *)chanhdl);
return (IBT_CM_ACCEPT);
}
/*
* Handle an incoming CM REP
* Pre-post recv buffers for the QP
*/
/* ARGSUSED */
static ibt_cm_status_t
{
/* pre-post recv buffers in the RQ */
sizeof (rds_cm_private_data_t));
rargsp->cm_ret_len = 0;
return (IBT_CM_ACCEPT);
}
/*
* Handle CONN EST
*/
static ibt_cm_status_t
{
(void) rds_session_active(sp);
return (IBT_CM_ACCEPT);
}
/*
* Handle CONN CLOSED
*/
static ibt_cm_status_t
{
/* Catch DREQs but ignore DREPs */
RDS_DPRINTF2("rds_handle_cm_conn_closed",
return (IBT_CM_ACCEPT);
}
/* Ignore this DREQ */
RDS_DPRINTF2("rds_handle_cm_conn_closed",
return (IBT_CM_ACCEPT);
}
sp->session_state);
switch (sp->session_state) {
"RDS_SESSION_STATE_PASSIVE_CLOSING", sp);
break;
"RDS_SESSION_STATE_CLOSED", sp);
RDS_DPRINTF3("rds_handle_cm_conn_closed",
"SP(%p) State RDS_SESSION_STATE_FINI", sp);
break;
case RDS_SESSION_STATE_ERROR:
case RDS_SESSION_STATE_CLOSED:
break;
case RDS_SESSION_STATE_INIT:
"RDS_SESSION_STATE_ERROR", sp);
RDS_DPRINTF3("rds_handle_cm_conn_closed",
"SP(%p) State RDS_SESSION_STATE_FAILED", sp);
break;
default:
RDS_DPRINTF2("rds_handle_cm_conn_closed",
"RDS_SESSION_STATE_FAILED", sp);
}
return (IBT_CM_ACCEPT);
}
/*
* Handle EVENT FAILURE
*/
static ibt_cm_status_t
{
int ret;
return (IBT_CM_ACCEPT);
}
RDS_DPRINTF2("rds_handle_cm_event_failure",
RDS_DPRINTF3("rds_handle_cm_event_failure",
"SP(%p) State RDS_SESSION_STATE_ERROR", sp);
/*
* Store the cm_channel for freeing later
* Active side frees it on ibt_open_rc_channel
* failure
*/
}
/*
* rds_passive_session_fini should not be called
* directly in the CM handler. It will cause a deadlock.
*/
rds_cleanup_passive_session, (void *)sp,
if (ret != DDI_SUCCESS) {
RDS_DPRINTF1("rds_handle_cm_event_failure",
}
return (IBT_CM_ACCEPT);
}
}
return (IBT_CM_ACCEPT);
}
/*
* CM Handler
*
* Called by IBCM
* The cm_private type differs for active and passive events.
*/
{
case IBT_CM_EVENT_REQ_RCV:
break;
case IBT_CM_EVENT_REP_RCV:
break;
case IBT_CM_EVENT_MRA_RCV:
/* Not supported */
break;
case IBT_CM_EVENT_CONN_EST:
break;
case IBT_CM_EVENT_CONN_CLOSED:
break;
case IBT_CM_EVENT_FAILURE:
break;
case IBT_CM_EVENT_LAP_RCV:
/* Not supported */
break;
case IBT_CM_EVENT_APR_RCV:
/* Not supported */
break;
default:
break;
}
return (ret);
}
/*
* Register the wellknown service with service id: RDS_SERVICE_ID
* Incoming connection requests should arrive on this service id.
*/
{
int ret;
if (ret != IBT_SUCCESS) {
ret);
return (NULL);
}
return (srvhdl);
}
/* Bind the RDS service on all ports */
int
{
int ret;
nports++;
/*
* service bind will be called in the async
* handler when the port comes up
*/
continue;
}
/* pass statep as cm_private */
if (ret != IBT_SUCCESS) {
"HCA: 0x%llx Port: %d gid %llx:%llx "
continue;
}
nbinds++;
}
}
#if 0
if (nbinds == 0) {
return (-1);
}
#endif
return (0);
}
/* Open an RC connection */
int
{
int ret = 0;
return (-1);
}
if (ret != IBT_SUCCESS) {
(void) ibt_flush_channel(hdl);
(void) ibt_free_channel(hdl);
/* cleanup stuff allocated in rds_ep_alloc_rc_channel */
return (-1);
}
*chanhdl);
return (0);
}
int
{
int ret;
return (ret);
}