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