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