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