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