Skip to content

Commit 1d29377

Browse files
committedMar 1, 2012
[iscsi] Send any padding inline with the data segment
Some iSCSI targets respond to a PDU before receiving the padding bytes. If the target responds quickly enough, this can cause iPXE to start processing a new TX PDU before the padding bytes have been sent, which results in a protocol violation. Fix by always transmitting the padding bytes along with the data segment. Originally-fixed-by: Shyam Iyer <shyam_iyer@dell.com> Signed-off-by: Michael Brown <mcb30@ipxe.org>
1 parent cb10137 commit 1d29377

File tree

2 files changed

+9
-30
lines changed

2 files changed

+9
-30
lines changed
 

‎src/include/ipxe/iscsi.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -515,8 +515,6 @@ enum iscsi_tx_state {
515515
ISCSI_TX_AHS,
516516
/** Sending the data segment */
517517
ISCSI_TX_DATA,
518-
/** Sending the data segment padding */
519-
ISCSI_TX_DATA_PADDING,
520518
};
521519

522520
/** State of an iSCSI RX engine */

‎src/net/tcp/iscsi.c

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -570,20 +570,23 @@ static int iscsi_tx_data_out ( struct iscsi_session *iscsi ) {
570570
struct io_buffer *iobuf;
571571
unsigned long offset;
572572
size_t len;
573+
size_t pad_len;
573574

574575
offset = ntohl ( data_out->offset );
575576
len = ISCSI_DATA_LEN ( data_out->lengths );
577+
pad_len = ISCSI_DATA_PAD_LEN ( data_out->lengths );
576578

577579
assert ( iscsi->command != NULL );
578580
assert ( iscsi->command->data_out );
579581
assert ( ( offset + len ) <= iscsi->command->data_out_len );
580582

581-
iobuf = xfer_alloc_iob ( &iscsi->socket, len );
583+
iobuf = xfer_alloc_iob ( &iscsi->socket, ( len + pad_len ) );
582584
if ( ! iobuf )
583585
return -ENOMEM;
584586

585587
copy_from_user ( iob_put ( iobuf, len ),
586588
iscsi->command->data_out, offset, len );
589+
memset ( iob_put ( iobuf, pad_len ), 0, pad_len );
587590

588591
return xfer_deliver_iob ( &iscsi->socket, iobuf );
589592
}
@@ -801,13 +804,17 @@ static int iscsi_tx_login_request ( struct iscsi_session *iscsi ) {
801804
struct iscsi_bhs_login_request *request = &iscsi->tx_bhs.login_request;
802805
struct io_buffer *iobuf;
803806
size_t len;
807+
size_t pad_len;
804808

805809
len = ISCSI_DATA_LEN ( request->lengths );
806-
iobuf = xfer_alloc_iob ( &iscsi->socket, len );
810+
pad_len = ISCSI_DATA_PAD_LEN ( request->lengths );
811+
iobuf = xfer_alloc_iob ( &iscsi->socket, ( len + pad_len ) );
807812
if ( ! iobuf )
808813
return -ENOMEM;
809814
iob_put ( iobuf, len );
810815
iscsi_build_login_request_strings ( iscsi, iobuf->data, len );
816+
memset ( iob_put ( iobuf, pad_len ), 0, pad_len );
817+
811818
return xfer_deliver_iob ( &iscsi->socket, iobuf );
812819
}
813820

@@ -1415,27 +1422,6 @@ static int iscsi_tx_data ( struct iscsi_session *iscsi ) {
14151422
}
14161423
}
14171424

1418-
/**
1419-
* Transmit data padding of an iSCSI PDU
1420-
*
1421-
* @v iscsi iSCSI session
1422-
* @ret rc Return status code
1423-
*
1424-
* Handle transmission of any data padding in a PDU data segment.
1425-
* iscsi::tx_bhs will be valid when this is called.
1426-
*/
1427-
static int iscsi_tx_data_padding ( struct iscsi_session *iscsi ) {
1428-
static const char pad[] = { '\0', '\0', '\0' };
1429-
struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
1430-
size_t pad_len;
1431-
1432-
pad_len = ISCSI_DATA_PAD_LEN ( common->lengths );
1433-
if ( ! pad_len )
1434-
return 0;
1435-
1436-
return xfer_deliver_raw ( &iscsi->socket, pad, pad_len );
1437-
}
1438-
14391425
/**
14401426
* Complete iSCSI PDU transmission
14411427
*
@@ -1494,11 +1480,6 @@ static void iscsi_tx_step ( struct iscsi_session *iscsi ) {
14941480
case ISCSI_TX_DATA:
14951481
tx = iscsi_tx_data;
14961482
tx_len = ISCSI_DATA_LEN ( common->lengths );
1497-
next_state = ISCSI_TX_DATA_PADDING;
1498-
break;
1499-
case ISCSI_TX_DATA_PADDING:
1500-
tx = iscsi_tx_data_padding;
1501-
tx_len = ISCSI_DATA_PAD_LEN ( common->lengths );
15021483
next_state = ISCSI_TX_IDLE;
15031484
break;
15041485
case ISCSI_TX_IDLE:

0 commit comments

Comments
 (0)
Please sign in to comment.