Ver código fonte

[infiniband] Disambiguate CM connection rejection reasons

There is diagnostic value in being able to disambiguate between the
various reasons why an IB CM has rejected a connection attempt.  In
particular, reason 8 "invalid service ID" can be used to identify an
incorrect SRP service_id root-path component, and reason 28 "consumer
reject" corresponds to a genuine SRP login rejection IU, which can be
passed up to the SRP layer.

For rejection reasons other than "consumer reject", we should not pass
through the private data, since it is most likely generated by the CM
without any protocol-specific knowledge.
tags/v0.9.8
Michael Brown 15 anos atrás
pai
commit
0ff5c456cb

+ 5
- 0
src/include/gpxe/ib_mad.h Ver arquivo

402
 	uint8_t private_data[148];
402
 	uint8_t private_data[148];
403
 } __attribute__ (( packed ));
403
 } __attribute__ (( packed ));
404
 
404
 
405
+/** CM rejection reasons */
406
+#define IB_CM_REJECT_BAD_SERVICE_ID	8
407
+#define IB_CM_REJECT_STALE_CONN		10
408
+#define IB_CM_REJECT_CONSUMER		28
409
+
405
 /** A communication management connection reply
410
 /** A communication management connection reply
406
  *
411
  *
407
  * Defined in section 12.6.8 of the IBA.
412
  * Defined in section 12.6.8 of the IBA.

+ 25
- 3
src/net/infiniband/ib_cm.c Ver arquivo

122
 	},
122
 	},
123
 };
123
 };
124
 
124
 
125
+/**
126
+ * Convert connection rejection reason to return status code
127
+ *
128
+ * @v reason		Rejection reason (in network byte order)
129
+ * @ret rc		Return status code
130
+ */
131
+static int ib_cm_rejection_reason_to_rc ( uint16_t reason ) {
132
+	switch ( reason ) {
133
+	case htons ( IB_CM_REJECT_BAD_SERVICE_ID ) :
134
+		return -ENODEV;
135
+	case htons ( IB_CM_REJECT_STALE_CONN ) :
136
+		return -EALREADY;
137
+	case htons ( IB_CM_REJECT_CONSUMER ) :
138
+		return -ENOTTY;
139
+	default:
140
+		return -EPERM;
141
+	}
142
+}
143
+
125
 /**
144
 /**
126
  * Handle connection request transaction completion
145
  * Handle connection request transaction completion
127
  *
146
  *
189
 		/* Extract fields */
208
 		/* Extract fields */
190
 		DBGC ( conn, "CM %p connection rejected (reason %d)\n",
209
 		DBGC ( conn, "CM %p connection rejected (reason %d)\n",
191
 		       conn, ntohs ( connect_rej->reason ) );
210
 		       conn, ntohs ( connect_rej->reason ) );
192
-		private_data = &connect_rej->private_data;
193
-		private_data_len = sizeof ( connect_rej->private_data );
194
-		rc = -ENOTCONN;
211
+		/* Private data is valid only for a Consumer Reject */
212
+		if ( connect_rej->reason == htons ( IB_CM_REJECT_CONSUMER ) ) {
213
+			private_data = &connect_rej->private_data;
214
+			private_data_len = sizeof (connect_rej->private_data);
215
+		}
216
+		rc = ib_cm_rejection_reason_to_rc ( connect_rej->reason );
195
 		break;
217
 		break;
196
 
218
 
197
 	default:
219
 	default:

+ 2
- 1
src/net/infiniband/ib_cmrc.c Ver arquivo

172
 	/* Pass up any private data */
172
 	/* Pass up any private data */
173
 	DBGC2 ( cmrc, "CMRC %p received private data:\n", cmrc );
173
 	DBGC2 ( cmrc, "CMRC %p received private data:\n", cmrc );
174
 	DBGC2_HDA ( cmrc, 0, private_data, private_data_len );
174
 	DBGC2_HDA ( cmrc, 0, private_data, private_data_len );
175
-	if ( ( rc_xfer = xfer_deliver_raw ( &cmrc->xfer, private_data,
175
+	if ( private_data &&
176
+	     ( rc_xfer = xfer_deliver_raw ( &cmrc->xfer, private_data,
176
 					    private_data_len ) ) != 0 ) {
177
 					    private_data_len ) ) != 0 ) {
177
 		DBGC ( cmrc, "CMRC %p could not deliver private data: %s\n",
178
 		DBGC ( cmrc, "CMRC %p could not deliver private data: %s\n",
178
 		       cmrc, strerror ( rc_xfer ) );
179
 		       cmrc, strerror ( rc_xfer ) );

Carregando…
Cancelar
Salvar