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