|
@@ -291,30 +291,45 @@ static void iscsi_tx_data_out ( struct iscsi_session *iscsi,
|
291
|
291
|
*/
|
292
|
292
|
static int iscsi_build_login_request_strings ( struct iscsi_session *iscsi,
|
293
|
293
|
void *data, size_t len ) {
|
294
|
|
- return snprintf ( data, len,
|
295
|
|
- "InitiatorName=%s%c"
|
296
|
|
- "TargetName=%s%c"
|
297
|
|
- "SessionType=Normal%c"
|
298
|
|
- "HeaderDigest=None%c"
|
299
|
|
- "DataDigest=None%c"
|
300
|
|
- "InitialR2T=Yes%c"
|
301
|
|
- "DefaultTime2Wait=0%c"
|
302
|
|
- "DefaultTime2Retain=0%c"
|
303
|
|
- "MaxOutstandingR2T=1%c"
|
304
|
|
- "DataPDUInOrder=Yes%c"
|
305
|
|
- "DataSequenceInOrder=Yes%c"
|
306
|
|
- "ErrorRecoveryLevel=0%c",
|
307
|
|
- iscsi->initiator, 0, iscsi->target, 0,
|
308
|
|
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 );
|
|
294
|
+ struct iscsi_bhs_login_request *request = &iscsi->tx_bhs.login_request;
|
|
295
|
+
|
|
296
|
+ switch ( request->flags & ISCSI_LOGIN_CSG_MASK ) {
|
|
297
|
+ case ISCSI_LOGIN_CSG_SECURITY_NEGOTIATION:
|
|
298
|
+ return snprintf ( data, len,
|
|
299
|
+ "InitiatorName=%s%c"
|
|
300
|
+ "TargetName=%s%c"
|
|
301
|
+ "SessionType=Normal%c"
|
|
302
|
+ "AuthMethod=CHAP,None%c"
|
|
303
|
+ "CHAP_A=5%c",
|
|
304
|
+ iscsi->initiator, 0, iscsi->target, 0,
|
|
305
|
+ 0, 0, 0 );
|
|
306
|
+ case ISCSI_LOGIN_CSG_OPERATIONAL_NEGOTIATION:
|
|
307
|
+ return snprintf ( data, len,
|
|
308
|
+ "HeaderDigest=None%c"
|
|
309
|
+ "DataDigest=None%c"
|
|
310
|
+ "InitialR2T=Yes%c"
|
|
311
|
+ "DefaultTime2Wait=0%c"
|
|
312
|
+ "DefaultTime2Retain=0%c"
|
|
313
|
+ "MaxOutstandingR2T=1%c"
|
|
314
|
+ "DataPDUInOrder=Yes%c"
|
|
315
|
+ "DataSequenceInOrder=Yes%c"
|
|
316
|
+ "ErrorRecoveryLevel=0%c",
|
|
317
|
+ 0, 0, 0, 0, 0, 0, 0, 0, 0 );
|
|
318
|
+ default:
|
|
319
|
+ assert ( 0 );
|
|
320
|
+ return 0;
|
|
321
|
+ }
|
309
|
322
|
}
|
310
|
323
|
|
311
|
324
|
/**
|
312
|
325
|
* Build iSCSI login request BHS
|
313
|
326
|
*
|
314
|
327
|
* @v iscsi iSCSI session
|
315
|
|
- * @v first Login request is the first in a sequence
|
|
328
|
+ * @v stage Current stage of iSCSI login
|
|
329
|
+ * @v send_strings Send login strings with this login request
|
316
|
330
|
*/
|
317
|
|
-static void iscsi_start_login ( struct iscsi_session *iscsi, int first ) {
|
|
331
|
+static void iscsi_start_login ( struct iscsi_session *iscsi,
|
|
332
|
+ int stage, int send_strings ) {
|
318
|
333
|
struct iscsi_bhs_login_request *request = &iscsi->tx_bhs.login_request;
|
319
|
334
|
int len;
|
320
|
335
|
|
|
@@ -322,11 +337,10 @@ static void iscsi_start_login ( struct iscsi_session *iscsi, int first ) {
|
322
|
337
|
iscsi_start_tx ( iscsi );
|
323
|
338
|
request->opcode = ( ISCSI_OPCODE_LOGIN_REQUEST |
|
324
|
339
|
ISCSI_FLAG_IMMEDIATE );
|
325
|
|
- request->flags = ( ISCSI_LOGIN_FLAG_TRANSITION |
|
326
|
|
- ISCSI_LOGIN_CSG_OPERATIONAL_NEGOTIATION |
|
327
|
|
- ISCSI_LOGIN_NSG_FULL_FEATURE_PHASE );
|
|
340
|
+ request->flags = ( ISCSI_LOGIN_FLAG_TRANSITION | stage );
|
|
341
|
+
|
328
|
342
|
/* version_max and version_min left as zero */
|
329
|
|
- if ( first ) {
|
|
343
|
+ if ( send_strings ) {
|
330
|
344
|
len = iscsi_build_login_request_strings ( iscsi, NULL, 0 );
|
331
|
345
|
ISCSI_SET_LENGTHS ( request->lengths, 0, len );
|
332
|
346
|
}
|
|
@@ -334,8 +348,6 @@ static void iscsi_start_login ( struct iscsi_session *iscsi, int first ) {
|
334
|
348
|
IANA_EN_FEN_SYSTEMS );
|
335
|
349
|
/* isid_iana_qual left as zero */
|
336
|
350
|
request->tsih = htons ( iscsi->tsih );
|
337
|
|
- if ( first )
|
338
|
|
- iscsi->itt++;
|
339
|
351
|
request->itt = htonl ( iscsi->itt );
|
340
|
352
|
/* cid left as zero */
|
341
|
353
|
request->cmdsn = htonl ( iscsi->cmdsn );
|
|
@@ -387,7 +399,17 @@ static void iscsi_rx_login_response ( struct iscsi_session *iscsi,
|
387
|
399
|
* request without any login strings.
|
388
|
400
|
*/
|
389
|
401
|
if ( ! ( response->flags & ISCSI_LOGIN_FLAG_TRANSITION ) ) {
|
390
|
|
- iscsi_start_login ( iscsi, 0 );
|
|
402
|
+ iscsi_start_login ( iscsi, ( response->flags &
|
|
403
|
+ ISCSI_LOGIN_STAGE_MASK ), 0 );
|
|
404
|
+ return;
|
|
405
|
+ }
|
|
406
|
+
|
|
407
|
+ /* If we are transitioning to the operational phase, send the
|
|
408
|
+ * operational phase login request.
|
|
409
|
+ */
|
|
410
|
+ if ( ( response->flags & ISCSI_LOGIN_NSG_MASK ) ==
|
|
411
|
+ ISCSI_LOGIN_NSG_OPERATIONAL_NEGOTIATION ) {
|
|
412
|
+ iscsi_start_login ( iscsi, ISCSI_LOGIN_STAGE_OP, 1 );
|
391
|
413
|
return;
|
392
|
414
|
}
|
393
|
415
|
|
|
@@ -762,8 +784,11 @@ static void iscsi_connected ( struct tcp_connection *conn ) {
|
762
|
784
|
iscsi->rx_state = ISCSI_RX_BHS;
|
763
|
785
|
iscsi->rx_offset = 0;
|
764
|
786
|
|
|
787
|
+ /* Assign fresh initiator task tag */
|
|
788
|
+ iscsi->itt++;
|
|
789
|
+
|
765
|
790
|
/* Start logging in */
|
766
|
|
- iscsi_start_login ( iscsi, 1 );
|
|
791
|
+ iscsi_start_login ( iscsi, ISCSI_LOGIN_STAGE_SEC, 1 );
|
767
|
792
|
}
|
768
|
793
|
|
769
|
794
|
/** iSCSI TCP operations */
|