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