xref: /spdk/include/spdk/iscsi_spec.h (revision da6841e4509a8eec7972dfe154ea9f13d09d9be1)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2008-2012 Daisuke Aoyama <aoyama@peach.ne.jp>.
3  *   Copyright (C) 2016 Intel Corporation.
4  *   All rights reserved.
5  */
6 
7 /**
8  * \file
9  * iSCSI specification definitions
10  */
11 
12 #ifndef SPDK_ISCSI_SPEC_H
13 #define SPDK_ISCSI_SPEC_H
14 
15 #include "spdk/stdinc.h"
16 
17 #include "spdk/assert.h"
18 
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22 
23 #define ISCSI_BHS_LEN 48
24 #define ISCSI_DIGEST_LEN 4
25 #define ISCSI_ALIGNMENT 4
26 
27 /** support version - RFC3720(10.12.4) */
28 #define ISCSI_VERSION 0x00
29 
30 #define ISCSI_ALIGN(SIZE) \
31 	(((SIZE) + (ISCSI_ALIGNMENT - 1)) & ~(ISCSI_ALIGNMENT - 1))
32 
33 /** for authentication key (non encoded 1024bytes) RFC3720(5.1/11.1.4) */
34 #define ISCSI_TEXT_MAX_VAL_LEN 8192
35 
36 /**
37  * RFC 3720 5.1
38  * If not otherwise specified, the maximum length of a simple-value
39  * (not its encoded representation) is 255 bytes, not including the delimiter
40  * (comma or zero byte).
41  */
42 #define ISCSI_TEXT_MAX_SIMPLE_VAL_LEN 255
43 
44 #define ISCSI_TEXT_MAX_KEY_LEN 63
45 
46 enum iscsi_op {
47 	/* Initiator opcodes */
48 	ISCSI_OP_NOPOUT         = 0x00,
49 	ISCSI_OP_SCSI           = 0x01,
50 	ISCSI_OP_TASK           = 0x02,
51 	ISCSI_OP_LOGIN          = 0x03,
52 	ISCSI_OP_TEXT           = 0x04,
53 	ISCSI_OP_SCSI_DATAOUT   = 0x05,
54 	ISCSI_OP_LOGOUT         = 0x06,
55 	ISCSI_OP_SNACK          = 0x10,
56 	ISCSI_OP_VENDOR_1C      = 0x1c,
57 	ISCSI_OP_VENDOR_1D      = 0x1d,
58 	ISCSI_OP_VENDOR_1E      = 0x1e,
59 
60 	/* Target opcodes */
61 	ISCSI_OP_NOPIN          = 0x20,
62 	ISCSI_OP_SCSI_RSP       = 0x21,
63 	ISCSI_OP_TASK_RSP       = 0x22,
64 	ISCSI_OP_LOGIN_RSP      = 0x23,
65 	ISCSI_OP_TEXT_RSP       = 0x24,
66 	ISCSI_OP_SCSI_DATAIN    = 0x25,
67 	ISCSI_OP_LOGOUT_RSP     = 0x26,
68 	ISCSI_OP_R2T            = 0x31,
69 	ISCSI_OP_ASYNC          = 0x32,
70 	ISCSI_OP_VENDOR_3C      = 0x3c,
71 	ISCSI_OP_VENDOR_3D      = 0x3d,
72 	ISCSI_OP_VENDOR_3E      = 0x3e,
73 	ISCSI_OP_REJECT         = 0x3f,
74 };
75 
76 enum iscsi_task_func {
77 	ISCSI_TASK_FUNC_ABORT_TASK = 1,
78 	ISCSI_TASK_FUNC_ABORT_TASK_SET = 2,
79 	ISCSI_TASK_FUNC_CLEAR_ACA = 3,
80 	ISCSI_TASK_FUNC_CLEAR_TASK_SET = 4,
81 	ISCSI_TASK_FUNC_LOGICAL_UNIT_RESET = 5,
82 	ISCSI_TASK_FUNC_TARGET_WARM_RESET = 6,
83 	ISCSI_TASK_FUNC_TARGET_COLD_RESET = 7,
84 	ISCSI_TASK_FUNC_TASK_REASSIGN = 8,
85 };
86 
87 enum iscsi_task_func_resp {
88 	ISCSI_TASK_FUNC_RESP_COMPLETE = 0,
89 	ISCSI_TASK_FUNC_RESP_TASK_NOT_EXIST = 1,
90 	ISCSI_TASK_FUNC_RESP_LUN_NOT_EXIST = 2,
91 	ISCSI_TASK_FUNC_RESP_TASK_STILL_ALLEGIANT = 3,
92 	ISCSI_TASK_FUNC_RESP_REASSIGNMENT_NOT_SUPPORTED = 4,
93 	ISCSI_TASK_FUNC_RESP_FUNC_NOT_SUPPORTED = 5,
94 	ISCSI_TASK_FUNC_RESP_AUTHORIZATION_FAILED = 6,
95 	ISCSI_TASK_FUNC_REJECTED = 255
96 };
97 
98 struct iscsi_bhs {
99 	uint8_t opcode		: 6;
100 	uint8_t immediate	: 1;
101 	uint8_t reserved	: 1;
102 	uint8_t flags;
103 	uint8_t rsv[2];
104 	uint8_t total_ahs_len;
105 	uint8_t data_segment_len[3];
106 	uint64_t lun;
107 	uint32_t itt;
108 	uint32_t ttt;
109 	uint32_t stat_sn;
110 	uint32_t exp_stat_sn;
111 	uint32_t max_stat_sn;
112 	uint8_t res3[12];
113 };
114 SPDK_STATIC_ASSERT(sizeof(struct iscsi_bhs) == ISCSI_BHS_LEN, "ISCSI_BHS_LEN mismatch");
115 
116 struct iscsi_bhs_async {
117 	uint8_t opcode		: 6;	/* opcode = 0x32 */
118 	uint8_t reserved	: 2;
119 	uint8_t flags;
120 	uint8_t res[2];
121 
122 	uint8_t total_ahs_len;
123 	uint8_t data_segment_len[3];
124 
125 	uint64_t lun;
126 	uint32_t ffffffff;
127 	uint32_t res3;
128 	uint32_t stat_sn;
129 	uint32_t exp_cmd_sn;
130 	uint32_t max_cmd_sn;
131 	uint8_t async_event;
132 	uint8_t async_vcode;
133 	uint16_t param1;
134 	uint16_t param2;
135 	uint16_t param3;
136 	uint8_t res4[4];
137 };
138 
139 struct iscsi_bhs_login_req {
140 	uint8_t opcode		: 6;	/* opcode = 0x03 */
141 	uint8_t immediate	: 1;
142 	uint8_t reserved	: 1;
143 	uint8_t flags;
144 	uint8_t version_max;
145 	uint8_t version_min;
146 	uint8_t total_ahs_len;
147 	uint8_t data_segment_len[3];
148 	uint8_t isid[6];
149 	uint16_t tsih;
150 	uint32_t itt;
151 	uint16_t cid;
152 	uint16_t res2;
153 	uint32_t cmd_sn;
154 	uint32_t exp_stat_sn;
155 	uint8_t res3[16];
156 };
157 
158 struct iscsi_bhs_login_rsp {
159 	uint8_t opcode		: 6;	/* opcode = 0x23 */
160 	uint8_t reserved	: 2;
161 	uint8_t flags;
162 	uint8_t version_max;
163 	uint8_t version_act;
164 	uint8_t total_ahs_len;
165 	uint8_t data_segment_len[3];
166 	uint8_t isid[6];
167 	uint16_t tsih;
168 	uint32_t itt;
169 	uint32_t res2;
170 	uint32_t stat_sn;
171 	uint32_t exp_cmd_sn;
172 	uint32_t max_cmd_sn;
173 	uint8_t status_class;
174 	uint8_t status_detail;
175 	uint8_t res3[10];
176 };
177 
178 struct iscsi_bhs_logout_req {
179 	uint8_t opcode		: 6;	/* opcode = 0x06 */
180 	uint8_t immediate	: 1;
181 	uint8_t reserved	: 1;
182 	uint8_t reason		: 7;
183 	uint8_t reason_1	: 1;
184 	uint8_t res[2];
185 	uint8_t total_ahs_len;
186 	uint8_t data_segment_len[3];
187 	uint8_t res2[8];
188 	uint32_t itt;
189 	uint16_t cid;
190 	uint16_t res3;
191 	uint32_t cmd_sn;
192 	uint32_t exp_stat_sn;
193 	uint8_t res4[16];
194 };
195 
196 struct iscsi_bhs_logout_resp {
197 	uint8_t opcode		: 6;	/* opcode = 0x26 */
198 	uint8_t reserved	: 2;
199 	uint8_t flags;
200 	uint8_t response;
201 	uint8_t res;
202 	uint8_t total_ahs_len;
203 	uint8_t data_segment_len[3];
204 	uint8_t res2[8];
205 	uint32_t itt;
206 	uint32_t res3;
207 	uint32_t stat_sn;
208 	uint32_t exp_cmd_sn;
209 	uint32_t max_cmd_sn;
210 	uint32_t res4;
211 	uint16_t time_2_wait;
212 	uint16_t time_2_retain;
213 	uint32_t res5;
214 };
215 
216 struct iscsi_bhs_nop_in {
217 	uint8_t opcode		: 6;	/* opcode = 0x20 */
218 	uint8_t reserved	: 2;
219 	uint8_t flags;
220 	uint8_t res[2];
221 	uint8_t total_ahs_len;
222 	uint8_t data_segment_len[3];
223 	uint64_t lun;
224 	uint32_t itt;
225 	uint32_t ttt;
226 	uint32_t stat_sn;
227 	uint32_t exp_cmd_sn;
228 	uint32_t max_cmd_sn;
229 	uint8_t res3[12];
230 };
231 
232 struct iscsi_bhs_nop_out {
233 	uint8_t opcode		: 6;	/* opcode = 0x00 */
234 	uint8_t immediate	: 1;
235 	uint8_t reserved	: 1;
236 	uint8_t flags;
237 	uint8_t res[2];
238 	uint8_t total_ahs_len;
239 	uint8_t data_segment_len[3];
240 	uint64_t lun;
241 	uint32_t itt;
242 	uint32_t ttt;
243 	uint32_t cmd_sn;
244 	uint32_t exp_stat_sn;
245 	uint8_t res4[16];
246 };
247 
248 struct iscsi_bhs_r2t {
249 	uint8_t opcode		: 6;	/* opcode = 0x31 */
250 	uint8_t reserved	: 2;
251 	uint8_t flags;
252 	uint8_t rsv[2];
253 	uint8_t total_ahs_len;
254 	uint8_t data_segment_len[3];
255 	uint64_t lun;
256 	uint32_t itt;
257 	uint32_t ttt;
258 	uint32_t stat_sn;
259 	uint32_t exp_cmd_sn;
260 	uint32_t max_cmd_sn;
261 	uint32_t r2t_sn;
262 	uint32_t buffer_offset;
263 	uint32_t desired_xfer_len;
264 };
265 
266 struct iscsi_bhs_reject {
267 	uint8_t opcode		: 6;	/* opcode = 0x3f */
268 	uint8_t reserved	: 2;
269 	uint8_t flags;
270 	uint8_t reason;
271 	uint8_t res;
272 	uint8_t total_ahs_len;
273 	uint8_t data_segment_len[3];
274 	uint8_t res2[8];
275 	uint32_t ffffffff;
276 	uint32_t res3;
277 	uint32_t stat_sn;
278 	uint32_t exp_cmd_sn;
279 	uint32_t max_cmd_sn;
280 	uint32_t data_sn;
281 	uint8_t res4[8];
282 };
283 
284 struct iscsi_bhs_scsi_req {
285 	uint8_t opcode		: 6;	/* opcode = 0x01 */
286 	uint8_t immediate	: 1;
287 	uint8_t reserved	: 1;
288 	uint8_t attribute	: 3;
289 	uint8_t reserved2	: 2;
290 	uint8_t write_bit	: 1;
291 	uint8_t read_bit	: 1;
292 	uint8_t final_bit	: 1;
293 	uint8_t res[2];
294 	uint8_t total_ahs_len;
295 	uint8_t data_segment_len[3];
296 	uint64_t lun;
297 	uint32_t itt;
298 	uint32_t expected_data_xfer_len;
299 	uint32_t cmd_sn;
300 	uint32_t exp_stat_sn;
301 	uint8_t cdb[16];
302 };
303 
304 struct iscsi_bhs_scsi_resp {
305 	uint8_t opcode		: 6;	/* opcode = 0x21 */
306 	uint8_t reserved	: 2;
307 	uint8_t flags;
308 	uint8_t response;
309 	uint8_t status;
310 	uint8_t total_ahs_len;
311 	uint8_t data_segment_len[3];
312 	uint8_t res4[8];
313 	uint32_t itt;
314 	uint32_t snacktag;
315 	uint32_t stat_sn;
316 	uint32_t exp_cmd_sn;
317 	uint32_t max_cmd_sn;
318 	uint32_t exp_data_sn;
319 	uint32_t bi_read_res_cnt;
320 	uint32_t res_cnt;
321 };
322 
323 struct iscsi_bhs_data_in {
324 	uint8_t opcode		: 6;	/* opcode = 0x05 */
325 	uint8_t reserved	: 2;
326 	uint8_t flags;
327 	uint8_t res;
328 	uint8_t status;
329 	uint8_t total_ahs_len;
330 	uint8_t data_segment_len[3];
331 	uint64_t lun;
332 	uint32_t itt;
333 	uint32_t ttt;
334 	uint32_t stat_sn;
335 	uint32_t exp_cmd_sn;
336 	uint32_t max_cmd_sn;
337 	uint32_t data_sn;
338 	uint32_t buffer_offset;
339 	uint32_t res_cnt;
340 };
341 
342 struct iscsi_bhs_data_out {
343 	uint8_t opcode		: 6;	/* opcode = 0x25 */
344 	uint8_t reserved	: 2;
345 	uint8_t flags;
346 	uint8_t res[2];
347 	uint8_t total_ahs_len;
348 	uint8_t data_segment_len[3];
349 	uint64_t lun;
350 	uint32_t itt;
351 	uint32_t ttt;
352 	uint32_t res3;
353 	uint32_t exp_stat_sn;
354 	uint32_t res4;
355 	uint32_t data_sn;
356 	uint32_t buffer_offset;
357 	uint32_t res5;
358 };
359 
360 struct iscsi_bhs_snack_req {
361 	uint8_t opcode		: 6;	/* opcode = 0x10 */
362 	uint8_t reserved	: 2;
363 	uint8_t flags;
364 	uint8_t res[2];
365 	uint8_t total_ahs_len;
366 	uint8_t data_segment_len[3];
367 	uint64_t lun;
368 	uint32_t itt;
369 	uint32_t ttt;
370 	uint32_t res5;
371 	uint32_t exp_stat_sn;
372 	uint8_t res6[8];
373 	uint32_t beg_run;
374 	uint32_t run_len;
375 };
376 
377 struct iscsi_bhs_task_req {
378 	uint8_t opcode		: 6;	/* opcode = 0x02 */
379 	uint8_t immediate	: 1;
380 	uint8_t reserved	: 1;
381 	uint8_t flags;
382 	uint8_t res[2];
383 	uint8_t total_ahs_len;
384 	uint8_t data_segment_len[3];
385 	uint64_t lun;
386 	uint32_t itt;
387 	uint32_t ref_task_tag;
388 	uint32_t cmd_sn;
389 	uint32_t exp_stat_sn;
390 	uint32_t ref_cmd_sn;
391 	uint32_t exp_data_sn;
392 	uint8_t res5[8];
393 };
394 
395 struct iscsi_bhs_task_resp {
396 	uint8_t opcode		: 6;	/* opcode = 0x22 */
397 	uint8_t reserved	: 2;
398 	uint8_t flags;
399 	uint8_t response;
400 	uint8_t res;
401 	uint8_t total_ahs_len;
402 	uint8_t data_segment_len[3];
403 	uint8_t res2[8];
404 	uint32_t itt;
405 	uint32_t res3;
406 	uint32_t stat_sn;
407 	uint32_t exp_cmd_sn;
408 	uint32_t max_cmd_sn;
409 	uint8_t res4[12];
410 };
411 
412 struct iscsi_bhs_text_req {
413 	uint8_t opcode		: 6;	/* opcode = 0x04 */
414 	uint8_t immediate	: 1;
415 	uint8_t reserved	: 1;
416 	uint8_t flags;
417 	uint8_t res[2];
418 	uint8_t total_ahs_len;
419 	uint8_t data_segment_len[3];
420 	uint64_t lun;
421 	uint32_t itt;
422 	uint32_t ttt;
423 	uint32_t cmd_sn;
424 	uint32_t exp_stat_sn;
425 	uint8_t res3[16];
426 };
427 
428 struct iscsi_bhs_text_resp {
429 	uint8_t opcode		: 6;	/* opcode = 0x24 */
430 	uint8_t reserved	: 2;
431 	uint8_t flags;
432 	uint8_t res[2];
433 	uint8_t total_ahs_len;
434 	uint8_t data_segment_len[3];
435 	uint64_t lun;
436 	uint32_t itt;
437 	uint32_t ttt;
438 	uint32_t stat_sn;
439 	uint32_t exp_cmd_sn;
440 	uint32_t max_cmd_sn;
441 	uint8_t res4[12];
442 };
443 
444 /* generic flags */
445 #define ISCSI_FLAG_FINAL			0x80
446 
447 /* login flags */
448 #define ISCSI_LOGIN_TRANSIT			0x80
449 #define ISCSI_LOGIN_CONTINUE			0x40
450 #define ISCSI_LOGIN_CURRENT_STAGE_MASK		0x0c
451 #define ISCSI_LOGIN_CURRENT_STAGE_0		0x04
452 #define ISCSI_LOGIN_CURRENT_STAGE_1		0x08
453 #define ISCSI_LOGIN_CURRENT_STAGE_3		0x0c
454 #define ISCSI_LOGIN_NEXT_STAGE_MASK		0x03
455 #define ISCSI_LOGIN_NEXT_STAGE_0		0x01
456 #define ISCSI_LOGIN_NEXT_STAGE_1		0x02
457 #define ISCSI_LOGIN_NEXT_STAGE_3		0x03
458 
459 /* text flags */
460 #define ISCSI_TEXT_CONTINUE			0x40
461 
462 /* datain flags */
463 #define ISCSI_DATAIN_ACKNOWLEDGE		0x40
464 #define ISCSI_DATAIN_OVERFLOW			0x04
465 #define ISCSI_DATAIN_UNDERFLOW			0x02
466 #define ISCSI_DATAIN_STATUS			0x01
467 
468 /* SCSI resp flags */
469 #define ISCSI_SCSI_BIDI_OVERFLOW		0x10
470 #define ISCSI_SCSI_BIDI_UNDERFLOW		0x08
471 #define ISCSI_SCSI_OVERFLOW			0x04
472 #define ISCSI_SCSI_UNDERFLOW			0x02
473 
474 /* SCSI task flags */
475 #define ISCSI_TASK_FUNCTION_MASK		0x7f
476 
477 /* Reason for Reject */
478 #define ISCSI_REASON_RESERVED			0x1
479 #define ISCSI_REASON_DATA_DIGEST_ERROR		0x2
480 #define ISCSI_REASON_DATA_SNACK_REJECT		0x3
481 #define ISCSI_REASON_PROTOCOL_ERROR		0x4
482 #define ISCSI_REASON_CMD_NOT_SUPPORTED		0x5
483 #define ISCSI_REASON_IMM_CMD_REJECT		0x6
484 #define ISCSI_REASON_TASK_IN_PROGRESS		0x7
485 #define ISCSI_REASON_INVALID_SNACK		0x8
486 #define ISCSI_REASON_INVALID_PDU_FIELD		0x9
487 #define ISCSI_REASON_LONG_OPERATION_REJECT	0xa
488 #define ISCSI_REASON_NEGOTIATION_RESET		0xb
489 #define ISCSI_REASON_WAIT_FOR_RESET		0xc
490 
491 #define ISCSI_FLAG_SNACK_TYPE_DATA		0
492 #define ISCSI_FLAG_SNACK_TYPE_R2T		0
493 #define ISCSI_FLAG_SNACK_TYPE_STATUS		1
494 #define ISCSI_FLAG_SNACK_TYPE_DATA_ACK		2
495 #define ISCSI_FLAG_SNACK_TYPE_RDATA		3
496 #define ISCSI_FLAG_SNACK_TYPE_MASK		0x0F	/* 4 bits */
497 
498 struct iscsi_ahs {
499 	/* 0-3 */
500 	uint8_t ahs_len[2];
501 	uint8_t ahs_type;
502 	uint8_t ahs_specific1;
503 	/* 4-x */
504 	uint8_t ahs_specific2[];
505 };
506 
507 #define ISCSI_BHS_LOGIN_GET_TBIT(X) (!!(X & ISCSI_LOGIN_TRANSIT))
508 #define ISCSI_BHS_LOGIN_GET_CBIT(X) (!!(X & ISCSI_LOGIN_CONTINUE))
509 #define ISCSI_BHS_LOGIN_GET_CSG(X) ((X & ISCSI_LOGIN_CURRENT_STAGE_MASK) >> 2)
510 #define ISCSI_BHS_LOGIN_GET_NSG(X) (X & ISCSI_LOGIN_NEXT_STAGE_MASK)
511 
512 #define ISCSI_CLASS_SUCCESS			0x00
513 #define ISCSI_CLASS_REDIRECT			0x01
514 #define ISCSI_CLASS_INITIATOR_ERROR		0x02
515 #define ISCSI_CLASS_TARGET_ERROR		0x03
516 
517 /* Class (Success) detailed info: 0 */
518 #define ISCSI_LOGIN_ACCEPT			0x00
519 
520 /* Class (Redirection) detailed info: 1 */
521 #define ISCSI_LOGIN_TARGET_TEMPORARILY_MOVED	0x01
522 #define ISCSI_LOGIN_TARGET_PERMANENTLY_MOVED	0x02
523 
524 /* Class (Initiator Error) detailed info: 2 */
525 #define ISCSI_LOGIN_INITIATOR_ERROR		0x00
526 #define ISCSI_LOGIN_AUTHENT_FAIL		0x01
527 #define ISCSI_LOGIN_AUTHORIZATION_FAIL		0x02
528 #define ISCSI_LOGIN_TARGET_NOT_FOUND		0x03
529 #define ISCSI_LOGIN_TARGET_REMOVED		0x04
530 #define ISCSI_LOGIN_UNSUPPORTED_VERSION		0x05
531 #define ISCSI_LOGIN_TOO_MANY_CONNECTIONS	0x06
532 #define ISCSI_LOGIN_MISSING_PARMS		0x07
533 #define ISCSI_LOGIN_CONN_ADD_FAIL		0x08
534 #define ISCSI_LOGIN_NOT_SUPPORTED_SESSION_TYPE	0x09
535 #define ISCSI_LOGIN_NO_SESSION			0x0a
536 #define ISCSI_LOGIN_INVALID_LOGIN_REQUEST	0x0b
537 
538 /* Class (Target Error) detailed info: 3 */
539 #define ISCSI_LOGIN_STATUS_TARGET_ERROR		0x00
540 #define ISCSI_LOGIN_STATUS_SERVICE_UNAVAILABLE	0x01
541 #define ISCSI_LOGIN_STATUS_NO_RESOURCES		0x02
542 
543 #ifdef __cplusplus
544 }
545 #endif
546 
547 #endif /* SPDK_ISCSI_SPEC_H */
548