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