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 */
679