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