Cannot immediately overwrite the peer address when we parse
[gpxe.git] / src / include / gpxe / iscsi.h
1 #ifndef _GPXE_ISCSI_H
2 #define _GPXE_ISCSI_H
3
4 /** @file
5  *
6  * iSCSI protocol
7  *
8  */
9
10 #include <stdint.h>
11 #include <gpxe/tcp.h>
12 #include <gpxe/async.h>
13 #include <gpxe/scsi.h>
14 #include <gpxe/chap.h>
15
16 /** Default iSCSI port */
17 #define ISCSI_PORT 3260
18
19 /**
20  * iSCSI segment lengths
21  *
22  * iSCSI uses an icky structure with one one-byte field (a dword
23  * count) and one three-byte field (a byte count).  This structure,
24  * and the accompanying macros, relieve some of the pain.
25  */
26 union iscsi_segment_lengths {
27         struct {
28                 /** The AHS length (measured in dwords) */
29                 uint8_t ahs_len;
30                 /** The data length (measured in bytes), in network
31                  * byte order
32                  */
33                 uint8_t data_len[3];
34         } bytes;
35         /** Ths data length (measured in bytes), in network byte
36          * order, with ahs_len as the first byte.
37          */
38         uint32_t ahs_and_data_len;
39 };
40
41 /** The length of the additional header segment, in dwords */
42 #define ISCSI_AHS_LEN( segment_lengths ) \
43         ( (segment_lengths).bytes.ahs_len )
44
45 /** The length of the data segment, in bytes, excluding any padding */
46 #define ISCSI_DATA_LEN( segment_lengths ) \
47         ( ntohl ( (segment_lengths).ahs_and_data_len ) & 0xffffff )
48
49 /** The padding of the data segment, in bytes */
50 #define ISCSI_DATA_PAD_LEN( segment_lengths ) \
51         ( ( 0 - (segment_lengths).bytes.data_len[2] ) & 0x03 )
52
53 /** Set additional header and data segment lengths */
54 #define ISCSI_SET_LENGTHS( segment_lengths, ahs_len, data_len ) do {    \
55         (segment_lengths).ahs_and_data_len =                            \
56                 htonl ( data_len | ( ahs_len << 24 ) );                 \
57         } while ( 0 )
58
59 /**
60  * iSCSI basic header segment common fields
61  *
62  */
63 struct iscsi_bhs_common {
64         /** Opcode */
65         uint8_t opcode;
66         /** Flags */
67         uint8_t flags;
68         /** Fields specific to the PDU type */
69         uint8_t other_a[2];
70         /** Segment lengths */
71         union iscsi_segment_lengths lengths;
72         /** Fields specific to the PDU type */
73         uint8_t other_b[8];
74         /** Initiator Task Tag */
75         uint32_t itt;
76         /** Fields specific to the PDU type */
77         uint8_t other_c[28];
78 };
79
80 /** Opcode mask */
81 #define ISCSI_OPCODE_MASK 0x3f
82
83 /** Immediate delivery */
84 #define ISCSI_FLAG_IMMEDIATE 0x40
85
86 /** Final PDU of a sequence */
87 #define ISCSI_FLAG_FINAL 0x80
88
89 /**
90  * iSCSI basic header segment common request fields
91  *
92  */
93 struct iscsi_bhs_common_response {
94         /** Opcode */
95         uint8_t opcode;
96         /** Flags */
97         uint8_t flags;
98         /** Fields specific to the PDU type */
99         uint8_t other_a[2];
100         /** Segment lengths */
101         union iscsi_segment_lengths lengths;
102         /** Fields specific to the PDU type */
103         uint8_t other_b[8];
104         /** Initiator Task Tag */
105         uint32_t itt;
106         /** Fields specific to the PDU type */
107         uint8_t other_c[4];
108         /** Status sequence number */
109         uint32_t statsn;
110         /** Expected command sequence number */
111         uint32_t expcmdsn;
112         /** Fields specific to the PDU type */
113         uint8_t other_d[16];
114 };
115
116 /**
117  * iSCSI login request basic header segment
118  *
119  */
120 struct iscsi_bhs_login_request {
121         /** Opcode */
122         uint8_t opcode;
123         /** Flags */
124         uint8_t flags;
125         /** Maximum supported version number */
126         uint8_t version_max;
127         /** Minimum supported version number */
128         uint8_t version_min;
129         /** Segment lengths */
130         union iscsi_segment_lengths lengths;
131         /** Initiator session ID (IANA format) enterprise number and flags */
132         uint32_t isid_iana_en;
133         /** Initiator session ID (IANA format) qualifier */
134         uint16_t isid_iana_qual;
135         /** Target session identifying handle */
136         uint16_t tsih;
137         /** Initiator Task Tag */
138         uint32_t itt;
139         /** Connection ID */
140         uint16_t cid;
141         /** Reserved */
142         uint16_t reserved_a;
143         /** Command sequence number */
144         uint32_t cmdsn;
145         /** Expected status sequence number */
146         uint32_t expstatsn;
147         /** Reserved */
148         uint8_t reserved_b[16];
149 };
150
151 /** Login request opcode */
152 #define ISCSI_OPCODE_LOGIN_REQUEST 0x03
153
154 /** Willingness to transition to next stage */
155 #define ISCSI_LOGIN_FLAG_TRANSITION 0x80
156
157 /** Key=value pairs continued in subsequent request */
158 #define ISCSI_LOGIN_FLAG_CONTINUE 0x40
159
160 /* Current stage values and mask */
161 #define ISCSI_LOGIN_CSG_MASK 0x0c
162 #define ISCSI_LOGIN_CSG_SECURITY_NEGOTIATION 0x00
163 #define ISCSI_LOGIN_CSG_OPERATIONAL_NEGOTIATION 0x04
164 #define ISCSI_LOGIN_CSG_FULL_FEATURE_PHASE 0x0c
165
166 /* Next stage values and mask */
167 #define ISCSI_LOGIN_NSG_MASK 0x03
168 #define ISCSI_LOGIN_NSG_SECURITY_NEGOTIATION 0x00
169 #define ISCSI_LOGIN_NSG_OPERATIONAL_NEGOTIATION 0x01
170 #define ISCSI_LOGIN_NSG_FULL_FEATURE_PHASE 0x03
171
172 /** ISID IANA format marker */
173 #define ISCSI_ISID_IANA 0x40000000
174
175 /** Fen Systems Ltd. IANA enterprise number
176  *
177  * Permission is hereby granted to use Fen Systems Ltd.'s IANA
178  * enterprise number with this iSCSI implementation.
179  */
180 #define IANA_EN_FEN_SYSTEMS 10019
181
182 /**
183  * iSCSI login response basic header segment
184  *
185  */
186 struct iscsi_bhs_login_response {
187         /** Opcode */
188         uint8_t opcode;
189         /** Flags */
190         uint8_t flags;
191         /** Maximum supported version number */
192         uint8_t version_max;
193         /** Minimum supported version number */
194         uint8_t version_min;
195         /** Segment lengths */
196         union iscsi_segment_lengths lengths;
197         /** Initiator session ID (IANA format) enterprise number and flags */
198         uint32_t isid_iana_en;
199         /** Initiator session ID (IANA format) qualifier */
200         uint16_t isid_iana_qual;
201         /** Target session identifying handle */
202         uint16_t tsih;
203         /** Initiator Task Tag */
204         uint32_t itt;
205         /** Reserved */
206         uint32_t reserved_a;
207         /** Status sequence number */
208         uint32_t statsn;
209         /** Expected command sequence number */
210         uint32_t expcmdsn;
211         /** Maximum command sequence number */
212         uint32_t maxcmdsn;
213         /** Status class */
214         uint8_t status_class;
215         /** Status detail */
216         uint8_t status_detail;
217         /** Reserved */
218         uint8_t reserved_b[10];
219 };
220
221 /** Login response opcode */
222 #define ISCSI_OPCODE_LOGIN_RESPONSE 0x23
223
224 /* Login response status codes */
225 #define ISCSI_STATUS_SUCCESS            0x00
226 #define ISCSI_STATUS_REDIRECT           0x01
227 #define ISCSI_STATUS_INITIATOR_ERROR    0x02
228 #define ISCSI_STATUS_TARGET_ERROR       0x03
229
230 /**
231  * iSCSI SCSI command basic header segment
232  *
233  */
234 struct iscsi_bhs_scsi_command {
235         /** Opcode */
236         uint8_t opcode;
237         /** Flags */
238         uint8_t flags;
239         /** Reserved */
240         uint16_t reserved_a;
241         /** Segment lengths */
242         union iscsi_segment_lengths lengths;
243         /** SCSI Logical Unit Number */
244         uint64_t lun;
245         /** Initiator Task Tag */
246         uint32_t itt;
247         /** Expected data transfer length */
248         uint32_t exp_len;
249         /** Command sequence number */
250         uint32_t cmdsn;
251         /** Expected status sequence number */
252         uint32_t expstatsn;
253         /** SCSI Command Descriptor Block (CDB) */
254         union scsi_cdb cdb;
255 };
256
257 /** SCSI command opcode */
258 #define ISCSI_OPCODE_SCSI_COMMAND 0x01
259
260 /** Command will read data */
261 #define ISCSI_COMMAND_FLAG_READ 0x40
262
263 /** Command will write data */
264 #define ISCSI_COMMAND_FLAG_WRITE 0x20
265
266 /* Task attributes */
267 #define ISCSI_COMMAND_ATTR_UNTAGGED 0x00
268 #define ISCSI_COMMAND_ATTR_SIMPLE 0x01
269 #define ISCSI_COMMAND_ATTR_ORDERED 0x02
270 #define ISCSI_COMMAND_ATTR_HEAD_OF_QUEUE 0x03
271 #define ISCSI_COMMAND_ATTR_ACA 0x04
272
273 /**
274  * iSCSI SCSI response basic header segment
275  *
276  */
277 struct iscsi_bhs_scsi_response {
278         /** Opcode */
279         uint8_t opcode;
280         /** Flags */
281         uint8_t flags;
282         /** Response code */
283         uint8_t response;
284         /** SCSI status code */
285         uint8_t status;
286         /** Segment lengths */
287         union iscsi_segment_lengths lengths;
288         /** Reserved */
289         uint8_t reserved_a[8];
290         /** Initiator Task Tag */
291         uint32_t itt;
292         /** SNACK tag */
293         uint32_t snack;
294         /** Status sequence number */
295         uint32_t statsn;
296         /** Expected command sequence number */
297         uint32_t expcmdsn;
298         /** Maximum command sequence number */
299         uint32_t maxcmdsn;
300         /** Expected data sequence number */
301         uint32_t expdatasn;
302         /** Reserved */
303         uint8_t reserved_b[8];
304 };
305
306 /** SCSI response opcode */
307 #define ISCSI_OPCODE_SCSI_RESPONSE 0x21
308
309 /** SCSI command completed at target */
310 #define ISCSI_RESPONSE_COMMAND_COMPLETE 0x00
311
312 /** SCSI target failure */
313 #define ISCSI_RESPONSE_TARGET_FAILURE 0x01
314
315 /** SCSI sense response code offset
316  *
317  * The SCSI response may contain unsolicited sense data in the data
318  * segment.  If it does, this is the offset to the sense response code
319  * byte, which is the only byte we care about.
320  */
321 #define ISCSI_SENSE_RESPONSE_CODE_OFFSET 2
322
323 /**
324  * iSCSI data-in basic header segment
325  *
326  */
327 struct iscsi_bhs_data_in {
328         /** Opcode */
329         uint8_t opcode;
330         /** Flags */
331         uint8_t flags;
332         /** Reserved */
333         uint8_t reserved_a;
334         /** SCSI status code */
335         uint8_t status;
336         /** Segment lengths */
337         union iscsi_segment_lengths lengths;
338         /** Logical Unit Number */
339         uint64_t lun;
340         /** Initiator Task Tag */
341         uint32_t itt;
342         /** Target Transfer Tag */
343         uint32_t ttt;
344         /** Status sequence number */
345         uint32_t statsn;
346         /** Expected command sequence number */
347         uint32_t expcmdsn;
348         /** Maximum command sequence number */
349         uint32_t maxcmdsn;
350         /** Data sequence number */
351         uint32_t datasn;
352         /** Buffer offset */
353         uint32_t offset;
354         /** Residual count */
355         uint32_t residual_count;
356 };
357
358 /** Data-in opcode */
359 #define ISCSI_OPCODE_DATA_IN 0x25
360
361 /** Data requires acknowledgement */
362 #define ISCSI_DATA_FLAG_ACKNOWLEDGE 0x40
363
364 /** Data overflow occurred */
365 #define ISCSI_DATA_FLAG_OVERFLOW 0x04
366
367 /** Data underflow occurred */
368 #define ISCSI_DATA_FLAG_UNDERFLOW 0x02
369
370 /** SCSI status code and overflow/underflow flags are valid */
371 #define ISCSI_DATA_FLAG_STATUS 0x01
372
373 /**
374  * iSCSI data-out basic header segment
375  *
376  */
377 struct iscsi_bhs_data_out {
378         /** Opcode */
379         uint8_t opcode;
380         /** Flags */
381         uint8_t flags;
382         /** Reserved */
383         uint16_t reserved_a;
384         /** Segment lengths */
385         union iscsi_segment_lengths lengths;
386         /** Logical Unit Number */
387         uint64_t lun;
388         /** Initiator Task Tag */
389         uint32_t itt;
390         /** Target Transfer Tag */
391         uint32_t ttt;
392         /** Reserved */
393         uint32_t reserved_b;
394         /** Expected status sequence number */
395         uint32_t expstatsn;
396         /** Reserved */
397         uint32_t reserved_c;
398         /** Data sequence number */
399         uint32_t datasn;
400         /** Buffer offset */
401         uint32_t offset;
402         /** Reserved */
403         uint32_t reserved_d;
404 };
405
406 /** Data-out opcode */
407 #define ISCSI_OPCODE_DATA_OUT 0x05
408
409 /**
410  * iSCSI request to transfer basic header segment
411  *
412  */
413 struct iscsi_bhs_r2t {
414         /** Opcode */
415         uint8_t opcode;
416         /** Flags */
417         uint8_t flags;
418         /** Reserved */
419         uint16_t reserved_a;
420         /** Segment lengths */
421         union iscsi_segment_lengths lengths;
422         /** Logical Unit Number */
423         uint64_t lun;
424         /** Initiator Task Tag */
425         uint32_t itt;
426         /** Target Transfer Tag */
427         uint32_t ttt;
428         /** Status sequence number */
429         uint32_t statsn;
430         /** Expected command sequence number */
431         uint32_t expcmdsn;
432         /** Maximum command sequence number */
433         uint32_t maxcmdsn;
434         /** R2T sequence number */
435         uint32_t r2tsn;
436         /** Buffer offset */
437         uint32_t offset;
438         /** Desired data transfer length */
439         uint32_t len;
440 };
441
442 /** R2T opcode */
443 #define ISCSI_OPCODE_R2T 0x31
444
445 /**
446  * An iSCSI basic header segment
447  */
448 union iscsi_bhs {
449         struct iscsi_bhs_common common;
450         struct iscsi_bhs_common_response common_response;
451         struct iscsi_bhs_login_request login_request;
452         struct iscsi_bhs_login_response login_response;
453         struct iscsi_bhs_scsi_command scsi_command;
454         struct iscsi_bhs_scsi_response scsi_response;
455         struct iscsi_bhs_data_in data_in;
456         struct iscsi_bhs_data_out data_out;
457         struct iscsi_bhs_r2t r2t;
458         unsigned char bytes[ sizeof ( struct iscsi_bhs_common ) ];
459 };
460
461 /** State of an iSCSI TX engine */
462 enum iscsi_tx_state {
463         /** Nothing to send */
464         ISCSI_TX_IDLE = 0,
465         /** Sending the basic header segment */
466         ISCSI_TX_BHS,
467         /** Sending the additional header segment */
468         ISCSI_TX_AHS,
469         /** Sending the data segment */
470         ISCSI_TX_DATA,
471         /** Sending the data segment padding */
472         ISCSI_TX_DATA_PADDING,
473 };
474
475 /** State of an iSCSI RX engine */
476 enum iscsi_rx_state {
477         /** Receiving the basic header segment */
478         ISCSI_RX_BHS = 0,
479         /** Receiving the additional header segment */
480         ISCSI_RX_AHS,
481         /** Receiving the data segment */
482         ISCSI_RX_DATA,
483         /** Receiving the data segment padding */
484         ISCSI_RX_DATA_PADDING,
485 };
486
487 /** An iSCSI session */
488 struct iscsi_session {
489         /** TCP connection for this session */
490         struct tcp_connection tcp;
491         /** Session status
492          *
493          * This is the bitwise-OR of zero or more ISCSI_STATUS_XXX
494          * constants.
495          */
496         int status;
497         /** Asynchronous operation for the current iSCSI operation */
498         struct async_operation aop;
499         /** Retry count
500          *
501          * Number of times that the connection has been retried.
502          * Reset upon a successful connection.
503          */
504         int retry_count;
505
506         /** Initiator IQN */
507         const char *initiator_iqn;
508         /** Target address
509          *
510          * Kept separate from the TCP connection structure because we
511          * may need to handle login redirection.
512          */
513         struct sockaddr_tcpip target;
514         /** Target IQN */
515         const char *target_iqn;
516         /** Logical Unit Number (LUN) */
517         uint64_t lun;
518
519         /** Username */
520         const char *username;
521         /** Password */
522         const char *password;
523         /** CHAP challenge/response */
524         struct chap_challenge chap;
525
526         /** Target session identifying handle
527          *
528          * This is assigned by the target when we first log in, and
529          * must be reused on subsequent login attempts.
530          */
531         uint16_t tsih;
532         /** Initiator task tag
533          *
534          * This is the tag of the current command.  It is incremented
535          * whenever a new command is started.
536          */
537         uint32_t itt;
538         /** Target transfer tag
539          *
540          * This is the tag attached to a sequence of data-out PDUs in
541          * response to an R2T.
542          */
543         uint32_t ttt;
544         /**
545          * Transfer offset
546          *
547          * This is the offset for an in-progress sequence of data-out
548          * PDUs in response to an R2T.
549          */
550         uint32_t transfer_offset;
551         /**
552          * Transfer length
553          *
554          * This is the length for an in-progress sequence of data-out
555          * PDUs in response to an R2T.
556          */
557         uint32_t transfer_len;
558         /** Command sequence number
559          *
560          * This is the sequence number of the current command, used to
561          * fill out the CmdSN field in iSCSI request PDUs.  It is
562          * updated with the value of the ExpCmdSN field whenever we
563          * receive an iSCSI response PDU containing such a field.
564          */
565         uint32_t cmdsn;
566         /** Status sequence number
567          *
568          * This is the most recent status sequence number present in
569          * the StatSN field of an iSCSI response PDU containing such a
570          * field.  Whenever we send an iSCSI request PDU, we fill out
571          * the ExpStatSN field with this value plus one.
572          */
573         uint32_t statsn;
574         
575         /** Basic header segment for current TX PDU */
576         union iscsi_bhs tx_bhs;
577         /** State of the TX engine */
578         enum iscsi_tx_state tx_state;
579         /** Byte offset within the current TX state */
580         size_t tx_offset;
581         /** Length of the current TX state */
582         size_t tx_len;
583
584         /** Basic header segment for current RX PDU */
585         union iscsi_bhs rx_bhs;
586         /** State of the RX engine */
587         enum iscsi_rx_state rx_state;
588         /** Byte offset within the current RX state */
589         size_t rx_offset;
590         /** Length of the current RX state */
591         size_t rx_len;
592         /** Buffer for received data (not always used) */
593         void *rx_buffer;
594
595         /** Current SCSI command
596          *
597          * Set to NULL when command is complete.
598          */
599         struct scsi_command *command;
600 };
601
602 /** iSCSI session is currently in the security negotiation phase */
603 #define ISCSI_STATUS_SECURITY_NEGOTIATION_PHASE         \
604         ( ISCSI_LOGIN_CSG_SECURITY_NEGOTIATION |        \
605           ISCSI_LOGIN_NSG_OPERATIONAL_NEGOTIATION )
606
607 /** iSCSI session is currently in the operational parameter
608  * negotiation phase
609  */
610 #define ISCSI_STATUS_OPERATIONAL_NEGOTIATION_PHASE      \
611         ( ISCSI_LOGIN_CSG_OPERATIONAL_NEGOTIATION |     \
612           ISCSI_LOGIN_NSG_FULL_FEATURE_PHASE )
613
614 /** iSCSI session is currently in the full feature phase */
615 #define ISCSI_STATUS_FULL_FEATURE_PHASE ISCSI_LOGIN_CSG_FULL_FEATURE_PHASE
616
617 /** Mask for all iSCSI session phases */
618 #define ISCSI_STATUS_PHASE_MASK ( ISCSI_LOGIN_CSG_MASK | ISCSI_LOGIN_NSG_MASK )
619
620 /** iSCSI session needs to send the initial security negotiation strings */
621 #define ISCSI_STATUS_STRINGS_SECURITY 0x0100
622
623 /** iSCSI session needs to send the CHAP_A string */
624 #define ISCSI_STATUS_STRINGS_CHAP_ALGORITHM 0x0200
625
626 /** iSCSI session needs to send the CHAP response */
627 #define ISCSI_STATUS_STRINGS_CHAP_RESPONSE 0x0400
628
629 /** iSCSI session needs to send the operational negotiation strings */
630 #define ISCSI_STATUS_STRINGS_OPERATIONAL 0x0800
631
632 /** Mask for all iSCSI "needs to send" flags */
633 #define ISCSI_STATUS_STRINGS_MASK 0xff00
634
635 /** iSCSI session is closing down */
636 #define ISCSI_STATUS_CLOSING 0x00010000
637
638 /** Maximum number of retries at connecting */
639 #define ISCSI_MAX_RETRIES 2
640
641 extern struct async_operation * iscsi_issue ( struct iscsi_session *iscsi,
642                                               struct scsi_command *command );
643 extern struct async_operation * iscsi_shutdown ( struct iscsi_session *iscsi );
644
645 /** An iSCSI device */
646 struct iscsi_device {
647         /** SCSI device interface */
648         struct scsi_device scsi;
649         /** iSCSI protocol instance */
650         struct iscsi_session iscsi;
651 };
652
653 extern int init_iscsidev ( struct iscsi_device *iscsidev );
654 extern void fini_iscsidev ( struct iscsi_device *iscsidev );
655
656 #endif /* _GPXE_ISCSI_H */