uint8_t private_data[148];
} __attribute__ (( packed ));
+/** CM rejection reasons */
+#define IB_CM_REJECT_BAD_SERVICE_ID 8
+#define IB_CM_REJECT_STALE_CONN 10
+#define IB_CM_REJECT_CONSUMER 28
+
/** A communication management connection reply
*
* Defined in section 12.6.8 of the IBA.
},
};
+/**
+ * Convert connection rejection reason to return status code
+ *
+ * @v reason Rejection reason (in network byte order)
+ * @ret rc Return status code
+ */
+static int ib_cm_rejection_reason_to_rc ( uint16_t reason ) {
+ switch ( reason ) {
+ case htons ( IB_CM_REJECT_BAD_SERVICE_ID ) :
+ return -ENODEV;
+ case htons ( IB_CM_REJECT_STALE_CONN ) :
+ return -EALREADY;
+ case htons ( IB_CM_REJECT_CONSUMER ) :
+ return -ENOTTY;
+ default:
+ return -EPERM;
+ }
+}
+
/**
* Handle connection request transaction completion
*
/* Extract fields */
DBGC ( conn, "CM %p connection rejected (reason %d)\n",
conn, ntohs ( connect_rej->reason ) );
- private_data = &connect_rej->private_data;
- private_data_len = sizeof ( connect_rej->private_data );
- rc = -ENOTCONN;
+ /* Private data is valid only for a Consumer Reject */
+ if ( connect_rej->reason == htons ( IB_CM_REJECT_CONSUMER ) ) {
+ private_data = &connect_rej->private_data;
+ private_data_len = sizeof (connect_rej->private_data);
+ }
+ rc = ib_cm_rejection_reason_to_rc ( connect_rej->reason );
break;
default:
/* Pass up any private data */
DBGC2 ( cmrc, "CMRC %p received private data:\n", cmrc );
DBGC2_HDA ( cmrc, 0, private_data, private_data_len );
- if ( ( rc_xfer = xfer_deliver_raw ( &cmrc->xfer, private_data,
+ if ( private_data &&
+ ( rc_xfer = xfer_deliver_raw ( &cmrc->xfer, private_data,
private_data_len ) ) != 0 ) {
DBGC ( cmrc, "CMRC %p could not deliver private data: %s\n",
cmrc, strerror ( rc_xfer ) );