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