xref: /spdk/lib/iscsi/iscsi.c (revision 2fac05e919e1940137e4502f01beabb81ebbef9c)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright (C) 2008-2012 Daisuke Aoyama <aoyama@peach.ne.jp>.
5  *   Copyright (c) Intel Corporation.
6  *   All rights reserved.
7  *
8  *   Redistribution and use in source and binary forms, with or without
9  *   modification, are permitted provided that the following conditions
10  *   are met:
11  *
12  *     * Redistributions of source code must retain the above copyright
13  *       notice, this list of conditions and the following disclaimer.
14  *     * Redistributions in binary form must reproduce the above copyright
15  *       notice, this list of conditions and the following disclaimer in
16  *       the documentation and/or other materials provided with the
17  *       distribution.
18  *     * Neither the name of Intel Corporation nor the names of its
19  *       contributors may be used to endorse or promote products derived
20  *       from this software without specific prior written permission.
21  *
22  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 #include "spdk/stdinc.h"
36 
37 #include "spdk/crc32.h"
38 #include "spdk/endian.h"
39 #include "spdk/env.h"
40 #include "spdk/trace.h"
41 #include "spdk/string.h"
42 #include "spdk/queue.h"
43 #include "spdk/conf.h"
44 #include "spdk/net.h"
45 
46 #include "iscsi/md5.h"
47 #include "iscsi/iscsi.h"
48 #include "iscsi/param.h"
49 #include "iscsi/tgt_node.h"
50 #include "iscsi/task.h"
51 #include "iscsi/conn.h"
52 #include "spdk/scsi.h"
53 #include "spdk/bdev.h"
54 #include "iscsi/portal_grp.h"
55 #include "iscsi/acceptor.h"
56 
57 #include "spdk_internal/log.h"
58 
59 #define MAX_TMPBUF 1024
60 
61 #define SPDK_CRC32C_INITIAL    0xffffffffUL
62 #define SPDK_CRC32C_XOR        0xffffffffUL
63 
64 #ifdef __FreeBSD__
65 #define HAVE_SRANDOMDEV 1
66 #define HAVE_ARC4RANDOM 1
67 #endif
68 
69 struct spdk_iscsi_globals g_spdk_iscsi = {
70 	.mutex = PTHREAD_MUTEX_INITIALIZER,
71 	.portal_head = TAILQ_HEAD_INITIALIZER(g_spdk_iscsi.portal_head),
72 	.pg_head = TAILQ_HEAD_INITIALIZER(g_spdk_iscsi.pg_head),
73 	.ig_head = TAILQ_HEAD_INITIALIZER(g_spdk_iscsi.ig_head),
74 	.target_head = TAILQ_HEAD_INITIALIZER(g_spdk_iscsi.target_head),
75 };
76 
77 /* random value generation */
78 static void spdk_gen_random(uint8_t *buf, size_t len);
79 #ifndef HAVE_SRANDOMDEV
80 static void srandomdev(void);
81 #endif /* HAVE_SRANDOMDEV */
82 #ifndef HAVE_ARC4RANDOM
83 //static uint32_t arc4random(void);
84 #endif /* HAVE_ARC4RANDOM */
85 
86 /* convert from/to bin/hex */
87 static int spdk_bin2hex(char *buf, size_t len, const uint8_t *data, size_t data_len);
88 static int spdk_hex2bin(uint8_t *data, size_t data_len, const char *str);
89 
90 static int spdk_add_transfer_task(struct spdk_iscsi_conn *conn,
91 				  struct spdk_iscsi_task *task);
92 
93 static int spdk_iscsi_send_r2t(struct spdk_iscsi_conn *conn,
94 			       struct spdk_iscsi_task *task, int offset,
95 			       int len, uint32_t transfer_tag, uint32_t *R2TSN);
96 static int spdk_iscsi_send_r2t_recovery(struct spdk_iscsi_conn *conn,
97 					struct spdk_iscsi_task *r2t_task, uint32_t r2t_sn,
98 					bool send_new_r2tsn);
99 
100 static int spdk_create_iscsi_sess(struct spdk_iscsi_conn *conn,
101 				  struct spdk_iscsi_tgt_node *target, enum session_type session_type);
102 static int spdk_append_iscsi_sess(struct spdk_iscsi_conn *conn,
103 				  const char *initiator_port_name, uint16_t tsih, uint16_t cid);
104 
105 static void spdk_remove_acked_pdu(struct spdk_iscsi_conn *conn, uint32_t ExpStatSN);
106 
107 static int spdk_iscsi_reject(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu,
108 			     int reason);
109 
110 #define DMIN32(A,B) ((uint32_t) ((uint32_t)(A) > (uint32_t)(B) ? (uint32_t)(B) : (uint32_t)(A)))
111 #define DMIN64(A,B) ((uint64_t) ((A) > (B) ? (B) : (A)))
112 
113 #define MATCH_DIGEST_WORD(BUF, CRC32C) \
114 	(    ((((uint32_t) *((uint8_t *)(BUF)+0)) << 0)		\
115 	    | (((uint32_t) *((uint8_t *)(BUF)+1)) << 8)		\
116 	    | (((uint32_t) *((uint8_t *)(BUF)+2)) << 16)	\
117 	    | (((uint32_t) *((uint8_t *)(BUF)+3)) << 24))	\
118 	    == (CRC32C))
119 
120 #define MAKE_DIGEST_WORD(BUF, CRC32C) \
121 	(   ((*((uint8_t *)(BUF)+0)) = (uint8_t)((uint32_t)(CRC32C) >> 0)), \
122 	    ((*((uint8_t *)(BUF)+1)) = (uint8_t)((uint32_t)(CRC32C) >> 8)), \
123 	    ((*((uint8_t *)(BUF)+2)) = (uint8_t)((uint32_t)(CRC32C) >> 16)), \
124 	    ((*((uint8_t *)(BUF)+3)) = (uint8_t)((uint32_t)(CRC32C) >> 24)))
125 
126 #if 0
127 static int
128 spdk_match_digest_word(const uint8_t *buf, uint32_t crc32c)
129 {
130 	uint32_t l;
131 
132 	l = (buf[0] & 0xffU) << 0;
133 	l |= (buf[1] & 0xffU) << 8;
134 	l |= (buf[2] & 0xffU) << 16;
135 	l |= (buf[3] & 0xffU) << 24;
136 	return (l == crc32c);
137 }
138 
139 static uint8_t *
140 spdk_make_digest_word(uint8_t *buf, size_t len, uint32_t crc32c)
141 {
142 	if (len < ISCSI_DIGEST_LEN) {
143 		return NULL;
144 	}
145 
146 	buf[0] = (crc32c >> 0) & 0xffU;
147 	buf[1] = (crc32c >> 8) & 0xffU;
148 	buf[2] = (crc32c >> 16) & 0xffU;
149 	buf[3] = (crc32c >> 24) & 0xffU;
150 	return buf;
151 }
152 #endif
153 
154 #ifndef HAVE_SRANDOMDEV
155 static void
156 srandomdev(void)
157 {
158 	unsigned long seed;
159 	time_t now;
160 	pid_t pid;
161 
162 	pid = getpid();
163 	now = time(NULL);
164 	seed = pid ^ now;
165 	srandom(seed);
166 }
167 #endif /* HAVE_SRANDOMDEV */
168 
169 #ifndef HAVE_ARC4RANDOM
170 static int spdk_arc4random_initialized = 0;
171 
172 static uint32_t
173 arc4random(void)
174 {
175 	uint32_t r;
176 	uint32_t r1, r2;
177 
178 	if (!spdk_arc4random_initialized) {
179 		srandomdev();
180 		spdk_arc4random_initialized = 1;
181 	}
182 	r1 = (uint32_t)(random() & 0xffff);
183 	r2 = (uint32_t)(random() & 0xffff);
184 	r = (r1 << 16) | r2;
185 	return r;
186 }
187 #endif /* HAVE_ARC4RANDOM */
188 
189 static void
190 spdk_gen_random(uint8_t *buf, size_t len)
191 {
192 #ifdef USE_RANDOM
193 	long l;
194 	size_t idx;
195 
196 	srandomdev();
197 	for (idx = 0; idx < len; idx++) {
198 		l = random();
199 		buf[idx] = (uint8_t) l;
200 	}
201 #else
202 	uint32_t r;
203 	size_t idx;
204 
205 	for (idx = 0; idx < len; idx++) {
206 		r = arc4random();
207 		buf[idx] = (uint8_t) r;
208 	}
209 #endif /* USE_RANDOM */
210 }
211 
212 static uint64_t
213 spdk_iscsi_get_isid(const uint8_t isid[6])
214 {
215 	return (uint64_t)isid[0] << 40 |
216 	       (uint64_t)isid[1] << 32 |
217 	       (uint64_t)isid[2] << 24 |
218 	       (uint64_t)isid[3] << 16 |
219 	       (uint64_t)isid[4] << 8 |
220 	       (uint64_t)isid[5];
221 }
222 
223 static int
224 spdk_bin2hex(char *buf, size_t len, const uint8_t *data, size_t data_len)
225 {
226 	const char *digits = "0123456789ABCDEF";
227 	size_t total = 0;
228 	size_t idx;
229 
230 	if (len < 3) {
231 		return -1;
232 	}
233 	buf[total] = '0';
234 	total++;
235 	buf[total] = 'x';
236 	total++;
237 	buf[total] = '\0';
238 
239 	for (idx = 0; idx < data_len; idx++) {
240 		if (total + 3 > len) {
241 			buf[total] = '\0';
242 			return - 1;
243 		}
244 		buf[total] = digits[(data[idx] >> 4) & 0x0fU];
245 		total++;
246 		buf[total] = digits[data[idx] & 0x0fU];
247 		total++;
248 	}
249 	buf[total] = '\0';
250 	return total;
251 }
252 
253 static int
254 spdk_hex2bin(uint8_t *data, size_t data_len, const char *str)
255 {
256 	const char *digits = "0123456789ABCDEF";
257 	const char *dp;
258 	const char *p;
259 	size_t total = 0;
260 	int n0, n1;
261 
262 	p = str;
263 	if (p[0] != '0' && (p[1] != 'x' && p[1] != 'X')) {
264 		return -1;
265 	}
266 	p += 2;
267 
268 	while (p[0] != '\0' && p[1] != '\0') {
269 		if (total >= data_len) {
270 			return -1;
271 		}
272 		dp = strchr(digits, toupper((int) p[0]));
273 		if (dp == NULL) {
274 			return -1;
275 		}
276 		n0 = (int)(dp - digits);
277 		dp = strchr(digits, toupper((int) p[1]));
278 		if (dp == NULL) {
279 			return -1;
280 		}
281 		n1 = (int)(dp - digits);
282 
283 		data[total] = (uint8_t)(((n0 & 0x0fU) << 4) | (n1 & 0x0fU));
284 		total++;
285 		p += 2;
286 	}
287 	return total;
288 }
289 
290 static int
291 spdk_islun2lun(uint64_t islun)
292 {
293 	uint64_t fmt_lun;
294 	uint64_t method;
295 	int lun_i;
296 
297 	fmt_lun = islun;
298 	method = (fmt_lun >> 62) & 0x03U;
299 	fmt_lun = fmt_lun >> 48;
300 	if (method == 0x00U) {
301 		lun_i = (int)(fmt_lun & 0x00ffU);
302 	} else if (method == 0x01U) {
303 		lun_i = (int)(fmt_lun & 0x3fffU);
304 	} else {
305 		lun_i = 0xffffU;
306 	}
307 	return lun_i;
308 }
309 
310 static uint32_t
311 spdk_iscsi_pdu_calc_header_digest(struct spdk_iscsi_pdu *pdu)
312 {
313 	uint32_t crc32c;
314 	uint32_t ahs_len_bytes = pdu->bhs.total_ahs_len * 4;
315 
316 	crc32c = SPDK_CRC32C_INITIAL;
317 	crc32c = spdk_crc32c_update(&pdu->bhs, ISCSI_BHS_LEN, crc32c);
318 
319 	if (ahs_len_bytes) {
320 		crc32c = spdk_crc32c_update(pdu->ahs, ahs_len_bytes, crc32c);
321 	}
322 
323 	/* BHS and AHS are always 4-byte multiples in length, so no padding is necessary. */
324 	crc32c = crc32c ^ SPDK_CRC32C_XOR;
325 	return crc32c;
326 }
327 
328 static uint32_t
329 spdk_iscsi_pdu_calc_data_digest(struct spdk_iscsi_pdu *pdu)
330 {
331 	uint32_t data_len = DGET24(pdu->bhs.data_segment_len);
332 	uint32_t crc32c;
333 	uint32_t mod;
334 
335 	crc32c = SPDK_CRC32C_INITIAL;
336 	crc32c = spdk_crc32c_update(pdu->data, data_len, crc32c);
337 
338 	mod = data_len % ISCSI_ALIGNMENT;
339 	if (mod != 0) {
340 		uint32_t pad_length = ISCSI_ALIGNMENT - mod;
341 		uint8_t pad[3] = {0, 0, 0};
342 
343 		assert(pad_length > 0);
344 		assert(pad_length <= sizeof(pad));
345 		crc32c = spdk_crc32c_update(pad, pad_length, crc32c);
346 	}
347 
348 	crc32c = crc32c ^ SPDK_CRC32C_XOR;
349 	return crc32c;
350 }
351 
352 int
353 spdk_iscsi_read_pdu(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu **_pdu)
354 {
355 	struct spdk_iscsi_pdu *pdu;
356 	struct spdk_mempool *pool;
357 	uint32_t crc32c;
358 	int ahs_len;
359 	int data_len;
360 	int max_segment_len;
361 	int rc;
362 
363 	if (conn->pdu_in_progress == NULL) {
364 		conn->pdu_in_progress = spdk_get_pdu();
365 		if (conn->pdu_in_progress == NULL) {
366 			return SPDK_ISCSI_CONNECTION_FATAL;
367 		}
368 	}
369 
370 	pdu = conn->pdu_in_progress;
371 
372 	if (pdu->bhs_valid_bytes < ISCSI_BHS_LEN) {
373 		rc = spdk_iscsi_conn_read_data(conn,
374 					       ISCSI_BHS_LEN - pdu->bhs_valid_bytes,
375 					       (uint8_t *)&pdu->bhs + pdu->bhs_valid_bytes);
376 		if (rc < 0) {
377 			*_pdu = NULL;
378 			spdk_put_pdu(pdu);
379 			conn->pdu_in_progress = NULL;
380 			return rc;
381 		}
382 		pdu->bhs_valid_bytes += rc;
383 		if (pdu->bhs_valid_bytes < ISCSI_BHS_LEN) {
384 			*_pdu = NULL;
385 			return SPDK_SUCCESS;
386 		}
387 	}
388 
389 	data_len = ISCSI_ALIGN(DGET24(pdu->bhs.data_segment_len));
390 
391 	/* AHS */
392 	ahs_len = pdu->bhs.total_ahs_len * 4;
393 	assert(ahs_len <= ISCSI_AHS_LEN);
394 	if (pdu->ahs_valid_bytes < ahs_len) {
395 		rc = spdk_iscsi_conn_read_data(conn,
396 					       ahs_len - pdu->ahs_valid_bytes,
397 					       pdu->ahs + pdu->ahs_valid_bytes);
398 		if (rc < 0) {
399 			*_pdu = NULL;
400 			spdk_put_pdu(pdu);
401 			conn->pdu_in_progress = NULL;
402 			return rc;
403 		}
404 
405 		pdu->ahs_valid_bytes += rc;
406 		if (pdu->ahs_valid_bytes < ahs_len) {
407 			*_pdu = NULL;
408 			return SPDK_SUCCESS;
409 		}
410 	}
411 
412 	/* Header Digest */
413 	if (conn->header_digest &&
414 	    pdu->hdigest_valid_bytes < ISCSI_DIGEST_LEN) {
415 		rc = spdk_iscsi_conn_read_data(conn,
416 					       ISCSI_DIGEST_LEN - pdu->hdigest_valid_bytes,
417 					       pdu->header_digest + pdu->hdigest_valid_bytes);
418 		if (rc < 0) {
419 			*_pdu = NULL;
420 			spdk_put_pdu(pdu);
421 			conn->pdu_in_progress = NULL;
422 			return rc;
423 		}
424 
425 		pdu->hdigest_valid_bytes += rc;
426 		if (pdu->hdigest_valid_bytes < ISCSI_DIGEST_LEN) {
427 			*_pdu = NULL;
428 			return SPDK_SUCCESS;
429 		}
430 	}
431 
432 	/* copy the actual data into local buffer */
433 	if (pdu->data_valid_bytes < data_len) {
434 		if (pdu->data_buf == NULL) {
435 			if (data_len <= spdk_get_immediate_data_buffer_size()) {
436 				pool = g_spdk_iscsi.pdu_immediate_data_pool;
437 			} else if (data_len <= spdk_get_data_out_buffer_size()) {
438 				pool = g_spdk_iscsi.pdu_data_out_pool;
439 			} else {
440 				SPDK_ERRLOG("Data(%d) > MaxSegment(%d)\n",
441 					    data_len, spdk_get_data_out_buffer_size());
442 				*_pdu = NULL;
443 				spdk_put_pdu(pdu);
444 				conn->pdu_in_progress = NULL;
445 				return SPDK_ISCSI_CONNECTION_FATAL;
446 			}
447 			pdu->mobj = spdk_mempool_get(pool);
448 			if (pdu->mobj == NULL) {
449 				*_pdu = NULL;
450 				return SPDK_SUCCESS;
451 			}
452 			pdu->data_buf = pdu->mobj->buf;
453 		}
454 
455 		rc = spdk_iscsi_conn_read_data(conn,
456 					       data_len - pdu->data_valid_bytes,
457 					       pdu->data_buf + pdu->data_valid_bytes);
458 		if (rc < 0) {
459 			*_pdu = NULL;
460 			spdk_put_pdu(pdu);
461 			conn->pdu_in_progress = NULL;
462 			return rc;
463 		}
464 
465 		pdu->data_valid_bytes += rc;
466 		if (pdu->data_valid_bytes < data_len) {
467 			*_pdu = NULL;
468 			return SPDK_SUCCESS;
469 		}
470 	}
471 
472 	/* copy out the data digest */
473 	if (conn->data_digest && data_len != 0 &&
474 	    pdu->ddigest_valid_bytes < ISCSI_DIGEST_LEN) {
475 		rc = spdk_iscsi_conn_read_data(conn,
476 					       ISCSI_DIGEST_LEN - pdu->ddigest_valid_bytes,
477 					       pdu->data_digest + pdu->ddigest_valid_bytes);
478 		if (rc < 0) {
479 			*_pdu = NULL;
480 			spdk_put_pdu(pdu);
481 			conn->pdu_in_progress = NULL;
482 			return rc;
483 		}
484 
485 		pdu->ddigest_valid_bytes += rc;
486 		if (pdu->ddigest_valid_bytes < ISCSI_DIGEST_LEN) {
487 			*_pdu = NULL;
488 			return SPDK_SUCCESS;
489 		}
490 	}
491 
492 	/* All data for this PDU has now been read from the socket. */
493 	conn->pdu_in_progress = NULL;
494 
495 	spdk_trace_record(TRACE_READ_PDU, conn->id, pdu->data_valid_bytes,
496 			  (uintptr_t)pdu, pdu->bhs.opcode);
497 
498 	/* Data Segment */
499 	if (data_len != 0) {
500 		/*
501 		 * Determine the maximum segment length expected for this PDU.
502 		 *  This will be used to make sure the initiator did not send
503 		 *  us too much immediate data.
504 		 *
505 		 * This value is specified separately by the initiator and target,
506 		 *  and not negotiated.  So we can use the #define safely here,
507 		 *  since the value is not dependent on the initiator's maximum
508 		 *  segment lengths (FirstBurstLength/MaxRecvDataSegmentLength),
509 		 *  and SPDK currently does not allow configuration of these values
510 		 *  at runtime.
511 		 */
512 		if (conn->sess == NULL) {
513 			/*
514 			 * If the connection does not yet have a session, then
515 			 *  login is not complete and we use the 8KB default
516 			 *  FirstBurstLength as our maximum data segment length
517 			 *  value.
518 			 */
519 			max_segment_len = DEFAULT_FIRSTBURSTLENGTH;
520 		} else if (pdu->bhs.opcode == ISCSI_OP_SCSI_DATAOUT) {
521 			max_segment_len = spdk_get_data_out_buffer_size();
522 		} else if (pdu->bhs.opcode == ISCSI_OP_NOPOUT) {
523 			max_segment_len = SPDK_ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH;
524 		} else {
525 			max_segment_len = spdk_get_immediate_data_buffer_size();
526 		}
527 		if (data_len > max_segment_len) {
528 			SPDK_ERRLOG("Data(%d) > MaxSegment(%d)\n", data_len, max_segment_len);
529 			rc = spdk_iscsi_reject(conn, pdu, ISCSI_REASON_PROTOCOL_ERROR);
530 			spdk_put_pdu(pdu);
531 
532 			/*
533 			 * If spdk_iscsi_reject() was not able to reject the PDU,
534 			 * treat it as a fatal connection error.  Otherwise,
535 			 * return SUCCESS here so that the caller will continue
536 			 * to attempt to read PDUs.
537 			 */
538 			rc = (rc < 0) ? SPDK_ISCSI_CONNECTION_FATAL : SPDK_SUCCESS;
539 			return rc;
540 		}
541 
542 		pdu->data = pdu->data_buf;
543 		pdu->data_from_mempool = true;
544 		pdu->data_segment_len = data_len;
545 	}
546 
547 	/* check digest */
548 	if (conn->header_digest) {
549 		crc32c = spdk_iscsi_pdu_calc_header_digest(pdu);
550 		rc = MATCH_DIGEST_WORD(pdu->header_digest, crc32c);
551 		if (rc == 0) {
552 			SPDK_ERRLOG("header digest error (%s)\n", conn->initiator_name);
553 			spdk_put_pdu(pdu);
554 			return SPDK_ISCSI_CONNECTION_FATAL;
555 		}
556 	}
557 	if (conn->data_digest && data_len != 0) {
558 		crc32c = spdk_iscsi_pdu_calc_data_digest(pdu);
559 		rc = MATCH_DIGEST_WORD(pdu->data_digest, crc32c);
560 		if (rc == 0) {
561 			SPDK_ERRLOG("data digest error (%s)\n", conn->initiator_name);
562 			spdk_put_pdu(pdu);
563 			return SPDK_ISCSI_CONNECTION_FATAL;
564 		}
565 	}
566 
567 	*_pdu = pdu;
568 	return 1;
569 }
570 
571 int
572 spdk_iscsi_build_iovecs(struct spdk_iscsi_conn *conn, struct iovec *iovec,
573 			struct spdk_iscsi_pdu *pdu)
574 {
575 	int iovec_cnt = 0;
576 	uint32_t crc32c;
577 	int enable_digest;
578 	int total_ahs_len;
579 	int data_len;
580 
581 	total_ahs_len = pdu->bhs.total_ahs_len;
582 	data_len = DGET24(pdu->bhs.data_segment_len);
583 
584 	enable_digest = 1;
585 	if (pdu->bhs.opcode == ISCSI_OP_LOGIN_RSP) {
586 		/* this PDU should be sent without digest */
587 		enable_digest = 0;
588 	}
589 
590 	/* BHS */
591 	iovec[iovec_cnt].iov_base = &pdu->bhs;
592 	iovec[iovec_cnt].iov_len = ISCSI_BHS_LEN;
593 	iovec_cnt++;
594 
595 	/* AHS */
596 	if (total_ahs_len > 0) {
597 		iovec[iovec_cnt].iov_base = pdu->ahs;
598 		iovec[iovec_cnt].iov_len = 4 * total_ahs_len;
599 		iovec_cnt++;
600 	}
601 
602 	/* Header Digest */
603 	if (enable_digest && conn->header_digest) {
604 		crc32c = spdk_iscsi_pdu_calc_header_digest(pdu);
605 		MAKE_DIGEST_WORD(pdu->header_digest, crc32c);
606 
607 		iovec[iovec_cnt].iov_base = pdu->header_digest;
608 		iovec[iovec_cnt].iov_len = ISCSI_DIGEST_LEN;
609 		iovec_cnt++;
610 	}
611 
612 	/* Data Segment */
613 	if (data_len > 0) {
614 		iovec[iovec_cnt].iov_base = pdu->data;
615 		iovec[iovec_cnt].iov_len = ISCSI_ALIGN(data_len);
616 		iovec_cnt++;
617 	}
618 
619 	/* Data Digest */
620 	if (enable_digest && conn->data_digest && data_len != 0) {
621 		crc32c = spdk_iscsi_pdu_calc_data_digest(pdu);
622 		MAKE_DIGEST_WORD(pdu->data_digest, crc32c);
623 
624 		iovec[iovec_cnt].iov_base = pdu->data_digest;
625 		iovec[iovec_cnt].iov_len = ISCSI_DIGEST_LEN;
626 		iovec_cnt++;
627 	}
628 
629 	return iovec_cnt;
630 }
631 
632 static int
633 spdk_iscsi_append_text(struct spdk_iscsi_conn *conn __attribute__((__unused__)),
634 		       const char *key, const char *val, uint8_t *data,
635 		       int alloc_len, int data_len)
636 {
637 	int total;
638 	int len;
639 
640 	total = data_len;
641 	if (alloc_len < 1) {
642 		return 0;
643 	}
644 	if (total > alloc_len) {
645 		total = alloc_len;
646 		data[total - 1] = '\0';
647 		return total;
648 	}
649 
650 	if (alloc_len - total < 1) {
651 		SPDK_ERRLOG("data space small %d\n", alloc_len);
652 		return total;
653 	}
654 	len = snprintf((char *) data + total, alloc_len - total, "%s=%s", key, val);
655 	total += len + 1;
656 
657 	return total;
658 }
659 
660 static int
661 spdk_iscsi_append_param(struct spdk_iscsi_conn *conn, const char *key,
662 			uint8_t *data, int alloc_len, int data_len)
663 {
664 	struct iscsi_param *param;
665 	int rc;
666 
667 	param = spdk_iscsi_param_find(conn->params, key);
668 	if (param == NULL) {
669 		param = spdk_iscsi_param_find(conn->sess->params, key);
670 		if (param == NULL) {
671 			SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "no key %.64s\n", key);
672 			return data_len;
673 		}
674 	}
675 	rc = spdk_iscsi_append_text(conn, param->key, param->val, data,
676 				    alloc_len, data_len);
677 	return rc;
678 }
679 
680 static int
681 spdk_iscsi_chap_get_authinfo(struct iscsi_chap_auth *auth, const char *authfile,
682 			     const char *authuser, int ag_tag)
683 {
684 	struct spdk_conf *config = NULL;
685 	struct spdk_conf_section *sp;
686 	const char *val;
687 	const char *user, *muser;
688 	const char *secret, *msecret;
689 	int rc;
690 	int i;
691 
692 	if (auth->user != NULL) {
693 		free(auth->user);
694 		free(auth->secret);
695 		free(auth->muser);
696 		free(auth->msecret);
697 		auth->user = auth->secret = NULL;
698 		auth->muser = auth->msecret = NULL;
699 	}
700 
701 	/* read config files */
702 	config = spdk_conf_allocate();
703 	if (config == NULL) {
704 		SPDK_ERRLOG("allocate config fail\n");
705 		return -1;
706 	}
707 	rc = spdk_conf_read(config, authfile);
708 	if (rc < 0) {
709 		SPDK_ERRLOG("auth conf error\n");
710 		spdk_conf_free(config);
711 		return -1;
712 	}
713 	//spdk_conf_print(config);
714 
715 	sp = spdk_conf_first_section(config);
716 	while (sp != NULL) {
717 		if (spdk_conf_section_match_prefix(sp, "AuthGroup")) {
718 			int group = spdk_conf_section_get_num(sp);
719 			if (group == 0) {
720 				SPDK_ERRLOG("Group 0 is invalid\n");
721 				spdk_conf_free(config);
722 				return -1;
723 			}
724 			if (ag_tag != group) {
725 				goto skip_ag_tag;
726 			}
727 
728 			val = spdk_conf_section_get_val(sp, "Comment");
729 			if (val != NULL) {
730 				SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Comment %s\n", val);
731 			}
732 			for (i = 0; ; i++) {
733 				val = spdk_conf_section_get_nval(sp, "Auth", i);
734 				if (val == NULL) {
735 					break;
736 				}
737 				user = spdk_conf_section_get_nmval(sp, "Auth", i, 0);
738 				secret = spdk_conf_section_get_nmval(sp, "Auth", i, 1);
739 				muser = spdk_conf_section_get_nmval(sp, "Auth", i, 2);
740 				msecret = spdk_conf_section_get_nmval(sp, "Auth", i, 3);
741 				if (user != NULL) {
742 					if (strcasecmp(authuser, user) == 0) {
743 						/* match user */
744 						auth->user = xstrdup(user);
745 						auth->secret = xstrdup(secret);
746 						auth->muser = xstrdup(muser);
747 						auth->msecret = xstrdup(msecret);
748 						spdk_conf_free(config);
749 						return 0;
750 					}
751 				} else {
752 					SPDK_ERRLOG("Invalid Auth format, skip this line\n");
753 					continue;
754 				}
755 			}
756 		}
757 skip_ag_tag:
758 		sp = spdk_conf_next_section(sp);
759 	}
760 
761 	spdk_conf_free(config);
762 	return 0;
763 }
764 
765 static int
766 spdk_iscsi_get_authinfo(struct spdk_iscsi_conn *conn, const char *authuser)
767 {
768 	char *authfile = NULL;
769 	int ag_tag;
770 	int rc;
771 
772 	if (conn->sess->target != NULL) {
773 		ag_tag = conn->sess->target->chap_group;
774 	} else {
775 		ag_tag = -1;
776 	}
777 	if (ag_tag < 0) {
778 		pthread_mutex_lock(&g_spdk_iscsi.mutex);
779 		ag_tag = g_spdk_iscsi.discovery_auth_group;
780 		pthread_mutex_unlock(&g_spdk_iscsi.mutex);
781 	}
782 	SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "ag_tag=%d\n", ag_tag);
783 
784 	pthread_mutex_lock(&g_spdk_iscsi.mutex);
785 	authfile = strdup(g_spdk_iscsi.authfile);
786 	pthread_mutex_unlock(&g_spdk_iscsi.mutex);
787 	if (!authfile) {
788 		SPDK_ERRLOG("strdup() failed for authfile\n");
789 		return -ENOMEM;
790 	}
791 
792 	rc = spdk_iscsi_chap_get_authinfo(&conn->auth, authfile, authuser, ag_tag);
793 	if (rc < 0) {
794 		SPDK_ERRLOG("chap_get_authinfo() failed\n");
795 		free(authfile);
796 		return -1;
797 	}
798 	free(authfile);
799 	return 0;
800 }
801 
802 static int
803 spdk_iscsi_auth_params(struct spdk_iscsi_conn *conn,
804 		       struct iscsi_param *params, const char *method, uint8_t *data,
805 		       int alloc_len, int data_len)
806 {
807 	char *in_val;
808 	char *in_next;
809 	char *new_val;
810 	const char *val;
811 	const char *user;
812 	const char *response;
813 	const char *challenge;
814 	int total;
815 	int rc;
816 
817 	if (conn == NULL || params == NULL || method == NULL) {
818 		return -1;
819 	}
820 	if (strcasecmp(method, "CHAP") == 0) {
821 		/* method OK */
822 	} else {
823 		SPDK_ERRLOG("unsupported AuthMethod %.64s\n", method);
824 		return -1;
825 	}
826 
827 	total = data_len;
828 	if (alloc_len < 1) {
829 		return 0;
830 	}
831 	if (total > alloc_len) {
832 		total = alloc_len;
833 		data[total - 1] = '\0';
834 		return total;
835 	}
836 
837 	/* for temporary store */
838 	in_val = malloc(ISCSI_TEXT_MAX_VAL_LEN + 1);
839 	if (!in_val) {
840 		SPDK_ERRLOG("malloc() failed for temporary store\n");
841 		return -ENOMEM;
842 	}
843 
844 	/* CHAP method (RFC1994) */
845 	if ((val = spdk_iscsi_param_get_val(params, "CHAP_A")) != NULL) {
846 		if (conn->auth.chap_phase != ISCSI_CHAP_PHASE_WAIT_A) {
847 			SPDK_ERRLOG("CHAP sequence error\n");
848 			goto error_return;
849 		}
850 
851 		/* CHAP_A is LIST type */
852 		snprintf(in_val, ISCSI_TEXT_MAX_VAL_LEN + 1, "%s", val);
853 		in_next = in_val;
854 		while ((new_val = spdk_strsepq(&in_next, ",")) != NULL) {
855 			if (strcasecmp(new_val, "5") == 0) {
856 				/* CHAP with MD5 */
857 				break;
858 			}
859 		}
860 		if (new_val == NULL) {
861 			snprintf(in_val, ISCSI_TEXT_MAX_VAL_LEN + 1, "%s", "Reject");
862 			new_val = in_val;
863 			spdk_iscsi_append_text(conn, "CHAP_A", new_val,
864 					       data, alloc_len, total);
865 			goto error_return;
866 		}
867 		/* selected algorithm is 5 (MD5) */
868 		SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "got CHAP_A=%s\n", new_val);
869 		total = spdk_iscsi_append_text(conn, "CHAP_A", new_val,
870 					       data, alloc_len, total);
871 
872 		/* Identifier is one octet */
873 		spdk_gen_random(conn->auth.chap_id, 1);
874 		snprintf(in_val, ISCSI_TEXT_MAX_VAL_LEN, "%d",
875 			 (int) conn->auth.chap_id[0]);
876 		total = spdk_iscsi_append_text(conn, "CHAP_I", in_val,
877 					       data, alloc_len, total);
878 
879 		/* Challenge Value is a variable stream of octets */
880 		/* (binary length MUST not exceed 1024 bytes) */
881 		conn->auth.chap_challenge_len = ISCSI_CHAP_CHALLENGE_LEN;
882 		spdk_gen_random(conn->auth.chap_challenge,
883 				conn->auth.chap_challenge_len);
884 		spdk_bin2hex(in_val, ISCSI_TEXT_MAX_VAL_LEN,
885 			     conn->auth.chap_challenge,
886 			     conn->auth.chap_challenge_len);
887 		total = spdk_iscsi_append_text(conn, "CHAP_C", in_val,
888 					       data, alloc_len, total);
889 
890 		conn->auth.chap_phase = ISCSI_CHAP_PHASE_WAIT_NR;
891 	} else if ((val = spdk_iscsi_param_get_val(params, "CHAP_N")) != NULL) {
892 		uint8_t resmd5[SPDK_MD5DIGEST_LEN];
893 		uint8_t tgtmd5[SPDK_MD5DIGEST_LEN];
894 		struct spdk_md5ctx md5ctx;
895 
896 		user = val;
897 		if (conn->auth.chap_phase != ISCSI_CHAP_PHASE_WAIT_NR) {
898 			SPDK_ERRLOG("CHAP sequence error\n");
899 			goto error_return;
900 		}
901 
902 		response = spdk_iscsi_param_get_val(params, "CHAP_R");
903 		if (response == NULL) {
904 			SPDK_ERRLOG("no response\n");
905 			goto error_return;
906 		}
907 		rc = spdk_hex2bin(resmd5, SPDK_MD5DIGEST_LEN, response);
908 		if (rc < 0 || rc != SPDK_MD5DIGEST_LEN) {
909 			SPDK_ERRLOG("response format error\n");
910 			goto error_return;
911 		}
912 		SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "got CHAP_N/CHAP_R\n");
913 
914 		rc = spdk_iscsi_get_authinfo(conn, val);
915 		if (rc < 0) {
916 			//SPDK_ERRLOG("auth user or secret is missing\n");
917 			SPDK_ERRLOG("iscsi_get_authinfo() failed\n");
918 			goto error_return;
919 		}
920 		if (conn->auth.user == NULL || conn->auth.secret == NULL) {
921 			//SPDK_ERRLOG("auth user or secret is missing\n");
922 			SPDK_ERRLOG("auth failed (user %.64s)\n", user);
923 			goto error_return;
924 		}
925 
926 		spdk_md5init(&md5ctx);
927 		/* Identifier */
928 		spdk_md5update(&md5ctx, conn->auth.chap_id, 1);
929 		/* followed by secret */
930 		spdk_md5update(&md5ctx, conn->auth.secret,
931 			       strlen(conn->auth.secret));
932 		/* followed by Challenge Value */
933 		spdk_md5update(&md5ctx, conn->auth.chap_challenge,
934 			       conn->auth.chap_challenge_len);
935 		/* tgtmd5 is expecting Response Value */
936 		spdk_md5final(tgtmd5, &md5ctx);
937 
938 		spdk_bin2hex(in_val, ISCSI_TEXT_MAX_VAL_LEN,
939 			     tgtmd5, SPDK_MD5DIGEST_LEN);
940 
941 #if 0
942 		SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "tgtmd5=%s, resmd5=%s\n", in_val, response);
943 		spdk_dump("tgtmd5", tgtmd5, SPDK_MD5DIGEST_LEN);
944 		spdk_dump("resmd5", resmd5, SPDK_MD5DIGEST_LEN);
945 #endif
946 
947 		/* compare MD5 digest */
948 		if (memcmp(tgtmd5, resmd5, SPDK_MD5DIGEST_LEN) != 0) {
949 			/* not match */
950 			//SPDK_ERRLOG("auth user or secret is missing\n");
951 			SPDK_ERRLOG("auth failed (user %.64s)\n", user);
952 			goto error_return;
953 		}
954 		/* OK initiator's secret */
955 		conn->authenticated = 1;
956 
957 		/* mutual CHAP? */
958 		val = spdk_iscsi_param_get_val(params, "CHAP_I");
959 		if (val != NULL) {
960 			conn->auth.chap_mid[0] = (uint8_t) strtol(val, NULL, 10);
961 			challenge = spdk_iscsi_param_get_val(params, "CHAP_C");
962 			if (challenge == NULL) {
963 				SPDK_ERRLOG("CHAP sequence error\n");
964 				goto error_return;
965 			}
966 			rc = spdk_hex2bin(conn->auth.chap_mchallenge,
967 					  ISCSI_CHAP_CHALLENGE_LEN,
968 					  challenge);
969 			if (rc < 0) {
970 				SPDK_ERRLOG("challenge format error\n");
971 				goto error_return;
972 			}
973 			conn->auth.chap_mchallenge_len = rc;
974 #if 0
975 			spdk_dump("MChallenge", conn->auth.chap_mchallenge,
976 				  conn->auth.chap_mchallenge_len);
977 #endif
978 			SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "got CHAP_I/CHAP_C\n");
979 
980 			if (conn->auth.muser == NULL || conn->auth.msecret == NULL) {
981 				//SPDK_ERRLOG("mutual auth user or secret is missing\n");
982 				SPDK_ERRLOG("auth failed (user %.64s)\n", user);
983 				goto error_return;
984 			}
985 
986 			spdk_md5init(&md5ctx);
987 			/* Identifier */
988 			spdk_md5update(&md5ctx, conn->auth.chap_mid, 1);
989 			/* followed by secret */
990 			spdk_md5update(&md5ctx, conn->auth.msecret,
991 				       strlen(conn->auth.msecret));
992 			/* followed by Challenge Value */
993 			spdk_md5update(&md5ctx, conn->auth.chap_mchallenge,
994 				       conn->auth.chap_mchallenge_len);
995 			/* tgtmd5 is Response Value */
996 			spdk_md5final(tgtmd5, &md5ctx);
997 
998 			spdk_bin2hex(in_val, ISCSI_TEXT_MAX_VAL_LEN,
999 				     tgtmd5, SPDK_MD5DIGEST_LEN);
1000 
1001 			total = spdk_iscsi_append_text(conn, "CHAP_N",
1002 						       conn->auth.muser, data, alloc_len, total);
1003 			total = spdk_iscsi_append_text(conn, "CHAP_R",
1004 						       in_val, data, alloc_len, total);
1005 		} else {
1006 			/* not mutual */
1007 			if (conn->req_mutual) {
1008 				SPDK_ERRLOG("required mutual CHAP\n");
1009 				goto error_return;
1010 			}
1011 		}
1012 
1013 		conn->auth.chap_phase = ISCSI_CHAP_PHASE_END;
1014 	} else {
1015 		/* not found CHAP keys */
1016 		SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "start CHAP\n");
1017 		conn->auth.chap_phase = ISCSI_CHAP_PHASE_WAIT_A;
1018 	}
1019 
1020 	free(in_val);
1021 	return total;
1022 
1023 error_return:
1024 	conn->auth.chap_phase = ISCSI_CHAP_PHASE_WAIT_A;
1025 	free(in_val);
1026 	return -1;
1027 }
1028 
1029 static int
1030 spdk_iscsi_reject(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu,
1031 		  int reason)
1032 {
1033 	struct spdk_iscsi_pdu *rsp_pdu;
1034 	struct iscsi_bhs_reject *rsph;
1035 	uint8_t *data;
1036 	int total_ahs_len;
1037 	int data_len;
1038 	int alloc_len;
1039 
1040 	total_ahs_len = pdu->bhs.total_ahs_len;
1041 	data_len = 0;
1042 	alloc_len = ISCSI_BHS_LEN + (4 * total_ahs_len);
1043 
1044 	if (conn->header_digest) {
1045 		alloc_len += ISCSI_DIGEST_LEN;
1046 	}
1047 
1048 	data = calloc(1, alloc_len);
1049 	if (!data) {
1050 		SPDK_ERRLOG("calloc() failed for data segment\n");
1051 		return -ENOMEM;
1052 	}
1053 
1054 	SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Reject PDU reason=%d\n", reason);
1055 
1056 	if (conn->sess != NULL) {
1057 		SPDK_DEBUGLOG(SPDK_LOG_ISCSI,
1058 			      "StatSN=%u, ExpCmdSN=%u, MaxCmdSN=%u\n",
1059 			      conn->StatSN, conn->sess->ExpCmdSN,
1060 			      conn->sess->MaxCmdSN);
1061 	} else {
1062 		SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "StatSN=%u\n", conn->StatSN);
1063 	}
1064 
1065 	memcpy(data, &pdu->bhs, ISCSI_BHS_LEN);
1066 	data_len += ISCSI_BHS_LEN;
1067 
1068 	if (total_ahs_len != 0) {
1069 		memcpy(data + data_len, pdu->ahs, (4 * total_ahs_len));
1070 		data_len += (4 * total_ahs_len);
1071 	}
1072 
1073 	if (conn->header_digest) {
1074 		memcpy(data + data_len, pdu->header_digest, ISCSI_DIGEST_LEN);
1075 		data_len += ISCSI_DIGEST_LEN;
1076 	}
1077 
1078 	rsp_pdu = spdk_get_pdu();
1079 	if (rsp_pdu == NULL) {
1080 		free(data);
1081 		return -ENOMEM;
1082 	}
1083 
1084 	rsph = (struct iscsi_bhs_reject *)&rsp_pdu->bhs;
1085 	rsp_pdu->data = data;
1086 	rsph->opcode = ISCSI_OP_REJECT;
1087 	rsph->flags |= 0x80;	/* bit 0 is default to 1 */
1088 	rsph->reason = reason;
1089 	DSET24(rsph->data_segment_len, data_len);
1090 
1091 	rsph->ffffffff = 0xffffffffU;
1092 	to_be32(&rsph->stat_sn, conn->StatSN);
1093 	conn->StatSN++;
1094 
1095 	if (conn->sess != NULL) {
1096 		to_be32(&rsph->exp_cmd_sn, conn->sess->ExpCmdSN);
1097 		to_be32(&rsph->max_cmd_sn, conn->sess->MaxCmdSN);
1098 	} else {
1099 		to_be32(&rsph->exp_cmd_sn, 1);
1100 		to_be32(&rsph->max_cmd_sn, 1);
1101 	}
1102 
1103 	SPDK_TRACEDUMP(SPDK_LOG_ISCSI, "PDU", (void *)&rsp_pdu->bhs, ISCSI_BHS_LEN);
1104 
1105 	spdk_iscsi_conn_write_pdu(conn, rsp_pdu);
1106 
1107 	return 0;
1108 }
1109 
1110 static int
1111 spdk_iscsi_check_values(struct spdk_iscsi_conn *conn)
1112 {
1113 	if (conn->sess->FirstBurstLength > conn->sess->MaxBurstLength) {
1114 		SPDK_ERRLOG("FirstBurstLength(%d) > MaxBurstLength(%d)\n",
1115 			    conn->sess->FirstBurstLength,
1116 			    conn->sess->MaxBurstLength);
1117 		return -1;
1118 	}
1119 	if (conn->sess->FirstBurstLength > SPDK_ISCSI_FIRST_BURST_LENGTH) {
1120 		SPDK_ERRLOG("FirstBurstLength(%d) > iSCSI target restriction(%d)\n",
1121 			    conn->sess->FirstBurstLength, SPDK_ISCSI_FIRST_BURST_LENGTH);
1122 		return -1;
1123 	}
1124 	if (conn->sess->MaxBurstLength > 0x00ffffff) {
1125 		SPDK_ERRLOG("MaxBurstLength(%d) > 0x00ffffff\n",
1126 			    conn->sess->MaxBurstLength);
1127 		return -1;
1128 	}
1129 
1130 	if (conn->MaxRecvDataSegmentLength < 512) {
1131 		SPDK_ERRLOG("MaxRecvDataSegmentLength(%d) < 512\n",
1132 			    conn->MaxRecvDataSegmentLength);
1133 		return -1;
1134 	}
1135 	if (conn->MaxRecvDataSegmentLength > 0x00ffffff) {
1136 		SPDK_ERRLOG("MaxRecvDataSegmentLength(%d) > 0x00ffffff\n",
1137 			    conn->MaxRecvDataSegmentLength);
1138 		return -1;
1139 	}
1140 	return 0;
1141 }
1142 
1143 /*
1144  * The response function of spdk_iscsi_op_login
1145  * return:
1146  * 0:success;
1147  * -1:error;
1148  */
1149 static int
1150 spdk_iscsi_op_login_response(struct spdk_iscsi_conn *conn,
1151 			     struct spdk_iscsi_pdu *rsp_pdu, struct iscsi_param *params)
1152 {
1153 	struct iscsi_bhs_login_rsp *rsph;
1154 	int rc;
1155 
1156 	rsph = (struct iscsi_bhs_login_rsp *)&rsp_pdu->bhs;
1157 	rsph->version_max = ISCSI_VERSION;
1158 	rsph->version_act = ISCSI_VERSION;
1159 	DSET24(rsph->data_segment_len, rsp_pdu->data_segment_len);
1160 
1161 	to_be32(&rsph->stat_sn, conn->StatSN);
1162 	conn->StatSN++;
1163 
1164 	if (conn->sess != NULL) {
1165 		to_be32(&rsph->exp_cmd_sn, conn->sess->ExpCmdSN);
1166 		to_be32(&rsph->max_cmd_sn, conn->sess->MaxCmdSN);
1167 	} else {
1168 		to_be32(&rsph->exp_cmd_sn, rsp_pdu->cmd_sn);
1169 		to_be32(&rsph->max_cmd_sn, rsp_pdu->cmd_sn);
1170 	}
1171 
1172 	SPDK_TRACEDUMP(SPDK_LOG_ISCSI, "PDU", (uint8_t *)rsph, ISCSI_BHS_LEN);
1173 	SPDK_TRACEDUMP(SPDK_LOG_ISCSI, "DATA", rsp_pdu->data, rsp_pdu->data_segment_len);
1174 
1175 	/* Set T/CSG/NSG to reserved if login error. */
1176 	if (rsph->status_class != 0) {
1177 		rsph->flags &= ~ISCSI_LOGIN_TRANSIT;
1178 		rsph->flags &= ~ISCSI_LOGIN_CURRENT_STAGE_MASK;
1179 		rsph->flags &= ~ISCSI_LOGIN_NEXT_STAGE_MASK;
1180 	}
1181 	spdk_iscsi_conn_write_pdu(conn, rsp_pdu);
1182 
1183 	/* after send PDU digest on/off */
1184 	if (conn->full_feature) {
1185 		/* update internal variables */
1186 		rc = spdk_iscsi_copy_param2var(conn);
1187 		if (rc < 0) {
1188 			SPDK_ERRLOG("spdk_iscsi_copy_param2var() failed\n");
1189 			spdk_iscsi_param_free(params);
1190 			return -1;
1191 		}
1192 		/* check value */
1193 		rc = spdk_iscsi_check_values(conn);
1194 		if (rc < 0) {
1195 			SPDK_ERRLOG("iscsi_check_values() failed\n");
1196 			spdk_iscsi_param_free(params);
1197 			return -1;
1198 		}
1199 	}
1200 
1201 	spdk_iscsi_param_free(params);
1202 	return 0;
1203 }
1204 
1205 /*
1206  * This function is used to del the original param and update it with new
1207  * value
1208  * return:
1209  * 0: success
1210  * otherwise: error
1211  */
1212 static int
1213 spdk_iscsi_op_login_update_param(struct spdk_iscsi_conn *conn,
1214 				 const char *key, const char *value,
1215 				 const char *list)
1216 {
1217 	int rc = 0;
1218 	struct iscsi_param *new_param, *orig_param;
1219 	int index;
1220 
1221 	orig_param = spdk_iscsi_param_find(conn->params, key);
1222 	if (orig_param == NULL) {
1223 		SPDK_ERRLOG("orig_param %s not found\n", key);
1224 		return SPDK_ISCSI_LOGIN_ERROR_PARAMETER;
1225 	}
1226 
1227 	index = orig_param->state_index;
1228 	rc = spdk_iscsi_param_del(&conn->params, key);
1229 	if (rc < 0) {
1230 		SPDK_ERRLOG("iscsi_param_del(%s) failed\n", key);
1231 		return SPDK_ISCSI_LOGIN_ERROR_PARAMETER;
1232 	}
1233 	rc = spdk_iscsi_param_add(&conn->params, key, value, list, ISPT_LIST);
1234 	if (rc < 0) {
1235 		SPDK_ERRLOG("iscsi_param_add() failed\n");
1236 		return SPDK_ISCSI_LOGIN_ERROR_PARAMETER;
1237 	}
1238 	new_param = spdk_iscsi_param_find(conn->params, key);
1239 	if (new_param == NULL) {
1240 		SPDK_ERRLOG("spdk_iscsi_param_find() failed\n");
1241 		return SPDK_ISCSI_LOGIN_ERROR_PARAMETER;
1242 	}
1243 	new_param->state_index = index;
1244 	return rc;
1245 }
1246 
1247 /*
1248  * The function which is used to handle the part of session discovery
1249  * return:
1250  * 0, success;
1251  * otherwise: error;
1252  */
1253 static int
1254 spdk_iscsi_op_login_session_discovery_chap(struct spdk_iscsi_conn *conn)
1255 {
1256 	int rc = 0;
1257 
1258 	if (g_spdk_iscsi.no_discovery_auth) {
1259 		conn->req_auth = 0;
1260 		rc = spdk_iscsi_op_login_update_param(conn, "AuthMethod", "None", "None");
1261 		if (rc < 0) {
1262 			return rc;
1263 		}
1264 	} else if (g_spdk_iscsi.req_discovery_auth) {
1265 		conn->req_auth = 1;
1266 		rc = spdk_iscsi_op_login_update_param(conn, "AuthMethod", "CHAP", "CHAP");
1267 		if (rc < 0) {
1268 			return rc;
1269 		}
1270 	}
1271 	if (g_spdk_iscsi.req_discovery_auth_mutual) {
1272 		conn->req_mutual = 1;
1273 	}
1274 
1275 	return rc;
1276 }
1277 
1278 /*
1279  * This function is used to update the param related with chap
1280  * return:
1281  * 0: success
1282  * otherwise: error
1283  */
1284 static int
1285 spdk_iscsi_op_login_negotiate_chap_param(struct spdk_iscsi_conn *conn,
1286 		struct spdk_iscsi_pdu *rsp_pdu,
1287 		struct spdk_iscsi_tgt_node *target)
1288 {
1289 	int rc;
1290 
1291 	if (target->disable_chap) {
1292 		conn->req_auth = 0;
1293 		rc = spdk_iscsi_op_login_update_param(conn, "AuthMethod", "None", "None");
1294 		if (rc < 0) {
1295 			return rc;
1296 		}
1297 	} else if (target->require_chap) {
1298 		conn->req_auth = 1;
1299 		rc = spdk_iscsi_op_login_update_param(conn, "AuthMethod", "CHAP", "CHAP");
1300 		if (rc < 0) {
1301 			return rc;
1302 		}
1303 	}
1304 
1305 	if (target->mutual_chap) {
1306 		conn->req_mutual = 1;
1307 	}
1308 
1309 	if (target->header_digest) {
1310 		/*
1311 		 * User specified header digests, so update the list of
1312 		 *  HeaderDigest values to remove "None" so that only
1313 		 *  initiators who support CRC32C can connect.
1314 		 */
1315 		rc = spdk_iscsi_op_login_update_param(conn, "HeaderDigest", "CRC32C", "CRC32C");
1316 		if (rc < 0) {
1317 			return rc;
1318 		}
1319 	}
1320 
1321 	if (target->data_digest) {
1322 		/*
1323 		 * User specified data digests, so update the list of
1324 		 *  DataDigest values to remove "None" so that only
1325 		 *  initiators who support CRC32C can connect.
1326 		 */
1327 		rc = spdk_iscsi_op_login_update_param(conn, "DataDigest", "CRC32C", "CRC32C");
1328 		if (rc < 0) {
1329 			return rc;
1330 		}
1331 	}
1332 
1333 	return 0;
1334 }
1335 
1336 /*
1337  * This function use to check the session
1338  * return:
1339  * 0, success
1340  * otherwise: error
1341  */
1342 static int
1343 spdk_iscsi_op_login_check_session(struct spdk_iscsi_conn *conn,
1344 				  struct spdk_iscsi_pdu *rsp_pdu,
1345 				  char *initiator_port_name, int cid)
1346 
1347 {
1348 	int rc = 0;
1349 	struct iscsi_bhs_login_rsp *rsph;
1350 
1351 	rsph = (struct iscsi_bhs_login_rsp *)&rsp_pdu->bhs;
1352 	/* check existing session */
1353 	SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "isid=%"PRIx64", tsih=%u, cid=%u\n",
1354 		      spdk_iscsi_get_isid(rsph->isid), from_be16(&rsph->tsih), cid);
1355 	if (rsph->tsih != 0) {
1356 		/* multiple connections */
1357 		rc = spdk_append_iscsi_sess(conn, initiator_port_name,
1358 					    from_be16(&rsph->tsih), cid);
1359 		if (rc < 0) {
1360 			SPDK_ERRLOG("isid=%"PRIx64", tsih=%u, cid=%u:"
1361 				    "spdk_append_iscsi_sess() failed\n",
1362 				    spdk_iscsi_get_isid(rsph->isid), from_be16(&rsph->tsih),
1363 				    cid);
1364 			/* Can't include in session */
1365 			rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR;
1366 			rsph->status_detail = ISCSI_LOGIN_CONN_ADD_FAIL;
1367 			return SPDK_ISCSI_LOGIN_ERROR_RESPONSE;
1368 		}
1369 	} else if (!g_spdk_iscsi.AllowDuplicateIsid) {
1370 		/* new session, drop old sess by the initiator */
1371 		spdk_iscsi_drop_conns(conn, initiator_port_name, 0 /* drop old */);
1372 	}
1373 
1374 	return rc;
1375 }
1376 
1377 /*
1378  * This function is used to check the target info
1379  * return:
1380  * 0: success
1381  * otherwise: error
1382  */
1383 static int
1384 spdk_iscsi_op_login_check_target(struct spdk_iscsi_conn *conn,
1385 				 struct spdk_iscsi_pdu *rsp_pdu,
1386 				 const char *target_name,
1387 				 struct spdk_iscsi_tgt_node **target)
1388 {
1389 	bool result;
1390 	struct iscsi_bhs_login_rsp *rsph;
1391 
1392 	rsph = (struct iscsi_bhs_login_rsp *)&rsp_pdu->bhs;
1393 	*target = spdk_iscsi_find_tgt_node(target_name);
1394 	if (*target == NULL) {
1395 		SPDK_WARNLOG("target %s not found\n", target_name);
1396 		/* Not found */
1397 		rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR;
1398 		rsph->status_detail = ISCSI_LOGIN_TARGET_NOT_FOUND;
1399 		return SPDK_ISCSI_LOGIN_ERROR_RESPONSE;
1400 	}
1401 	result = spdk_iscsi_tgt_node_access(conn, *target,
1402 					    conn->initiator_name,
1403 					    conn->initiator_addr);
1404 	if (!result) {
1405 		SPDK_ERRLOG("access denied\n");
1406 		/* Not found */
1407 		rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR;
1408 		rsph->status_detail = ISCSI_LOGIN_TARGET_NOT_FOUND;
1409 		return SPDK_ISCSI_LOGIN_ERROR_RESPONSE;
1410 	}
1411 
1412 	return 0;
1413 }
1414 
1415 /*
1416  * The function which is used to handle the part of normal login session
1417  * return:
1418  * 0, success;
1419  * SPDK_ISCSI_LOGIN_ERROR_PARAMETER, parameter error;
1420  */
1421 static int
1422 spdk_iscsi_op_login_session_normal(struct spdk_iscsi_conn *conn,
1423 				   struct spdk_iscsi_pdu *rsp_pdu,
1424 				   char *initiator_port_name,
1425 				   struct iscsi_param *params,
1426 				   struct spdk_iscsi_tgt_node **target,
1427 				   int cid)
1428 {
1429 	const char *target_name;
1430 	const char *target_short_name;
1431 	struct iscsi_bhs_login_rsp *rsph;
1432 	int rc = 0;
1433 
1434 	rsph = (struct iscsi_bhs_login_rsp *)&rsp_pdu->bhs;
1435 	target_name = spdk_iscsi_param_get_val(params, "TargetName");
1436 
1437 	if (target_name == NULL) {
1438 		SPDK_ERRLOG("TargetName is empty\n");
1439 		/* Missing parameter */
1440 		rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR;
1441 		rsph->status_detail = ISCSI_LOGIN_MISSING_PARMS;
1442 		return SPDK_ISCSI_LOGIN_ERROR_RESPONSE;
1443 	}
1444 
1445 	memset(conn->target_short_name, 0, MAX_TARGET_NAME);
1446 	target_short_name = strstr(target_name, ":");
1447 	if (target_short_name != NULL) {
1448 		target_short_name++; /* Advance past the ':' */
1449 		if (strlen(target_short_name) >= MAX_TARGET_NAME) {
1450 			SPDK_ERRLOG("Target Short Name (%s) is more than %u characters\n",
1451 				    target_short_name, MAX_TARGET_NAME);
1452 			return rc;
1453 		}
1454 		snprintf(conn->target_short_name, MAX_TARGET_NAME, "%s",
1455 			 target_short_name);
1456 	}
1457 
1458 	pthread_mutex_lock(&g_spdk_iscsi.mutex);
1459 	rc = spdk_iscsi_op_login_check_target(conn, rsp_pdu, target_name, target);
1460 	pthread_mutex_unlock(&g_spdk_iscsi.mutex);
1461 
1462 	if (rc < 0) {
1463 		return rc;
1464 	}
1465 
1466 	conn->target = *target;
1467 	conn->dev = (*target)->dev;
1468 	conn->target_port = spdk_scsi_dev_find_port_by_id((*target)->dev,
1469 			    conn->portal->group->tag);
1470 
1471 	rc = spdk_iscsi_op_login_check_session(conn, rsp_pdu,
1472 					       initiator_port_name, cid);
1473 	if (rc < 0) {
1474 		return rc;
1475 	}
1476 
1477 	/* force target flags */
1478 	pthread_mutex_lock(&((*target)->mutex));
1479 	rc = spdk_iscsi_op_login_negotiate_chap_param(conn, rsp_pdu, *target);
1480 	pthread_mutex_unlock(&((*target)->mutex));
1481 
1482 	return rc;
1483 }
1484 
1485 /*
1486  * This function is used to judge the session type
1487  * return
1488  * 0: success
1489  * otherwise, error
1490  */
1491 static int
1492 spdk_iscsi_op_login_session_type(struct spdk_iscsi_conn *conn,
1493 				 struct spdk_iscsi_pdu *rsp_pdu,
1494 				 enum session_type *session_type,
1495 				 struct iscsi_param *params)
1496 {
1497 	const char *session_type_str;
1498 	struct iscsi_bhs_login_rsp *rsph;
1499 
1500 	rsph = (struct iscsi_bhs_login_rsp *)&rsp_pdu->bhs;
1501 	session_type_str = spdk_iscsi_param_get_val(params, "SessionType");
1502 	if (session_type_str == NULL) {
1503 		if (rsph->tsih != 0) {
1504 			*session_type = SESSION_TYPE_NORMAL;
1505 		} else {
1506 			SPDK_ERRLOG("SessionType is empty\n");
1507 			/* Missing parameter */
1508 			rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR;
1509 			rsph->status_detail = ISCSI_LOGIN_MISSING_PARMS;
1510 			return SPDK_ISCSI_LOGIN_ERROR_RESPONSE;
1511 		}
1512 	} else {
1513 		if (strcasecmp(session_type_str, "Discovery") == 0) {
1514 			*session_type = SESSION_TYPE_DISCOVERY;
1515 		} else if (strcasecmp(session_type_str, "Normal") == 0) {
1516 			*session_type = SESSION_TYPE_NORMAL;
1517 		} else {
1518 			*session_type = SESSION_TYPE_INVALID;
1519 			SPDK_ERRLOG("SessionType is invalid\n");
1520 			/* Missing parameter */
1521 			rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR;
1522 			rsph->status_detail = ISCSI_LOGIN_MISSING_PARMS;
1523 			return SPDK_ISCSI_LOGIN_ERROR_RESPONSE;
1524 		}
1525 	}
1526 	SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Session Type: %s\n", session_type_str);
1527 
1528 	return 0;
1529 }
1530 /*
1531  * This function is used to initialize the port info
1532  * return
1533  * 0: success
1534  * otherwise: error
1535  */
1536 static int
1537 spdk_iscsi_op_login_initialize_port(struct spdk_iscsi_conn *conn,
1538 				    struct spdk_iscsi_pdu *rsp_pdu,
1539 				    char *initiator_port_name,
1540 				    uint32_t name_length,
1541 				    struct iscsi_param *params)
1542 {
1543 	const char *val;
1544 	struct iscsi_bhs_login_rsp *rsph;
1545 	rsph = (struct iscsi_bhs_login_rsp *)&rsp_pdu->bhs;
1546 
1547 	/* Initiator Name and Port */
1548 	val = spdk_iscsi_param_get_val(params, "InitiatorName");
1549 	if (val == NULL) {
1550 		SPDK_ERRLOG("InitiatorName is empty\n");
1551 		/* Missing parameter */
1552 		rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR;
1553 		rsph->status_detail = ISCSI_LOGIN_MISSING_PARMS;
1554 		return SPDK_ISCSI_LOGIN_ERROR_RESPONSE;
1555 	}
1556 	snprintf(conn->initiator_name, sizeof(conn->initiator_name), "%s", val);
1557 	snprintf(initiator_port_name, name_length,
1558 		 "%s,i,0x%12.12" PRIx64, val, spdk_iscsi_get_isid(rsph->isid));
1559 	spdk_strlwr(conn->initiator_name);
1560 	spdk_strlwr(initiator_port_name);
1561 	SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Initiator name: %s\n", conn->initiator_name);
1562 	SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Initiator port: %s\n", initiator_port_name);
1563 
1564 	return 0;
1565 }
1566 
1567 /*
1568  * This function is used to set the info in the connection data structure
1569  * return
1570  * 0: success
1571  * otherwise: error
1572  */
1573 static int
1574 spdk_iscsi_op_login_set_conn_info(struct spdk_iscsi_conn *conn,
1575 				  struct spdk_iscsi_pdu *rsp_pdu,
1576 				  char *initiator_port_name,
1577 				  enum session_type session_type,
1578 				  struct spdk_iscsi_tgt_node *target, int cid)
1579 {
1580 	int rc = 0;
1581 	struct iscsi_bhs_login_rsp *rsph;
1582 
1583 	rsph = (struct iscsi_bhs_login_rsp *)&rsp_pdu->bhs;
1584 	conn->authenticated = 0;
1585 	conn->auth.chap_phase = ISCSI_CHAP_PHASE_WAIT_A;
1586 	conn->cid = cid;
1587 
1588 	if (conn->sess == NULL) {
1589 		/* new session */
1590 		rc = spdk_create_iscsi_sess(conn, target, session_type);
1591 		if (rc < 0) {
1592 			SPDK_ERRLOG("create_sess() failed\n");
1593 			rsph->status_class = ISCSI_CLASS_TARGET_ERROR;
1594 			rsph->status_detail = ISCSI_LOGIN_STATUS_NO_RESOURCES;
1595 			return SPDK_ISCSI_LOGIN_ERROR_RESPONSE;
1596 		}
1597 
1598 		/* initialize parameters */
1599 		conn->StatSN = from_be32(&rsph->stat_sn);
1600 		conn->sess->initiator_port = spdk_scsi_port_create(spdk_iscsi_get_isid(rsph->isid),
1601 					     0, initiator_port_name);
1602 		conn->sess->isid = spdk_iscsi_get_isid(rsph->isid);
1603 		conn->sess->target = target;
1604 
1605 		/* Discovery sessions will not have a target. */
1606 		if (target != NULL) {
1607 			conn->sess->queue_depth = target->queue_depth;
1608 		} else {
1609 			/*
1610 			 * Assume discovery sessions have an effective command
1611 			 *  windows size of 1.
1612 			 */
1613 			conn->sess->queue_depth = 1;
1614 		}
1615 		conn->sess->ExpCmdSN = rsp_pdu->cmd_sn;
1616 		conn->sess->MaxCmdSN = rsp_pdu->cmd_sn + conn->sess->queue_depth - 1;
1617 	}
1618 
1619 	conn->initiator_port = conn->sess->initiator_port;
1620 
1621 	return 0;
1622 }
1623 
1624 /*
1625  * This function is used to set the target info
1626  * return
1627  * 0: success
1628  * otherwise: error
1629  */
1630 static int
1631 spdk_iscsi_op_login_set_target_info(struct spdk_iscsi_conn *conn,
1632 				    struct spdk_iscsi_pdu *rsp_pdu,
1633 				    enum session_type session_type,
1634 				    int alloc_len,
1635 				    struct spdk_iscsi_tgt_node *target)
1636 {
1637 	char buf[MAX_TMPBUF];
1638 	const char *val;
1639 	int rc = 0;
1640 	struct spdk_iscsi_portal *portal = conn->portal;
1641 
1642 	/* declarative parameters */
1643 	if (target != NULL) {
1644 		pthread_mutex_lock(&target->mutex);
1645 		if (target->alias != NULL) {
1646 			snprintf(buf, sizeof buf, "%s", target->alias);
1647 		} else {
1648 			snprintf(buf, sizeof buf, "%s", "");
1649 		}
1650 		pthread_mutex_unlock(&target->mutex);
1651 		rc = spdk_iscsi_param_set(conn->sess->params, "TargetAlias", buf);
1652 		if (rc < 0) {
1653 			SPDK_ERRLOG("iscsi_param_set() failed\n");
1654 			return SPDK_ISCSI_LOGIN_ERROR_PARAMETER;
1655 		}
1656 	}
1657 	snprintf(buf, sizeof buf, "%s:%s,%d", portal->host, portal->port,
1658 		 portal->group->tag);
1659 	rc = spdk_iscsi_param_set(conn->sess->params, "TargetAddress", buf);
1660 	if (rc < 0) {
1661 		SPDK_ERRLOG("iscsi_param_set() failed\n");
1662 		return SPDK_ISCSI_LOGIN_ERROR_PARAMETER;
1663 	}
1664 	snprintf(buf, sizeof buf, "%d", portal->group->tag);
1665 	rc = spdk_iscsi_param_set(conn->sess->params, "TargetPortalGroupTag", buf);
1666 	if (rc < 0) {
1667 		SPDK_ERRLOG("iscsi_param_set() failed\n");
1668 		return SPDK_ISCSI_LOGIN_ERROR_PARAMETER;
1669 	}
1670 
1671 	/* write in response */
1672 	if (target != NULL) {
1673 		val = spdk_iscsi_param_get_val(conn->sess->params, "TargetAlias");
1674 		if (val != NULL && strlen(val) != 0) {
1675 			rsp_pdu->data_segment_len = spdk_iscsi_append_param(conn,
1676 						    "TargetAlias",
1677 						    rsp_pdu->data,
1678 						    alloc_len,
1679 						    rsp_pdu->data_segment_len);
1680 		}
1681 		if (session_type == SESSION_TYPE_DISCOVERY) {
1682 			rsp_pdu->data_segment_len = spdk_iscsi_append_param(conn,
1683 						    "TargetAddress",
1684 						    rsp_pdu->data,
1685 						    alloc_len,
1686 						    rsp_pdu->data_segment_len);
1687 		}
1688 		rsp_pdu->data_segment_len = spdk_iscsi_append_param(conn,
1689 					    "TargetPortalGroupTag",
1690 					    rsp_pdu->data,
1691 					    alloc_len,
1692 					    rsp_pdu->data_segment_len);
1693 	}
1694 
1695 	return rc;
1696 }
1697 
1698 /*
1699  * This function is used to handle the login of iscsi initiator when there is
1700  * no session
1701  * return:
1702  * 0, success;
1703  * SPDK_ISCSI_LOGIN_ERROR_PARAMETER, parameter error;
1704  * SPDK_ISCSI_LOGIN_ERROR_RESPONSE,  used to notify the login fail.
1705  */
1706 static int
1707 spdk_iscsi_op_login_phase_none(struct spdk_iscsi_conn *conn,
1708 			       struct spdk_iscsi_pdu *rsp_pdu,
1709 			       struct iscsi_param *params,
1710 			       int alloc_len, int cid)
1711 {
1712 	enum session_type session_type;
1713 	char initiator_port_name[MAX_INITIATOR_NAME];
1714 	struct iscsi_bhs_login_rsp *rsph;
1715 	struct spdk_iscsi_tgt_node *target = NULL;
1716 	int rc = 0;
1717 	rsph = (struct iscsi_bhs_login_rsp *)&rsp_pdu->bhs;
1718 
1719 	conn->target = NULL;
1720 	conn->dev = NULL;
1721 
1722 	rc = spdk_iscsi_op_login_initialize_port(conn, rsp_pdu,
1723 			initiator_port_name, MAX_INITIATOR_NAME, params);
1724 	if (rc < 0) {
1725 		return rc;
1726 	}
1727 
1728 	rc = spdk_iscsi_op_login_session_type(conn, rsp_pdu, &session_type,
1729 					      params);
1730 	if (rc < 0) {
1731 		return rc;
1732 	}
1733 
1734 	/* Target Name and Port */
1735 	if (session_type == SESSION_TYPE_NORMAL) {
1736 		rc = spdk_iscsi_op_login_session_normal(conn, rsp_pdu,
1737 							initiator_port_name,
1738 							params, &target, cid);
1739 		if (rc < 0) {
1740 			return rc;
1741 		}
1742 
1743 	} else if (session_type == SESSION_TYPE_DISCOVERY) {
1744 		target = NULL;
1745 		rsph->tsih = 0;
1746 
1747 		/* force target flags */
1748 		pthread_mutex_lock(&g_spdk_iscsi.mutex);
1749 		rc = spdk_iscsi_op_login_session_discovery_chap(conn);
1750 		pthread_mutex_unlock(&g_spdk_iscsi.mutex);
1751 		if (rc < 0) {
1752 			return rc;
1753 		}
1754 	} else {
1755 		SPDK_ERRLOG("unknown session type\n");
1756 		/* Missing parameter */
1757 		rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR;
1758 		rsph->status_detail = ISCSI_LOGIN_MISSING_PARMS;
1759 		return SPDK_ISCSI_LOGIN_ERROR_RESPONSE;
1760 	}
1761 
1762 	rc = spdk_iscsi_op_login_set_conn_info(conn, rsp_pdu, initiator_port_name,
1763 					       session_type, target, cid);
1764 	if (rc < 0) {
1765 		return rc;
1766 	}
1767 
1768 	/* limit conns on discovery session */
1769 	if (session_type == SESSION_TYPE_DISCOVERY) {
1770 		conn->sess->MaxConnections = 1;
1771 		rc = spdk_iscsi_param_set_int(conn->sess->params,
1772 					      "MaxConnections",
1773 					      conn->sess->MaxConnections);
1774 		if (rc < 0) {
1775 			SPDK_ERRLOG("iscsi_param_set_int() failed\n");
1776 			return SPDK_ISCSI_LOGIN_ERROR_PARAMETER;
1777 		}
1778 	}
1779 
1780 	rc = spdk_iscsi_op_login_set_target_info(conn, rsp_pdu, session_type,
1781 			alloc_len, target);
1782 	if (rc < 0) {
1783 		return rc;
1784 	}
1785 
1786 	return rc;
1787 }
1788 
1789 /*
1790  * The function which is used to initalize the internal response data
1791  * structure of iscsi login function.
1792  * return:
1793  * 0, success;
1794  * otherwise, error;
1795  */
1796 static int
1797 spdk_iscsi_op_login_rsp_init(struct spdk_iscsi_conn *conn,
1798 			     struct spdk_iscsi_pdu *pdu, struct spdk_iscsi_pdu *rsp_pdu,
1799 			     struct iscsi_param **params, int *alloc_len, int *cid)
1800 {
1801 
1802 	struct iscsi_bhs_login_req *reqh;
1803 	struct iscsi_bhs_login_rsp *rsph;
1804 	int rc;
1805 
1806 	rsph = (struct iscsi_bhs_login_rsp *)&rsp_pdu->bhs;
1807 	rsph->opcode = ISCSI_OP_LOGIN_RSP;
1808 	rsph->status_class = ISCSI_CLASS_SUCCESS;
1809 	rsph->status_detail = ISCSI_LOGIN_ACCEPT;
1810 	rsp_pdu->data_segment_len = 0;
1811 
1812 	/* Default MaxRecvDataSegmentLength - RFC3720(12.12) */
1813 	if (conn->MaxRecvDataSegmentLength < 8192) {
1814 		*alloc_len = 8192;
1815 	} else {
1816 		*alloc_len = conn->MaxRecvDataSegmentLength;
1817 	}
1818 
1819 	rsp_pdu->data = calloc(1, *alloc_len);
1820 	if (!rsp_pdu->data) {
1821 		SPDK_ERRLOG("calloc() failed for data segment\n");
1822 		return -ENOMEM;
1823 	}
1824 
1825 	reqh = (struct iscsi_bhs_login_req *)&pdu->bhs;
1826 	rsph->flags |= (reqh->flags & ISCSI_LOGIN_TRANSIT);
1827 	rsph->flags |= (reqh->flags & ISCSI_LOGIN_CONTINUE);
1828 	rsph->flags |= (reqh->flags & ISCSI_LOGIN_CURRENT_STAGE_MASK);
1829 	if (ISCSI_BHS_LOGIN_GET_TBIT(rsph->flags)) {
1830 		rsph->flags |= (reqh->flags & ISCSI_LOGIN_NEXT_STAGE_MASK);
1831 	}
1832 
1833 	/* We don't need to convert from network byte order. Just store it */
1834 	memcpy(&rsph->isid, reqh->isid, 6);
1835 	rsph->tsih = reqh->tsih;
1836 	rsph->itt = reqh->itt;
1837 	rsp_pdu->cmd_sn = from_be32(&reqh->cmd_sn);
1838 	*cid = from_be16(&reqh->cid);
1839 
1840 	if (rsph->tsih) {
1841 		rsph->stat_sn = reqh->exp_stat_sn;
1842 	}
1843 
1844 	SPDK_TRACEDUMP(SPDK_LOG_ISCSI, "PDU", (uint8_t *)&pdu->bhs, ISCSI_BHS_LEN);
1845 
1846 	SPDK_DEBUGLOG(SPDK_LOG_ISCSI,
1847 		      "T=%d, C=%d, CSG=%d, NSG=%d, Min=%d, Max=%d, ITT=%x\n",
1848 		      ISCSI_BHS_LOGIN_GET_TBIT(rsph->flags),
1849 		      ISCSI_BHS_LOGIN_GET_CBIT(rsph->flags),
1850 		      ISCSI_BHS_LOGIN_GET_CSG(rsph->flags),
1851 		      ISCSI_BHS_LOGIN_GET_NSG(rsph->flags),
1852 		      reqh->version_min, reqh->version_max, from_be32(&rsph->itt));
1853 
1854 	if (conn->sess != NULL) {
1855 		SPDK_DEBUGLOG(SPDK_LOG_ISCSI,
1856 			      "CmdSN=%u, ExpStatSN=%u, StatSN=%u, ExpCmdSN=%u,"
1857 			      "MaxCmdSN=%u\n", rsp_pdu->cmd_sn,
1858 			      from_be32(&rsph->stat_sn), conn->StatSN,
1859 			      conn->sess->ExpCmdSN,
1860 			      conn->sess->MaxCmdSN);
1861 	} else {
1862 		SPDK_DEBUGLOG(SPDK_LOG_ISCSI,
1863 			      "CmdSN=%u, ExpStatSN=%u, StatSN=%u\n",
1864 			      rsp_pdu->cmd_sn, from_be32(&rsph->stat_sn),
1865 			      conn->StatSN);
1866 	}
1867 
1868 	if (ISCSI_BHS_LOGIN_GET_TBIT(rsph->flags) &&
1869 	    ISCSI_BHS_LOGIN_GET_CBIT(rsph->flags)) {
1870 		SPDK_ERRLOG("transit error\n");
1871 		return SPDK_ISCSI_LOGIN_ERROR_RESPONSE;
1872 	}
1873 	/* make sure reqh->version_max < ISCSI_VERSION */
1874 	if (reqh->version_min > ISCSI_VERSION) {
1875 		SPDK_ERRLOG("unsupported version %d/%d\n", reqh->version_min,
1876 			    reqh->version_max);
1877 		/* Unsupported version */
1878 		/* set all reserved flag to zero */
1879 		rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR;
1880 		rsph->status_detail = ISCSI_LOGIN_UNSUPPORTED_VERSION;
1881 		return SPDK_ISCSI_LOGIN_ERROR_RESPONSE;
1882 	}
1883 
1884 	if ((ISCSI_BHS_LOGIN_GET_NSG(rsph->flags) == ISCSI_NSG_RESERVED_CODE) &&
1885 	    ISCSI_BHS_LOGIN_GET_TBIT(rsph->flags)) {
1886 		/* set NSG to zero */
1887 		rsph->flags &= ~ISCSI_LOGIN_NEXT_STAGE_MASK;
1888 		/* also set other bits to zero */
1889 		rsph->flags &= ~ISCSI_LOGIN_TRANSIT;
1890 		rsph->flags &= ~ISCSI_LOGIN_CURRENT_STAGE_MASK;
1891 		SPDK_ERRLOG("Received reserved NSG code: %d\n", ISCSI_NSG_RESERVED_CODE);
1892 		/* Initiator error */
1893 		rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR;
1894 		rsph->status_detail = ISCSI_LOGIN_INITIATOR_ERROR;
1895 		return SPDK_ISCSI_LOGIN_ERROR_RESPONSE;
1896 	}
1897 
1898 	/* store incoming parameters */
1899 	rc = spdk_iscsi_parse_params(params, pdu->data,
1900 				     pdu->data_segment_len, ISCSI_BHS_LOGIN_GET_CBIT(reqh->flags),
1901 				     &conn->partial_text_parameter);
1902 	if (rc < 0) {
1903 		SPDK_ERRLOG("iscsi_parse_params() failed\n");
1904 		rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR;
1905 		rsph->status_detail = ISCSI_LOGIN_INITIATOR_ERROR;
1906 		return SPDK_ISCSI_LOGIN_ERROR_PARAMETER;
1907 	}
1908 	return 0;
1909 }
1910 
1911 /*
1912  * This function is used to set the csg bit case in rsp
1913  * return:
1914  * 0, success
1915  * otherwise: error
1916  */
1917 static int
1918 spdk_iscsi_op_login_rsp_handle_csg_bit(struct spdk_iscsi_conn *conn,
1919 				       struct spdk_iscsi_pdu *rsp_pdu,
1920 				       struct iscsi_param *params, int alloc_len)
1921 {
1922 	const char *auth_method;
1923 	int rc;
1924 	struct iscsi_bhs_login_rsp *rsph;
1925 	rsph = (struct iscsi_bhs_login_rsp *)&rsp_pdu->bhs;
1926 
1927 	switch (ISCSI_BHS_LOGIN_GET_CSG(rsph->flags)) {
1928 	case ISCSI_SECURITY_NEGOTIATION_PHASE:
1929 		/* SecurityNegotiation */
1930 		auth_method = spdk_iscsi_param_get_val(conn->params, "AuthMethod");
1931 		if (auth_method == NULL) {
1932 			SPDK_ERRLOG("AuthMethod is empty\n");
1933 			/* Missing parameter */
1934 			rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR;
1935 			rsph->status_detail = ISCSI_LOGIN_MISSING_PARMS;
1936 			return SPDK_ISCSI_LOGIN_ERROR_RESPONSE;
1937 		}
1938 		if (strcasecmp(auth_method, "None") == 0) {
1939 			conn->authenticated = 1;
1940 		} else {
1941 			rc = spdk_iscsi_auth_params(conn, params, auth_method,
1942 						    rsp_pdu->data, alloc_len,
1943 						    rsp_pdu->data_segment_len);
1944 			if (rc < 0) {
1945 				SPDK_ERRLOG("iscsi_auth_params() failed\n");
1946 				/* Authentication failure */
1947 				rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR;
1948 				rsph->status_detail = ISCSI_LOGIN_AUTHENT_FAIL;
1949 				return SPDK_ISCSI_LOGIN_ERROR_RESPONSE;
1950 			}
1951 			rsp_pdu->data_segment_len = rc;
1952 			if (conn->authenticated == 0) {
1953 				/* not complete */
1954 				rsph->flags &= ~ISCSI_LOGIN_TRANSIT;
1955 			} else {
1956 				if (conn->auth.chap_phase != ISCSI_CHAP_PHASE_END) {
1957 					SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "CHAP phase not complete");
1958 				}
1959 			}
1960 
1961 			SPDK_TRACEDUMP(SPDK_LOG_ISCSI, "Negotiated Auth Params",
1962 				       rsp_pdu->data, rsp_pdu->data_segment_len);
1963 		}
1964 		break;
1965 
1966 	case ISCSI_OPERATIONAL_NEGOTIATION_PHASE:
1967 		/* LoginOperationalNegotiation */
1968 		if (conn->state == ISCSI_CONN_STATE_INVALID) {
1969 			if (conn->req_auth) {
1970 				/* Authentication failure */
1971 				rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR;
1972 				rsph->status_detail = ISCSI_LOGIN_AUTHENT_FAIL;
1973 				return SPDK_ISCSI_LOGIN_ERROR_RESPONSE;
1974 			} else {
1975 				/* AuthMethod=None */
1976 				conn->authenticated = 1;
1977 			}
1978 		}
1979 		if (conn->authenticated == 0) {
1980 			SPDK_ERRLOG("authentication error\n");
1981 			/* Authentication failure */
1982 			rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR;
1983 			rsph->status_detail = ISCSI_LOGIN_AUTHENT_FAIL;
1984 			return SPDK_ISCSI_LOGIN_ERROR_RESPONSE;
1985 		}
1986 		break;
1987 
1988 	case ISCSI_FULL_FEATURE_PHASE:
1989 		/* FullFeaturePhase */
1990 		SPDK_ERRLOG("XXX Login in FullFeaturePhase\n");
1991 		/* Initiator error */
1992 		rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR;
1993 		rsph->status_detail = ISCSI_LOGIN_INITIATOR_ERROR;
1994 		return SPDK_ISCSI_LOGIN_ERROR_RESPONSE;
1995 
1996 	default:
1997 		SPDK_ERRLOG("unknown stage\n");
1998 		/* Initiator error */
1999 		rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR;
2000 		rsph->status_detail = ISCSI_LOGIN_INITIATOR_ERROR;
2001 		return SPDK_ISCSI_LOGIN_ERROR_RESPONSE;
2002 	}
2003 
2004 	return 0;
2005 }
2006 
2007 /* This function is used to notify the session info
2008  * return
2009  * 0: success
2010  * otherwise: error
2011  */
2012 static int
2013 spdk_iscsi_op_login_notify_session_info(struct spdk_iscsi_conn *conn,
2014 					struct spdk_iscsi_pdu *rsp_pdu)
2015 {
2016 	struct spdk_iscsi_portal *portal = conn->portal;
2017 	struct iscsi_bhs_login_rsp *rsph;
2018 
2019 	rsph = (struct iscsi_bhs_login_rsp *)&rsp_pdu->bhs;
2020 	if (conn->sess->session_type == SESSION_TYPE_NORMAL) {
2021 		/* normal session */
2022 		SPDK_NOTICELOG("Login from %s (%s) on %s tgt_node%d"
2023 			       " (%s:%s,%d), ISID=%"PRIx64", TSIH=%u,"
2024 			       " CID=%u, HeaderDigest=%s, DataDigest=%s\n",
2025 			       conn->initiator_name, conn->initiator_addr,
2026 			       conn->target->name, conn->target->num,
2027 			       portal->host, portal->port, portal->group->tag,
2028 			       conn->sess->isid, conn->sess->tsih, conn->cid,
2029 			       (spdk_iscsi_param_eq_val(conn->params, "HeaderDigest", "CRC32C")
2030 				? "on" : "off"),
2031 			       (spdk_iscsi_param_eq_val(conn->params, "DataDigest", "CRC32C")
2032 				? "on" : "off"));
2033 	} else if (conn->sess->session_type == SESSION_TYPE_DISCOVERY) {
2034 		/* discovery session */
2035 		SPDK_NOTICELOG("Login(discovery) from %s (%s) on"
2036 			       " (%s:%s,%d), ISID=%"PRIx64", TSIH=%u,"
2037 			       " CID=%u, HeaderDigest=%s, DataDigest=%s\n",
2038 			       conn->initiator_name, conn->initiator_addr,
2039 			       portal->host, portal->port, portal->group->tag,
2040 			       conn->sess->isid, conn->sess->tsih, conn->cid,
2041 			       (spdk_iscsi_param_eq_val(conn->params, "HeaderDigest", "CRC32C")
2042 				? "on" : "off"),
2043 			       (spdk_iscsi_param_eq_val(conn->params, "DataDigest", "CRC32C")
2044 				? "on" : "off"));
2045 	} else {
2046 		SPDK_ERRLOG("unknown session type\n");
2047 		/* Initiator error */
2048 		rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR;
2049 		rsph->status_detail = ISCSI_LOGIN_INITIATOR_ERROR;
2050 		return SPDK_ISCSI_LOGIN_ERROR_RESPONSE;
2051 	}
2052 
2053 	return 0;
2054 }
2055 
2056 /*
2057  * This function is to handle the tbit cases
2058  * return
2059  * 0: success
2060  * otherwise error
2061  */
2062 static int
2063 spdk_iscsi_op_login_rsp_handle_t_bit(struct spdk_iscsi_conn *conn,
2064 				     struct spdk_iscsi_pdu *rsp_pdu)
2065 {
2066 	int rc;
2067 	struct iscsi_bhs_login_rsp *rsph;
2068 	rsph = (struct iscsi_bhs_login_rsp *)&rsp_pdu->bhs;
2069 
2070 	switch (ISCSI_BHS_LOGIN_GET_NSG(rsph->flags)) {
2071 	case ISCSI_SECURITY_NEGOTIATION_PHASE:
2072 		/* SecurityNegotiation */
2073 		conn->login_phase = ISCSI_SECURITY_NEGOTIATION_PHASE;
2074 		break;
2075 
2076 	case ISCSI_OPERATIONAL_NEGOTIATION_PHASE:
2077 		/* LoginOperationalNegotiation */
2078 		conn->login_phase = ISCSI_OPERATIONAL_NEGOTIATION_PHASE;
2079 		break;
2080 
2081 	case ISCSI_FULL_FEATURE_PHASE:
2082 		/* FullFeaturePhase */
2083 		conn->login_phase = ISCSI_FULL_FEATURE_PHASE;
2084 		to_be16(&rsph->tsih, conn->sess->tsih);
2085 
2086 		rc = spdk_iscsi_op_login_notify_session_info(conn, rsp_pdu);
2087 		if (rc < 0) {
2088 			return rc;
2089 		}
2090 
2091 		conn->full_feature = 1;
2092 		spdk_iscsi_conn_migration(conn);
2093 		break;
2094 
2095 	default:
2096 		SPDK_ERRLOG("unknown stage\n");
2097 		/* Initiator error */
2098 		rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR;
2099 		rsph->status_detail = ISCSI_LOGIN_INITIATOR_ERROR;
2100 		return SPDK_ISCSI_LOGIN_ERROR_RESPONSE;
2101 	}
2102 
2103 	return 0;
2104 }
2105 
2106 /*
2107  * This function is used to set the values of the internal data structure used
2108  * by spdk_iscsi_op_login function
2109  * return:
2110  * 0, used to notify the a successful login
2111  * SPDK_ISCSI_LOGIN_ERROR_RESPONSE,  used to notify a failure login.
2112  */
2113 static int
2114 spdk_iscsi_op_login_rsp_handle(struct spdk_iscsi_conn *conn,
2115 			       struct spdk_iscsi_pdu *rsp_pdu, struct iscsi_param **params,
2116 			       int alloc_len)
2117 {
2118 	int rc;
2119 	struct iscsi_bhs_login_rsp *rsph;
2120 	rsph = (struct iscsi_bhs_login_rsp *)&rsp_pdu->bhs;
2121 
2122 	/* negotiate parameters */
2123 	rc = spdk_iscsi_negotiate_params(conn, params, rsp_pdu->data, alloc_len,
2124 					 rsp_pdu->data_segment_len);
2125 	if (rc < 0) {
2126 		/*
2127 		 * spdk_iscsi_negotiate_params just returns -1 on failure,
2128 		 *  so translate this into meaningful response codes and
2129 		 *  return values.
2130 		 */
2131 		rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR;
2132 		rsph->status_detail = ISCSI_LOGIN_INITIATOR_ERROR;
2133 		return SPDK_ISCSI_LOGIN_ERROR_RESPONSE;
2134 	}
2135 
2136 	rsp_pdu->data_segment_len = rc;
2137 	SPDK_TRACEDUMP(SPDK_LOG_ISCSI, "Negotiated Params", rsp_pdu->data, rc);
2138 
2139 	/* handle the CSG bit case */
2140 	rc = spdk_iscsi_op_login_rsp_handle_csg_bit(conn, rsp_pdu, *params,
2141 			alloc_len);
2142 	if (rc < 0) {
2143 		return rc;
2144 	}
2145 
2146 	/* handle the T bit case */
2147 	if (ISCSI_BHS_LOGIN_GET_TBIT(rsph->flags)) {
2148 		rc = spdk_iscsi_op_login_rsp_handle_t_bit(conn, rsp_pdu);
2149 	}
2150 
2151 	return rc;
2152 }
2153 
2154 static int
2155 spdk_iscsi_op_login(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
2156 {
2157 	int rc;
2158 	struct spdk_iscsi_pdu *rsp_pdu;
2159 	struct iscsi_param *params = NULL;
2160 	struct iscsi_param **params_p = &params;
2161 	int alloc_len;
2162 	int cid;
2163 
2164 	if (conn->full_feature && conn->sess != NULL &&
2165 	    conn->sess->session_type == SESSION_TYPE_DISCOVERY) {
2166 		return SPDK_ISCSI_CONNECTION_FATAL;
2167 	}
2168 
2169 	rsp_pdu = spdk_get_pdu();
2170 	if (rsp_pdu == NULL) {
2171 		return SPDK_ISCSI_CONNECTION_FATAL;
2172 	}
2173 	rc = spdk_iscsi_op_login_rsp_init(conn, pdu, rsp_pdu, params_p,
2174 					  &alloc_len, &cid);
2175 	if (rc == SPDK_ISCSI_LOGIN_ERROR_RESPONSE || rc == SPDK_ISCSI_LOGIN_ERROR_PARAMETER) {
2176 		spdk_iscsi_op_login_response(conn, rsp_pdu, *params_p);
2177 		return rc;
2178 	}
2179 
2180 	/* For other values, we need to directly return */
2181 	if (rc < 0) {
2182 		spdk_put_pdu(rsp_pdu);
2183 		return rc;
2184 	}
2185 
2186 	if (conn->state == ISCSI_CONN_STATE_INVALID) {
2187 		rc = spdk_iscsi_op_login_phase_none(conn, rsp_pdu, *params_p,
2188 						    alloc_len, cid);
2189 		if (rc == SPDK_ISCSI_LOGIN_ERROR_RESPONSE || rc == SPDK_ISCSI_LOGIN_ERROR_PARAMETER) {
2190 			spdk_iscsi_op_login_response(conn, rsp_pdu, *params_p);
2191 			return rc;
2192 		}
2193 	}
2194 
2195 	rc = spdk_iscsi_op_login_rsp_handle(conn, rsp_pdu, params_p, alloc_len);
2196 	if (rc == SPDK_ISCSI_LOGIN_ERROR_RESPONSE) {
2197 		spdk_iscsi_op_login_response(conn, rsp_pdu, *params_p);
2198 		return rc;
2199 	}
2200 
2201 	rc = spdk_iscsi_op_login_response(conn, rsp_pdu, *params_p);
2202 	if (rc == 0) {
2203 		conn->state = ISCSI_CONN_STATE_RUNNING;
2204 	} else {
2205 		SPDK_ERRLOG("login error - connection will be destroyed\n");
2206 	}
2207 
2208 	return rc;
2209 }
2210 
2211 static int
2212 spdk_iscsi_op_text(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
2213 {
2214 	struct iscsi_param *params = NULL;
2215 	struct iscsi_param **params_p = &params;
2216 	struct spdk_iscsi_pdu *rsp_pdu;
2217 	uint8_t *data;
2218 	uint64_t lun;
2219 	uint32_t task_tag;
2220 	uint32_t CmdSN;
2221 	uint32_t ExpStatSN;
2222 	const char *val;
2223 	int F_bit, C_bit;
2224 	int data_len;
2225 	int alloc_len;
2226 	int rc;
2227 	struct iscsi_bhs_text_req *reqh;
2228 	struct iscsi_bhs_text_resp *rsph;
2229 
2230 	data_len = 0;
2231 	alloc_len = conn->MaxRecvDataSegmentLength;
2232 
2233 	reqh = (struct iscsi_bhs_text_req *)&pdu->bhs;
2234 
2235 	F_bit = !!(reqh->flags & ISCSI_FLAG_FINAL);
2236 	C_bit = !!(reqh->flags & ISCSI_TEXT_CONTINUE);
2237 	lun = from_be64(&reqh->lun);
2238 	task_tag = from_be32(&reqh->itt);
2239 	CmdSN = from_be32(&reqh->cmd_sn);
2240 	pdu->cmd_sn = CmdSN;
2241 	ExpStatSN = from_be32(&reqh->exp_stat_sn);
2242 
2243 	SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "I=%d, F=%d, C=%d, ITT=%x, TTT=%x\n",
2244 		      reqh->immediate, F_bit, C_bit, task_tag, from_be32(&reqh->ttt));
2245 
2246 	SPDK_DEBUGLOG(SPDK_LOG_ISCSI,
2247 		      "CmdSN=%u, ExpStatSN=%u, StatSN=%u, ExpCmdSN=%u, MaxCmdSN=%u\n",
2248 		      CmdSN, ExpStatSN, conn->StatSN, conn->sess->ExpCmdSN,
2249 		      conn->sess->MaxCmdSN);
2250 
2251 	if (ExpStatSN != conn->StatSN) {
2252 #if 0
2253 		SPDK_ERRLOG("StatSN(%u) error\n", ExpStatSN);
2254 		return -1;
2255 #else
2256 		/* StarPort have a bug */
2257 		SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "StatSN(%u) rewound\n", ExpStatSN);
2258 		conn->StatSN = ExpStatSN;
2259 #endif
2260 	}
2261 
2262 	if (F_bit && C_bit) {
2263 		SPDK_ERRLOG("final and continue\n");
2264 		return -1;
2265 	}
2266 
2267 	/*
2268 	 * If this is the first text op in a sequence, save the ITT so we can
2269 	 * compare it against the ITT for subsequent ops in the same sequence.
2270 	 * If a subsequent text op in same sequence has a different ITT, reject
2271 	 * that PDU.
2272 	 */
2273 	if (conn->sess->current_text_itt == 0xffffffffU) {
2274 		conn->sess->current_text_itt = task_tag;
2275 	} else if (conn->sess->current_text_itt != task_tag) {
2276 		SPDK_ERRLOG("The correct itt is %u, and the current itt is %u...\n",
2277 			    conn->sess->current_text_itt, task_tag);
2278 		return spdk_iscsi_reject(conn, pdu, ISCSI_REASON_PROTOCOL_ERROR);
2279 	}
2280 
2281 	/* store incoming parameters */
2282 	rc = spdk_iscsi_parse_params(&params, pdu->data, pdu->data_segment_len,
2283 				     C_bit, &conn->partial_text_parameter);
2284 	if (rc < 0) {
2285 		SPDK_ERRLOG("iscsi_parse_params() failed\n");
2286 		spdk_iscsi_param_free(params);
2287 		return -1;
2288 	}
2289 
2290 	data = calloc(1, alloc_len);
2291 	if (!data) {
2292 		SPDK_ERRLOG("calloc() failed for data segment\n");
2293 		spdk_iscsi_param_free(params);
2294 		return -ENOMEM;
2295 	}
2296 
2297 	/* negotiate parameters */
2298 	data_len = spdk_iscsi_negotiate_params(conn, params_p,
2299 					       data, alloc_len, data_len);
2300 	if (data_len < 0) {
2301 		SPDK_ERRLOG("spdk_iscsi_negotiate_params() failed\n");
2302 		spdk_iscsi_param_free(*params_p);
2303 		free(data);
2304 		return -1;
2305 	}
2306 
2307 	/* sendtargets is special case */
2308 	val = spdk_iscsi_param_get_val(*params_p, "SendTargets");
2309 	if (val != NULL) {
2310 		if (spdk_iscsi_param_eq_val(conn->sess->params,
2311 					    "SessionType", "Discovery")) {
2312 			if (strcasecmp(val, "") == 0) {
2313 				val = "ALL";
2314 			}
2315 
2316 			data_len = spdk_iscsi_send_tgts(conn,
2317 							conn->initiator_name,
2318 							conn->initiator_addr,
2319 							val, data, alloc_len,
2320 							data_len);
2321 		} else {
2322 			if (strcasecmp(val, "") == 0) {
2323 				val = conn->target->name;
2324 			}
2325 
2326 			if (strcasecmp(val, "ALL") == 0) {
2327 				/* not in discovery session */
2328 				data_len = spdk_iscsi_append_text(conn,
2329 								  "SendTargets",
2330 								  "Reject", data,
2331 								  alloc_len,
2332 								  data_len);
2333 			} else {
2334 				data_len = spdk_iscsi_send_tgts(conn,
2335 								conn->initiator_name,
2336 								conn->initiator_addr,
2337 								val, data, alloc_len,
2338 								data_len);
2339 			}
2340 		}
2341 	} else {
2342 		if (spdk_iscsi_param_eq_val(conn->sess->params, "SessionType", "Discovery")) {
2343 			spdk_iscsi_param_free(*params_p);
2344 			free(data);
2345 			return SPDK_ISCSI_CONNECTION_FATAL;
2346 		}
2347 	}
2348 
2349 	SPDK_TRACEDUMP(SPDK_LOG_ISCSI, "Negotiated Params", data, data_len);
2350 
2351 	/* response PDU */
2352 	rsp_pdu = spdk_get_pdu();
2353 	if (rsp_pdu == NULL) {
2354 		spdk_iscsi_param_free(*params_p);
2355 		free(data);
2356 		return SPDK_ISCSI_CONNECTION_FATAL;
2357 	}
2358 	rsph = (struct iscsi_bhs_text_resp *)&rsp_pdu->bhs;
2359 
2360 	rsp_pdu->data = data;
2361 	rsph->opcode = ISCSI_OP_TEXT_RSP;
2362 
2363 	if (F_bit) {
2364 		rsph->flags |= ISCSI_FLAG_FINAL;
2365 	}
2366 
2367 	if (C_bit) {
2368 		rsph->flags |= ISCSI_TEXT_CONTINUE;
2369 	}
2370 
2371 	DSET24(rsph->data_segment_len, data_len);
2372 	to_be64(&rsph->lun, lun);
2373 	to_be32(&rsph->itt, task_tag);
2374 
2375 	if (F_bit) {
2376 		rsph->ttt = 0xffffffffU;
2377 		conn->sess->current_text_itt = 0xffffffffU;
2378 	} else {
2379 		to_be32(&rsph->ttt, 1 + conn->id);
2380 	}
2381 
2382 	to_be32(&rsph->stat_sn, conn->StatSN);
2383 	conn->StatSN++;
2384 
2385 	if (reqh->immediate == 0) {
2386 		conn->sess->MaxCmdSN++;
2387 	}
2388 
2389 	to_be32(&rsph->exp_cmd_sn, conn->sess->ExpCmdSN);
2390 	to_be32(&rsph->max_cmd_sn, conn->sess->MaxCmdSN);
2391 
2392 	spdk_iscsi_conn_write_pdu(conn, rsp_pdu);
2393 
2394 	/* update internal variables */
2395 	rc = spdk_iscsi_copy_param2var(conn);
2396 	if (rc < 0) {
2397 		SPDK_ERRLOG("spdk_iscsi_copy_param2var() failed\n");
2398 		spdk_iscsi_param_free(*params_p);
2399 		return -1;
2400 	}
2401 
2402 	/* check value */
2403 	rc = spdk_iscsi_check_values(conn);
2404 	if (rc < 0) {
2405 		SPDK_ERRLOG("iscsi_check_values() failed\n");
2406 		spdk_iscsi_param_free(*params_p);
2407 		return -1;
2408 	}
2409 
2410 	spdk_iscsi_param_free(*params_p);
2411 	return 0;
2412 }
2413 
2414 static int
2415 spdk_iscsi_op_logout(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
2416 {
2417 	char buf[MAX_TMPBUF];
2418 	struct spdk_iscsi_pdu *rsp_pdu;
2419 	uint32_t task_tag;
2420 	uint32_t CmdSN;
2421 	uint32_t ExpStatSN;
2422 	int response;
2423 	struct iscsi_bhs_logout_req *reqh;
2424 	struct iscsi_bhs_logout_resp *rsph;
2425 	uint16_t cid;
2426 
2427 	reqh = (struct iscsi_bhs_logout_req *)&pdu->bhs;
2428 
2429 	cid = from_be16(&reqh->cid);
2430 	task_tag = from_be32(&reqh->itt);
2431 	CmdSN = from_be32(&reqh->cmd_sn);
2432 	pdu->cmd_sn = CmdSN;
2433 	ExpStatSN = from_be32(&reqh->exp_stat_sn);
2434 
2435 	SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "reason=%d, ITT=%x, cid=%d\n",
2436 		      reqh->reason, task_tag, cid);
2437 
2438 	if (reqh->reason != 0 && conn->sess->session_type == SESSION_TYPE_DISCOVERY) {
2439 		SPDK_ERRLOG("only logout with close the session reason can be in discovery session");
2440 		return SPDK_ISCSI_CONNECTION_FATAL;
2441 	}
2442 
2443 	if (conn->sess != NULL) {
2444 		SPDK_DEBUGLOG(SPDK_LOG_ISCSI,
2445 			      "CmdSN=%u, ExpStatSN=%u, StatSN=%u, ExpCmdSN=%u, MaxCmdSN=%u\n",
2446 			      CmdSN, ExpStatSN, conn->StatSN,
2447 			      conn->sess->ExpCmdSN, conn->sess->MaxCmdSN);
2448 
2449 		if (CmdSN != conn->sess->ExpCmdSN) {
2450 			SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "CmdSN(%u) might have dropped\n", CmdSN);
2451 			/* ignore error */
2452 		}
2453 	} else {
2454 		SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "CmdSN=%u, ExpStatSN=%u, StatSN=%u\n",
2455 			      CmdSN, ExpStatSN, conn->StatSN);
2456 	}
2457 
2458 	if (ExpStatSN != conn->StatSN) {
2459 		SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "StatSN(%u/%u) might have dropped\n",
2460 			      ExpStatSN, conn->StatSN);
2461 		/* ignore error */
2462 	}
2463 
2464 	if (conn->id == cid) {
2465 		response = 0; // connection or session closed successfully
2466 		spdk_iscsi_conn_logout(conn);
2467 	} else {
2468 		response = 1;
2469 	}
2470 
2471 	/* response PDU */
2472 	rsp_pdu = spdk_get_pdu();
2473 	if (rsp_pdu == NULL) {
2474 		return SPDK_ISCSI_CONNECTION_FATAL;
2475 	}
2476 	rsph = (struct iscsi_bhs_logout_resp *)&rsp_pdu->bhs;
2477 	rsp_pdu->data = NULL;
2478 	rsph->opcode = ISCSI_OP_LOGOUT_RSP;
2479 	rsph->flags |= 0x80; /* bit 0 must be 1 */
2480 	rsph->response = response;
2481 	DSET24(rsph->data_segment_len, 0);
2482 	to_be32(&rsph->itt, task_tag);
2483 
2484 	if (conn->sess != NULL) {
2485 		to_be32(&rsph->stat_sn, conn->StatSN);
2486 		conn->StatSN++;
2487 
2488 		if (conn->sess->connections == 1) {
2489 			conn->sess->MaxCmdSN++;
2490 		}
2491 
2492 		to_be32(&rsph->exp_cmd_sn, conn->sess->ExpCmdSN);
2493 		to_be32(&rsph->max_cmd_sn, conn->sess->MaxCmdSN);
2494 	} else {
2495 		to_be32(&rsph->stat_sn, conn->StatSN);
2496 		conn->StatSN++;
2497 		to_be32(&rsph->exp_cmd_sn, CmdSN);
2498 		to_be32(&rsph->max_cmd_sn, CmdSN);
2499 	}
2500 
2501 	rsph->time_2_wait = 0;
2502 	rsph->time_2_retain = 0;
2503 
2504 	spdk_iscsi_conn_write_pdu(conn, rsp_pdu);
2505 
2506 	if (conn->sess == NULL) {
2507 		/*
2508 		 * login failed but initiator still sent a logout rather than
2509 		 *  just closing the TCP connection.
2510 		 */
2511 		snprintf(buf, sizeof buf, "Logout(login failed) from %s (%s) on"
2512 			 " (%s:%s,%d)\n",
2513 			 conn->initiator_name, conn->initiator_addr,
2514 			 conn->portal_host, conn->portal_port, conn->pg_tag);
2515 	} else if (spdk_iscsi_param_eq_val(conn->sess->params, "SessionType", "Normal")) {
2516 		snprintf(buf, sizeof buf, "Logout from %s (%s) on %s tgt_node%d"
2517 			 " (%s:%s,%d), ISID=%"PRIx64", TSIH=%u,"
2518 			 " CID=%u, HeaderDigest=%s, DataDigest=%s\n",
2519 			 conn->initiator_name, conn->initiator_addr,
2520 			 conn->target->name, conn->target->num,
2521 			 conn->portal_host, conn->portal_port, conn->pg_tag,
2522 			 conn->sess->isid, conn->sess->tsih, conn->cid,
2523 			 (spdk_iscsi_param_eq_val(conn->params, "HeaderDigest", "CRC32C")
2524 			  ? "on" : "off"),
2525 			 (spdk_iscsi_param_eq_val(conn->params, "DataDigest", "CRC32C")
2526 			  ? "on" : "off"));
2527 	} else {
2528 		/* discovery session */
2529 		snprintf(buf, sizeof buf, "Logout(discovery) from %s (%s) on"
2530 			 " (%s:%s,%d), ISID=%"PRIx64", TSIH=%u,"
2531 			 " CID=%u, HeaderDigest=%s, DataDigest=%s\n",
2532 			 conn->initiator_name, conn->initiator_addr,
2533 			 conn->portal_host, conn->portal_port, conn->pg_tag,
2534 			 conn->sess->isid, conn->sess->tsih, conn->cid,
2535 			 (spdk_iscsi_param_eq_val(conn->params, "HeaderDigest", "CRC32C")
2536 			  ? "on" : "off"),
2537 			 (spdk_iscsi_param_eq_val(conn->params, "DataDigest", "CRC32C")
2538 			  ? "on" : "off"));
2539 	}
2540 
2541 	SPDK_NOTICELOG("%s", buf);
2542 
2543 	return 0;
2544 }
2545 
2546 /* This function returns the spdk_scsi_task by searching the snack list via
2547  * task transfertag and the pdu's opcode
2548  */
2549 static struct spdk_iscsi_task *
2550 spdk_get_scsi_task_from_ttt(struct spdk_iscsi_conn *conn,
2551 			    uint32_t transfer_tag)
2552 {
2553 	struct spdk_iscsi_pdu *pdu;
2554 	struct iscsi_bhs_data_in *datain_bhs;
2555 
2556 	TAILQ_FOREACH(pdu, &conn->snack_pdu_list, tailq) {
2557 		if (pdu->bhs.opcode == ISCSI_OP_SCSI_DATAIN) {
2558 			datain_bhs = (struct iscsi_bhs_data_in *)&pdu->bhs;
2559 			if (from_be32(&datain_bhs->ttt) == transfer_tag) {
2560 				return pdu->task;
2561 			}
2562 		}
2563 	}
2564 
2565 	return NULL;
2566 }
2567 
2568 /* This function returns the spdk_scsi_task by searching the snack list via
2569  * initiator task tag and the pdu's opcode
2570  */
2571 static struct spdk_iscsi_task *
2572 spdk_get_scsi_task_from_itt(struct spdk_iscsi_conn *conn,
2573 			    uint32_t task_tag, enum iscsi_op opcode)
2574 {
2575 	struct spdk_iscsi_pdu *pdu;
2576 
2577 	TAILQ_FOREACH(pdu, &conn->snack_pdu_list, tailq) {
2578 		if (pdu->bhs.opcode == opcode &&
2579 		    pdu->task != NULL &&
2580 		    pdu->task->tag == task_tag) {
2581 			return pdu->task;
2582 		}
2583 	}
2584 
2585 	return NULL;
2586 }
2587 
2588 static int
2589 spdk_iscsi_send_datain(struct spdk_iscsi_conn *conn,
2590 		       struct spdk_iscsi_task *task, int datain_flag,
2591 		       int residual_len, int offset, int DataSN, int len)
2592 {
2593 	struct spdk_iscsi_pdu *rsp_pdu;
2594 	struct iscsi_bhs_data_in *rsph;
2595 	uint32_t task_tag;
2596 	uint32_t transfer_tag;
2597 	int F_bit, U_bit, O_bit, S_bit;
2598 	struct spdk_iscsi_task *primary;
2599 
2600 	primary = spdk_iscsi_task_get_primary(task);
2601 
2602 	/* DATA PDU */
2603 	rsp_pdu = spdk_get_pdu();
2604 	rsph = (struct iscsi_bhs_data_in *)&rsp_pdu->bhs;
2605 	rsp_pdu->data = task->scsi.iovs[0].iov_base + offset;
2606 	rsp_pdu->data_from_mempool = true;
2607 
2608 	task_tag = task->tag;
2609 	transfer_tag = 0xffffffffU;
2610 
2611 	F_bit = datain_flag & ISCSI_FLAG_FINAL;
2612 	O_bit = datain_flag & ISCSI_DATAIN_OVERFLOW;
2613 	U_bit = datain_flag & ISCSI_DATAIN_UNDERFLOW;
2614 	S_bit = datain_flag & ISCSI_DATAIN_STATUS;
2615 
2616 	/*
2617 	 * we need to hold onto this task/cmd because until the
2618 	 * PDU has been written out
2619 	 */
2620 	rsp_pdu->task = task;
2621 	task->scsi.ref++;
2622 
2623 	rsph->opcode = ISCSI_OP_SCSI_DATAIN;
2624 
2625 	if (F_bit) {
2626 		rsph->flags |= ISCSI_FLAG_FINAL;
2627 	}
2628 
2629 	/* we leave the A_bit clear */
2630 
2631 	if (F_bit && S_bit)  {
2632 		if (O_bit) {
2633 			rsph->flags |= ISCSI_DATAIN_OVERFLOW;
2634 		}
2635 
2636 		if (U_bit) {
2637 			rsph->flags |= ISCSI_DATAIN_UNDERFLOW;
2638 		}
2639 	}
2640 
2641 	if (S_bit) {
2642 		rsph->flags |= ISCSI_DATAIN_STATUS;
2643 		rsph->status = task->scsi.status;
2644 	}
2645 
2646 	DSET24(rsph->data_segment_len, len);
2647 
2648 	to_be32(&rsph->itt, task_tag);
2649 	to_be32(&rsph->ttt, transfer_tag);
2650 
2651 	if (S_bit) {
2652 		to_be32(&rsph->stat_sn, conn->StatSN);
2653 		conn->StatSN++;
2654 	}
2655 
2656 	if (F_bit && S_bit && !spdk_iscsi_task_is_immediate(primary)) {
2657 		conn->sess->MaxCmdSN++;
2658 	}
2659 
2660 	to_be32(&rsph->exp_cmd_sn, conn->sess->ExpCmdSN);
2661 	to_be32(&rsph->max_cmd_sn, conn->sess->MaxCmdSN);
2662 
2663 	to_be32(&rsph->data_sn, DataSN);
2664 
2665 	if (conn->sess->ErrorRecoveryLevel >= 1) {
2666 		primary->datain_datasn = DataSN;
2667 	}
2668 	DataSN++;
2669 
2670 	if (task->parent) {
2671 		offset += primary->scsi.data_transferred;
2672 	}
2673 	to_be32(&rsph->buffer_offset, (uint32_t)offset);
2674 
2675 	if (F_bit && S_bit) {
2676 		to_be32(&rsph->res_cnt, residual_len);
2677 	}
2678 
2679 	spdk_iscsi_conn_write_pdu(conn, rsp_pdu);
2680 
2681 	return DataSN;
2682 }
2683 
2684 static int
2685 spdk_iscsi_transfer_in(struct spdk_iscsi_conn *conn,
2686 		       struct spdk_iscsi_task *task)
2687 {
2688 	uint32_t DataSN;
2689 	int transfer_len;
2690 	int data_len;
2691 	int segment_len;
2692 	int offset;
2693 	int residual_len = 0;
2694 	int sent_status;
2695 	int len;
2696 	int datain_flag = 0;
2697 	int datain_seq_cnt;
2698 	int i;
2699 	int sequence_end;
2700 	struct spdk_iscsi_task *primary;
2701 
2702 	primary = spdk_iscsi_task_get_primary(task);
2703 	segment_len = conn->MaxRecvDataSegmentLength;
2704 	data_len = task->scsi.data_transferred;
2705 	transfer_len = task->scsi.length;
2706 
2707 	if (task->scsi.status != SPDK_SCSI_STATUS_GOOD) {
2708 		if (task != primary) {
2709 			conn->data_in_cnt--;
2710 			/* Handle the case when primary task return success but the subtask failed */
2711 			if (primary->bytes_completed == primary->scsi.transfer_len &&
2712 			    primary->scsi.status == SPDK_SCSI_STATUS_GOOD) {
2713 				conn->data_in_cnt--;
2714 			}
2715 		} else {
2716 			/* handle the case that it is a primary task which has subtasks */
2717 			if (primary->scsi.transfer_len != primary->scsi.length) {
2718 				conn->data_in_cnt--;
2719 			}
2720 		}
2721 
2722 		return 0;
2723 	}
2724 
2725 	if (data_len < transfer_len) {
2726 		/* underflow */
2727 		SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Underflow %u/%u\n", data_len, transfer_len);
2728 		residual_len = transfer_len - data_len;
2729 		transfer_len = data_len;
2730 		datain_flag |= ISCSI_DATAIN_UNDERFLOW;
2731 	} else if (data_len > transfer_len) {
2732 		/* overflow */
2733 		SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Overflow %u/%u\n", data_len, transfer_len);
2734 		residual_len = data_len - transfer_len;
2735 		datain_flag |= ISCSI_DATAIN_OVERFLOW;
2736 	} else {
2737 		SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Transfer %u\n", transfer_len);
2738 		residual_len = 0;
2739 	}
2740 
2741 	DataSN = primary->datain_datasn;
2742 	sent_status = 0;
2743 
2744 	/* calculate the number of sequences for all data-in pdus */
2745 	datain_seq_cnt = 1 + ((transfer_len - 1) / (int)conn->sess->MaxBurstLength);
2746 	for (i = 0; i < datain_seq_cnt; i++) {
2747 		offset = i * conn->sess->MaxBurstLength;
2748 		sequence_end = DMIN32(((i + 1) * conn->sess->MaxBurstLength),
2749 				      transfer_len);
2750 
2751 		/* send data splitted by segment_len */
2752 		for (; offset < sequence_end; offset += segment_len) {
2753 			len = DMIN32(segment_len, (sequence_end - offset));
2754 
2755 			datain_flag &= ~ISCSI_FLAG_FINAL;
2756 			datain_flag &= ~ISCSI_DATAIN_STATUS;
2757 
2758 			if (offset + len == sequence_end) {
2759 				/* last PDU in a sequence */
2760 				datain_flag |= ISCSI_FLAG_FINAL;
2761 				if (task->scsi.sense_data_len == 0) {
2762 					/* The last pdu in all data-in pdus */
2763 					if ((offset + len) == transfer_len &&
2764 					    (primary->bytes_completed == primary->scsi.transfer_len)) {
2765 						datain_flag |= ISCSI_DATAIN_STATUS;
2766 						sent_status = 1;
2767 					}
2768 				}
2769 			}
2770 
2771 			SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Transfer=%d, Offset=%d, Len=%d\n",
2772 				      sequence_end, offset, len);
2773 			SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "StatSN=%u, DataSN=%u, Offset=%u, Len=%d\n",
2774 				      conn->StatSN, DataSN, offset, len);
2775 
2776 			DataSN = spdk_iscsi_send_datain(conn, task, datain_flag, residual_len,
2777 							offset, DataSN, len);
2778 		}
2779 	}
2780 
2781 	if (task != primary) {
2782 		primary->scsi.data_transferred += task->scsi.data_transferred;
2783 	}
2784 	primary->datain_datasn = DataSN;
2785 
2786 	return sent_status;
2787 }
2788 
2789 /*
2790  *  This function compare the input pdu's bhs with the pdu's bhs associated by
2791  *  active_r2t_tasks and queued_r2t_tasks in a connection
2792  */
2793 static bool
2794 spdk_iscsi_compare_pdu_bhs_within_existed_r2t_tasks(struct spdk_iscsi_conn *conn,
2795 		struct spdk_iscsi_pdu *pdu)
2796 {
2797 	struct spdk_iscsi_task	*task;
2798 
2799 	TAILQ_FOREACH(task, &conn->active_r2t_tasks, link) {
2800 		if (!memcmp(&pdu->bhs, spdk_iscsi_task_get_bhs(task), ISCSI_BHS_LEN)) {
2801 			return true;
2802 		}
2803 	}
2804 
2805 	TAILQ_FOREACH(task, &conn->queued_r2t_tasks, link) {
2806 		if (!memcmp(&pdu->bhs, spdk_iscsi_task_get_bhs(task), ISCSI_BHS_LEN)) {
2807 			return true;
2808 		}
2809 	}
2810 
2811 	return false;
2812 }
2813 
2814 static void spdk_iscsi_queue_task(struct spdk_iscsi_conn *conn,
2815 				  struct spdk_iscsi_task *task)
2816 {
2817 	spdk_trace_record(TRACE_ISCSI_TASK_QUEUE, conn->id, task->scsi.length,
2818 			  (uintptr_t)task, (uintptr_t)task->pdu);
2819 	spdk_scsi_dev_queue_task(conn->dev, &task->scsi);
2820 }
2821 
2822 static void spdk_iscsi_queue_mgmt_task(struct spdk_iscsi_conn *conn,
2823 				       struct spdk_iscsi_task *task,
2824 				       enum spdk_scsi_task_func func)
2825 {
2826 	spdk_scsi_dev_queue_mgmt_task(conn->dev, &task->scsi, func);
2827 }
2828 
2829 int spdk_iscsi_conn_handle_queued_datain_tasks(struct spdk_iscsi_conn *conn)
2830 {
2831 	struct spdk_iscsi_task *task;
2832 
2833 	while (!TAILQ_EMPTY(&conn->queued_datain_tasks) &&
2834 	       conn->data_in_cnt < MAX_LARGE_DATAIN_PER_CONNECTION) {
2835 		task = TAILQ_FIRST(&conn->queued_datain_tasks);
2836 		assert(task->current_datain_offset <= task->scsi.transfer_len);
2837 
2838 		if (task->current_datain_offset == 0) {
2839 			task->scsi.lun = spdk_scsi_dev_get_lun(conn->dev, task->lun_id);
2840 			if (task->scsi.lun == NULL) {
2841 				TAILQ_REMOVE(&conn->queued_datain_tasks, task, link);
2842 				spdk_scsi_task_process_null_lun(&task->scsi);
2843 				spdk_iscsi_task_cpl(&task->scsi);
2844 				return 0;
2845 			}
2846 			task->current_datain_offset = task->scsi.length;
2847 			conn->data_in_cnt++;
2848 			spdk_iscsi_queue_task(conn, task);
2849 			continue;
2850 		}
2851 		if (task->current_datain_offset < task->scsi.transfer_len) {
2852 			struct spdk_iscsi_task *subtask;
2853 			uint32_t remaining_size = 0;
2854 
2855 			remaining_size = task->scsi.transfer_len - task->current_datain_offset;
2856 			subtask = spdk_iscsi_task_get(conn, task, spdk_iscsi_task_cpl);
2857 			assert(subtask != NULL);
2858 			subtask->scsi.offset = task->current_datain_offset;
2859 			subtask->scsi.length = DMIN32(SPDK_BDEV_LARGE_BUF_MAX_SIZE, remaining_size);
2860 			spdk_scsi_task_set_data(&subtask->scsi, NULL, 0);
2861 			task->current_datain_offset += subtask->scsi.length;
2862 			conn->data_in_cnt++;
2863 
2864 			task->scsi.lun = spdk_scsi_dev_get_lun(conn->dev, task->lun_id);
2865 			if (task->scsi.lun == NULL) {
2866 				/* Remove the primary task from the list if this is the last subtask */
2867 				if (task->current_datain_offset == task->scsi.transfer_len) {
2868 					TAILQ_REMOVE(&conn->queued_datain_tasks, task, link);
2869 				}
2870 				subtask->scsi.transfer_len = subtask->scsi.length;
2871 				spdk_scsi_task_process_null_lun(&subtask->scsi);
2872 				spdk_iscsi_task_cpl(&subtask->scsi);
2873 				return 0;
2874 			}
2875 
2876 			spdk_iscsi_queue_task(conn, subtask);
2877 		}
2878 		if (task->current_datain_offset == task->scsi.transfer_len) {
2879 			TAILQ_REMOVE(&conn->queued_datain_tasks, task, link);
2880 		}
2881 	}
2882 	return 0;
2883 }
2884 
2885 static int spdk_iscsi_op_scsi_read(struct spdk_iscsi_conn *conn,
2886 				   struct spdk_iscsi_task *task)
2887 {
2888 	int32_t remaining_size;
2889 
2890 	TAILQ_INIT(&task->subtask_list);
2891 	task->scsi.dxfer_dir = SPDK_SCSI_DIR_FROM_DEV;
2892 	task->parent = NULL;
2893 	task->scsi.offset = 0;
2894 	task->scsi.length = DMIN32(SPDK_BDEV_LARGE_BUF_MAX_SIZE, task->scsi.transfer_len);
2895 	spdk_scsi_task_set_data(&task->scsi, NULL, 0);
2896 
2897 	remaining_size = task->scsi.transfer_len - task->scsi.length;
2898 	task->current_datain_offset = 0;
2899 
2900 	if (remaining_size == 0) {
2901 		spdk_iscsi_queue_task(conn, task);
2902 		return 0;
2903 	}
2904 
2905 	TAILQ_INSERT_TAIL(&conn->queued_datain_tasks, task, link);
2906 
2907 	return spdk_iscsi_conn_handle_queued_datain_tasks(conn);
2908 }
2909 
2910 static int
2911 spdk_iscsi_op_scsi(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
2912 {
2913 	struct spdk_iscsi_task	*task;
2914 	struct spdk_scsi_dev	*dev;
2915 	uint8_t *cdb;
2916 	uint64_t lun;
2917 	uint32_t task_tag;
2918 	uint32_t transfer_len;
2919 	int F_bit, R_bit, W_bit;
2920 	int lun_i, rc;
2921 	struct iscsi_bhs_scsi_req *reqh;
2922 
2923 	if (conn->sess->session_type != SESSION_TYPE_NORMAL) {
2924 		SPDK_ERRLOG("ISCSI_OP_SCSI not allowed in discovery and invalid session\n");
2925 		return SPDK_ISCSI_CONNECTION_FATAL;
2926 	}
2927 
2928 	reqh = (struct iscsi_bhs_scsi_req *)&pdu->bhs;
2929 
2930 	F_bit = reqh->final_bit;
2931 	R_bit = reqh->read_bit;
2932 	W_bit = reqh->write_bit;
2933 	lun = from_be64(&reqh->lun);
2934 	task_tag = from_be32(&reqh->itt);
2935 	transfer_len = from_be32(&reqh->expected_data_xfer_len);
2936 	cdb = reqh->cdb;
2937 
2938 	SPDK_TRACEDUMP(SPDK_LOG_ISCSI, "CDB", cdb, 16);
2939 
2940 	task = spdk_iscsi_task_get(conn, NULL, spdk_iscsi_task_cpl);
2941 	if (!task) {
2942 		SPDK_ERRLOG("Unable to acquire task\n");
2943 		return SPDK_ISCSI_CONNECTION_FATAL;
2944 	}
2945 
2946 	spdk_iscsi_task_associate_pdu(task, pdu);
2947 	lun_i = spdk_islun2lun(lun);
2948 	task->lun_id = lun_i;
2949 	dev = conn->dev;
2950 	task->scsi.lun = spdk_scsi_dev_get_lun(dev, lun_i);
2951 
2952 	if ((R_bit != 0) && (W_bit != 0)) {
2953 		SPDK_ERRLOG("Bidirectional CDB is not supported\n");
2954 		spdk_iscsi_task_put(task);
2955 		return SPDK_ISCSI_CONNECTION_FATAL;
2956 	}
2957 
2958 	task->scsi.cdb = cdb;
2959 	task->tag = task_tag;
2960 	task->scsi.transfer_len = transfer_len;
2961 	task->scsi.target_port = conn->target_port;
2962 	task->scsi.initiator_port = conn->initiator_port;
2963 	task->parent = NULL;
2964 
2965 	if (task->scsi.lun == NULL) {
2966 		spdk_scsi_task_process_null_lun(&task->scsi);
2967 		spdk_iscsi_task_cpl(&task->scsi);
2968 		return 0;
2969 	}
2970 
2971 	/* no bi-directional support */
2972 	if (R_bit) {
2973 		return spdk_iscsi_op_scsi_read(conn, task);
2974 	} else if (W_bit) {
2975 		task->scsi.dxfer_dir = SPDK_SCSI_DIR_TO_DEV;
2976 
2977 		if ((conn->sess->ErrorRecoveryLevel >= 1) &&
2978 		    (spdk_iscsi_compare_pdu_bhs_within_existed_r2t_tasks(conn, pdu))) {
2979 			spdk_iscsi_task_response(conn, task);
2980 			spdk_iscsi_task_put(task);
2981 			return 0;
2982 		}
2983 
2984 		if (pdu->data_segment_len > transfer_len) {
2985 			SPDK_ERRLOG("data segment len(=%d) > task transfer len(=%d)\n",
2986 				    (int)pdu->data_segment_len, transfer_len);
2987 			spdk_iscsi_task_put(task);
2988 			rc = spdk_iscsi_reject(conn, pdu,
2989 					       ISCSI_REASON_PROTOCOL_ERROR);
2990 			if (rc < 0) {
2991 				SPDK_ERRLOG("iscsi_reject() failed\n");
2992 			}
2993 			return rc;
2994 		}
2995 
2996 		/* check the ImmediateData and also pdu->data_segment_len */
2997 		if ((!conn->sess->ImmediateData && (pdu->data_segment_len > 0)) ||
2998 		    (pdu->data_segment_len > conn->sess->FirstBurstLength)) {
2999 			spdk_iscsi_task_put(task);
3000 			rc = spdk_iscsi_reject(conn, pdu, ISCSI_REASON_PROTOCOL_ERROR);
3001 			if (rc < 0) {
3002 				SPDK_ERRLOG("iscsi_reject() failed\n");
3003 			}
3004 			return rc;
3005 		}
3006 
3007 		if (F_bit && pdu->data_segment_len < transfer_len) {
3008 			/* needs R2T */
3009 			rc = spdk_add_transfer_task(conn, task);
3010 			if (rc < 0) {
3011 				SPDK_ERRLOG("add_transfer_task() failed\n");
3012 				spdk_iscsi_task_put(task);
3013 				return SPDK_ISCSI_CONNECTION_FATAL;
3014 			}
3015 
3016 			/* Non-immediate writes */
3017 			if (pdu->data_segment_len == 0) {
3018 				return 0;
3019 			} else {
3020 				/* we are doing the first partial write task */
3021 				task->scsi.ref++;
3022 				spdk_scsi_task_set_data(&task->scsi, pdu->data, pdu->data_segment_len);
3023 				task->scsi.length = pdu->data_segment_len;
3024 			}
3025 		}
3026 
3027 		if (pdu->data_segment_len == transfer_len) {
3028 			/* we are doing small writes with no R2T */
3029 			spdk_scsi_task_set_data(&task->scsi, pdu->data, transfer_len);
3030 			task->scsi.length = transfer_len;
3031 		}
3032 	} else {
3033 		/* neither R nor W bit set */
3034 		task->scsi.dxfer_dir = SPDK_SCSI_DIR_NONE;
3035 		if (transfer_len > 0) {
3036 			spdk_iscsi_task_put(task);
3037 			SPDK_ERRLOG("Reject scsi cmd with EDTL > 0 but (R | W) == 0\n");
3038 			return spdk_iscsi_reject(conn, pdu, ISCSI_REASON_INVALID_PDU_FIELD);
3039 		}
3040 	}
3041 
3042 	spdk_iscsi_queue_task(conn, task);
3043 	return 0;
3044 }
3045 
3046 void
3047 spdk_iscsi_task_mgmt_response(struct spdk_iscsi_conn *conn,
3048 			      struct spdk_iscsi_task *task)
3049 {
3050 	struct spdk_iscsi_pdu *rsp_pdu;
3051 	struct iscsi_bhs_task_req *reqh;
3052 	struct iscsi_bhs_task_resp *rsph;
3053 
3054 	if (task->pdu == NULL) {
3055 		/*
3056 		 * This was an internally generated task management command,
3057 		 *  usually from LUN cleanup when a connection closes.
3058 		 */
3059 		return;
3060 	}
3061 
3062 	reqh = (struct iscsi_bhs_task_req *)&task->pdu->bhs;
3063 	/* response PDU */
3064 	rsp_pdu = spdk_get_pdu();
3065 	rsph = (struct iscsi_bhs_task_resp *)&rsp_pdu->bhs;
3066 	rsph->opcode = ISCSI_OP_TASK_RSP;
3067 	rsph->flags |= 0x80; /* bit 0 default to 1 */
3068 	switch (task->scsi.response) {
3069 	case SPDK_SCSI_TASK_MGMT_RESP_COMPLETE:
3070 		rsph->response = ISCSI_TASK_FUNC_RESP_COMPLETE;
3071 		break;
3072 	case SPDK_SCSI_TASK_MGMT_RESP_SUCCESS:
3073 		rsph->response = ISCSI_TASK_FUNC_RESP_COMPLETE;
3074 		break;
3075 	case SPDK_SCSI_TASK_MGMT_RESP_REJECT:
3076 		rsph->response = ISCSI_TASK_FUNC_REJECTED;
3077 		break;
3078 	case SPDK_SCSI_TASK_MGMT_RESP_INVALID_LUN:
3079 		rsph->response = ISCSI_TASK_FUNC_RESP_LUN_NOT_EXIST;
3080 		break;
3081 	case SPDK_SCSI_TASK_MGMT_RESP_TARGET_FAILURE:
3082 		rsph->response = ISCSI_TASK_FUNC_REJECTED;
3083 		break;
3084 	case SPDK_SCSI_TASK_MGMT_RESP_REJECT_FUNC_NOT_SUPPORTED:
3085 		rsph->response = ISCSI_TASK_FUNC_RESP_FUNC_NOT_SUPPORTED;
3086 		break;
3087 	}
3088 	rsph->itt = reqh->itt;
3089 
3090 	to_be32(&rsph->stat_sn, conn->StatSN);
3091 	conn->StatSN++;
3092 
3093 	if (reqh->immediate == 0) {
3094 		conn->sess->MaxCmdSN++;
3095 	}
3096 
3097 	to_be32(&rsph->exp_cmd_sn, conn->sess->ExpCmdSN);
3098 	to_be32(&rsph->max_cmd_sn, conn->sess->MaxCmdSN);
3099 
3100 	spdk_iscsi_conn_write_pdu(conn, rsp_pdu);
3101 }
3102 
3103 void spdk_iscsi_task_response(struct spdk_iscsi_conn *conn,
3104 			      struct spdk_iscsi_task *task)
3105 {
3106 	struct spdk_iscsi_pdu *rsp_pdu;
3107 	struct iscsi_bhs_scsi_resp *rsph;
3108 	uint32_t task_tag;
3109 	uint32_t transfer_len;
3110 	size_t residual_len;
3111 	size_t data_len;
3112 	int o_bit, u_bit, O_bit, U_bit;
3113 	int bidi_residual_len;
3114 	int rc;
3115 	struct spdk_iscsi_task *primary;
3116 
3117 	primary = spdk_iscsi_task_get_primary(task);
3118 
3119 	transfer_len = primary->scsi.transfer_len;
3120 	task_tag = task->tag;
3121 
3122 	/* transfer data from logical unit */
3123 	/* (direction is view of initiator side) */
3124 	if (spdk_iscsi_task_is_read(primary)) {
3125 		rc = spdk_iscsi_transfer_in(conn, task);
3126 		if (rc > 0) {
3127 			/* sent status by last DATAIN PDU */
3128 			return;
3129 		}
3130 
3131 		if (primary->bytes_completed != primary->scsi.transfer_len) {
3132 			return;
3133 		}
3134 	}
3135 
3136 	o_bit = u_bit = O_bit = U_bit = 0;
3137 	bidi_residual_len = residual_len = 0;
3138 	data_len = primary->bytes_completed;
3139 
3140 	if ((transfer_len != 0) &&
3141 	    (task->scsi.status == SPDK_SCSI_STATUS_GOOD)) {
3142 		if (data_len < transfer_len) {
3143 			/* underflow */
3144 			SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Underflow %zu/%u\n", data_len, transfer_len);
3145 			residual_len = transfer_len - data_len;
3146 			U_bit = 1;
3147 		} else if (data_len > transfer_len) {
3148 			/* overflow */
3149 			SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Overflow %zu/%u\n", data_len, transfer_len);
3150 			residual_len = data_len - transfer_len;
3151 			O_bit = 1;
3152 		} else {
3153 			SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Transfer %u\n", transfer_len);
3154 		}
3155 	}
3156 
3157 	/* response PDU */
3158 	rsp_pdu = spdk_get_pdu();
3159 	rsph = (struct iscsi_bhs_scsi_resp *)&rsp_pdu->bhs;
3160 	assert(task->scsi.sense_data_len <= sizeof(rsp_pdu->sense.data));
3161 	memcpy(rsp_pdu->sense.data, task->scsi.sense_data, task->scsi.sense_data_len);
3162 	to_be16(&rsp_pdu->sense.length, task->scsi.sense_data_len);
3163 	rsp_pdu->data = (uint8_t *)&rsp_pdu->sense;
3164 	rsp_pdu->data_from_mempool = true;
3165 
3166 	/*
3167 	 * we need to hold onto this task/cmd because until the
3168 	 * PDU has been written out
3169 	 */
3170 	rsp_pdu->task = task;
3171 	task->scsi.ref++;
3172 
3173 	rsph->opcode = ISCSI_OP_SCSI_RSP;
3174 	rsph->flags |= 0x80; /* bit 0 is default to 1 */
3175 
3176 	if (o_bit) {
3177 		rsph->flags |= ISCSI_SCSI_BIDI_OVERFLOW;
3178 	}
3179 
3180 	if (u_bit) {
3181 		rsph->flags |= ISCSI_SCSI_BIDI_UNDERFLOW;
3182 	}
3183 
3184 	if (O_bit) {
3185 		rsph->flags |= ISCSI_SCSI_OVERFLOW;
3186 	}
3187 
3188 	if (U_bit) {
3189 		rsph->flags |= ISCSI_SCSI_UNDERFLOW;
3190 	}
3191 
3192 	rsph->status = task->scsi.status;
3193 	if (task->scsi.sense_data_len) {
3194 		/* SenseLength (2 bytes) + SenseData  */
3195 		DSET24(rsph->data_segment_len, 2 + task->scsi.sense_data_len);
3196 	}
3197 	to_be32(&rsph->itt, task_tag);
3198 
3199 	to_be32(&rsph->stat_sn, conn->StatSN);
3200 	conn->StatSN++;
3201 
3202 	if (!spdk_iscsi_task_is_immediate(primary)) {
3203 		conn->sess->MaxCmdSN++;
3204 	}
3205 
3206 	to_be32(&rsph->exp_cmd_sn, conn->sess->ExpCmdSN);
3207 	to_be32(&rsph->max_cmd_sn, conn->sess->MaxCmdSN);
3208 
3209 	to_be32(&rsph->bi_read_res_cnt, bidi_residual_len);
3210 	to_be32(&rsph->res_cnt, residual_len);
3211 
3212 	spdk_iscsi_conn_write_pdu(conn, rsp_pdu);
3213 }
3214 
3215 static struct spdk_iscsi_task *
3216 spdk_get_transfer_task(struct spdk_iscsi_conn *conn, uint32_t transfer_tag)
3217 {
3218 	int i;
3219 
3220 	for (i = 0; i < conn->pending_r2t; i++) {
3221 		if (conn->outstanding_r2t_tasks[i]->ttt == transfer_tag) {
3222 			return (conn->outstanding_r2t_tasks[i]);
3223 		}
3224 	}
3225 
3226 	return NULL;
3227 }
3228 
3229 static int
3230 spdk_iscsi_op_task(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
3231 {
3232 	struct iscsi_bhs_task_req *reqh;
3233 	uint64_t lun;
3234 	uint32_t task_tag;
3235 	uint32_t ref_task_tag;
3236 	uint8_t function;
3237 	int lun_i;
3238 	struct spdk_iscsi_task *task;
3239 	struct spdk_scsi_dev *dev;
3240 
3241 	if (conn->sess->session_type != SESSION_TYPE_NORMAL) {
3242 		SPDK_ERRLOG("ISCSI_OP_TASK not allowed in discovery and invalid session\n");
3243 		return SPDK_ISCSI_CONNECTION_FATAL;
3244 	}
3245 
3246 	reqh = (struct iscsi_bhs_task_req *)&pdu->bhs;
3247 	function = reqh->flags & ISCSI_TASK_FUNCTION_MASK;
3248 	lun = from_be64(&reqh->lun);
3249 	task_tag = from_be32(&reqh->itt);
3250 	ref_task_tag = from_be32(&reqh->ref_task_tag);
3251 
3252 	SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "I=%d, func=%d, ITT=%x, ref TT=%x, LUN=0x%16.16"PRIx64"\n",
3253 		      reqh->immediate, function, task_tag, ref_task_tag, lun);
3254 
3255 	SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "StatSN=%u, ExpCmdSN=%u, MaxCmdSN=%u\n",
3256 		      conn->StatSN, conn->sess->ExpCmdSN, conn->sess->MaxCmdSN);
3257 
3258 	lun_i = spdk_islun2lun(lun);
3259 	dev = conn->dev;
3260 
3261 	task = spdk_iscsi_task_get(conn, NULL, spdk_iscsi_task_mgmt_cpl);
3262 	if (!task) {
3263 		SPDK_ERRLOG("Unable to acquire task\n");
3264 		return SPDK_ISCSI_CONNECTION_FATAL;
3265 	}
3266 
3267 	spdk_iscsi_task_associate_pdu(task, pdu);
3268 	task->scsi.target_port = conn->target_port;
3269 	task->scsi.initiator_port = conn->initiator_port;
3270 	task->tag = task_tag;
3271 	task->scsi.lun = spdk_scsi_dev_get_lun(dev, lun_i);
3272 
3273 	switch (function) {
3274 	/* abort task identified by Referenced Task Tag field */
3275 	case ISCSI_TASK_FUNC_ABORT_TASK:
3276 		SPDK_NOTICELOG("ABORT_TASK\n");
3277 
3278 		task->scsi.abort_id = ref_task_tag;
3279 
3280 		spdk_iscsi_queue_mgmt_task(conn, task, SPDK_SCSI_TASK_FUNC_ABORT_TASK);
3281 		spdk_del_transfer_task(conn, ref_task_tag);
3282 
3283 		return SPDK_SUCCESS;
3284 
3285 	/* abort all tasks issued via this session on the LUN */
3286 	case ISCSI_TASK_FUNC_ABORT_TASK_SET:
3287 		SPDK_NOTICELOG("ABORT_TASK_SET\n");
3288 
3289 		spdk_iscsi_queue_mgmt_task(conn, task, SPDK_SCSI_TASK_FUNC_ABORT_TASK_SET);
3290 		spdk_clear_all_transfer_task(conn, task->scsi.lun);
3291 
3292 		return SPDK_SUCCESS;
3293 
3294 	case ISCSI_TASK_FUNC_CLEAR_TASK_SET:
3295 		task->scsi.response = SPDK_SCSI_TASK_MGMT_RESP_REJECT_FUNC_NOT_SUPPORTED;
3296 		SPDK_NOTICELOG("CLEAR_TASK_SET (Unsupported)\n");
3297 		break;
3298 
3299 	case ISCSI_TASK_FUNC_CLEAR_ACA:
3300 		task->scsi.response = SPDK_SCSI_TASK_MGMT_RESP_REJECT_FUNC_NOT_SUPPORTED;
3301 		SPDK_NOTICELOG("CLEAR_ACA (Unsupported)\n");
3302 		break;
3303 
3304 	case ISCSI_TASK_FUNC_LOGICAL_UNIT_RESET:
3305 		SPDK_NOTICELOG("LOGICAL_UNIT_RESET\n");
3306 
3307 		spdk_iscsi_queue_mgmt_task(conn, task, SPDK_SCSI_TASK_FUNC_LUN_RESET);
3308 		spdk_clear_all_transfer_task(conn, task->scsi.lun);
3309 		return SPDK_SUCCESS;
3310 
3311 	case ISCSI_TASK_FUNC_TARGET_WARM_RESET:
3312 		SPDK_NOTICELOG("TARGET_WARM_RESET (Unsupported)\n");
3313 
3314 #if 0
3315 		spdk_iscsi_drop_conns(conn, conn->initiator_name, 1 /* drop all */);
3316 		rc = spdk_iscsi_tgt_node_reset(conn->sess->target, lun);
3317 		if (rc < 0) {
3318 			SPDK_ERRLOG("tgt_node reset failed\n");
3319 		}
3320 #else
3321 		task->scsi.response = SPDK_SCSI_TASK_MGMT_RESP_REJECT_FUNC_NOT_SUPPORTED;
3322 #endif
3323 		break;
3324 
3325 	case ISCSI_TASK_FUNC_TARGET_COLD_RESET:
3326 		SPDK_NOTICELOG("TARGET_COLD_RESET\n");
3327 
3328 #if 0
3329 		spdk_iscsi_drop_conns(conn, conn->initiator_name, 1 /* drop all */);
3330 
3331 		rc = spdk_iscsi_tgt_node_reset(conn->sess->target, lun);
3332 		if (rc < 0) {
3333 			SPDK_ERRLOG("tgt_node reset failed\n");
3334 		}
3335 
3336 		conn->state = ISCSI_CONN_STATE_EXITING;
3337 #else
3338 		task->scsi.response = SPDK_SCSI_TASK_MGMT_RESP_REJECT_FUNC_NOT_SUPPORTED;
3339 #endif
3340 		break;
3341 
3342 	case ISCSI_TASK_FUNC_TASK_REASSIGN:
3343 		SPDK_NOTICELOG("TASK_REASSIGN (Unsupported)\n");
3344 		task->scsi.response = SPDK_SCSI_TASK_MGMT_RESP_REJECT_FUNC_NOT_SUPPORTED;
3345 		break;
3346 
3347 	default:
3348 		SPDK_ERRLOG("unsupported function %d\n", function);
3349 		task->scsi.response = SPDK_SCSI_TASK_MGMT_RESP_REJECT;
3350 		break;
3351 	}
3352 
3353 	spdk_iscsi_task_mgmt_response(conn, task);
3354 	spdk_iscsi_task_put(task);
3355 	return 0;
3356 }
3357 
3358 static int
3359 spdk_iscsi_op_nopout(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
3360 {
3361 	struct spdk_iscsi_pdu *rsp_pdu;
3362 	struct iscsi_bhs_nop_out *reqh;
3363 	struct iscsi_bhs_nop_in *rsph;
3364 	uint8_t *data;
3365 	uint64_t lun;
3366 	uint32_t task_tag;
3367 	uint32_t transfer_tag;
3368 	uint32_t CmdSN;
3369 	int I_bit;
3370 	int data_len;
3371 
3372 	if (conn->sess->session_type == SESSION_TYPE_DISCOVERY) {
3373 		SPDK_ERRLOG("ISCSI_OP_NOPOUT not allowed in discovery session\n");
3374 		return SPDK_ISCSI_CONNECTION_FATAL;
3375 	}
3376 
3377 	reqh = (struct iscsi_bhs_nop_out *)&pdu->bhs;
3378 	I_bit = reqh->immediate;
3379 
3380 	data_len = DGET24(reqh->data_segment_len);
3381 	if (data_len > conn->MaxRecvDataSegmentLength) {
3382 		data_len = conn->MaxRecvDataSegmentLength;
3383 	}
3384 
3385 	lun = from_be64(&reqh->lun);
3386 	task_tag = from_be32(&reqh->itt);
3387 	transfer_tag = from_be32(&reqh->ttt);
3388 	CmdSN = from_be32(&reqh->cmd_sn);
3389 	pdu->cmd_sn = CmdSN;
3390 
3391 	SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "I=%d, ITT=%x, TTT=%x\n",
3392 		      I_bit, task_tag, transfer_tag);
3393 
3394 	SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "CmdSN=%u, StatSN=%u, ExpCmdSN=%u, MaxCmdSN=%u\n",
3395 		      CmdSN, conn->StatSN, conn->sess->ExpCmdSN,
3396 		      conn->sess->MaxCmdSN);
3397 
3398 	if (transfer_tag != 0xFFFFFFFF && transfer_tag != (uint32_t)conn->id) {
3399 		SPDK_ERRLOG("invalid transfer tag 0x%x\n", transfer_tag);
3400 		/*
3401 		 * Technically we should probably fail the connection here, but for now
3402 		 *  just print the error message and continue.
3403 		 */
3404 	}
3405 
3406 	/*
3407 	 * We don't actually check to see if this is a response to the NOP-In
3408 	 * that we sent.  Our goal is to just verify that the initiator is
3409 	 * alive and responding to commands, not to verify that it tags
3410 	 * NOP-Outs correctly
3411 	 */
3412 	conn->nop_outstanding = false;
3413 
3414 	if (task_tag == 0xffffffffU) {
3415 		if (I_bit == 1) {
3416 			SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "got NOPOUT ITT=0xffffffff\n");
3417 			return SPDK_SUCCESS;
3418 		} else {
3419 			SPDK_ERRLOG("got NOPOUT ITT=0xffffffff, I=0\n");
3420 			return SPDK_ISCSI_CONNECTION_FATAL;
3421 		}
3422 	}
3423 
3424 	data = calloc(1, data_len);
3425 	if (!data) {
3426 		SPDK_ERRLOG("calloc() failed for ping data\n");
3427 		return SPDK_ISCSI_CONNECTION_FATAL;
3428 	}
3429 
3430 	/* response of NOPOUT */
3431 	if (data_len > 0) {
3432 		/* copy ping data */
3433 		memcpy(data, pdu->data, data_len);
3434 	}
3435 
3436 	transfer_tag = 0xffffffffU;
3437 
3438 	/* response PDU */
3439 	rsp_pdu = spdk_get_pdu();
3440 	if (rsp_pdu == NULL) {
3441 		free(data);
3442 		return SPDK_ISCSI_CONNECTION_FATAL;
3443 	}
3444 	rsph = (struct iscsi_bhs_nop_in *)&rsp_pdu->bhs;
3445 	rsp_pdu->data = data;
3446 	rsph->opcode = ISCSI_OP_NOPIN;
3447 	rsph->flags |= 0x80; /* bit 0 default to 1 */
3448 	DSET24(rsph->data_segment_len, data_len);
3449 	to_be64(&rsph->lun, lun);
3450 	to_be32(&rsph->itt, task_tag);
3451 	to_be32(&rsph->ttt, transfer_tag);
3452 
3453 	to_be32(&rsph->stat_sn, conn->StatSN);
3454 	conn->StatSN++;
3455 
3456 	if (I_bit == 0) {
3457 		conn->sess->MaxCmdSN++;
3458 	}
3459 
3460 	to_be32(&rsph->exp_cmd_sn, conn->sess->ExpCmdSN);
3461 	to_be32(&rsph->max_cmd_sn, conn->sess->MaxCmdSN);
3462 
3463 	spdk_iscsi_conn_write_pdu(conn, rsp_pdu);
3464 	conn->last_nopin = spdk_get_ticks();
3465 
3466 	return SPDK_SUCCESS;
3467 }
3468 
3469 static int
3470 spdk_add_transfer_task(struct spdk_iscsi_conn *conn,
3471 		       struct spdk_iscsi_task *task)
3472 {
3473 	uint32_t transfer_len;
3474 	size_t max_burst_len;
3475 	size_t segment_len;
3476 	size_t data_len;
3477 	int len;
3478 	int idx;
3479 	int rc;
3480 	int data_out_req;
3481 
3482 	transfer_len = task->scsi.transfer_len;
3483 	data_len = spdk_iscsi_task_get_pdu(task)->data_segment_len;
3484 	max_burst_len = conn->sess->MaxBurstLength;
3485 	segment_len = SPDK_ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH;
3486 	data_out_req = 1 + (transfer_len - data_len - 1) / segment_len;
3487 	task->data_out_cnt = data_out_req;
3488 
3489 	/*
3490 	 * If we already have too many tasks using R2T, then queue this task
3491 	 *  and start sending R2T for it after some of the tasks using R2T/data
3492 	 *  out buffers complete.
3493 	 */
3494 	if (conn->pending_r2t >= DEFAULT_MAXR2T) {
3495 		TAILQ_INSERT_TAIL(&conn->queued_r2t_tasks, task, link);
3496 		return SPDK_SUCCESS;
3497 	}
3498 
3499 	conn->data_out_cnt += data_out_req;
3500 	idx = conn->pending_r2t++;
3501 
3502 	conn->outstanding_r2t_tasks[idx] = task;
3503 	task->next_expected_r2t_offset = data_len;
3504 	task->current_r2t_length = 0;
3505 	task->R2TSN = 0;
3506 	task->ttt = ++conn->ttt;
3507 
3508 	while (data_len != transfer_len) {
3509 		len = DMIN32(max_burst_len, (transfer_len - data_len));
3510 		rc = spdk_iscsi_send_r2t(conn, task, data_len, len,
3511 					 task->ttt, &task->R2TSN);
3512 		if (rc < 0) {
3513 			SPDK_ERRLOG("iscsi_send_r2t() failed\n");
3514 			return rc;
3515 		}
3516 		data_len += len;
3517 		task->next_r2t_offset = data_len;
3518 		task->outstanding_r2t++;
3519 		if (conn->sess->MaxOutstandingR2T == task->outstanding_r2t) {
3520 			break;
3521 		}
3522 	}
3523 
3524 	TAILQ_INSERT_TAIL(&conn->active_r2t_tasks, task, link);
3525 	return SPDK_SUCCESS;
3526 }
3527 
3528 void spdk_del_transfer_task(struct spdk_iscsi_conn *conn, uint32_t task_tag)
3529 {
3530 	struct spdk_iscsi_task *task, *tmp;
3531 	int i;
3532 
3533 	for (i = 0; i < conn->pending_r2t; i++) {
3534 		if (conn->outstanding_r2t_tasks[i]->tag == task_tag) {
3535 			task = conn->outstanding_r2t_tasks[i];
3536 			conn->data_out_cnt -= task->data_out_cnt;
3537 
3538 			conn->pending_r2t--;
3539 			for (; i < conn->pending_r2t; i++) {
3540 				conn->outstanding_r2t_tasks[i] = conn->outstanding_r2t_tasks[i + 1];
3541 			}
3542 			conn->outstanding_r2t_tasks[conn->pending_r2t] = NULL;
3543 			break;
3544 		}
3545 	}
3546 
3547 	/*
3548 	 * A large write was just completed, so if there are additional large
3549 	 *  writes queued for R2Ts, start them now.  But first check to make
3550 	 *  sure each of the tasks will fit without the connection's allotment
3551 	 *  for total R2T tasks.
3552 	 */
3553 	TAILQ_FOREACH_SAFE(task, &conn->queued_r2t_tasks, link, tmp) {
3554 		if (conn->pending_r2t < DEFAULT_MAXR2T) {
3555 			TAILQ_REMOVE(&conn->queued_r2t_tasks, task, link);
3556 			spdk_add_transfer_task(conn, task);
3557 		} else {
3558 			break;
3559 		}
3560 	}
3561 }
3562 
3563 static void
3564 spdk_del_connection_queued_task(void *tailq, struct spdk_scsi_lun *lun)
3565 {
3566 	struct spdk_iscsi_task *task, *task_tmp;
3567 	/*
3568 	 * Temporary used to index spdk_scsi_task related
3569 	 *  queues of the connection.
3570 	 */
3571 	TAILQ_HEAD(queued_tasks, spdk_iscsi_task) *head;
3572 	head = (struct queued_tasks *)tailq;
3573 
3574 	TAILQ_FOREACH_SAFE(task, head, link, task_tmp) {
3575 		if (lun == NULL || lun == task->scsi.lun) {
3576 			TAILQ_REMOVE(head, task, link);
3577 			spdk_iscsi_task_put(task);
3578 		}
3579 	}
3580 }
3581 
3582 void spdk_clear_all_transfer_task(struct spdk_iscsi_conn *conn,
3583 				  struct spdk_scsi_lun *lun)
3584 {
3585 	int i, j, pending_r2t;
3586 	struct spdk_iscsi_task *task;
3587 
3588 	pending_r2t = conn->pending_r2t;
3589 	for (i = 0; i < pending_r2t; i++) {
3590 		task = conn->outstanding_r2t_tasks[i];
3591 		if (lun == NULL || lun == task->scsi.lun) {
3592 			conn->outstanding_r2t_tasks[i] = NULL;
3593 			task->outstanding_r2t = 0;
3594 			task->next_r2t_offset = 0;
3595 			task->next_expected_r2t_offset = 0;
3596 			conn->data_out_cnt -= task->data_out_cnt;
3597 			conn->pending_r2t--;
3598 		}
3599 	}
3600 
3601 	for (i = 0; i < pending_r2t; i++) {
3602 		if (conn->outstanding_r2t_tasks[i] != NULL) {
3603 			continue;
3604 		}
3605 		for (j = i + 1; j < pending_r2t; j++) {
3606 			if (conn->outstanding_r2t_tasks[j] != NULL) {
3607 				conn->outstanding_r2t_tasks[i] = conn->outstanding_r2t_tasks[j];
3608 				conn->outstanding_r2t_tasks[j] = NULL;
3609 				break;
3610 			}
3611 		}
3612 	}
3613 
3614 	spdk_del_connection_queued_task(&conn->active_r2t_tasks, lun);
3615 	spdk_del_connection_queued_task(&conn->queued_r2t_tasks, lun);
3616 }
3617 
3618 /* This function is used to handle the r2t snack */
3619 static int
3620 spdk_iscsi_handle_r2t_snack(struct spdk_iscsi_conn *conn,
3621 			    struct spdk_iscsi_task *task,
3622 			    struct spdk_iscsi_pdu *pdu, uint32_t beg_run,
3623 			    uint32_t run_length, int32_t task_tag)
3624 {
3625 	int32_t last_r2tsn;
3626 	int i;
3627 
3628 	if (beg_run < task->acked_r2tsn) {
3629 		SPDK_ERRLOG("ITT: 0x%08x, R2T SNACK requests retransmission of"
3630 			    "R2TSN: from 0x%08x to 0x%08x. But it has already"
3631 			    "ack to R2TSN:0x%08x, protocol error.\n",
3632 			    task_tag, beg_run, (beg_run + run_length),
3633 			    (task->acked_r2tsn - 1));
3634 		return spdk_iscsi_reject(conn, pdu, ISCSI_REASON_PROTOCOL_ERROR);
3635 	}
3636 
3637 	if (run_length) {
3638 		if ((beg_run + run_length) > task->R2TSN) {
3639 			SPDK_ERRLOG("ITT: 0x%08x, received R2T SNACK with"
3640 				    "BegRun: 0x%08x, RunLength: 0x%08x, exceeds"
3641 				    "current R2TSN: 0x%08x, protocol error.\n",
3642 				    task_tag, beg_run, run_length,
3643 				    task->R2TSN);
3644 
3645 			return spdk_iscsi_reject(conn, pdu,
3646 						 ISCSI_REASON_INVALID_PDU_FIELD);
3647 		}
3648 		last_r2tsn = (beg_run + run_length);
3649 	} else {
3650 		last_r2tsn = task->R2TSN;
3651 	}
3652 
3653 	for (i = beg_run; i < last_r2tsn; i++) {
3654 		if (spdk_iscsi_send_r2t_recovery(conn, task, i, false) < 0) {
3655 			SPDK_ERRLOG("The r2t_sn=%d of r2t_task=%p is not sent\n", i, task);
3656 		}
3657 	}
3658 	return 0;
3659 }
3660 
3661 /* This function is used to recover the data in packet */
3662 static int
3663 spdk_iscsi_handle_recovery_datain(struct spdk_iscsi_conn *conn,
3664 				  struct spdk_iscsi_task *task,
3665 				  struct spdk_iscsi_pdu *pdu, uint32_t beg_run,
3666 				  uint32_t run_length, uint32_t task_tag)
3667 {
3668 	struct spdk_iscsi_pdu *old_pdu, *pdu_temp;
3669 	uint32_t i;
3670 	struct iscsi_bhs_data_in *datain_header;
3671 	uint32_t last_statsn;
3672 
3673 	task = spdk_iscsi_task_get_primary(task);
3674 
3675 	SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "spdk_iscsi_handle_recovery_datain\n");
3676 
3677 	if (beg_run < task->acked_data_sn) {
3678 		SPDK_ERRLOG("ITT: 0x%08x, DATA IN SNACK requests retransmission of"
3679 			    "DATASN: from 0x%08x to 0x%08x but already acked to "
3680 			    "DATASN: 0x%08x protocol error\n",
3681 			    task_tag, beg_run,
3682 			    (beg_run + run_length), (task->acked_data_sn - 1));
3683 
3684 		return spdk_iscsi_reject(conn, pdu, ISCSI_REASON_PROTOCOL_ERROR);
3685 	}
3686 
3687 	if (run_length == 0) {
3688 		/* as the DataSN begins at 0 */
3689 		run_length = task->datain_datasn + 1;
3690 	}
3691 
3692 	if ((beg_run + run_length - 1) > task->datain_datasn) {
3693 		SPDK_ERRLOG("Initiator requests BegRun: 0x%08x, RunLength:"
3694 			    "0x%08x greater than maximum DataSN: 0x%08x.\n",
3695 			    beg_run, run_length, task->datain_datasn);
3696 
3697 		return -1;
3698 	} else {
3699 		last_statsn = beg_run + run_length - 1;
3700 	}
3701 
3702 	for (i = beg_run; i <= last_statsn; i++) {
3703 		TAILQ_FOREACH_SAFE(old_pdu, &conn->snack_pdu_list, tailq, pdu_temp) {
3704 			if (old_pdu->bhs.opcode == ISCSI_OP_SCSI_DATAIN) {
3705 				datain_header = (struct iscsi_bhs_data_in *)&old_pdu->bhs;
3706 				if (from_be32(&datain_header->itt) == task_tag &&
3707 				    from_be32(&datain_header->data_sn) == i) {
3708 					TAILQ_REMOVE(&conn->snack_pdu_list, old_pdu, tailq);
3709 					spdk_iscsi_conn_write_pdu(conn, old_pdu);
3710 					break;
3711 				}
3712 			}
3713 		}
3714 	}
3715 	return 0;
3716 }
3717 
3718 /* This function is used to handle the status snack */
3719 static int
3720 spdk_iscsi_handle_status_snack(struct spdk_iscsi_conn *conn,
3721 			       struct spdk_iscsi_pdu *pdu)
3722 {
3723 	uint32_t beg_run;
3724 	uint32_t run_length;
3725 	struct iscsi_bhs_snack_req *reqh;
3726 	uint32_t i;
3727 	uint32_t last_statsn;
3728 	bool found_pdu;
3729 	struct spdk_iscsi_pdu *old_pdu;
3730 
3731 	reqh = (struct iscsi_bhs_snack_req *)&pdu->bhs;
3732 	beg_run = from_be32(&reqh->beg_run);
3733 	run_length = from_be32(&reqh->run_len);
3734 
3735 	SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "beg_run=%d, run_length=%d, conn->StatSN="
3736 		      "%d, conn->exp_statsn=%d\n", beg_run, run_length,
3737 		      conn->StatSN, conn->exp_statsn);
3738 
3739 	if (!beg_run) {
3740 		beg_run = conn->exp_statsn;
3741 	} else if (beg_run < conn->exp_statsn) {
3742 		SPDK_ERRLOG("Got Status SNACK Begrun: 0x%08x, RunLength: 0x%08x "
3743 			    "but already got ExpStatSN: 0x%08x on CID:%hu.\n",
3744 			    beg_run, run_length, conn->StatSN, conn->cid);
3745 
3746 		return spdk_iscsi_reject(conn, pdu, ISCSI_REASON_INVALID_PDU_FIELD);
3747 	}
3748 
3749 	last_statsn = (!run_length) ? conn->StatSN : (beg_run + run_length);
3750 
3751 	for (i = beg_run; i < last_statsn; i++) {
3752 		found_pdu = false;
3753 		TAILQ_FOREACH(old_pdu, &conn->snack_pdu_list, tailq) {
3754 			if (from_be32(&old_pdu->bhs.stat_sn) == i) {
3755 				found_pdu = true;
3756 				break;
3757 			}
3758 		}
3759 
3760 		if (!found_pdu) {
3761 			SPDK_ERRLOG("Unable to find StatSN: 0x%08x. For a Status"
3762 				    "SNACK, assuming this is a proactive SNACK "
3763 				    "for an untransmitted StatSN, ignoring.\n",
3764 				    beg_run);
3765 		} else {
3766 			TAILQ_REMOVE(&conn->snack_pdu_list, old_pdu, tailq);
3767 			spdk_iscsi_conn_write_pdu(conn, old_pdu);
3768 		}
3769 	}
3770 
3771 	return 0;
3772 }
3773 
3774 /* This function is used to handle the data ack snack */
3775 static int
3776 spdk_iscsi_handle_data_ack(struct spdk_iscsi_conn *conn,
3777 			   struct spdk_iscsi_pdu *pdu)
3778 {
3779 	uint32_t transfer_tag;
3780 	uint32_t beg_run;
3781 	uint32_t run_length;
3782 	struct spdk_iscsi_pdu *old_pdu;
3783 	uint32_t old_datasn;
3784 	int rc;
3785 	struct iscsi_bhs_snack_req *reqh;
3786 	struct spdk_iscsi_task *task;
3787 	struct iscsi_bhs_data_in *datain_header;
3788 	struct spdk_iscsi_task *primary;
3789 
3790 	reqh = (struct iscsi_bhs_snack_req *)&pdu->bhs;
3791 	transfer_tag = from_be32(&reqh->ttt);
3792 	beg_run = from_be32(&reqh->beg_run);
3793 	run_length = from_be32(&reqh->run_len);
3794 	task = NULL;
3795 	datain_header = NULL;
3796 
3797 	SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "beg_run=%d,transfer_tag=%d,run_len=%d\n",
3798 		      beg_run, transfer_tag, run_length);
3799 
3800 	task = spdk_get_scsi_task_from_ttt(conn, transfer_tag);
3801 	if (!task) {
3802 		SPDK_ERRLOG("Data ACK SNACK for TTT: 0x%08x is invalid.\n",
3803 			    transfer_tag);
3804 		goto reject_return;
3805 	}
3806 
3807 	primary = spdk_iscsi_task_get_primary(task);
3808 	if ((run_length != 0) || (beg_run < primary->acked_data_sn)) {
3809 		SPDK_ERRLOG("TTT: 0x%08x Data ACK SNACK BegRUN: %d is less than "
3810 			    "the next expected acked DataSN: %d\n",
3811 			    transfer_tag, beg_run, primary->acked_data_sn);
3812 		goto reject_return;
3813 	}
3814 
3815 	primary->acked_data_sn = beg_run;
3816 
3817 	/* To free the pdu */
3818 	TAILQ_FOREACH(old_pdu, &conn->snack_pdu_list, tailq) {
3819 		if (old_pdu->bhs.opcode == ISCSI_OP_SCSI_DATAIN) {
3820 			datain_header = (struct iscsi_bhs_data_in *) &old_pdu->bhs;
3821 			old_datasn = from_be32(&datain_header->data_sn);
3822 			if ((from_be32(&datain_header->ttt) == transfer_tag) &&
3823 			    (old_datasn == beg_run - 1)) {
3824 				TAILQ_REMOVE(&conn->snack_pdu_list, old_pdu, tailq);
3825 				if (old_pdu->task) {
3826 					spdk_iscsi_task_put(old_pdu->task);
3827 				}
3828 				spdk_put_pdu(old_pdu);
3829 				break;
3830 			}
3831 		}
3832 	}
3833 
3834 	SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Received Data ACK SNACK for TTT: 0x%08x,"
3835 		      " updated acked DataSN to 0x%08x.\n", transfer_tag,
3836 		      (task->acked_data_sn - 1));
3837 
3838 	return 0;
3839 
3840 reject_return:
3841 	rc = spdk_iscsi_reject(conn, pdu, ISCSI_REASON_INVALID_SNACK);
3842 	if (rc < 0) {
3843 		SPDK_ERRLOG("iscsi_reject() failed\n");
3844 		return -1;
3845 	}
3846 
3847 	return 0;
3848 }
3849 
3850 /* This function is used to remove the r2t pdu from snack_pdu_list by < task, r2t_sn> info */
3851 static struct spdk_iscsi_pdu *
3852 spdk_iscsi_remove_r2t_pdu_from_snack_list(struct spdk_iscsi_conn *conn,
3853 		struct spdk_iscsi_task *task,
3854 		uint32_t r2t_sn)
3855 {
3856 	struct spdk_iscsi_pdu *pdu;
3857 	struct iscsi_bhs_r2t *r2t_header;
3858 
3859 	TAILQ_FOREACH(pdu, &conn->snack_pdu_list, tailq) {
3860 		if (pdu->bhs.opcode == ISCSI_OP_R2T) {
3861 			r2t_header = (struct iscsi_bhs_r2t *)&pdu->bhs;
3862 			if (pdu->task == task &&
3863 			    from_be32(&r2t_header->r2t_sn) == r2t_sn) {
3864 				TAILQ_REMOVE(&conn->snack_pdu_list, pdu, tailq);
3865 				return pdu;
3866 			}
3867 		}
3868 	}
3869 
3870 	return NULL;
3871 }
3872 
3873 /* This function is used re-send the r2t packet */
3874 static int
3875 spdk_iscsi_send_r2t_recovery(struct spdk_iscsi_conn *conn,
3876 			     struct spdk_iscsi_task *task, uint32_t r2t_sn,
3877 			     bool send_new_r2tsn)
3878 {
3879 	struct spdk_iscsi_pdu *pdu;
3880 	struct iscsi_bhs_r2t *rsph;
3881 	uint32_t transfer_len;
3882 	uint32_t len;
3883 	int rc;
3884 
3885 	/* remove the r2t pdu from the snack_list */
3886 	pdu = spdk_iscsi_remove_r2t_pdu_from_snack_list(conn, task, r2t_sn);
3887 	if (!pdu) {
3888 		SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "No pdu is found\n");
3889 		return -1;
3890 	}
3891 
3892 	/* flag
3893 	 * false: only need to re-send the old r2t with changing statsn
3894 	 * true: we send a r2t with new r2tsn
3895 	 */
3896 	if (!send_new_r2tsn) {
3897 		to_be32(&pdu->bhs.stat_sn, conn->StatSN);
3898 		spdk_iscsi_conn_write_pdu(conn, pdu);
3899 	} else {
3900 		rsph = (struct iscsi_bhs_r2t *)&pdu->bhs;
3901 		transfer_len = from_be32(&rsph->desired_xfer_len);
3902 
3903 		/* still need to increase the acked r2tsn */
3904 		task->acked_r2tsn++;
3905 		len = DMIN32(conn->sess->MaxBurstLength, (transfer_len -
3906 				task->next_expected_r2t_offset));
3907 
3908 		/* remove the old_r2t_pdu */
3909 		if (pdu->task) {
3910 			spdk_iscsi_task_put(pdu->task);
3911 		}
3912 		spdk_put_pdu(pdu);
3913 
3914 		/* re-send a new r2t pdu */
3915 		rc = spdk_iscsi_send_r2t(conn, task, task->next_expected_r2t_offset,
3916 					 len, task->ttt, &task->R2TSN);
3917 		if (rc < 0) {
3918 			return SPDK_ISCSI_CONNECTION_FATAL;
3919 		}
3920 	}
3921 
3922 	return 0;
3923 }
3924 
3925 /* This function is used to handle the snack request from the initiator */
3926 static int
3927 spdk_iscsi_op_snack(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
3928 {
3929 	struct iscsi_bhs_snack_req *reqh;
3930 	struct spdk_iscsi_task *task;
3931 	int type;
3932 	uint32_t task_tag;
3933 	uint32_t beg_run;
3934 	uint32_t run_length;
3935 	int rc;
3936 
3937 	if (conn->sess->session_type == SESSION_TYPE_DISCOVERY) {
3938 		SPDK_ERRLOG("ISCSI_OP_SNACK not allowed in  discovery session\n");
3939 		return SPDK_ISCSI_CONNECTION_FATAL;
3940 	}
3941 
3942 	reqh = (struct iscsi_bhs_snack_req *)&pdu->bhs;
3943 	if (!conn->sess->ErrorRecoveryLevel) {
3944 		SPDK_ERRLOG("Got a SNACK request in ErrorRecoveryLevel=0\n");
3945 		rc = spdk_iscsi_reject(conn, pdu, ISCSI_REASON_PROTOCOL_ERROR);
3946 		if (rc < 0) {
3947 			SPDK_ERRLOG("iscsi_reject() failed\n");
3948 			return -1;
3949 		}
3950 		return rc;
3951 	}
3952 
3953 	type = reqh->flags & ISCSI_FLAG_SNACK_TYPE_MASK;
3954 	SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "The value of type is %d\n", type);
3955 
3956 	switch (type) {
3957 	case 0:
3958 		reqh = (struct iscsi_bhs_snack_req *)&pdu->bhs;
3959 		task_tag = from_be32(&reqh->itt);
3960 		beg_run = from_be32(&reqh->beg_run);
3961 		run_length = from_be32(&reqh->run_len);
3962 
3963 		SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "beg_run=%d, run_length=%d, "
3964 			      "task_tag=%x, transfer_tag=%u\n", beg_run,
3965 			      run_length, task_tag, from_be32(&reqh->ttt));
3966 
3967 		task = spdk_get_scsi_task_from_itt(conn, task_tag,
3968 						   ISCSI_OP_SCSI_DATAIN);
3969 		if (task) {
3970 			return spdk_iscsi_handle_recovery_datain(conn, task, pdu,
3971 					beg_run, run_length, task_tag);
3972 		}
3973 		task = spdk_get_scsi_task_from_itt(conn, task_tag, ISCSI_OP_R2T);
3974 		if (task) {
3975 			return spdk_iscsi_handle_r2t_snack(conn, task, pdu, beg_run,
3976 							   run_length, task_tag);
3977 		}
3978 		SPDK_ERRLOG("It is Neither datain nor r2t recovery request\n");
3979 		rc = -1;
3980 		break;
3981 	case ISCSI_FLAG_SNACK_TYPE_STATUS:
3982 		rc = spdk_iscsi_handle_status_snack(conn, pdu);
3983 		break;
3984 	case ISCSI_FLAG_SNACK_TYPE_DATA_ACK:
3985 		rc = spdk_iscsi_handle_data_ack(conn, pdu);
3986 		break;
3987 	case ISCSI_FLAG_SNACK_TYPE_RDATA:
3988 		SPDK_ERRLOG("R-Data SNACK is Not Supported int spdk\n");
3989 		rc = spdk_iscsi_reject(conn, pdu, ISCSI_REASON_PROTOCOL_ERROR);
3990 		break;
3991 	default:
3992 		SPDK_ERRLOG("Unknown SNACK type %d, protocol error\n", type);
3993 		rc = spdk_iscsi_reject(conn, pdu, ISCSI_REASON_PROTOCOL_ERROR);
3994 		break;
3995 	}
3996 
3997 	return rc;
3998 }
3999 
4000 /* This fucntion is used to refree the pdu when it is acknowledged */
4001 static void
4002 spdk_remove_acked_pdu(struct spdk_iscsi_conn *conn,
4003 		      uint32_t ExpStatSN)
4004 {
4005 	struct spdk_iscsi_pdu *pdu, *pdu_temp;
4006 	uint32_t stat_sn;
4007 
4008 	conn->exp_statsn = DMIN32(ExpStatSN, conn->StatSN);
4009 	TAILQ_FOREACH_SAFE(pdu, &conn->snack_pdu_list, tailq, pdu_temp) {
4010 		stat_sn = from_be32(&pdu->bhs.stat_sn);
4011 		if (SN32_LT(stat_sn, conn->exp_statsn)) {
4012 			TAILQ_REMOVE(&conn->snack_pdu_list, pdu, tailq);
4013 			spdk_iscsi_conn_free_pdu(conn, pdu);
4014 		}
4015 	}
4016 }
4017 
4018 static int spdk_iscsi_op_data(struct spdk_iscsi_conn *conn,
4019 			      struct spdk_iscsi_pdu *pdu)
4020 {
4021 	struct spdk_iscsi_task	*task, *subtask;
4022 	struct iscsi_bhs_data_out *reqh;
4023 	struct spdk_scsi_lun	*lun_dev;
4024 	uint32_t transfer_tag;
4025 	uint32_t task_tag;
4026 	uint32_t transfer_len;
4027 	uint32_t DataSN;
4028 	uint32_t buffer_offset;
4029 	uint32_t len;
4030 	uint64_t lun;
4031 	int lun_i;
4032 	int F_bit;
4033 	int rc;
4034 	int reject_reason = ISCSI_REASON_INVALID_PDU_FIELD;
4035 
4036 	if (conn->sess->session_type == SESSION_TYPE_DISCOVERY) {
4037 		SPDK_ERRLOG("ISCSI_OP_SCSI_DATAOUT not allowed in discovery session\n");
4038 		return SPDK_ISCSI_CONNECTION_FATAL;
4039 	}
4040 
4041 	reqh = (struct iscsi_bhs_data_out *)&pdu->bhs;
4042 	F_bit = !!(reqh->flags & ISCSI_FLAG_FINAL);
4043 	transfer_tag = from_be32(&reqh->ttt);
4044 	task_tag = from_be32(&reqh->itt);
4045 	DataSN = from_be32(&reqh->data_sn);
4046 	buffer_offset = from_be32(&reqh->buffer_offset);
4047 	lun = from_be64(&reqh->lun);
4048 	lun_i = spdk_islun2lun(lun);
4049 	lun_dev = spdk_scsi_dev_get_lun(conn->dev, lun_i);
4050 
4051 	task = spdk_get_transfer_task(conn, transfer_tag);
4052 	if (task == NULL) {
4053 		SPDK_ERRLOG("Not found task for transfer_tag=%x\n", transfer_tag);
4054 		goto reject_return;
4055 	}
4056 
4057 	if (pdu->data_segment_len > task->desired_data_transfer_length) {
4058 		SPDK_ERRLOG("the dataout pdu data length is larger than the value sent by R2T PDU\n");
4059 		return SPDK_ISCSI_CONNECTION_FATAL;
4060 	}
4061 
4062 	if (task->tag != task_tag) {
4063 		SPDK_ERRLOG("The r2t task tag is %u, and the dataout task tag is %u\n",
4064 			    task->tag, task_tag);
4065 		goto reject_return;
4066 	}
4067 
4068 	if (DataSN != task->r2t_datasn) {
4069 		SPDK_ERRLOG("DataSN(%u) exp=%d error\n", DataSN, task->r2t_datasn);
4070 		if (conn->sess->ErrorRecoveryLevel >= 1) {
4071 			goto send_r2t_recovery_return;
4072 		} else {
4073 			reject_reason = ISCSI_REASON_PROTOCOL_ERROR;
4074 			goto reject_return;
4075 		}
4076 	}
4077 
4078 	if (buffer_offset != task->next_expected_r2t_offset) {
4079 		SPDK_ERRLOG("offset(%u) error\n", buffer_offset);
4080 		return SPDK_ISCSI_CONNECTION_FATAL;
4081 	}
4082 
4083 	transfer_len = task->scsi.transfer_len;
4084 	task->current_r2t_length += pdu->data_segment_len;
4085 	task->next_expected_r2t_offset += pdu->data_segment_len;
4086 	task->r2t_datasn++;
4087 
4088 	if (task->current_r2t_length > conn->sess->MaxBurstLength) {
4089 		SPDK_ERRLOG("R2T burst(%u) > MaxBurstLength(%u)\n",
4090 			    task->current_r2t_length,
4091 			    conn->sess->MaxBurstLength);
4092 		return SPDK_ISCSI_CONNECTION_FATAL;
4093 	}
4094 
4095 	if (F_bit) {
4096 		/*
4097 		 * This R2T burst is done.  Clear the length before we
4098 		 *  receive a PDU for the next R2T burst.
4099 		 */
4100 		task->current_r2t_length = 0;
4101 	}
4102 
4103 	subtask = spdk_iscsi_task_get(conn, task, spdk_iscsi_task_cpl);
4104 	if (subtask == NULL) {
4105 		SPDK_ERRLOG("Unable to acquire subtask\n");
4106 		return SPDK_ISCSI_CONNECTION_FATAL;
4107 	}
4108 	subtask->scsi.offset = buffer_offset;
4109 	subtask->scsi.length = pdu->data_segment_len;
4110 	spdk_scsi_task_set_data(&subtask->scsi, pdu->data, pdu->data_segment_len);
4111 	spdk_iscsi_task_associate_pdu(subtask, pdu);
4112 
4113 	if (task->next_expected_r2t_offset == transfer_len) {
4114 		task->acked_r2tsn++;
4115 	} else if (F_bit && (task->next_r2t_offset < transfer_len)) {
4116 		task->acked_r2tsn++;
4117 		len = DMIN32(conn->sess->MaxBurstLength, (transfer_len -
4118 				task->next_r2t_offset));
4119 		rc = spdk_iscsi_send_r2t(conn, task, task->next_r2t_offset, len,
4120 					 task->ttt, &task->R2TSN);
4121 		if (rc < 0) {
4122 			SPDK_ERRLOG("iscsi_send_r2t() failed\n");
4123 		}
4124 		task->next_r2t_offset += len;
4125 	}
4126 
4127 	if (lun_dev == NULL) {
4128 		SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "LUN %d is removed, complete the task immediately\n", lun_i);
4129 		subtask->scsi.transfer_len = subtask->scsi.length;
4130 		spdk_scsi_task_process_null_lun(&subtask->scsi);
4131 		spdk_iscsi_task_cpl(&subtask->scsi);
4132 		return 0;
4133 	}
4134 
4135 	spdk_iscsi_queue_task(conn, subtask);
4136 	return 0;
4137 
4138 send_r2t_recovery_return:
4139 	rc = spdk_iscsi_send_r2t_recovery(conn, task, task->acked_r2tsn, true);
4140 	if (rc == 0) {
4141 		return 0;
4142 	}
4143 
4144 reject_return:
4145 	rc = spdk_iscsi_reject(conn, pdu, reject_reason);
4146 	if (rc < 0) {
4147 		SPDK_ERRLOG("iscsi_reject() failed\n");
4148 		return SPDK_ISCSI_CONNECTION_FATAL;
4149 	}
4150 
4151 	return SPDK_SUCCESS;
4152 }
4153 
4154 static int
4155 spdk_iscsi_send_r2t(struct spdk_iscsi_conn *conn,
4156 		    struct spdk_iscsi_task *task, int offset,
4157 		    int len, uint32_t transfer_tag, uint32_t *R2TSN)
4158 {
4159 	struct spdk_iscsi_pdu *rsp_pdu;
4160 	struct iscsi_bhs_r2t *rsph;
4161 
4162 	/* R2T PDU */
4163 	rsp_pdu = spdk_get_pdu();
4164 	if (rsp_pdu == NULL) {
4165 		return SPDK_ISCSI_CONNECTION_FATAL;
4166 	}
4167 	rsph = (struct iscsi_bhs_r2t *)&rsp_pdu->bhs;
4168 	rsp_pdu->data = NULL;
4169 	rsph->opcode = ISCSI_OP_R2T;
4170 	rsph->flags |= 0x80; /* bit 0 is default to 1 */
4171 	to_be64(&rsph->lun, task->lun_id);
4172 	to_be32(&rsph->itt, task->tag);
4173 	to_be32(&rsph->ttt, transfer_tag);
4174 
4175 	to_be32(&rsph->stat_sn, conn->StatSN);
4176 	to_be32(&rsph->exp_cmd_sn, conn->sess->ExpCmdSN);
4177 	to_be32(&rsph->max_cmd_sn, conn->sess->MaxCmdSN);
4178 
4179 	to_be32(&rsph->r2t_sn, *R2TSN);
4180 	*R2TSN += 1;
4181 
4182 	task->r2t_datasn = 0; /* next expected datasn to ack */
4183 
4184 	to_be32(&rsph->buffer_offset, (uint32_t)offset);
4185 	to_be32(&rsph->desired_xfer_len, (uint32_t)len);
4186 	task->desired_data_transfer_length = (size_t)len;
4187 
4188 	/* we need to hold onto this task/cmd because until the PDU has been
4189 	 * written out */
4190 	rsp_pdu->task = task;
4191 	task->scsi.ref++;
4192 
4193 	spdk_iscsi_conn_write_pdu(conn, rsp_pdu);
4194 
4195 	return SPDK_SUCCESS;
4196 }
4197 
4198 void spdk_iscsi_send_nopin(struct spdk_iscsi_conn *conn)
4199 {
4200 	struct spdk_iscsi_pdu *rsp_pdu;
4201 	struct iscsi_bhs_nop_in	*rsp;
4202 
4203 	/* Only send nopin if we have logged in and are in a normal session. */
4204 	if (conn->sess == NULL ||
4205 	    !conn->full_feature ||
4206 	    !spdk_iscsi_param_eq_val(conn->sess->params, "SessionType", "Normal")) {
4207 		return;
4208 	}
4209 
4210 	SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "send NOPIN isid=%"PRIx64", tsih=%u, cid=%u\n",
4211 		      conn->sess->isid, conn->sess->tsih, conn->cid);
4212 	SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "StatSN=%u, ExpCmdSN=%u, MaxCmdSN=%u\n",
4213 		      conn->StatSN, conn->sess->ExpCmdSN,
4214 		      conn->sess->MaxCmdSN);
4215 
4216 	rsp_pdu = spdk_get_pdu();
4217 	rsp = (struct iscsi_bhs_nop_in *) &rsp_pdu->bhs;
4218 	rsp_pdu->data = NULL;
4219 
4220 	/*
4221 	 * spdk_get_pdu() memset's the PDU for us, so only fill out the needed
4222 	 *  fields.
4223 	 */
4224 	rsp->opcode = ISCSI_OP_NOPIN;
4225 	rsp->flags = 0x80;
4226 	/*
4227 	 * Technically the to_be32() is not needed here, since
4228 	 *  to_be32(0xFFFFFFFU) returns 0xFFFFFFFFU.
4229 	 */
4230 	to_be32(&rsp->itt, 0xFFFFFFFFU);
4231 	to_be32(&rsp->ttt, conn->id);
4232 	to_be32(&rsp->stat_sn, conn->StatSN);
4233 	to_be32(&rsp->exp_cmd_sn, conn->sess->ExpCmdSN);
4234 	to_be32(&rsp->max_cmd_sn, conn->sess->MaxCmdSN);
4235 
4236 	spdk_iscsi_conn_write_pdu(conn, rsp_pdu);
4237 	conn->last_nopin = spdk_get_ticks();
4238 	conn->nop_outstanding = true;
4239 }
4240 
4241 static void
4242 spdk_init_login_reject_response(struct spdk_iscsi_pdu *pdu, struct spdk_iscsi_pdu *rsp_pdu)
4243 {
4244 	struct iscsi_bhs_login_rsp *rsph;
4245 
4246 	memset(rsp_pdu, 0, sizeof(struct spdk_iscsi_pdu));
4247 	rsph = (struct iscsi_bhs_login_rsp *)&rsp_pdu->bhs;
4248 	rsph->version_max = ISCSI_VERSION;
4249 	rsph->version_act = ISCSI_VERSION;
4250 	rsph->opcode = ISCSI_OP_LOGIN_RSP;
4251 	rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR;
4252 	rsph->status_detail = ISCSI_LOGIN_INVALID_LOGIN_REQUEST;
4253 	rsph->itt = pdu->bhs.itt;
4254 }
4255 
4256 int
4257 spdk_iscsi_execute(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
4258 {
4259 	int opcode;
4260 	int rc;
4261 	struct spdk_iscsi_pdu *rsp_pdu = NULL;
4262 	uint32_t ExpStatSN;
4263 	uint32_t QCmdSN;
4264 	int I_bit;
4265 	struct spdk_iscsi_sess *sess;
4266 	struct iscsi_bhs_scsi_req *reqh;
4267 
4268 	if (pdu == NULL) {
4269 		return -1;
4270 	}
4271 
4272 	opcode = pdu->bhs.opcode;
4273 	reqh = (struct iscsi_bhs_scsi_req *)&pdu->bhs;
4274 	pdu->cmd_sn = from_be32(&reqh->cmd_sn);
4275 
4276 	SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "opcode %x\n", opcode);
4277 
4278 	if (opcode == ISCSI_OP_LOGIN) {
4279 		rc = spdk_iscsi_op_login(conn, pdu);
4280 		if (rc < 0) {
4281 			SPDK_ERRLOG("iscsi_op_login() failed\n");
4282 		}
4283 		return rc;
4284 	}
4285 
4286 	/* connection in login phase but receive non-login opcode
4287 	 * return response code 0x020b to initiator.
4288 	 * */
4289 	if (!conn->full_feature && conn->state == ISCSI_CONN_STATE_RUNNING) {
4290 		rsp_pdu = spdk_get_pdu();
4291 		if (rsp_pdu == NULL) {
4292 			return SPDK_ISCSI_CONNECTION_FATAL;
4293 		}
4294 		spdk_init_login_reject_response(pdu, rsp_pdu);
4295 		spdk_iscsi_conn_write_pdu(conn, rsp_pdu);
4296 		SPDK_ERRLOG("Received opcode %d in login phase\n", opcode);
4297 		return SPDK_ISCSI_LOGIN_ERROR_RESPONSE;
4298 	} else if (conn->state == ISCSI_CONN_STATE_INVALID) {
4299 		SPDK_ERRLOG("before Full Feature\n");
4300 		return SPDK_ISCSI_CONNECTION_FATAL;
4301 	}
4302 
4303 	sess = conn->sess;
4304 	if (!sess) {
4305 		SPDK_ERRLOG("Connection has no associated session!\n");
4306 		return SPDK_ISCSI_CONNECTION_FATAL;
4307 	}
4308 	I_bit = reqh->immediate;
4309 	if (I_bit == 0) {
4310 		if (SN32_LT(pdu->cmd_sn, sess->ExpCmdSN) ||
4311 		    SN32_GT(pdu->cmd_sn, sess->MaxCmdSN)) {
4312 			if (sess->session_type == SESSION_TYPE_NORMAL &&
4313 			    opcode != ISCSI_OP_SCSI_DATAOUT) {
4314 				SPDK_ERRLOG("CmdSN(%u) ignore (ExpCmdSN=%u, MaxCmdSN=%u)\n",
4315 					    pdu->cmd_sn, sess->ExpCmdSN, sess->MaxCmdSN);
4316 
4317 				if (sess->ErrorRecoveryLevel >= 1) {
4318 					SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Skip the error in ERL 1 and 2\n");
4319 				} else {
4320 					return SPDK_PDU_FATAL;
4321 				}
4322 			}
4323 		}
4324 	} else if (pdu->cmd_sn != sess->ExpCmdSN) {
4325 		SPDK_ERRLOG("CmdSN(%u) error ExpCmdSN=%u\n", pdu->cmd_sn, sess->ExpCmdSN);
4326 
4327 		if (sess->ErrorRecoveryLevel >= 1) {
4328 			SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Skip the error in ERL 1 and 2\n");
4329 		} else if (opcode != ISCSI_OP_NOPOUT) {
4330 			/*
4331 			 * The Linux initiator does not send valid CmdSNs for
4332 			 *  nopout under heavy load, so do not close the
4333 			 *  connection in that case.
4334 			 */
4335 			return SPDK_ISCSI_CONNECTION_FATAL;
4336 		}
4337 	}
4338 
4339 	ExpStatSN = from_be32(&reqh->exp_stat_sn);
4340 	if (SN32_GT(ExpStatSN, conn->StatSN)) {
4341 		SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "StatSN(%u) advanced\n", ExpStatSN);
4342 		ExpStatSN = conn->StatSN;
4343 	}
4344 
4345 	if (sess->ErrorRecoveryLevel >= 1) {
4346 		spdk_remove_acked_pdu(conn, ExpStatSN);
4347 	}
4348 
4349 	if (opcode == ISCSI_OP_NOPOUT || opcode == ISCSI_OP_SCSI) {
4350 		QCmdSN = sess->MaxCmdSN - sess->ExpCmdSN + 1;
4351 		QCmdSN += sess->queue_depth;
4352 		if (SN32_LT(ExpStatSN + QCmdSN, conn->StatSN)) {
4353 			SPDK_ERRLOG("StatSN(%u/%u) QCmdSN(%u) error\n",
4354 				    ExpStatSN, conn->StatSN, QCmdSN);
4355 			return SPDK_ISCSI_CONNECTION_FATAL;
4356 		}
4357 	}
4358 
4359 	if (!I_bit && opcode != ISCSI_OP_SCSI_DATAOUT) {
4360 		sess->ExpCmdSN++;
4361 	}
4362 
4363 	switch (opcode) {
4364 	case ISCSI_OP_NOPOUT:
4365 		rc = spdk_iscsi_op_nopout(conn, pdu);
4366 		if (rc < 0) {
4367 			SPDK_ERRLOG("spdk_iscsi_op_nopout() failed\n");
4368 			return rc;
4369 		}
4370 		break;
4371 
4372 	case ISCSI_OP_SCSI:
4373 		rc = spdk_iscsi_op_scsi(conn, pdu);
4374 		if (rc < 0) {
4375 			SPDK_ERRLOG("spdk_iscsi_op_scsi() failed\n");
4376 			return rc;
4377 		}
4378 		break;
4379 	case ISCSI_OP_TASK:
4380 		rc = spdk_iscsi_op_task(conn, pdu);
4381 		if (rc < 0) {
4382 			SPDK_ERRLOG("spdk_iscsi_op_task() failed\n");
4383 			return rc;
4384 		}
4385 		break;
4386 
4387 	case ISCSI_OP_TEXT:
4388 		rc = spdk_iscsi_op_text(conn, pdu);
4389 		if (rc < 0) {
4390 			SPDK_ERRLOG("spdk_iscsi_op_text() failed\n");
4391 			return rc;
4392 		}
4393 		break;
4394 
4395 	case ISCSI_OP_LOGOUT:
4396 		rc = spdk_iscsi_op_logout(conn, pdu);
4397 		if (rc < 0) {
4398 			SPDK_ERRLOG("spdk_iscsi_op_logout() failed\n");
4399 			return rc;
4400 		}
4401 		break;
4402 
4403 	case ISCSI_OP_SCSI_DATAOUT:
4404 		rc = spdk_iscsi_op_data(conn, pdu);
4405 		if (rc < 0) {
4406 			SPDK_ERRLOG("spdk_iscsi_op_data() failed\n");
4407 			return rc;
4408 		}
4409 		break;
4410 
4411 	case ISCSI_OP_SNACK:
4412 		rc = spdk_iscsi_op_snack(conn, pdu);
4413 		if (rc < 0) {
4414 			SPDK_ERRLOG("spdk_iscsi_op_snack() failed\n");
4415 			return rc;
4416 		}
4417 		break;
4418 
4419 	default:
4420 		SPDK_ERRLOG("unsupported opcode %x\n", opcode);
4421 		rc = spdk_iscsi_reject(conn, pdu, ISCSI_REASON_PROTOCOL_ERROR);
4422 		if (rc < 0) {
4423 			SPDK_ERRLOG("spdk_iscsi_reject() failed\n");
4424 			return rc;
4425 		}
4426 		break;
4427 	}
4428 
4429 	return 0;
4430 }
4431 
4432 void spdk_free_sess(struct spdk_iscsi_sess *sess)
4433 {
4434 	if (sess == NULL) {
4435 		return;
4436 	}
4437 
4438 	sess->tag = 0;
4439 	sess->target = NULL;
4440 	sess->session_type = SESSION_TYPE_INVALID;
4441 	spdk_iscsi_param_free(sess->params);
4442 	free(sess->conns);
4443 	spdk_scsi_port_free(&sess->initiator_port);
4444 	spdk_mempool_put(g_spdk_iscsi.session_pool, (void *)sess);
4445 }
4446 
4447 static int
4448 spdk_create_iscsi_sess(struct spdk_iscsi_conn *conn,
4449 		       struct spdk_iscsi_tgt_node *target,
4450 		       enum session_type session_type)
4451 {
4452 	struct spdk_iscsi_sess *sess;
4453 	int rc;
4454 
4455 	sess = spdk_mempool_get(g_spdk_iscsi.session_pool);
4456 	if (!sess) {
4457 		SPDK_ERRLOG("Unable to get session object\n");
4458 		SPDK_ERRLOG("MaxSessions set to %d\n", g_spdk_iscsi.MaxSessions);
4459 		return -ENOMEM;
4460 	}
4461 
4462 	/* configuration values */
4463 	pthread_mutex_lock(&g_spdk_iscsi.mutex);
4464 
4465 	sess->MaxConnections = g_spdk_iscsi.MaxConnectionsPerSession;
4466 	sess->MaxOutstandingR2T = DEFAULT_MAXOUTSTANDINGR2T;
4467 
4468 	sess->DefaultTime2Wait = g_spdk_iscsi.DefaultTime2Wait;
4469 	sess->DefaultTime2Retain = g_spdk_iscsi.DefaultTime2Retain;
4470 	sess->FirstBurstLength = SPDK_ISCSI_FIRST_BURST_LENGTH;
4471 	sess->MaxBurstLength = SPDK_ISCSI_MAX_BURST_LENGTH;
4472 	sess->InitialR2T = DEFAULT_INITIALR2T;
4473 	sess->ImmediateData = g_spdk_iscsi.ImmediateData;
4474 	sess->DataPDUInOrder = DEFAULT_DATAPDUINORDER;
4475 	sess->DataSequenceInOrder = DEFAULT_DATASEQUENCEINORDER;
4476 	sess->ErrorRecoveryLevel = g_spdk_iscsi.ErrorRecoveryLevel;
4477 
4478 	pthread_mutex_unlock(&g_spdk_iscsi.mutex);
4479 
4480 	sess->tag = conn->portal->group->tag;
4481 
4482 	sess->conns = calloc(sess->MaxConnections, sizeof(*sess->conns));
4483 	if (!sess->conns) {
4484 		SPDK_ERRLOG("calloc() failed for connection array\n");
4485 		return -ENOMEM;
4486 	}
4487 
4488 	sess->connections = 0;
4489 
4490 	sess->conns[sess->connections] = conn;
4491 	sess->connections++;
4492 
4493 	sess->params = NULL;
4494 	sess->target = NULL;
4495 	sess->isid = 0;
4496 	sess->session_type = session_type;
4497 	sess->current_text_itt = 0xffffffffU;
4498 
4499 	/* set default params */
4500 	rc = spdk_iscsi_sess_params_init(&sess->params);
4501 	if (rc < 0) {
4502 		SPDK_ERRLOG("iscsi_sess_params_init() failed\n");
4503 		goto error_return;
4504 	}
4505 	/* replace with config value */
4506 	rc = spdk_iscsi_param_set_int(sess->params, "MaxConnections",
4507 				      sess->MaxConnections);
4508 	if (rc < 0) {
4509 		SPDK_ERRLOG("iscsi_param_set_int() failed\n");
4510 		goto error_return;
4511 	}
4512 
4513 	rc = spdk_iscsi_param_set_int(sess->params, "MaxOutstandingR2T",
4514 				      sess->MaxOutstandingR2T);
4515 	if (rc < 0) {
4516 		SPDK_ERRLOG("iscsi_param_set_int() failed\n");
4517 		goto error_return;
4518 	}
4519 
4520 	rc = spdk_iscsi_param_set_int(sess->params, "DefaultTime2Wait",
4521 				      sess->DefaultTime2Wait);
4522 	if (rc < 0) {
4523 		SPDK_ERRLOG("iscsi_param_set_int() failed\n");
4524 		goto error_return;
4525 	}
4526 
4527 	rc = spdk_iscsi_param_set_int(sess->params, "DefaultTime2Retain",
4528 				      sess->DefaultTime2Retain);
4529 	if (rc < 0) {
4530 		SPDK_ERRLOG("iscsi_param_set_int() failed\n");
4531 		goto error_return;
4532 	}
4533 
4534 	rc = spdk_iscsi_param_set_int(sess->params, "FirstBurstLength",
4535 				      sess->FirstBurstLength);
4536 	if (rc < 0) {
4537 		SPDK_ERRLOG("iscsi_param_set_int() failed\n");
4538 		goto error_return;
4539 	}
4540 
4541 	rc = spdk_iscsi_param_set_int(sess->params, "MaxBurstLength",
4542 				      sess->MaxBurstLength);
4543 	if (rc < 0) {
4544 		SPDK_ERRLOG("iscsi_param_set_int() failed\n");
4545 		goto error_return;
4546 	}
4547 
4548 	rc = spdk_iscsi_param_set(sess->params, "InitialR2T",
4549 				  sess->InitialR2T ? "Yes" : "No");
4550 	if (rc < 0) {
4551 		SPDK_ERRLOG("iscsi_param_set() failed\n");
4552 		goto error_return;
4553 	}
4554 
4555 	rc = spdk_iscsi_param_set(sess->params, "ImmediateData",
4556 				  sess->ImmediateData ? "Yes" : "No");
4557 	if (rc < 0) {
4558 		SPDK_ERRLOG("iscsi_param_set() failed\n");
4559 		goto error_return;
4560 	}
4561 
4562 	rc = spdk_iscsi_param_set(sess->params, "DataPDUInOrder",
4563 				  sess->DataPDUInOrder ? "Yes" : "No");
4564 	if (rc < 0) {
4565 		SPDK_ERRLOG("iscsi_param_set() failed\n");
4566 		goto error_return;
4567 	}
4568 
4569 	rc = spdk_iscsi_param_set(sess->params, "DataSequenceInOrder",
4570 				  sess->DataSequenceInOrder ? "Yes" : "No");
4571 	if (rc < 0) {
4572 		SPDK_ERRLOG("iscsi_param_set() failed\n");
4573 		goto error_return;
4574 	}
4575 
4576 	rc = spdk_iscsi_param_set_int(sess->params, "ErrorRecoveryLevel",
4577 				      sess->ErrorRecoveryLevel);
4578 	if (rc < 0) {
4579 		SPDK_ERRLOG("iscsi_param_set_int() failed\n");
4580 		goto error_return;
4581 	}
4582 
4583 	/* realloc buffer */
4584 	rc = spdk_iscsi_param_set_int(conn->params, "MaxRecvDataSegmentLength",
4585 				      conn->MaxRecvDataSegmentLength);
4586 	if (rc < 0) {
4587 		SPDK_ERRLOG("iscsi_param_set_int() failed\n");
4588 		goto error_return;
4589 	}
4590 
4591 	/* sess for first connection of session */
4592 	conn->sess = sess;
4593 	return 0;
4594 
4595 error_return:
4596 	spdk_free_sess(sess);
4597 	conn->sess = NULL;
4598 	return -1;
4599 }
4600 
4601 static struct spdk_iscsi_sess *
4602 spdk_get_iscsi_sess_by_tsih(uint16_t tsih)
4603 {
4604 	struct spdk_iscsi_sess *session;
4605 
4606 	if (tsih == 0 || tsih > g_spdk_iscsi.MaxSessions) {
4607 		return NULL;
4608 	}
4609 
4610 	session = g_spdk_iscsi.session[tsih - 1];
4611 	assert(tsih == session->tsih);
4612 
4613 	return session;
4614 }
4615 
4616 static int
4617 spdk_append_iscsi_sess(struct spdk_iscsi_conn *conn,
4618 		       const char *initiator_port_name, uint16_t tsih, uint16_t cid)
4619 {
4620 	struct spdk_iscsi_sess *sess;
4621 
4622 	SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "append session: init port name=%s, tsih=%u, cid=%u\n",
4623 		      initiator_port_name, tsih, cid);
4624 
4625 	sess = spdk_get_iscsi_sess_by_tsih(tsih);
4626 	if (sess == NULL) {
4627 		SPDK_ERRLOG("spdk_get_iscsi_sess_by_tsih failed\n");
4628 		return -1;
4629 	}
4630 	if ((conn->portal->group->tag != sess->tag) ||
4631 	    (strcasecmp(initiator_port_name, spdk_scsi_port_get_name(sess->initiator_port)) != 0) ||
4632 	    (conn->target != sess->target)) {
4633 		/* no match */
4634 		SPDK_ERRLOG("no MCS session for init port name=%s, tsih=%d, cid=%d\n",
4635 			    initiator_port_name, tsih, cid);
4636 		return -1;
4637 	}
4638 
4639 	if (sess->connections >= sess->MaxConnections) {
4640 		/* no slot for connection */
4641 		SPDK_ERRLOG("too many connections for init port name=%s, tsih=%d, cid=%d\n",
4642 			    initiator_port_name, tsih, cid);
4643 		return -1;
4644 	}
4645 
4646 	SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Connections (tsih %d): %d\n", sess->tsih, sess->connections);
4647 	conn->sess = sess;
4648 
4649 	/*
4650 	 * TODO: need a mutex or other sync mechanism to protect the session's
4651 	 *  connection list.
4652 	 */
4653 	sess->conns[sess->connections] = conn;
4654 	sess->connections++;
4655 
4656 	return 0;
4657 }
4658 
4659 bool spdk_iscsi_is_deferred_free_pdu(struct spdk_iscsi_pdu *pdu)
4660 {
4661 	if (pdu == NULL) {
4662 		return false;
4663 	}
4664 
4665 	if (pdu->bhs.opcode == ISCSI_OP_R2T ||
4666 	    pdu->bhs.opcode == ISCSI_OP_SCSI_DATAIN) {
4667 		return true;
4668 	}
4669 
4670 	return false;
4671 }
4672