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