summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichael Brown2006-10-03 11:17:38 +0200
committerMichael Brown2006-10-03 11:17:38 +0200
commitfedc186fd76156017abdcd7981faae89c8fc0ad8 (patch)
treebe2f6054e5db04abdd4088ac20d6cf981d4a5912 /src
parentInhibit compiler warnings on DBG() when building a non-debug object, (diff)
downloadipxe-fedc186fd76156017abdcd7981faae89c8fc0ad8.tar.gz
ipxe-fedc186fd76156017abdcd7981faae89c8fc0ad8.tar.xz
ipxe-fedc186fd76156017abdcd7981faae89c8fc0ad8.zip
Split login into security negotation and operational parameter
negotiation phases, to allow inclusion of CHAP authentication.
Diffstat (limited to 'src')
-rw-r--r--src/include/gpxe/iscsi.h7
-rw-r--r--src/net/tcp/iscsi.c75
2 files changed, 57 insertions, 25 deletions
diff --git a/src/include/gpxe/iscsi.h b/src/include/gpxe/iscsi.h
index 4d0da132d..6c7b43e07 100644
--- a/src/include/gpxe/iscsi.h
+++ b/src/include/gpxe/iscsi.h
@@ -167,6 +167,13 @@ struct iscsi_bhs_login_request {
#define ISCSI_LOGIN_NSG_OPERATIONAL_NEGOTIATION 0x01
#define ISCSI_LOGIN_NSG_FULL_FEATURE_PHASE 0x03
+/* Combined stage values and mask */
+#define ISCSI_LOGIN_STAGE_MASK ( ISCSI_LOGIN_CSG_MASK | ISCSI_LOGIN_NSG_MASK )
+#define ISCSI_LOGIN_STAGE_SEC ( ISCSI_LOGIN_CSG_SECURITY_NEGOTIATION | \
+ ISCSI_LOGIN_NSG_OPERATIONAL_NEGOTIATION )
+#define ISCSI_LOGIN_STAGE_OP ( ISCSI_LOGIN_CSG_OPERATIONAL_NEGOTIATION | \
+ ISCSI_LOGIN_NSG_FULL_FEATURE_PHASE )
+
/** ISID IANA format marker */
#define ISCSI_ISID_IANA 0x40000000
diff --git a/src/net/tcp/iscsi.c b/src/net/tcp/iscsi.c
index 9412373f1..26fd35301 100644
--- a/src/net/tcp/iscsi.c
+++ b/src/net/tcp/iscsi.c
@@ -291,30 +291,45 @@ static void iscsi_tx_data_out ( struct iscsi_session *iscsi,
*/
static int iscsi_build_login_request_strings ( struct iscsi_session *iscsi,
void *data, size_t len ) {
- return snprintf ( data, len,
- "InitiatorName=%s%c"
- "TargetName=%s%c"
- "SessionType=Normal%c"
- "HeaderDigest=None%c"
- "DataDigest=None%c"
- "InitialR2T=Yes%c"
- "DefaultTime2Wait=0%c"
- "DefaultTime2Retain=0%c"
- "MaxOutstandingR2T=1%c"
- "DataPDUInOrder=Yes%c"
- "DataSequenceInOrder=Yes%c"
- "ErrorRecoveryLevel=0%c",
- iscsi->initiator, 0, iscsi->target, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 );
+ struct iscsi_bhs_login_request *request = &iscsi->tx_bhs.login_request;
+
+ switch ( request->flags & ISCSI_LOGIN_CSG_MASK ) {
+ case ISCSI_LOGIN_CSG_SECURITY_NEGOTIATION:
+ return snprintf ( data, len,
+ "InitiatorName=%s%c"
+ "TargetName=%s%c"
+ "SessionType=Normal%c"
+ "AuthMethod=CHAP,None%c"
+ "CHAP_A=5%c",
+ iscsi->initiator, 0, iscsi->target, 0,
+ 0, 0, 0 );
+ case ISCSI_LOGIN_CSG_OPERATIONAL_NEGOTIATION:
+ return snprintf ( data, len,
+ "HeaderDigest=None%c"
+ "DataDigest=None%c"
+ "InitialR2T=Yes%c"
+ "DefaultTime2Wait=0%c"
+ "DefaultTime2Retain=0%c"
+ "MaxOutstandingR2T=1%c"
+ "DataPDUInOrder=Yes%c"
+ "DataSequenceInOrder=Yes%c"
+ "ErrorRecoveryLevel=0%c",
+ 0, 0, 0, 0, 0, 0, 0, 0, 0 );
+ default:
+ assert ( 0 );
+ return 0;
+ }
}
/**
* Build iSCSI login request BHS
*
* @v iscsi iSCSI session
- * @v first Login request is the first in a sequence
+ * @v stage Current stage of iSCSI login
+ * @v send_strings Send login strings with this login request
*/
-static void iscsi_start_login ( struct iscsi_session *iscsi, int first ) {
+static void iscsi_start_login ( struct iscsi_session *iscsi,
+ int stage, int send_strings ) {
struct iscsi_bhs_login_request *request = &iscsi->tx_bhs.login_request;
int len;
@@ -322,11 +337,10 @@ static void iscsi_start_login ( struct iscsi_session *iscsi, int first ) {
iscsi_start_tx ( iscsi );
request->opcode = ( ISCSI_OPCODE_LOGIN_REQUEST |
ISCSI_FLAG_IMMEDIATE );
- request->flags = ( ISCSI_LOGIN_FLAG_TRANSITION |
- ISCSI_LOGIN_CSG_OPERATIONAL_NEGOTIATION |
- ISCSI_LOGIN_NSG_FULL_FEATURE_PHASE );
+ request->flags = ( ISCSI_LOGIN_FLAG_TRANSITION | stage );
+
/* version_max and version_min left as zero */
- if ( first ) {
+ if ( send_strings ) {
len = iscsi_build_login_request_strings ( iscsi, NULL, 0 );
ISCSI_SET_LENGTHS ( request->lengths, 0, len );
}
@@ -334,8 +348,6 @@ static void iscsi_start_login ( struct iscsi_session *iscsi, int first ) {
IANA_EN_FEN_SYSTEMS );
/* isid_iana_qual left as zero */
request->tsih = htons ( iscsi->tsih );
- if ( first )
- iscsi->itt++;
request->itt = htonl ( iscsi->itt );
/* cid left as zero */
request->cmdsn = htonl ( iscsi->cmdsn );
@@ -387,7 +399,17 @@ static void iscsi_rx_login_response ( struct iscsi_session *iscsi,
* request without any login strings.
*/
if ( ! ( response->flags & ISCSI_LOGIN_FLAG_TRANSITION ) ) {
- iscsi_start_login ( iscsi, 0 );
+ iscsi_start_login ( iscsi, ( response->flags &
+ ISCSI_LOGIN_STAGE_MASK ), 0 );
+ return;
+ }
+
+ /* If we are transitioning to the operational phase, send the
+ * operational phase login request.
+ */
+ if ( ( response->flags & ISCSI_LOGIN_NSG_MASK ) ==
+ ISCSI_LOGIN_NSG_OPERATIONAL_NEGOTIATION ) {
+ iscsi_start_login ( iscsi, ISCSI_LOGIN_STAGE_OP, 1 );
return;
}
@@ -762,8 +784,11 @@ static void iscsi_connected ( struct tcp_connection *conn ) {
iscsi->rx_state = ISCSI_RX_BHS;
iscsi->rx_offset = 0;
+ /* Assign fresh initiator task tag */
+ iscsi->itt++;
+
/* Start logging in */
- iscsi_start_login ( iscsi, 1 );
+ iscsi_start_login ( iscsi, ISCSI_LOGIN_STAGE_SEC, 1 );
}
/** iSCSI TCP operations */