iscsi.h
Go to the documentation of this file.00001 #ifndef _GPXE_ISCSI_H
00002 #define _GPXE_ISCSI_H
00003
00004
00005
00006
00007
00008
00009
00010 FILE_LICENCE ( GPL2_OR_LATER );
00011
00012 #include <stdint.h>
00013 #include <gpxe/socket.h>
00014 #include <gpxe/scsi.h>
00015 #include <gpxe/chap.h>
00016 #include <gpxe/refcnt.h>
00017 #include <gpxe/xfer.h>
00018 #include <gpxe/process.h>
00019
00020
00021 #define ISCSI_PORT 3260
00022
00023
00024
00025
00026
00027
00028
00029
00030 union iscsi_segment_lengths {
00031 struct {
00032
00033 uint8_t ahs_len;
00034
00035
00036
00037 uint8_t data_len[3];
00038 } bytes;
00039
00040
00041
00042 uint32_t ahs_and_data_len;
00043 };
00044
00045
00046 #define ISCSI_AHS_LEN( segment_lengths ) \
00047 ( (segment_lengths).bytes.ahs_len )
00048
00049
00050 #define ISCSI_DATA_LEN( segment_lengths ) \
00051 ( ntohl ( (segment_lengths).ahs_and_data_len ) & 0xffffff )
00052
00053
00054 #define ISCSI_DATA_PAD_LEN( segment_lengths ) \
00055 ( ( 0 - (segment_lengths).bytes.data_len[2] ) & 0x03 )
00056
00057
00058 #define ISCSI_SET_LENGTHS( segment_lengths, ahs_len, data_len ) do { \
00059 (segment_lengths).ahs_and_data_len = \
00060 htonl ( data_len | ( ahs_len << 24 ) ); \
00061 } while ( 0 )
00062
00063
00064
00065
00066
00067 struct iscsi_bhs_common {
00068
00069 uint8_t opcode;
00070
00071 uint8_t flags;
00072
00073 uint8_t other_a[2];
00074
00075 union iscsi_segment_lengths lengths;
00076
00077 uint8_t other_b[8];
00078
00079 uint32_t itt;
00080
00081 uint8_t other_c[28];
00082 };
00083
00084
00085 #define ISCSI_OPCODE_MASK 0x3f
00086
00087
00088 #define ISCSI_FLAG_IMMEDIATE 0x40
00089
00090
00091 #define ISCSI_FLAG_FINAL 0x80
00092
00093
00094
00095
00096
00097 struct iscsi_bhs_common_response {
00098
00099 uint8_t opcode;
00100
00101 uint8_t flags;
00102
00103 uint8_t other_a[2];
00104
00105 union iscsi_segment_lengths lengths;
00106
00107 uint8_t other_b[8];
00108
00109 uint32_t itt;
00110
00111 uint8_t other_c[4];
00112
00113 uint32_t statsn;
00114
00115 uint32_t expcmdsn;
00116
00117 uint8_t other_d[16];
00118 };
00119
00120
00121
00122
00123
00124 struct iscsi_bhs_login_request {
00125
00126 uint8_t opcode;
00127
00128 uint8_t flags;
00129
00130 uint8_t version_max;
00131
00132 uint8_t version_min;
00133
00134 union iscsi_segment_lengths lengths;
00135
00136 uint32_t isid_iana_en;
00137
00138 uint16_t isid_iana_qual;
00139
00140 uint16_t tsih;
00141
00142 uint32_t itt;
00143
00144 uint16_t cid;
00145
00146 uint16_t reserved_a;
00147
00148 uint32_t cmdsn;
00149
00150 uint32_t expstatsn;
00151
00152 uint8_t reserved_b[16];
00153 };
00154
00155
00156 #define ISCSI_OPCODE_LOGIN_REQUEST 0x03
00157
00158
00159 #define ISCSI_LOGIN_FLAG_TRANSITION 0x80
00160
00161
00162 #define ISCSI_LOGIN_FLAG_CONTINUE 0x40
00163
00164
00165 #define ISCSI_LOGIN_CSG_MASK 0x0c
00166 #define ISCSI_LOGIN_CSG_SECURITY_NEGOTIATION 0x00
00167 #define ISCSI_LOGIN_CSG_OPERATIONAL_NEGOTIATION 0x04
00168 #define ISCSI_LOGIN_CSG_FULL_FEATURE_PHASE 0x0c
00169
00170
00171 #define ISCSI_LOGIN_NSG_MASK 0x03
00172 #define ISCSI_LOGIN_NSG_SECURITY_NEGOTIATION 0x00
00173 #define ISCSI_LOGIN_NSG_OPERATIONAL_NEGOTIATION 0x01
00174 #define ISCSI_LOGIN_NSG_FULL_FEATURE_PHASE 0x03
00175
00176
00177 #define ISCSI_ISID_IANA 0x40000000
00178
00179
00180
00181
00182
00183
00184 #define IANA_EN_FEN_SYSTEMS 10019
00185
00186
00187
00188
00189
00190 struct iscsi_bhs_login_response {
00191
00192 uint8_t opcode;
00193
00194 uint8_t flags;
00195
00196 uint8_t version_max;
00197
00198 uint8_t version_min;
00199
00200 union iscsi_segment_lengths lengths;
00201
00202 uint32_t isid_iana_en;
00203
00204 uint16_t isid_iana_qual;
00205
00206 uint16_t tsih;
00207
00208 uint32_t itt;
00209
00210 uint32_t reserved_a;
00211
00212 uint32_t statsn;
00213
00214 uint32_t expcmdsn;
00215
00216 uint32_t maxcmdsn;
00217
00218 uint8_t status_class;
00219
00220 uint8_t status_detail;
00221
00222 uint8_t reserved_b[10];
00223 };
00224
00225
00226 #define ISCSI_OPCODE_LOGIN_RESPONSE 0x23
00227
00228
00229 #define ISCSI_STATUS_SUCCESS 0x00
00230 #define ISCSI_STATUS_REDIRECT 0x01
00231 #define ISCSI_STATUS_INITIATOR_ERROR 0x02
00232 #define ISCSI_STATUS_INITIATOR_ERROR_AUTHENTICATION 0x01
00233 #define ISCSI_STATUS_INITIATOR_ERROR_AUTHORISATION 0x02
00234 #define ISCSI_STATUS_INITIATOR_ERROR_NOT_FOUND 0x03
00235 #define ISCSI_STATUS_INITIATOR_ERROR_REMOVED 0x04
00236 #define ISCSI_STATUS_TARGET_ERROR 0x03
00237
00238
00239
00240
00241
00242 struct iscsi_bhs_scsi_command {
00243
00244 uint8_t opcode;
00245
00246 uint8_t flags;
00247
00248 uint16_t reserved_a;
00249
00250 union iscsi_segment_lengths lengths;
00251
00252 struct scsi_lun lun;
00253
00254 uint32_t itt;
00255
00256 uint32_t exp_len;
00257
00258 uint32_t cmdsn;
00259
00260 uint32_t expstatsn;
00261
00262 union scsi_cdb cdb;
00263 };
00264
00265
00266 #define ISCSI_OPCODE_SCSI_COMMAND 0x01
00267
00268
00269 #define ISCSI_COMMAND_FLAG_READ 0x40
00270
00271
00272 #define ISCSI_COMMAND_FLAG_WRITE 0x20
00273
00274
00275 #define ISCSI_COMMAND_ATTR_UNTAGGED 0x00
00276 #define ISCSI_COMMAND_ATTR_SIMPLE 0x01
00277 #define ISCSI_COMMAND_ATTR_ORDERED 0x02
00278 #define ISCSI_COMMAND_ATTR_HEAD_OF_QUEUE 0x03
00279 #define ISCSI_COMMAND_ATTR_ACA 0x04
00280
00281
00282
00283
00284
00285 struct iscsi_bhs_scsi_response {
00286
00287 uint8_t opcode;
00288
00289 uint8_t flags;
00290
00291 uint8_t response;
00292
00293 uint8_t status;
00294
00295 union iscsi_segment_lengths lengths;
00296
00297 uint8_t reserved_a[8];
00298
00299 uint32_t itt;
00300
00301 uint32_t snack;
00302
00303 uint32_t statsn;
00304
00305 uint32_t expcmdsn;
00306
00307 uint32_t maxcmdsn;
00308
00309 uint32_t expdatasn;
00310
00311 uint8_t reserved_b[8];
00312 };
00313
00314
00315 #define ISCSI_OPCODE_SCSI_RESPONSE 0x21
00316
00317
00318 #define ISCSI_RESPONSE_COMMAND_COMPLETE 0x00
00319
00320
00321 #define ISCSI_RESPONSE_TARGET_FAILURE 0x01
00322
00323
00324
00325
00326
00327
00328
00329 #define ISCSI_SENSE_RESPONSE_CODE_OFFSET 2
00330
00331
00332
00333
00334
00335 struct iscsi_bhs_data_in {
00336
00337 uint8_t opcode;
00338
00339 uint8_t flags;
00340
00341 uint8_t reserved_a;
00342
00343 uint8_t status;
00344
00345 union iscsi_segment_lengths lengths;
00346
00347 struct scsi_lun lun;
00348
00349 uint32_t itt;
00350
00351 uint32_t ttt;
00352
00353 uint32_t statsn;
00354
00355 uint32_t expcmdsn;
00356
00357 uint32_t maxcmdsn;
00358
00359 uint32_t datasn;
00360
00361 uint32_t offset;
00362
00363 uint32_t residual_count;
00364 };
00365
00366
00367 #define ISCSI_OPCODE_DATA_IN 0x25
00368
00369
00370 #define ISCSI_DATA_FLAG_ACKNOWLEDGE 0x40
00371
00372
00373 #define ISCSI_DATA_FLAG_OVERFLOW 0x04
00374
00375
00376 #define ISCSI_DATA_FLAG_UNDERFLOW 0x02
00377
00378
00379 #define ISCSI_DATA_FLAG_STATUS 0x01
00380
00381
00382
00383
00384
00385 struct iscsi_bhs_data_out {
00386
00387 uint8_t opcode;
00388
00389 uint8_t flags;
00390
00391 uint16_t reserved_a;
00392
00393 union iscsi_segment_lengths lengths;
00394
00395 struct scsi_lun lun;
00396
00397 uint32_t itt;
00398
00399 uint32_t ttt;
00400
00401 uint32_t reserved_b;
00402
00403 uint32_t expstatsn;
00404
00405 uint32_t reserved_c;
00406
00407 uint32_t datasn;
00408
00409 uint32_t offset;
00410
00411 uint32_t reserved_d;
00412 };
00413
00414
00415 #define ISCSI_OPCODE_DATA_OUT 0x05
00416
00417
00418
00419
00420
00421 struct iscsi_bhs_r2t {
00422
00423 uint8_t opcode;
00424
00425 uint8_t flags;
00426
00427 uint16_t reserved_a;
00428
00429 union iscsi_segment_lengths lengths;
00430
00431 struct scsi_lun lun;
00432
00433 uint32_t itt;
00434
00435 uint32_t ttt;
00436
00437 uint32_t statsn;
00438
00439 uint32_t expcmdsn;
00440
00441 uint32_t maxcmdsn;
00442
00443 uint32_t r2tsn;
00444
00445 uint32_t offset;
00446
00447 uint32_t len;
00448 };
00449
00450
00451 #define ISCSI_OPCODE_R2T 0x31
00452
00453
00454
00455
00456 union iscsi_bhs {
00457 struct iscsi_bhs_common common;
00458 struct iscsi_bhs_common_response common_response;
00459 struct iscsi_bhs_login_request login_request;
00460 struct iscsi_bhs_login_response login_response;
00461 struct iscsi_bhs_scsi_command scsi_command;
00462 struct iscsi_bhs_scsi_response scsi_response;
00463 struct iscsi_bhs_data_in data_in;
00464 struct iscsi_bhs_data_out data_out;
00465 struct iscsi_bhs_r2t r2t;
00466 unsigned char bytes[ sizeof ( struct iscsi_bhs_common ) ];
00467 };
00468
00469
00470 enum iscsi_tx_state {
00471
00472 ISCSI_TX_IDLE = 0,
00473
00474 ISCSI_TX_BHS,
00475
00476 ISCSI_TX_AHS,
00477
00478 ISCSI_TX_DATA,
00479
00480 ISCSI_TX_DATA_PADDING,
00481 };
00482
00483
00484 enum iscsi_rx_state {
00485
00486 ISCSI_RX_BHS = 0,
00487
00488 ISCSI_RX_AHS,
00489
00490 ISCSI_RX_DATA,
00491
00492 ISCSI_RX_DATA_PADDING,
00493 };
00494
00495
00496 struct iscsi_session {
00497
00498 struct refcnt refcnt;
00499
00500
00501 struct xfer_interface socket;
00502
00503
00504 char *target_address;
00505
00506 unsigned int target_port;
00507
00508 char *target_iqn;
00509
00510 struct scsi_lun lun;
00511
00512 struct sockaddr target_sockaddr;
00513
00514
00515
00516
00517
00518
00519 int status;
00520
00521
00522
00523
00524
00525 int retry_count;
00526
00527
00528 char *initiator_username;
00529
00530 char *initiator_password;
00531
00532 char *target_username;
00533
00534 char *target_password;
00535
00536
00537
00538
00539
00540
00541 unsigned char chap_challenge[17];
00542
00543 struct chap_response chap;
00544
00545
00546
00547
00548
00549
00550 uint16_t tsih;
00551
00552
00553
00554
00555
00556 uint32_t itt;
00557
00558
00559
00560
00561
00562 uint32_t ttt;
00563
00564
00565
00566
00567
00568
00569 uint32_t transfer_offset;
00570
00571
00572
00573
00574
00575
00576 uint32_t transfer_len;
00577
00578
00579
00580
00581
00582
00583
00584 uint32_t cmdsn;
00585
00586
00587
00588
00589
00590
00591
00592 uint32_t statsn;
00593
00594
00595 union iscsi_bhs tx_bhs;
00596
00597 enum iscsi_tx_state tx_state;
00598
00599 struct process process;
00600
00601
00602 union iscsi_bhs rx_bhs;
00603
00604 enum iscsi_rx_state rx_state;
00605
00606 size_t rx_offset;
00607
00608 size_t rx_len;
00609
00610 void *rx_buffer;
00611
00612
00613
00614
00615
00616 struct scsi_command *command;
00617
00618
00619
00620
00621
00622
00623 int instant_rc;
00624 };
00625
00626
00627 #define ISCSI_STATUS_SECURITY_NEGOTIATION_PHASE \
00628 ( ISCSI_LOGIN_CSG_SECURITY_NEGOTIATION | \
00629 ISCSI_LOGIN_NSG_OPERATIONAL_NEGOTIATION )
00630
00631
00632
00633
00634 #define ISCSI_STATUS_OPERATIONAL_NEGOTIATION_PHASE \
00635 ( ISCSI_LOGIN_CSG_OPERATIONAL_NEGOTIATION | \
00636 ISCSI_LOGIN_NSG_FULL_FEATURE_PHASE )
00637
00638
00639 #define ISCSI_STATUS_FULL_FEATURE_PHASE ISCSI_LOGIN_CSG_FULL_FEATURE_PHASE
00640
00641
00642 #define ISCSI_STATUS_PHASE_MASK ( ISCSI_LOGIN_CSG_MASK | ISCSI_LOGIN_NSG_MASK )
00643
00644
00645 #define ISCSI_STATUS_STRINGS_SECURITY 0x0100
00646
00647
00648 #define ISCSI_STATUS_STRINGS_CHAP_ALGORITHM 0x0200
00649
00650
00651 #define ISCSI_STATUS_STRINGS_CHAP_RESPONSE 0x0400
00652
00653
00654 #define ISCSI_STATUS_STRINGS_CHAP_CHALLENGE 0x0800
00655
00656
00657 #define ISCSI_STATUS_STRINGS_OPERATIONAL 0x1000
00658
00659
00660 #define ISCSI_STATUS_STRINGS_MASK 0xff00
00661
00662
00663 #define ISCSI_STATUS_AUTH_FORWARD_REQUIRED 0x00010000
00664
00665
00666 #define ISCSI_STATUS_AUTH_REVERSE_REQUIRED 0x00020000
00667
00668
00669 #define ISCSI_STATUS_AUTH_REVERSE_OK 0x00040000
00670
00671
00672 #define ISCSI_MAX_RETRIES 2
00673
00674 extern int iscsi_attach ( struct scsi_device *scsi, const char *root_path );
00675 extern void iscsi_detach ( struct scsi_device *scsi );
00676 extern const char * iscsi_initiator_iqn ( void );
00677
00678 #endif