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