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