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