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