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