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