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