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