[ipxe-devel] [PATCH] [iscsi] Process NOP-In commands.

Thomas Miletich thomas.miletich at gmail.com
Mon Feb 14 22:46:32 UTC 2011


Hello,
a user in #etherboot(Marc Lecuyer, CCed), reported a problem with his
Synology DS207+ nas acting as iscsi target.
The iscsi target was sending iscsi NOP-In[1] packets to gPXE, which it
didn't recognize and then aborted the iscsi transfer.
The following patch adds rudimentary support for processing nop-in packets.

I'm pretty sure there will be issues with this patch, but I don't know
enough about iSCSI and the [i|g]PXE iscsi code, so I hope someone more
knowledgeable can take a look at it.

Attached is also a single Nop-In packet sent from the target to the
gPXE client. A full packet capture is available, but I didn't want to
spam the list with a 400kb attachment.

[1] http://www.apps.ietf.org/rfc/rfc3720.html#sec-10.19

Thomas Miletich

------------------------


Add rudimentary support for iscsi NOP-In packets.

Reported-by: Marc Lecuyer <marc at maxiscreen.com>
Tested-by: Marc Lecuyer <marc at maxiscreen.com>
Signed-off-by: Thomas Miletich <thomas.miletich at gmail.com>
---
 src/include/gpxe/iscsi.h |   25 +++++++++++++++++++++++++
 src/net/tcp/iscsi.c      |   21 +++++++++++++++++++++
 2 files changed, 46 insertions(+), 0 deletions(-)

diff --git a/src/include/gpxe/iscsi.h b/src/include/gpxe/iscsi.h
index 00717d2..9be7347 100644
--- a/src/include/gpxe/iscsi.h
+++ b/src/include/gpxe/iscsi.h
@@ -411,6 +411,31 @@ struct iscsi_bhs_data_out {
       uint32_t reserved_d;
 };

+#define ISCSI_OPCODE_NOP_IN 0x20
+
+struct iscsi_nop_in {
+       /** Opcode */
+       uint8_t opcode;
+       /** Reserved */
+       uint8_t reserved_a[3];
+       /** Segment lengths */
+       union iscsi_segment_lengths lengths;
+       /** Logical Unit Number */
+       struct scsi_lun lun;
+       /** Initiator Task Tag */
+       uint32_t itt;
+       /** Target Transfer Tag */
+       uint32_t ttt;
+       /** Status sequence number */
+       uint32_t statsn;
+       /** Expected command sequence number */
+       uint32_t expcmdsn;
+       /** Maximum command sequence number */
+       uint32_t maxcmdsn;
+       /** Reserved */
+       uint8_t reserved_b[12];
+};
+
 /** Data-out opcode */
 #define ISCSI_OPCODE_DATA_OUT 0x05

diff --git a/src/net/tcp/iscsi.c b/src/net/tcp/iscsi.c
index c91bb8e..4c95d6e 100644
--- a/src/net/tcp/iscsi.c
+++ b/src/net/tcp/iscsi.c
@@ -383,6 +383,25 @@ static int iscsi_rx_r2t ( struct iscsi_session *iscsi,
 }

 /**
+ * Receive data segment of an iSCSI NOP-In
+ *
+ * @v iscsi            iSCSI session
+ * @v data             Received data
+ * @v len              Length of received data
+ * @v remaining                Data remaining after this data
+ * @ret rc             Return status code
+ */
+static int iscsi_rx_nop_in ( struct iscsi_session *iscsi,
+                         const void *data __unused, size_t len __unused,
+                         size_t remaining __unused ) {
+       struct iscsi_nop_in *nop = ( struct iscsi_nop_in * )iscsi->rx_bhs.bytes;
+
+       iscsi->cmdsn = ntohl ( nop->expcmdsn );
+
+       return 0;
+}
+
+/**
 * Build iSCSI data-out BHS
 *
 * @v iscsi            iSCSI session
@@ -1423,6 +1442,8 @@ static int iscsi_rx_data ( struct iscsi_session
*iscsi, const void *data,
               return iscsi_rx_data_in ( iscsi, data, len, remaining );
       case ISCSI_OPCODE_R2T:
               return iscsi_rx_r2t ( iscsi, data, len, remaining );
+       case ISCSI_OPCODE_NOP_IN:
+               return iscsi_rx_nop_in ( iscsi, data, len, remaining );
       default:
               if ( remaining )
                       return 0;
--
1.7.1
-------------- next part --------------
A non-text attachment was scrubbed...
Name: nop-in.pcap
Type: application/cap
Size: 158 bytes
Desc: not available
URL: <http://lists.ipxe.org/pipermail/ipxe-devel/attachments/20110214/6ba05c0d/attachment.bin>


More information about the ipxe-devel mailing list