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