1
From 1d293776ea290ae1f4d1228f3278030facf97a4b Mon Sep 17 00:00:00 2001
2
From: Michael Brown <mcb30@ipxe.org>
3
Date: Thu, 1 Mar 2012 16:26:38 +0000
4
Subject: [PATCH] [iscsi] Send any padding inline with the data segment
6
Some iSCSI targets respond to a PDU before receiving the padding
7
bytes. If the target responds quickly enough, this can cause iPXE to
8
start processing a new TX PDU before the padding bytes have been sent,
9
which results in a protocol violation.
11
Fix by always transmitting the padding bytes along with the data
14
Originally-fixed-by: Shyam Iyer <shyam_iyer@dell.com>
15
Signed-off-by: Michael Brown <mcb30@ipxe.org>
17
src/include/ipxe/iscsi.h | 2 --
18
src/net/tcp/iscsi.c | 37 +++++++++----------------------------
19
2 files changed, 9 insertions(+), 30 deletions(-)
21
diff --git a/src/include/ipxe/iscsi.h b/src/include/ipxe/iscsi.h
22
index 5d3d73b..b4de793 100644
23
--- a/src/include/ipxe/iscsi.h
24
+++ b/src/include/ipxe/iscsi.h
25
@@ -515,8 +515,6 @@ enum iscsi_tx_state {
27
/** Sending the data segment */
29
- /** Sending the data segment padding */
30
- ISCSI_TX_DATA_PADDING,
33
/** State of an iSCSI RX engine */
34
diff --git a/src/net/tcp/iscsi.c b/src/net/tcp/iscsi.c
35
index fa1bb39..9eaf3cc 100644
36
--- a/src/net/tcp/iscsi.c
37
+++ b/src/net/tcp/iscsi.c
38
@@ -570,20 +570,23 @@ static int iscsi_tx_data_out ( struct iscsi_session *iscsi ) {
39
struct io_buffer *iobuf;
44
offset = ntohl ( data_out->offset );
45
len = ISCSI_DATA_LEN ( data_out->lengths );
46
+ pad_len = ISCSI_DATA_PAD_LEN ( data_out->lengths );
48
assert ( iscsi->command != NULL );
49
assert ( iscsi->command->data_out );
50
assert ( ( offset + len ) <= iscsi->command->data_out_len );
52
- iobuf = xfer_alloc_iob ( &iscsi->socket, len );
53
+ iobuf = xfer_alloc_iob ( &iscsi->socket, ( len + pad_len ) );
57
copy_from_user ( iob_put ( iobuf, len ),
58
iscsi->command->data_out, offset, len );
59
+ memset ( iob_put ( iobuf, pad_len ), 0, pad_len );
61
return xfer_deliver_iob ( &iscsi->socket, iobuf );
63
@@ -801,13 +804,17 @@ static int iscsi_tx_login_request ( struct iscsi_session *iscsi ) {
64
struct iscsi_bhs_login_request *request = &iscsi->tx_bhs.login_request;
65
struct io_buffer *iobuf;
69
len = ISCSI_DATA_LEN ( request->lengths );
70
- iobuf = xfer_alloc_iob ( &iscsi->socket, len );
71
+ pad_len = ISCSI_DATA_PAD_LEN ( request->lengths );
72
+ iobuf = xfer_alloc_iob ( &iscsi->socket, ( len + pad_len ) );
75
iob_put ( iobuf, len );
76
iscsi_build_login_request_strings ( iscsi, iobuf->data, len );
77
+ memset ( iob_put ( iobuf, pad_len ), 0, pad_len );
79
return xfer_deliver_iob ( &iscsi->socket, iobuf );
82
@@ -1416,27 +1423,6 @@ static int iscsi_tx_data ( struct iscsi_session *iscsi ) {
86
- * Transmit data padding of an iSCSI PDU
88
- * @v iscsi iSCSI session
89
- * @ret rc Return status code
91
- * Handle transmission of any data padding in a PDU data segment.
92
- * iscsi::tx_bhs will be valid when this is called.
94
-static int iscsi_tx_data_padding ( struct iscsi_session *iscsi ) {
95
- static const char pad[] = { '\0', '\0', '\0' };
96
- struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
99
- pad_len = ISCSI_DATA_PAD_LEN ( common->lengths );
103
- return xfer_deliver_raw ( &iscsi->socket, pad, pad_len );
107
* Complete iSCSI PDU transmission
109
* @v iscsi iSCSI session
110
@@ -1494,11 +1480,6 @@ static void iscsi_tx_step ( struct iscsi_session *iscsi ) {
113
tx_len = ISCSI_DATA_LEN ( common->lengths );
114
- next_state = ISCSI_TX_DATA_PADDING;
116
- case ISCSI_TX_DATA_PADDING:
117
- tx = iscsi_tx_data_padding;
118
- tx_len = ISCSI_DATA_PAD_LEN ( common->lengths );
119
next_state = ISCSI_TX_IDLE;