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