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_ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH) { 433 pool = g_spdk_iscsi.pdu_data_out_pool; 434 } else { 435 SPDK_ERRLOG("Data(%d) > MaxSegment(%d)\n", 436 data_len, SPDK_ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH); 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 = SPDK_ISCSI_FIRST_BURST_LENGTH; 515 } else if (pdu->bhs.opcode == ISCSI_OP_SCSI_DATAOUT) { 516 max_segment_len = SPDK_ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH; 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 = true; 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->mutual_chap) { 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_LOGDUMP(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_LOGDUMP(SPDK_LOG_ISCSI, "PDU", (uint8_t *)rsph, ISCSI_BHS_LEN); 1094 SPDK_LOGDUMP(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 static int 1169 spdk_iscsi_negotiate_chap_param(struct spdk_iscsi_conn *conn, bool disable_chap, 1170 bool require_chap, bool mutual_chap) 1171 { 1172 int rc = 0; 1173 1174 if (disable_chap) { 1175 conn->require_chap = false; 1176 rc = spdk_iscsi_op_login_update_param(conn, "AuthMethod", "None", "None"); 1177 if (rc < 0) { 1178 return rc; 1179 } 1180 } else if (require_chap) { 1181 conn->require_chap = true; 1182 rc = spdk_iscsi_op_login_update_param(conn, "AuthMethod", "CHAP", "CHAP"); 1183 if (rc < 0) { 1184 return rc; 1185 } 1186 } 1187 if (mutual_chap) { 1188 conn->mutual_chap = true; 1189 } 1190 1191 return rc; 1192 } 1193 1194 /* 1195 * The function which is used to handle the part of session discovery 1196 * return: 1197 * 0, success; 1198 * otherwise: error; 1199 */ 1200 static int 1201 spdk_iscsi_op_login_session_discovery_chap(struct spdk_iscsi_conn *conn) 1202 { 1203 return spdk_iscsi_negotiate_chap_param(conn, g_spdk_iscsi.disable_chap, 1204 g_spdk_iscsi.require_chap, 1205 g_spdk_iscsi.mutual_chap); 1206 } 1207 1208 /* 1209 * This function is used to update the param related with chap 1210 * return: 1211 * 0: success 1212 * otherwise: error 1213 */ 1214 static int 1215 spdk_iscsi_op_login_negotiate_chap_param(struct spdk_iscsi_conn *conn, 1216 struct spdk_iscsi_tgt_node *target) 1217 { 1218 return spdk_iscsi_negotiate_chap_param(conn, target->disable_chap, 1219 target->require_chap, 1220 target->mutual_chap); 1221 } 1222 1223 static int 1224 spdk_iscsi_op_login_negotiate_digest_param(struct spdk_iscsi_conn *conn, 1225 struct spdk_iscsi_tgt_node *target) 1226 { 1227 int rc; 1228 1229 if (target->header_digest) { 1230 /* 1231 * User specified header digests, so update the list of 1232 * HeaderDigest values to remove "None" so that only 1233 * initiators who support CRC32C can connect. 1234 */ 1235 rc = spdk_iscsi_op_login_update_param(conn, "HeaderDigest", "CRC32C", "CRC32C"); 1236 if (rc < 0) { 1237 return rc; 1238 } 1239 } 1240 1241 if (target->data_digest) { 1242 /* 1243 * User specified data digests, so update the list of 1244 * DataDigest values to remove "None" so that only 1245 * initiators who support CRC32C can connect. 1246 */ 1247 rc = spdk_iscsi_op_login_update_param(conn, "DataDigest", "CRC32C", "CRC32C"); 1248 if (rc < 0) { 1249 return rc; 1250 } 1251 } 1252 1253 return 0; 1254 } 1255 1256 /* 1257 * This function use to check the session 1258 * return: 1259 * 0, success 1260 * otherwise: error 1261 */ 1262 static int 1263 spdk_iscsi_op_login_check_session(struct spdk_iscsi_conn *conn, 1264 struct spdk_iscsi_pdu *rsp_pdu, 1265 char *initiator_port_name, int cid) 1266 1267 { 1268 int rc = 0; 1269 struct iscsi_bhs_login_rsp *rsph; 1270 1271 rsph = (struct iscsi_bhs_login_rsp *)&rsp_pdu->bhs; 1272 /* check existing session */ 1273 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "isid=%"PRIx64", tsih=%u, cid=%u\n", 1274 spdk_iscsi_get_isid(rsph->isid), from_be16(&rsph->tsih), cid); 1275 if (rsph->tsih != 0) { 1276 /* multiple connections */ 1277 rc = spdk_append_iscsi_sess(conn, initiator_port_name, 1278 from_be16(&rsph->tsih), cid); 1279 if (rc < 0) { 1280 SPDK_ERRLOG("isid=%"PRIx64", tsih=%u, cid=%u:" 1281 "spdk_append_iscsi_sess() failed\n", 1282 spdk_iscsi_get_isid(rsph->isid), from_be16(&rsph->tsih), 1283 cid); 1284 /* Can't include in session */ 1285 rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR; 1286 rsph->status_detail = ISCSI_LOGIN_CONN_ADD_FAIL; 1287 return SPDK_ISCSI_LOGIN_ERROR_RESPONSE; 1288 } 1289 } else if (!g_spdk_iscsi.AllowDuplicateIsid) { 1290 /* new session, drop old sess by the initiator */ 1291 spdk_iscsi_drop_conns(conn, initiator_port_name, 0 /* drop old */); 1292 } 1293 1294 return rc; 1295 } 1296 1297 /* 1298 * This function is used to check the target info 1299 * return: 1300 * 0: success 1301 * otherwise: error 1302 */ 1303 static int 1304 spdk_iscsi_op_login_check_target(struct spdk_iscsi_conn *conn, 1305 struct spdk_iscsi_pdu *rsp_pdu, 1306 const char *target_name, 1307 struct spdk_iscsi_tgt_node **target) 1308 { 1309 bool result; 1310 struct iscsi_bhs_login_rsp *rsph; 1311 1312 rsph = (struct iscsi_bhs_login_rsp *)&rsp_pdu->bhs; 1313 *target = spdk_iscsi_find_tgt_node(target_name); 1314 if (*target == NULL) { 1315 SPDK_WARNLOG("target %s not found\n", target_name); 1316 /* Not found */ 1317 rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR; 1318 rsph->status_detail = ISCSI_LOGIN_TARGET_NOT_FOUND; 1319 return SPDK_ISCSI_LOGIN_ERROR_RESPONSE; 1320 } 1321 result = spdk_iscsi_tgt_node_access(conn, *target, 1322 conn->initiator_name, 1323 conn->initiator_addr); 1324 if (!result) { 1325 SPDK_ERRLOG("access denied\n"); 1326 /* Not found */ 1327 rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR; 1328 rsph->status_detail = ISCSI_LOGIN_TARGET_NOT_FOUND; 1329 return SPDK_ISCSI_LOGIN_ERROR_RESPONSE; 1330 } 1331 1332 return 0; 1333 } 1334 1335 /* 1336 * The function which is used to handle the part of normal login session 1337 * return: 1338 * 0, success; 1339 * SPDK_ISCSI_LOGIN_ERROR_PARAMETER, parameter error; 1340 */ 1341 static int 1342 spdk_iscsi_op_login_session_normal(struct spdk_iscsi_conn *conn, 1343 struct spdk_iscsi_pdu *rsp_pdu, 1344 char *initiator_port_name, 1345 struct iscsi_param *params, 1346 struct spdk_iscsi_tgt_node **target, 1347 int cid) 1348 { 1349 const char *target_name; 1350 const char *target_short_name; 1351 struct iscsi_bhs_login_rsp *rsph; 1352 int rc = 0; 1353 1354 rsph = (struct iscsi_bhs_login_rsp *)&rsp_pdu->bhs; 1355 target_name = spdk_iscsi_param_get_val(params, "TargetName"); 1356 1357 if (target_name == NULL) { 1358 SPDK_ERRLOG("TargetName is empty\n"); 1359 /* Missing parameter */ 1360 rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR; 1361 rsph->status_detail = ISCSI_LOGIN_MISSING_PARMS; 1362 return SPDK_ISCSI_LOGIN_ERROR_RESPONSE; 1363 } 1364 1365 memset(conn->target_short_name, 0, MAX_TARGET_NAME); 1366 target_short_name = strstr(target_name, ":"); 1367 if (target_short_name != NULL) { 1368 target_short_name++; /* Advance past the ':' */ 1369 if (strlen(target_short_name) >= MAX_TARGET_NAME) { 1370 SPDK_ERRLOG("Target Short Name (%s) is more than %u characters\n", 1371 target_short_name, MAX_TARGET_NAME); 1372 return rc; 1373 } 1374 snprintf(conn->target_short_name, MAX_TARGET_NAME, "%s", 1375 target_short_name); 1376 } 1377 1378 pthread_mutex_lock(&g_spdk_iscsi.mutex); 1379 rc = spdk_iscsi_op_login_check_target(conn, rsp_pdu, target_name, target); 1380 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 1381 1382 if (rc < 0) { 1383 return rc; 1384 } 1385 1386 conn->target = *target; 1387 conn->dev = (*target)->dev; 1388 conn->target_port = spdk_scsi_dev_find_port_by_id((*target)->dev, 1389 conn->portal->group->tag); 1390 1391 rc = spdk_iscsi_op_login_check_session(conn, rsp_pdu, 1392 initiator_port_name, cid); 1393 if (rc < 0) { 1394 return rc; 1395 } 1396 1397 /* force target flags */ 1398 pthread_mutex_lock(&((*target)->mutex)); 1399 rc = spdk_iscsi_op_login_negotiate_chap_param(conn, *target); 1400 pthread_mutex_unlock(&((*target)->mutex)); 1401 1402 if (rc != 0) { 1403 return rc; 1404 } 1405 1406 return spdk_iscsi_op_login_negotiate_digest_param(conn, *target); 1407 } 1408 1409 /* 1410 * This function is used to judge the session type 1411 * return 1412 * 0: success 1413 * otherwise, error 1414 */ 1415 static int 1416 spdk_iscsi_op_login_session_type(struct spdk_iscsi_conn *conn, 1417 struct spdk_iscsi_pdu *rsp_pdu, 1418 enum session_type *session_type, 1419 struct iscsi_param *params) 1420 { 1421 const char *session_type_str; 1422 struct iscsi_bhs_login_rsp *rsph; 1423 1424 rsph = (struct iscsi_bhs_login_rsp *)&rsp_pdu->bhs; 1425 session_type_str = spdk_iscsi_param_get_val(params, "SessionType"); 1426 if (session_type_str == NULL) { 1427 if (rsph->tsih != 0) { 1428 *session_type = SESSION_TYPE_NORMAL; 1429 } else { 1430 SPDK_ERRLOG("SessionType is empty\n"); 1431 /* Missing parameter */ 1432 rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR; 1433 rsph->status_detail = ISCSI_LOGIN_MISSING_PARMS; 1434 return SPDK_ISCSI_LOGIN_ERROR_RESPONSE; 1435 } 1436 } else { 1437 if (strcasecmp(session_type_str, "Discovery") == 0) { 1438 *session_type = SESSION_TYPE_DISCOVERY; 1439 } else if (strcasecmp(session_type_str, "Normal") == 0) { 1440 *session_type = SESSION_TYPE_NORMAL; 1441 } else { 1442 *session_type = SESSION_TYPE_INVALID; 1443 SPDK_ERRLOG("SessionType is invalid\n"); 1444 /* Missing parameter */ 1445 rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR; 1446 rsph->status_detail = ISCSI_LOGIN_MISSING_PARMS; 1447 return SPDK_ISCSI_LOGIN_ERROR_RESPONSE; 1448 } 1449 } 1450 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Session Type: %s\n", session_type_str); 1451 1452 return 0; 1453 } 1454 /* 1455 * This function is used to initialize the port info 1456 * return 1457 * 0: success 1458 * otherwise: error 1459 */ 1460 static int 1461 spdk_iscsi_op_login_initialize_port(struct spdk_iscsi_conn *conn, 1462 struct spdk_iscsi_pdu *rsp_pdu, 1463 char *initiator_port_name, 1464 uint32_t name_length, 1465 struct iscsi_param *params) 1466 { 1467 const char *val; 1468 struct iscsi_bhs_login_rsp *rsph; 1469 rsph = (struct iscsi_bhs_login_rsp *)&rsp_pdu->bhs; 1470 1471 /* Initiator Name and Port */ 1472 val = spdk_iscsi_param_get_val(params, "InitiatorName"); 1473 if (val == NULL) { 1474 SPDK_ERRLOG("InitiatorName is empty\n"); 1475 /* Missing parameter */ 1476 rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR; 1477 rsph->status_detail = ISCSI_LOGIN_MISSING_PARMS; 1478 return SPDK_ISCSI_LOGIN_ERROR_RESPONSE; 1479 } 1480 snprintf(conn->initiator_name, sizeof(conn->initiator_name), "%s", val); 1481 snprintf(initiator_port_name, name_length, 1482 "%s,i,0x%12.12" PRIx64, val, spdk_iscsi_get_isid(rsph->isid)); 1483 spdk_strlwr(conn->initiator_name); 1484 spdk_strlwr(initiator_port_name); 1485 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Initiator name: %s\n", conn->initiator_name); 1486 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Initiator port: %s\n", initiator_port_name); 1487 1488 return 0; 1489 } 1490 1491 /* 1492 * This function is used to set the info in the connection data structure 1493 * return 1494 * 0: success 1495 * otherwise: error 1496 */ 1497 static int 1498 spdk_iscsi_op_login_set_conn_info(struct spdk_iscsi_conn *conn, 1499 struct spdk_iscsi_pdu *rsp_pdu, 1500 char *initiator_port_name, 1501 enum session_type session_type, 1502 struct spdk_iscsi_tgt_node *target, int cid) 1503 { 1504 int rc = 0; 1505 struct iscsi_bhs_login_rsp *rsph; 1506 struct spdk_scsi_port *initiator_port; 1507 1508 rsph = (struct iscsi_bhs_login_rsp *)&rsp_pdu->bhs; 1509 conn->authenticated = false; 1510 conn->auth.chap_phase = ISCSI_CHAP_PHASE_WAIT_A; 1511 conn->cid = cid; 1512 1513 if (conn->sess == NULL) { 1514 /* create initiator port */ 1515 initiator_port = spdk_scsi_port_create(spdk_iscsi_get_isid(rsph->isid), 0, initiator_port_name); 1516 if (initiator_port == NULL) { 1517 SPDK_ERRLOG("create_port() failed\n"); 1518 rsph->status_class = ISCSI_CLASS_TARGET_ERROR; 1519 rsph->status_detail = ISCSI_LOGIN_STATUS_NO_RESOURCES; 1520 return SPDK_ISCSI_LOGIN_ERROR_RESPONSE; 1521 } 1522 1523 /* new session */ 1524 rc = spdk_create_iscsi_sess(conn, target, session_type); 1525 if (rc < 0) { 1526 spdk_scsi_port_free(&initiator_port); 1527 SPDK_ERRLOG("create_sess() failed\n"); 1528 rsph->status_class = ISCSI_CLASS_TARGET_ERROR; 1529 rsph->status_detail = ISCSI_LOGIN_STATUS_NO_RESOURCES; 1530 return SPDK_ISCSI_LOGIN_ERROR_RESPONSE; 1531 } 1532 /* initialize parameters */ 1533 conn->sess->initiator_port = initiator_port; 1534 conn->StatSN = from_be32(&rsph->stat_sn); 1535 conn->sess->isid = spdk_iscsi_get_isid(rsph->isid); 1536 conn->sess->target = target; 1537 1538 /* Initiator port TransportID */ 1539 spdk_scsi_port_set_iscsi_transport_id(conn->sess->initiator_port, 1540 conn->initiator_name, 1541 conn->sess->isid); 1542 1543 /* Discovery sessions will not have a target. */ 1544 if (target != NULL) { 1545 conn->sess->queue_depth = target->queue_depth; 1546 } else { 1547 /* 1548 * Assume discovery sessions have an effective command 1549 * windows size of 1. 1550 */ 1551 conn->sess->queue_depth = 1; 1552 } 1553 conn->sess->ExpCmdSN = rsp_pdu->cmd_sn; 1554 conn->sess->MaxCmdSN = rsp_pdu->cmd_sn + conn->sess->queue_depth - 1; 1555 } 1556 1557 conn->initiator_port = conn->sess->initiator_port; 1558 1559 return 0; 1560 } 1561 1562 /* 1563 * This function is used to set the target info 1564 * return 1565 * 0: success 1566 * otherwise: error 1567 */ 1568 static int 1569 spdk_iscsi_op_login_set_target_info(struct spdk_iscsi_conn *conn, 1570 struct spdk_iscsi_pdu *rsp_pdu, 1571 enum session_type session_type, 1572 int alloc_len, 1573 struct spdk_iscsi_tgt_node *target) 1574 { 1575 char buf[MAX_TMPBUF]; 1576 const char *val; 1577 int rc = 0; 1578 struct spdk_iscsi_portal *portal = conn->portal; 1579 1580 /* declarative parameters */ 1581 if (target != NULL) { 1582 pthread_mutex_lock(&target->mutex); 1583 if (target->alias != NULL) { 1584 snprintf(buf, sizeof buf, "%s", target->alias); 1585 } else { 1586 snprintf(buf, sizeof buf, "%s", ""); 1587 } 1588 pthread_mutex_unlock(&target->mutex); 1589 rc = spdk_iscsi_param_set(conn->sess->params, "TargetAlias", buf); 1590 if (rc < 0) { 1591 SPDK_ERRLOG("iscsi_param_set() failed\n"); 1592 return SPDK_ISCSI_LOGIN_ERROR_PARAMETER; 1593 } 1594 } 1595 snprintf(buf, sizeof buf, "%s:%s,%d", portal->host, portal->port, 1596 portal->group->tag); 1597 rc = spdk_iscsi_param_set(conn->sess->params, "TargetAddress", buf); 1598 if (rc < 0) { 1599 SPDK_ERRLOG("iscsi_param_set() failed\n"); 1600 return SPDK_ISCSI_LOGIN_ERROR_PARAMETER; 1601 } 1602 snprintf(buf, sizeof buf, "%d", portal->group->tag); 1603 rc = spdk_iscsi_param_set(conn->sess->params, "TargetPortalGroupTag", buf); 1604 if (rc < 0) { 1605 SPDK_ERRLOG("iscsi_param_set() failed\n"); 1606 return SPDK_ISCSI_LOGIN_ERROR_PARAMETER; 1607 } 1608 1609 /* write in response */ 1610 if (target != NULL) { 1611 val = spdk_iscsi_param_get_val(conn->sess->params, "TargetAlias"); 1612 if (val != NULL && strlen(val) != 0) { 1613 rsp_pdu->data_segment_len = spdk_iscsi_append_param(conn, 1614 "TargetAlias", 1615 rsp_pdu->data, 1616 alloc_len, 1617 rsp_pdu->data_segment_len); 1618 } 1619 if (session_type == SESSION_TYPE_DISCOVERY) { 1620 rsp_pdu->data_segment_len = spdk_iscsi_append_param(conn, 1621 "TargetAddress", 1622 rsp_pdu->data, 1623 alloc_len, 1624 rsp_pdu->data_segment_len); 1625 } 1626 rsp_pdu->data_segment_len = spdk_iscsi_append_param(conn, 1627 "TargetPortalGroupTag", 1628 rsp_pdu->data, 1629 alloc_len, 1630 rsp_pdu->data_segment_len); 1631 } 1632 1633 return rc; 1634 } 1635 1636 /* 1637 * This function is used to handle the login of iscsi initiator when there is 1638 * no session 1639 * return: 1640 * 0, success; 1641 * SPDK_ISCSI_LOGIN_ERROR_PARAMETER, parameter error; 1642 * SPDK_ISCSI_LOGIN_ERROR_RESPONSE, used to notify the login fail. 1643 */ 1644 static int 1645 spdk_iscsi_op_login_phase_none(struct spdk_iscsi_conn *conn, 1646 struct spdk_iscsi_pdu *rsp_pdu, 1647 struct iscsi_param *params, 1648 int alloc_len, int cid) 1649 { 1650 enum session_type session_type; 1651 char initiator_port_name[MAX_INITIATOR_PORT_NAME]; 1652 struct iscsi_bhs_login_rsp *rsph; 1653 struct spdk_iscsi_tgt_node *target = NULL; 1654 int rc = 0; 1655 rsph = (struct iscsi_bhs_login_rsp *)&rsp_pdu->bhs; 1656 1657 conn->target = NULL; 1658 conn->dev = NULL; 1659 1660 rc = spdk_iscsi_op_login_initialize_port(conn, rsp_pdu, 1661 initiator_port_name, MAX_INITIATOR_PORT_NAME, params); 1662 if (rc < 0) { 1663 return rc; 1664 } 1665 1666 rc = spdk_iscsi_op_login_session_type(conn, rsp_pdu, &session_type, 1667 params); 1668 if (rc < 0) { 1669 return rc; 1670 } 1671 1672 /* Target Name and Port */ 1673 if (session_type == SESSION_TYPE_NORMAL) { 1674 rc = spdk_iscsi_op_login_session_normal(conn, rsp_pdu, 1675 initiator_port_name, 1676 params, &target, cid); 1677 if (rc < 0) { 1678 return rc; 1679 } 1680 1681 } else if (session_type == SESSION_TYPE_DISCOVERY) { 1682 target = NULL; 1683 rsph->tsih = 0; 1684 1685 /* force target flags */ 1686 pthread_mutex_lock(&g_spdk_iscsi.mutex); 1687 rc = spdk_iscsi_op_login_session_discovery_chap(conn); 1688 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 1689 if (rc < 0) { 1690 return rc; 1691 } 1692 } else { 1693 SPDK_ERRLOG("unknown session type\n"); 1694 /* Missing parameter */ 1695 rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR; 1696 rsph->status_detail = ISCSI_LOGIN_MISSING_PARMS; 1697 return SPDK_ISCSI_LOGIN_ERROR_RESPONSE; 1698 } 1699 1700 rc = spdk_iscsi_op_login_set_conn_info(conn, rsp_pdu, initiator_port_name, 1701 session_type, target, cid); 1702 if (rc < 0) { 1703 return rc; 1704 } 1705 1706 /* limit conns on discovery session */ 1707 if (session_type == SESSION_TYPE_DISCOVERY) { 1708 conn->sess->MaxConnections = 1; 1709 rc = spdk_iscsi_param_set_int(conn->sess->params, 1710 "MaxConnections", 1711 conn->sess->MaxConnections); 1712 if (rc < 0) { 1713 SPDK_ERRLOG("iscsi_param_set_int() failed\n"); 1714 return SPDK_ISCSI_LOGIN_ERROR_PARAMETER; 1715 } 1716 } 1717 1718 return spdk_iscsi_op_login_set_target_info(conn, rsp_pdu, session_type, 1719 alloc_len, target); 1720 } 1721 1722 /* 1723 * The function which is used to initialize the internal response data 1724 * structure of iscsi login function. 1725 * return: 1726 * 0, success; 1727 * otherwise, error; 1728 */ 1729 static int 1730 spdk_iscsi_op_login_rsp_init(struct spdk_iscsi_conn *conn, 1731 struct spdk_iscsi_pdu *pdu, struct spdk_iscsi_pdu *rsp_pdu, 1732 struct iscsi_param **params, int *alloc_len, int *cid) 1733 { 1734 1735 struct iscsi_bhs_login_req *reqh; 1736 struct iscsi_bhs_login_rsp *rsph; 1737 int rc; 1738 1739 rsph = (struct iscsi_bhs_login_rsp *)&rsp_pdu->bhs; 1740 rsph->opcode = ISCSI_OP_LOGIN_RSP; 1741 rsph->status_class = ISCSI_CLASS_SUCCESS; 1742 rsph->status_detail = ISCSI_LOGIN_ACCEPT; 1743 rsp_pdu->data_segment_len = 0; 1744 1745 /* Default MaxRecvDataSegmentLength - RFC3720(12.12) */ 1746 if (conn->MaxRecvDataSegmentLength < 8192) { 1747 *alloc_len = 8192; 1748 } else { 1749 *alloc_len = conn->MaxRecvDataSegmentLength; 1750 } 1751 1752 rsp_pdu->data = calloc(1, *alloc_len); 1753 if (!rsp_pdu->data) { 1754 SPDK_ERRLOG("calloc() failed for data segment\n"); 1755 return -ENOMEM; 1756 } 1757 1758 reqh = (struct iscsi_bhs_login_req *)&pdu->bhs; 1759 rsph->flags |= (reqh->flags & ISCSI_LOGIN_TRANSIT); 1760 rsph->flags |= (reqh->flags & ISCSI_LOGIN_CONTINUE); 1761 rsph->flags |= (reqh->flags & ISCSI_LOGIN_CURRENT_STAGE_MASK); 1762 if (ISCSI_BHS_LOGIN_GET_TBIT(rsph->flags)) { 1763 rsph->flags |= (reqh->flags & ISCSI_LOGIN_NEXT_STAGE_MASK); 1764 } 1765 1766 /* We don't need to convert from network byte order. Just store it */ 1767 memcpy(&rsph->isid, reqh->isid, 6); 1768 rsph->tsih = reqh->tsih; 1769 rsph->itt = reqh->itt; 1770 rsp_pdu->cmd_sn = from_be32(&reqh->cmd_sn); 1771 *cid = from_be16(&reqh->cid); 1772 1773 if (rsph->tsih) { 1774 rsph->stat_sn = reqh->exp_stat_sn; 1775 } 1776 1777 SPDK_LOGDUMP(SPDK_LOG_ISCSI, "PDU", (uint8_t *)&pdu->bhs, ISCSI_BHS_LEN); 1778 1779 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, 1780 "T=%d, C=%d, CSG=%d, NSG=%d, Min=%d, Max=%d, ITT=%x\n", 1781 ISCSI_BHS_LOGIN_GET_TBIT(rsph->flags), 1782 ISCSI_BHS_LOGIN_GET_CBIT(rsph->flags), 1783 ISCSI_BHS_LOGIN_GET_CSG(rsph->flags), 1784 ISCSI_BHS_LOGIN_GET_NSG(rsph->flags), 1785 reqh->version_min, reqh->version_max, from_be32(&rsph->itt)); 1786 1787 if (conn->sess != NULL) { 1788 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, 1789 "CmdSN=%u, ExpStatSN=%u, StatSN=%u, ExpCmdSN=%u," 1790 "MaxCmdSN=%u\n", rsp_pdu->cmd_sn, 1791 from_be32(&rsph->stat_sn), conn->StatSN, 1792 conn->sess->ExpCmdSN, 1793 conn->sess->MaxCmdSN); 1794 } else { 1795 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, 1796 "CmdSN=%u, ExpStatSN=%u, StatSN=%u\n", 1797 rsp_pdu->cmd_sn, from_be32(&rsph->stat_sn), 1798 conn->StatSN); 1799 } 1800 1801 if (ISCSI_BHS_LOGIN_GET_TBIT(rsph->flags) && 1802 ISCSI_BHS_LOGIN_GET_CBIT(rsph->flags)) { 1803 SPDK_ERRLOG("transit error\n"); 1804 return SPDK_ISCSI_LOGIN_ERROR_RESPONSE; 1805 } 1806 /* make sure reqh->version_max < ISCSI_VERSION */ 1807 if (reqh->version_min > ISCSI_VERSION) { 1808 SPDK_ERRLOG("unsupported version %d/%d\n", reqh->version_min, 1809 reqh->version_max); 1810 /* Unsupported version */ 1811 /* set all reserved flag to zero */ 1812 rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR; 1813 rsph->status_detail = ISCSI_LOGIN_UNSUPPORTED_VERSION; 1814 return SPDK_ISCSI_LOGIN_ERROR_RESPONSE; 1815 } 1816 1817 if ((ISCSI_BHS_LOGIN_GET_NSG(rsph->flags) == ISCSI_NSG_RESERVED_CODE) && 1818 ISCSI_BHS_LOGIN_GET_TBIT(rsph->flags)) { 1819 /* set NSG to zero */ 1820 rsph->flags &= ~ISCSI_LOGIN_NEXT_STAGE_MASK; 1821 /* also set other bits to zero */ 1822 rsph->flags &= ~ISCSI_LOGIN_TRANSIT; 1823 rsph->flags &= ~ISCSI_LOGIN_CURRENT_STAGE_MASK; 1824 SPDK_ERRLOG("Received reserved NSG code: %d\n", ISCSI_NSG_RESERVED_CODE); 1825 /* Initiator error */ 1826 rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR; 1827 rsph->status_detail = ISCSI_LOGIN_INITIATOR_ERROR; 1828 return SPDK_ISCSI_LOGIN_ERROR_RESPONSE; 1829 } 1830 1831 /* store incoming parameters */ 1832 rc = spdk_iscsi_parse_params(params, pdu->data, 1833 pdu->data_segment_len, ISCSI_BHS_LOGIN_GET_CBIT(reqh->flags), 1834 &conn->partial_text_parameter); 1835 if (rc < 0) { 1836 SPDK_ERRLOG("iscsi_parse_params() failed\n"); 1837 rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR; 1838 rsph->status_detail = ISCSI_LOGIN_INITIATOR_ERROR; 1839 return SPDK_ISCSI_LOGIN_ERROR_PARAMETER; 1840 } 1841 return 0; 1842 } 1843 1844 /* 1845 * This function is used to set the csg bit case in rsp 1846 * return: 1847 * 0, success 1848 * otherwise: error 1849 */ 1850 static int 1851 spdk_iscsi_op_login_rsp_handle_csg_bit(struct spdk_iscsi_conn *conn, 1852 struct spdk_iscsi_pdu *rsp_pdu, 1853 struct iscsi_param *params, int alloc_len) 1854 { 1855 const char *auth_method; 1856 int rc; 1857 struct iscsi_bhs_login_rsp *rsph; 1858 rsph = (struct iscsi_bhs_login_rsp *)&rsp_pdu->bhs; 1859 1860 switch (ISCSI_BHS_LOGIN_GET_CSG(rsph->flags)) { 1861 case ISCSI_SECURITY_NEGOTIATION_PHASE: 1862 /* SecurityNegotiation */ 1863 auth_method = spdk_iscsi_param_get_val(conn->params, "AuthMethod"); 1864 if (auth_method == NULL) { 1865 SPDK_ERRLOG("AuthMethod is empty\n"); 1866 /* Missing parameter */ 1867 rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR; 1868 rsph->status_detail = ISCSI_LOGIN_MISSING_PARMS; 1869 return SPDK_ISCSI_LOGIN_ERROR_RESPONSE; 1870 } 1871 if (strcasecmp(auth_method, "None") == 0) { 1872 conn->authenticated = true; 1873 } else { 1874 rc = spdk_iscsi_auth_params(conn, params, auth_method, 1875 rsp_pdu->data, alloc_len, 1876 rsp_pdu->data_segment_len); 1877 if (rc < 0) { 1878 SPDK_ERRLOG("iscsi_auth_params() failed\n"); 1879 /* Authentication failure */ 1880 rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR; 1881 rsph->status_detail = ISCSI_LOGIN_AUTHENT_FAIL; 1882 return SPDK_ISCSI_LOGIN_ERROR_RESPONSE; 1883 } 1884 rsp_pdu->data_segment_len = rc; 1885 if (!conn->authenticated) { 1886 /* not complete */ 1887 rsph->flags &= ~ISCSI_LOGIN_TRANSIT; 1888 } else { 1889 if (conn->auth.chap_phase != ISCSI_CHAP_PHASE_END) { 1890 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "CHAP phase not complete"); 1891 } 1892 } 1893 1894 SPDK_LOGDUMP(SPDK_LOG_ISCSI, "Negotiated Auth Params", 1895 rsp_pdu->data, rsp_pdu->data_segment_len); 1896 } 1897 break; 1898 1899 case ISCSI_OPERATIONAL_NEGOTIATION_PHASE: 1900 /* LoginOperationalNegotiation */ 1901 if (conn->state == ISCSI_CONN_STATE_INVALID) { 1902 if (conn->require_chap) { 1903 /* Authentication failure */ 1904 rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR; 1905 rsph->status_detail = ISCSI_LOGIN_AUTHENT_FAIL; 1906 return SPDK_ISCSI_LOGIN_ERROR_RESPONSE; 1907 } else { 1908 /* AuthMethod=None */ 1909 conn->authenticated = true; 1910 } 1911 } 1912 if (!conn->authenticated) { 1913 SPDK_ERRLOG("authentication error\n"); 1914 /* Authentication failure */ 1915 rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR; 1916 rsph->status_detail = ISCSI_LOGIN_AUTHENT_FAIL; 1917 return SPDK_ISCSI_LOGIN_ERROR_RESPONSE; 1918 } 1919 break; 1920 1921 case ISCSI_FULL_FEATURE_PHASE: 1922 /* FullFeaturePhase */ 1923 SPDK_ERRLOG("XXX Login in FullFeaturePhase\n"); 1924 /* Initiator error */ 1925 rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR; 1926 rsph->status_detail = ISCSI_LOGIN_INITIATOR_ERROR; 1927 return SPDK_ISCSI_LOGIN_ERROR_RESPONSE; 1928 1929 default: 1930 SPDK_ERRLOG("unknown stage\n"); 1931 /* Initiator error */ 1932 rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR; 1933 rsph->status_detail = ISCSI_LOGIN_INITIATOR_ERROR; 1934 return SPDK_ISCSI_LOGIN_ERROR_RESPONSE; 1935 } 1936 1937 return 0; 1938 } 1939 1940 /* This function is used to notify the session info 1941 * return 1942 * 0: success 1943 * otherwise: error 1944 */ 1945 static int 1946 spdk_iscsi_op_login_notify_session_info(struct spdk_iscsi_conn *conn, 1947 struct spdk_iscsi_pdu *rsp_pdu) 1948 { 1949 struct iscsi_bhs_login_rsp *rsph; 1950 1951 rsph = (struct iscsi_bhs_login_rsp *)&rsp_pdu->bhs; 1952 if (conn->sess->session_type == SESSION_TYPE_NORMAL) { 1953 /* normal session */ 1954 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Login from %s (%s) on %s tgt_node%d" 1955 " (%s:%s,%d), ISID=%"PRIx64", TSIH=%u," 1956 " CID=%u, HeaderDigest=%s, DataDigest=%s\n", 1957 conn->initiator_name, conn->initiator_addr, 1958 conn->target->name, conn->target->num, 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 if (conn->sess->session_type == SESSION_TYPE_DISCOVERY) { 1966 /* discovery session */ 1967 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Login(discovery) from %s (%s) on" 1968 " (%s:%s,%d), ISID=%"PRIx64", TSIH=%u," 1969 " CID=%u, HeaderDigest=%s, DataDigest=%s\n", 1970 conn->initiator_name, conn->initiator_addr, 1971 conn->portal->host, conn->portal->port, conn->portal->group->tag, 1972 conn->sess->isid, conn->sess->tsih, conn->cid, 1973 (spdk_iscsi_param_eq_val(conn->params, "HeaderDigest", "CRC32C") 1974 ? "on" : "off"), 1975 (spdk_iscsi_param_eq_val(conn->params, "DataDigest", "CRC32C") 1976 ? "on" : "off")); 1977 } else { 1978 SPDK_ERRLOG("unknown session type\n"); 1979 /* Initiator error */ 1980 rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR; 1981 rsph->status_detail = ISCSI_LOGIN_INITIATOR_ERROR; 1982 return SPDK_ISCSI_LOGIN_ERROR_RESPONSE; 1983 } 1984 1985 return 0; 1986 } 1987 1988 /* 1989 * This function is to handle the tbit cases 1990 * return 1991 * 0: success 1992 * otherwise error 1993 */ 1994 static int 1995 spdk_iscsi_op_login_rsp_handle_t_bit(struct spdk_iscsi_conn *conn, 1996 struct spdk_iscsi_pdu *rsp_pdu) 1997 { 1998 int rc; 1999 struct iscsi_bhs_login_rsp *rsph; 2000 rsph = (struct iscsi_bhs_login_rsp *)&rsp_pdu->bhs; 2001 2002 switch (ISCSI_BHS_LOGIN_GET_NSG(rsph->flags)) { 2003 case ISCSI_SECURITY_NEGOTIATION_PHASE: 2004 /* SecurityNegotiation */ 2005 conn->login_phase = ISCSI_SECURITY_NEGOTIATION_PHASE; 2006 break; 2007 2008 case ISCSI_OPERATIONAL_NEGOTIATION_PHASE: 2009 /* LoginOperationalNegotiation */ 2010 conn->login_phase = ISCSI_OPERATIONAL_NEGOTIATION_PHASE; 2011 break; 2012 2013 case ISCSI_FULL_FEATURE_PHASE: 2014 /* FullFeaturePhase */ 2015 conn->login_phase = ISCSI_FULL_FEATURE_PHASE; 2016 to_be16(&rsph->tsih, conn->sess->tsih); 2017 2018 rc = spdk_iscsi_op_login_notify_session_info(conn, rsp_pdu); 2019 if (rc < 0) { 2020 return rc; 2021 } 2022 2023 conn->full_feature = 1; 2024 spdk_iscsi_conn_migration(conn); 2025 break; 2026 2027 default: 2028 SPDK_ERRLOG("unknown stage\n"); 2029 /* Initiator error */ 2030 rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR; 2031 rsph->status_detail = ISCSI_LOGIN_INITIATOR_ERROR; 2032 return SPDK_ISCSI_LOGIN_ERROR_RESPONSE; 2033 } 2034 2035 return 0; 2036 } 2037 2038 /* 2039 * This function is used to set the values of the internal data structure used 2040 * by spdk_iscsi_op_login function 2041 * return: 2042 * 0, used to notify the a successful login 2043 * SPDK_ISCSI_LOGIN_ERROR_RESPONSE, used to notify a failure login. 2044 */ 2045 static int 2046 spdk_iscsi_op_login_rsp_handle(struct spdk_iscsi_conn *conn, 2047 struct spdk_iscsi_pdu *rsp_pdu, struct iscsi_param **params, 2048 int alloc_len) 2049 { 2050 int rc; 2051 struct iscsi_bhs_login_rsp *rsph; 2052 rsph = (struct iscsi_bhs_login_rsp *)&rsp_pdu->bhs; 2053 2054 /* negotiate parameters */ 2055 rc = spdk_iscsi_negotiate_params(conn, params, rsp_pdu->data, alloc_len, 2056 rsp_pdu->data_segment_len); 2057 if (rc < 0) { 2058 /* 2059 * spdk_iscsi_negotiate_params just returns -1 on failure, 2060 * so translate this into meaningful response codes and 2061 * return values. 2062 */ 2063 rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR; 2064 rsph->status_detail = ISCSI_LOGIN_INITIATOR_ERROR; 2065 return SPDK_ISCSI_LOGIN_ERROR_RESPONSE; 2066 } 2067 2068 rsp_pdu->data_segment_len = rc; 2069 SPDK_LOGDUMP(SPDK_LOG_ISCSI, "Negotiated Params", rsp_pdu->data, rc); 2070 2071 /* handle the CSG bit case */ 2072 rc = spdk_iscsi_op_login_rsp_handle_csg_bit(conn, rsp_pdu, *params, 2073 alloc_len); 2074 if (rc < 0) { 2075 return rc; 2076 } 2077 2078 /* handle the T bit case */ 2079 if (ISCSI_BHS_LOGIN_GET_TBIT(rsph->flags)) { 2080 rc = spdk_iscsi_op_login_rsp_handle_t_bit(conn, rsp_pdu); 2081 } 2082 2083 return rc; 2084 } 2085 2086 static int 2087 spdk_iscsi_op_login(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu) 2088 { 2089 int rc; 2090 struct spdk_iscsi_pdu *rsp_pdu; 2091 struct iscsi_param *params = NULL; 2092 struct iscsi_param **params_p = ¶ms; 2093 int alloc_len; 2094 int cid; 2095 2096 if (conn->full_feature && conn->sess != NULL && 2097 conn->sess->session_type == SESSION_TYPE_DISCOVERY) { 2098 return SPDK_ISCSI_CONNECTION_FATAL; 2099 } 2100 2101 rsp_pdu = spdk_get_pdu(); 2102 if (rsp_pdu == NULL) { 2103 return SPDK_ISCSI_CONNECTION_FATAL; 2104 } 2105 rc = spdk_iscsi_op_login_rsp_init(conn, pdu, rsp_pdu, params_p, 2106 &alloc_len, &cid); 2107 if (rc == SPDK_ISCSI_LOGIN_ERROR_RESPONSE || rc == SPDK_ISCSI_LOGIN_ERROR_PARAMETER) { 2108 spdk_iscsi_op_login_response(conn, rsp_pdu, *params_p); 2109 return rc; 2110 } 2111 2112 /* For other values, we need to directly return */ 2113 if (rc < 0) { 2114 spdk_put_pdu(rsp_pdu); 2115 return rc; 2116 } 2117 2118 if (conn->state == ISCSI_CONN_STATE_INVALID) { 2119 rc = spdk_iscsi_op_login_phase_none(conn, rsp_pdu, *params_p, 2120 alloc_len, cid); 2121 if (rc == SPDK_ISCSI_LOGIN_ERROR_RESPONSE || rc == SPDK_ISCSI_LOGIN_ERROR_PARAMETER) { 2122 spdk_iscsi_op_login_response(conn, rsp_pdu, *params_p); 2123 return rc; 2124 } 2125 } 2126 2127 rc = spdk_iscsi_op_login_rsp_handle(conn, rsp_pdu, params_p, alloc_len); 2128 if (rc == SPDK_ISCSI_LOGIN_ERROR_RESPONSE) { 2129 spdk_iscsi_op_login_response(conn, rsp_pdu, *params_p); 2130 return rc; 2131 } 2132 2133 rc = spdk_iscsi_op_login_response(conn, rsp_pdu, *params_p); 2134 if (rc == 0) { 2135 conn->state = ISCSI_CONN_STATE_RUNNING; 2136 } else { 2137 SPDK_ERRLOG("login error - connection will be destroyed\n"); 2138 } 2139 2140 return rc; 2141 } 2142 2143 static int 2144 spdk_iscsi_op_text(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu) 2145 { 2146 struct iscsi_param *params = NULL; 2147 struct iscsi_param **params_p = ¶ms; 2148 struct spdk_iscsi_pdu *rsp_pdu; 2149 uint8_t *data; 2150 uint64_t lun; 2151 uint32_t task_tag; 2152 uint32_t CmdSN; 2153 uint32_t ExpStatSN; 2154 const char *val; 2155 int F_bit, C_bit; 2156 int data_len; 2157 int alloc_len; 2158 int rc; 2159 struct iscsi_bhs_text_req *reqh; 2160 struct iscsi_bhs_text_resp *rsph; 2161 2162 data_len = 0; 2163 alloc_len = conn->MaxRecvDataSegmentLength; 2164 2165 reqh = (struct iscsi_bhs_text_req *)&pdu->bhs; 2166 2167 F_bit = !!(reqh->flags & ISCSI_FLAG_FINAL); 2168 C_bit = !!(reqh->flags & ISCSI_TEXT_CONTINUE); 2169 lun = from_be64(&reqh->lun); 2170 task_tag = from_be32(&reqh->itt); 2171 CmdSN = from_be32(&reqh->cmd_sn); 2172 pdu->cmd_sn = CmdSN; 2173 ExpStatSN = from_be32(&reqh->exp_stat_sn); 2174 2175 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "I=%d, F=%d, C=%d, ITT=%x, TTT=%x\n", 2176 reqh->immediate, F_bit, C_bit, task_tag, from_be32(&reqh->ttt)); 2177 2178 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, 2179 "CmdSN=%u, ExpStatSN=%u, StatSN=%u, ExpCmdSN=%u, MaxCmdSN=%u\n", 2180 CmdSN, ExpStatSN, conn->StatSN, conn->sess->ExpCmdSN, 2181 conn->sess->MaxCmdSN); 2182 2183 if (ExpStatSN != conn->StatSN) { 2184 #if 0 2185 SPDK_ERRLOG("StatSN(%u) error\n", ExpStatSN); 2186 return -1; 2187 #else 2188 /* StarPort have a bug */ 2189 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "StatSN(%u) rewound\n", ExpStatSN); 2190 conn->StatSN = ExpStatSN; 2191 #endif 2192 } 2193 2194 if (F_bit && C_bit) { 2195 SPDK_ERRLOG("final and continue\n"); 2196 return -1; 2197 } 2198 2199 /* 2200 * If this is the first text op in a sequence, save the ITT so we can 2201 * compare it against the ITT for subsequent ops in the same sequence. 2202 * If a subsequent text op in same sequence has a different ITT, reject 2203 * that PDU. 2204 */ 2205 if (conn->sess->current_text_itt == 0xffffffffU) { 2206 conn->sess->current_text_itt = task_tag; 2207 } else if (conn->sess->current_text_itt != task_tag) { 2208 SPDK_ERRLOG("The correct itt is %u, and the current itt is %u...\n", 2209 conn->sess->current_text_itt, task_tag); 2210 return spdk_iscsi_reject(conn, pdu, ISCSI_REASON_PROTOCOL_ERROR); 2211 } 2212 2213 /* store incoming parameters */ 2214 rc = spdk_iscsi_parse_params(¶ms, pdu->data, pdu->data_segment_len, 2215 C_bit, &conn->partial_text_parameter); 2216 if (rc < 0) { 2217 SPDK_ERRLOG("iscsi_parse_params() failed\n"); 2218 spdk_iscsi_param_free(params); 2219 return -1; 2220 } 2221 2222 data = calloc(1, alloc_len); 2223 if (!data) { 2224 SPDK_ERRLOG("calloc() failed for data segment\n"); 2225 spdk_iscsi_param_free(params); 2226 return -ENOMEM; 2227 } 2228 2229 /* negotiate parameters */ 2230 data_len = spdk_iscsi_negotiate_params(conn, params_p, 2231 data, alloc_len, data_len); 2232 if (data_len < 0) { 2233 SPDK_ERRLOG("spdk_iscsi_negotiate_params() failed\n"); 2234 spdk_iscsi_param_free(*params_p); 2235 free(data); 2236 return -1; 2237 } 2238 2239 /* sendtargets is special case */ 2240 val = spdk_iscsi_param_get_val(*params_p, "SendTargets"); 2241 if (val != NULL) { 2242 if (spdk_iscsi_param_eq_val(conn->sess->params, 2243 "SessionType", "Discovery")) { 2244 if (strcasecmp(val, "") == 0) { 2245 val = "ALL"; 2246 } 2247 2248 data_len = spdk_iscsi_send_tgts(conn, 2249 conn->initiator_name, 2250 conn->initiator_addr, 2251 val, data, alloc_len, 2252 data_len); 2253 } else { 2254 if (strcasecmp(val, "") == 0) { 2255 val = conn->target->name; 2256 } 2257 2258 if (strcasecmp(val, "ALL") == 0) { 2259 /* not in discovery session */ 2260 data_len = spdk_iscsi_append_text(conn, 2261 "SendTargets", 2262 "Reject", data, 2263 alloc_len, 2264 data_len); 2265 } else { 2266 data_len = spdk_iscsi_send_tgts(conn, 2267 conn->initiator_name, 2268 conn->initiator_addr, 2269 val, data, alloc_len, 2270 data_len); 2271 } 2272 } 2273 } else { 2274 if (spdk_iscsi_param_eq_val(conn->sess->params, "SessionType", "Discovery")) { 2275 spdk_iscsi_param_free(*params_p); 2276 free(data); 2277 return SPDK_ISCSI_CONNECTION_FATAL; 2278 } 2279 } 2280 2281 SPDK_LOGDUMP(SPDK_LOG_ISCSI, "Negotiated Params", data, data_len); 2282 2283 /* response PDU */ 2284 rsp_pdu = spdk_get_pdu(); 2285 if (rsp_pdu == NULL) { 2286 spdk_iscsi_param_free(*params_p); 2287 free(data); 2288 return SPDK_ISCSI_CONNECTION_FATAL; 2289 } 2290 rsph = (struct iscsi_bhs_text_resp *)&rsp_pdu->bhs; 2291 2292 rsp_pdu->data = data; 2293 rsph->opcode = ISCSI_OP_TEXT_RSP; 2294 2295 if (F_bit) { 2296 rsph->flags |= ISCSI_FLAG_FINAL; 2297 } 2298 2299 if (C_bit) { 2300 rsph->flags |= ISCSI_TEXT_CONTINUE; 2301 } 2302 2303 DSET24(rsph->data_segment_len, data_len); 2304 to_be64(&rsph->lun, lun); 2305 to_be32(&rsph->itt, task_tag); 2306 2307 if (F_bit) { 2308 rsph->ttt = 0xffffffffU; 2309 conn->sess->current_text_itt = 0xffffffffU; 2310 } else { 2311 to_be32(&rsph->ttt, 1 + conn->id); 2312 } 2313 2314 to_be32(&rsph->stat_sn, conn->StatSN); 2315 conn->StatSN++; 2316 2317 if (reqh->immediate == 0) { 2318 conn->sess->MaxCmdSN++; 2319 } 2320 2321 to_be32(&rsph->exp_cmd_sn, conn->sess->ExpCmdSN); 2322 to_be32(&rsph->max_cmd_sn, conn->sess->MaxCmdSN); 2323 2324 spdk_iscsi_conn_write_pdu(conn, rsp_pdu); 2325 2326 /* update internal variables */ 2327 rc = spdk_iscsi_copy_param2var(conn); 2328 if (rc < 0) { 2329 SPDK_ERRLOG("spdk_iscsi_copy_param2var() failed\n"); 2330 spdk_iscsi_param_free(*params_p); 2331 return -1; 2332 } 2333 2334 /* check value */ 2335 rc = spdk_iscsi_check_values(conn); 2336 if (rc < 0) { 2337 SPDK_ERRLOG("iscsi_check_values() failed\n"); 2338 spdk_iscsi_param_free(*params_p); 2339 return -1; 2340 } 2341 2342 spdk_iscsi_param_free(*params_p); 2343 return 0; 2344 } 2345 2346 static int 2347 spdk_iscsi_op_logout(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu) 2348 { 2349 char buf[MAX_TMPBUF]; 2350 struct spdk_iscsi_pdu *rsp_pdu; 2351 uint32_t task_tag; 2352 uint32_t CmdSN; 2353 uint32_t ExpStatSN; 2354 int response; 2355 struct iscsi_bhs_logout_req *reqh; 2356 struct iscsi_bhs_logout_resp *rsph; 2357 uint16_t cid; 2358 2359 reqh = (struct iscsi_bhs_logout_req *)&pdu->bhs; 2360 2361 cid = from_be16(&reqh->cid); 2362 task_tag = from_be32(&reqh->itt); 2363 CmdSN = from_be32(&reqh->cmd_sn); 2364 pdu->cmd_sn = CmdSN; 2365 ExpStatSN = from_be32(&reqh->exp_stat_sn); 2366 2367 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "reason=%d, ITT=%x, cid=%d\n", 2368 reqh->reason, task_tag, cid); 2369 2370 if (reqh->reason != 0 && conn->sess->session_type == SESSION_TYPE_DISCOVERY) { 2371 SPDK_ERRLOG("only logout with close the session reason can be in discovery session"); 2372 return SPDK_ISCSI_CONNECTION_FATAL; 2373 } 2374 2375 if (conn->sess != NULL) { 2376 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, 2377 "CmdSN=%u, ExpStatSN=%u, StatSN=%u, ExpCmdSN=%u, MaxCmdSN=%u\n", 2378 CmdSN, ExpStatSN, conn->StatSN, 2379 conn->sess->ExpCmdSN, conn->sess->MaxCmdSN); 2380 2381 if (CmdSN != conn->sess->ExpCmdSN) { 2382 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "CmdSN(%u) might have dropped\n", CmdSN); 2383 /* ignore error */ 2384 } 2385 } else { 2386 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "CmdSN=%u, ExpStatSN=%u, StatSN=%u\n", 2387 CmdSN, ExpStatSN, conn->StatSN); 2388 } 2389 2390 if (ExpStatSN != conn->StatSN) { 2391 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "StatSN(%u/%u) might have dropped\n", 2392 ExpStatSN, conn->StatSN); 2393 /* ignore error */ 2394 } 2395 2396 if (conn->id == cid) { 2397 /* connection or session closed successfully */ 2398 response = 0; 2399 spdk_iscsi_conn_logout(conn); 2400 } else { 2401 response = 1; 2402 } 2403 2404 /* response PDU */ 2405 rsp_pdu = spdk_get_pdu(); 2406 if (rsp_pdu == NULL) { 2407 return SPDK_ISCSI_CONNECTION_FATAL; 2408 } 2409 rsph = (struct iscsi_bhs_logout_resp *)&rsp_pdu->bhs; 2410 rsp_pdu->data = NULL; 2411 rsph->opcode = ISCSI_OP_LOGOUT_RSP; 2412 rsph->flags |= 0x80; /* bit 0 must be 1 */ 2413 rsph->response = response; 2414 DSET24(rsph->data_segment_len, 0); 2415 to_be32(&rsph->itt, task_tag); 2416 2417 if (conn->sess != NULL) { 2418 to_be32(&rsph->stat_sn, conn->StatSN); 2419 conn->StatSN++; 2420 2421 if (conn->sess->connections == 1) { 2422 conn->sess->MaxCmdSN++; 2423 } 2424 2425 to_be32(&rsph->exp_cmd_sn, conn->sess->ExpCmdSN); 2426 to_be32(&rsph->max_cmd_sn, conn->sess->MaxCmdSN); 2427 } else { 2428 to_be32(&rsph->stat_sn, conn->StatSN); 2429 conn->StatSN++; 2430 to_be32(&rsph->exp_cmd_sn, CmdSN); 2431 to_be32(&rsph->max_cmd_sn, CmdSN); 2432 } 2433 2434 rsph->time_2_wait = 0; 2435 rsph->time_2_retain = 0; 2436 2437 spdk_iscsi_conn_write_pdu(conn, rsp_pdu); 2438 2439 if (conn->sess == NULL) { 2440 /* 2441 * login failed but initiator still sent a logout rather than 2442 * just closing the TCP connection. 2443 */ 2444 snprintf(buf, sizeof buf, "Logout(login failed) from %s (%s) on" 2445 " (%s:%s,%d)\n", 2446 conn->initiator_name, conn->initiator_addr, 2447 conn->portal_host, conn->portal_port, conn->pg_tag); 2448 } else if (spdk_iscsi_param_eq_val(conn->sess->params, "SessionType", "Normal")) { 2449 snprintf(buf, sizeof buf, "Logout from %s (%s) on %s tgt_node%d" 2450 " (%s:%s,%d), ISID=%"PRIx64", TSIH=%u," 2451 " CID=%u, HeaderDigest=%s, DataDigest=%s\n", 2452 conn->initiator_name, conn->initiator_addr, 2453 conn->target->name, conn->target->num, 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 } else { 2461 /* discovery session */ 2462 snprintf(buf, sizeof buf, "Logout(discovery) from %s (%s) on" 2463 " (%s:%s,%d), ISID=%"PRIx64", TSIH=%u," 2464 " CID=%u, HeaderDigest=%s, DataDigest=%s\n", 2465 conn->initiator_name, conn->initiator_addr, 2466 conn->portal_host, conn->portal_port, conn->pg_tag, 2467 conn->sess->isid, conn->sess->tsih, conn->cid, 2468 (spdk_iscsi_param_eq_val(conn->params, "HeaderDigest", "CRC32C") 2469 ? "on" : "off"), 2470 (spdk_iscsi_param_eq_val(conn->params, "DataDigest", "CRC32C") 2471 ? "on" : "off")); 2472 } 2473 2474 SPDK_NOTICELOG("%s", buf); 2475 2476 return 0; 2477 } 2478 2479 /* This function returns the spdk_scsi_task by searching the snack list via 2480 * task transfertag and the pdu's opcode 2481 */ 2482 static struct spdk_iscsi_task * 2483 spdk_get_scsi_task_from_ttt(struct spdk_iscsi_conn *conn, 2484 uint32_t transfer_tag) 2485 { 2486 struct spdk_iscsi_pdu *pdu; 2487 struct iscsi_bhs_data_in *datain_bhs; 2488 2489 TAILQ_FOREACH(pdu, &conn->snack_pdu_list, tailq) { 2490 if (pdu->bhs.opcode == ISCSI_OP_SCSI_DATAIN) { 2491 datain_bhs = (struct iscsi_bhs_data_in *)&pdu->bhs; 2492 if (from_be32(&datain_bhs->ttt) == transfer_tag) { 2493 return pdu->task; 2494 } 2495 } 2496 } 2497 2498 return NULL; 2499 } 2500 2501 /* This function returns the spdk_scsi_task by searching the snack list via 2502 * initiator task tag and the pdu's opcode 2503 */ 2504 static struct spdk_iscsi_task * 2505 spdk_get_scsi_task_from_itt(struct spdk_iscsi_conn *conn, 2506 uint32_t task_tag, enum iscsi_op opcode) 2507 { 2508 struct spdk_iscsi_pdu *pdu; 2509 2510 TAILQ_FOREACH(pdu, &conn->snack_pdu_list, tailq) { 2511 if (pdu->bhs.opcode == opcode && 2512 pdu->task != NULL && 2513 pdu->task->tag == task_tag) { 2514 return pdu->task; 2515 } 2516 } 2517 2518 return NULL; 2519 } 2520 2521 static int 2522 spdk_iscsi_send_datain(struct spdk_iscsi_conn *conn, 2523 struct spdk_iscsi_task *task, int datain_flag, 2524 int residual_len, int offset, int DataSN, int len) 2525 { 2526 struct spdk_iscsi_pdu *rsp_pdu; 2527 struct iscsi_bhs_data_in *rsph; 2528 uint32_t task_tag; 2529 uint32_t transfer_tag; 2530 int F_bit, U_bit, O_bit, S_bit; 2531 struct spdk_iscsi_task *primary; 2532 2533 primary = spdk_iscsi_task_get_primary(task); 2534 2535 /* DATA PDU */ 2536 rsp_pdu = spdk_get_pdu(); 2537 rsph = (struct iscsi_bhs_data_in *)&rsp_pdu->bhs; 2538 rsp_pdu->data = task->scsi.iovs[0].iov_base + offset; 2539 rsp_pdu->data_from_mempool = true; 2540 2541 task_tag = task->tag; 2542 transfer_tag = 0xffffffffU; 2543 2544 F_bit = datain_flag & ISCSI_FLAG_FINAL; 2545 O_bit = datain_flag & ISCSI_DATAIN_OVERFLOW; 2546 U_bit = datain_flag & ISCSI_DATAIN_UNDERFLOW; 2547 S_bit = datain_flag & ISCSI_DATAIN_STATUS; 2548 2549 /* 2550 * we need to hold onto this task/cmd because until the 2551 * PDU has been written out 2552 */ 2553 rsp_pdu->task = task; 2554 task->scsi.ref++; 2555 2556 rsph->opcode = ISCSI_OP_SCSI_DATAIN; 2557 2558 if (F_bit) { 2559 rsph->flags |= ISCSI_FLAG_FINAL; 2560 } 2561 2562 /* we leave the A_bit clear */ 2563 2564 if (F_bit && S_bit) { 2565 if (O_bit) { 2566 rsph->flags |= ISCSI_DATAIN_OVERFLOW; 2567 } 2568 2569 if (U_bit) { 2570 rsph->flags |= ISCSI_DATAIN_UNDERFLOW; 2571 } 2572 } 2573 2574 if (S_bit) { 2575 rsph->flags |= ISCSI_DATAIN_STATUS; 2576 rsph->status = task->scsi.status; 2577 } 2578 2579 DSET24(rsph->data_segment_len, len); 2580 2581 to_be32(&rsph->itt, task_tag); 2582 to_be32(&rsph->ttt, transfer_tag); 2583 2584 if (S_bit) { 2585 to_be32(&rsph->stat_sn, conn->StatSN); 2586 conn->StatSN++; 2587 } 2588 2589 if (F_bit && S_bit && !spdk_iscsi_task_is_immediate(primary)) { 2590 conn->sess->MaxCmdSN++; 2591 } 2592 2593 to_be32(&rsph->exp_cmd_sn, conn->sess->ExpCmdSN); 2594 to_be32(&rsph->max_cmd_sn, conn->sess->MaxCmdSN); 2595 2596 to_be32(&rsph->data_sn, DataSN); 2597 2598 if (conn->sess->ErrorRecoveryLevel >= 1) { 2599 primary->datain_datasn = DataSN; 2600 } 2601 DataSN++; 2602 2603 if (task->parent) { 2604 offset += primary->scsi.data_transferred; 2605 } 2606 to_be32(&rsph->buffer_offset, (uint32_t)offset); 2607 2608 if (F_bit && S_bit) { 2609 to_be32(&rsph->res_cnt, residual_len); 2610 } 2611 2612 spdk_iscsi_conn_write_pdu(conn, rsp_pdu); 2613 2614 return DataSN; 2615 } 2616 2617 static int 2618 spdk_iscsi_transfer_in(struct spdk_iscsi_conn *conn, 2619 struct spdk_iscsi_task *task) 2620 { 2621 uint32_t DataSN; 2622 int transfer_len; 2623 int data_len; 2624 int segment_len; 2625 int offset; 2626 int residual_len = 0; 2627 int sent_status; 2628 int len; 2629 int datain_flag = 0; 2630 int datain_seq_cnt; 2631 int i; 2632 int sequence_end; 2633 struct spdk_iscsi_task *primary; 2634 2635 primary = spdk_iscsi_task_get_primary(task); 2636 segment_len = conn->MaxRecvDataSegmentLength; 2637 data_len = task->scsi.data_transferred; 2638 transfer_len = task->scsi.length; 2639 2640 if (task->scsi.status != SPDK_SCSI_STATUS_GOOD) { 2641 if (task != primary) { 2642 conn->data_in_cnt--; 2643 /* Handle the case when primary task return success but the subtask failed */ 2644 if (primary->bytes_completed == primary->scsi.transfer_len && 2645 primary->scsi.status == SPDK_SCSI_STATUS_GOOD) { 2646 conn->data_in_cnt--; 2647 } 2648 } else { 2649 /* handle the case that it is a primary task which has subtasks */ 2650 if (primary->scsi.transfer_len != primary->scsi.length) { 2651 conn->data_in_cnt--; 2652 } 2653 } 2654 2655 return 0; 2656 } 2657 2658 if (data_len < transfer_len) { 2659 /* underflow */ 2660 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Underflow %u/%u\n", data_len, transfer_len); 2661 residual_len = transfer_len - data_len; 2662 transfer_len = data_len; 2663 datain_flag |= ISCSI_DATAIN_UNDERFLOW; 2664 } else if (data_len > transfer_len) { 2665 /* overflow */ 2666 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Overflow %u/%u\n", data_len, transfer_len); 2667 residual_len = data_len - transfer_len; 2668 datain_flag |= ISCSI_DATAIN_OVERFLOW; 2669 } else { 2670 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Transfer %u\n", transfer_len); 2671 residual_len = 0; 2672 } 2673 2674 DataSN = primary->datain_datasn; 2675 sent_status = 0; 2676 2677 /* calculate the number of sequences for all data-in pdus */ 2678 datain_seq_cnt = 1 + ((transfer_len - 1) / (int)conn->sess->MaxBurstLength); 2679 for (i = 0; i < datain_seq_cnt; i++) { 2680 offset = i * conn->sess->MaxBurstLength; 2681 sequence_end = DMIN32(((i + 1) * conn->sess->MaxBurstLength), 2682 transfer_len); 2683 2684 /* send data splitted by segment_len */ 2685 for (; offset < sequence_end; offset += segment_len) { 2686 len = DMIN32(segment_len, (sequence_end - offset)); 2687 2688 datain_flag &= ~ISCSI_FLAG_FINAL; 2689 datain_flag &= ~ISCSI_DATAIN_STATUS; 2690 2691 if (offset + len == sequence_end) { 2692 /* last PDU in a sequence */ 2693 datain_flag |= ISCSI_FLAG_FINAL; 2694 if (task->scsi.sense_data_len == 0) { 2695 /* The last pdu in all data-in pdus */ 2696 if ((offset + len) == transfer_len && 2697 (primary->bytes_completed == primary->scsi.transfer_len)) { 2698 datain_flag |= ISCSI_DATAIN_STATUS; 2699 sent_status = 1; 2700 } 2701 } 2702 } 2703 2704 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Transfer=%d, Offset=%d, Len=%d\n", 2705 sequence_end, offset, len); 2706 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "StatSN=%u, DataSN=%u, Offset=%u, Len=%d\n", 2707 conn->StatSN, DataSN, offset, len); 2708 2709 DataSN = spdk_iscsi_send_datain(conn, task, datain_flag, residual_len, 2710 offset, DataSN, len); 2711 } 2712 } 2713 2714 if (task != primary) { 2715 primary->scsi.data_transferred += task->scsi.data_transferred; 2716 } 2717 primary->datain_datasn = DataSN; 2718 2719 return sent_status; 2720 } 2721 2722 /* 2723 * This function compare the input pdu's bhs with the pdu's bhs associated by 2724 * active_r2t_tasks and queued_r2t_tasks in a connection 2725 */ 2726 static bool 2727 spdk_iscsi_compare_pdu_bhs_within_existed_r2t_tasks(struct spdk_iscsi_conn *conn, 2728 struct spdk_iscsi_pdu *pdu) 2729 { 2730 struct spdk_iscsi_task *task; 2731 2732 TAILQ_FOREACH(task, &conn->active_r2t_tasks, link) { 2733 if (!memcmp(&pdu->bhs, spdk_iscsi_task_get_bhs(task), ISCSI_BHS_LEN)) { 2734 return true; 2735 } 2736 } 2737 2738 TAILQ_FOREACH(task, &conn->queued_r2t_tasks, link) { 2739 if (!memcmp(&pdu->bhs, spdk_iscsi_task_get_bhs(task), ISCSI_BHS_LEN)) { 2740 return true; 2741 } 2742 } 2743 2744 return false; 2745 } 2746 2747 static void spdk_iscsi_queue_task(struct spdk_iscsi_conn *conn, 2748 struct spdk_iscsi_task *task) 2749 { 2750 spdk_trace_record(TRACE_ISCSI_TASK_QUEUE, conn->id, task->scsi.length, 2751 (uintptr_t)task, (uintptr_t)task->pdu); 2752 task->is_queued = true; 2753 spdk_scsi_dev_queue_task(conn->dev, &task->scsi); 2754 } 2755 2756 static void spdk_iscsi_queue_mgmt_task(struct spdk_iscsi_conn *conn, 2757 struct spdk_iscsi_task *task) 2758 { 2759 spdk_scsi_dev_queue_mgmt_task(conn->dev, &task->scsi); 2760 } 2761 2762 int spdk_iscsi_conn_handle_queued_datain_tasks(struct spdk_iscsi_conn *conn) 2763 { 2764 struct spdk_iscsi_task *task; 2765 2766 while (!TAILQ_EMPTY(&conn->queued_datain_tasks) && 2767 conn->data_in_cnt < MAX_LARGE_DATAIN_PER_CONNECTION) { 2768 task = TAILQ_FIRST(&conn->queued_datain_tasks); 2769 assert(task->current_datain_offset <= task->scsi.transfer_len); 2770 2771 if (task->current_datain_offset == 0) { 2772 task->scsi.lun = spdk_scsi_dev_get_lun(conn->dev, task->lun_id); 2773 if (task->scsi.lun == NULL) { 2774 TAILQ_REMOVE(&conn->queued_datain_tasks, task, link); 2775 spdk_scsi_task_process_null_lun(&task->scsi); 2776 spdk_iscsi_task_cpl(&task->scsi); 2777 return 0; 2778 } 2779 task->current_datain_offset = task->scsi.length; 2780 conn->data_in_cnt++; 2781 spdk_iscsi_queue_task(conn, task); 2782 continue; 2783 } 2784 if (task->current_datain_offset < task->scsi.transfer_len) { 2785 struct spdk_iscsi_task *subtask; 2786 uint32_t remaining_size = 0; 2787 2788 remaining_size = task->scsi.transfer_len - task->current_datain_offset; 2789 subtask = spdk_iscsi_task_get(conn, task, spdk_iscsi_task_cpl); 2790 assert(subtask != NULL); 2791 subtask->scsi.offset = task->current_datain_offset; 2792 subtask->scsi.length = DMIN32(SPDK_BDEV_LARGE_BUF_MAX_SIZE, remaining_size); 2793 spdk_scsi_task_set_data(&subtask->scsi, NULL, 0); 2794 task->current_datain_offset += subtask->scsi.length; 2795 conn->data_in_cnt++; 2796 2797 task->scsi.lun = spdk_scsi_dev_get_lun(conn->dev, task->lun_id); 2798 if (task->scsi.lun == NULL) { 2799 /* Remove the primary task from the list if this is the last subtask */ 2800 if (task->current_datain_offset == task->scsi.transfer_len) { 2801 TAILQ_REMOVE(&conn->queued_datain_tasks, task, link); 2802 } 2803 subtask->scsi.transfer_len = subtask->scsi.length; 2804 spdk_scsi_task_process_null_lun(&subtask->scsi); 2805 spdk_iscsi_task_cpl(&subtask->scsi); 2806 return 0; 2807 } 2808 2809 spdk_iscsi_queue_task(conn, subtask); 2810 } 2811 if (task->current_datain_offset == task->scsi.transfer_len) { 2812 TAILQ_REMOVE(&conn->queued_datain_tasks, task, link); 2813 } 2814 } 2815 return 0; 2816 } 2817 2818 static int spdk_iscsi_op_scsi_read(struct spdk_iscsi_conn *conn, 2819 struct spdk_iscsi_task *task) 2820 { 2821 int32_t remaining_size; 2822 2823 TAILQ_INIT(&task->subtask_list); 2824 task->scsi.dxfer_dir = SPDK_SCSI_DIR_FROM_DEV; 2825 task->parent = NULL; 2826 task->scsi.offset = 0; 2827 task->scsi.length = DMIN32(SPDK_BDEV_LARGE_BUF_MAX_SIZE, task->scsi.transfer_len); 2828 spdk_scsi_task_set_data(&task->scsi, NULL, 0); 2829 2830 remaining_size = task->scsi.transfer_len - task->scsi.length; 2831 task->current_datain_offset = 0; 2832 2833 if (remaining_size == 0) { 2834 spdk_iscsi_queue_task(conn, task); 2835 return 0; 2836 } 2837 2838 TAILQ_INSERT_TAIL(&conn->queued_datain_tasks, task, link); 2839 2840 return spdk_iscsi_conn_handle_queued_datain_tasks(conn); 2841 } 2842 2843 static int 2844 spdk_iscsi_op_scsi(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu) 2845 { 2846 struct spdk_iscsi_task *task; 2847 struct spdk_scsi_dev *dev; 2848 uint8_t *cdb; 2849 uint64_t lun; 2850 uint32_t task_tag; 2851 uint32_t transfer_len; 2852 int F_bit, R_bit, W_bit; 2853 int lun_i, rc; 2854 struct iscsi_bhs_scsi_req *reqh; 2855 2856 if (conn->sess->session_type != SESSION_TYPE_NORMAL) { 2857 SPDK_ERRLOG("ISCSI_OP_SCSI not allowed in discovery and invalid session\n"); 2858 return SPDK_ISCSI_CONNECTION_FATAL; 2859 } 2860 2861 reqh = (struct iscsi_bhs_scsi_req *)&pdu->bhs; 2862 2863 F_bit = reqh->final_bit; 2864 R_bit = reqh->read_bit; 2865 W_bit = reqh->write_bit; 2866 lun = from_be64(&reqh->lun); 2867 task_tag = from_be32(&reqh->itt); 2868 transfer_len = from_be32(&reqh->expected_data_xfer_len); 2869 cdb = reqh->cdb; 2870 2871 SPDK_LOGDUMP(SPDK_LOG_ISCSI, "CDB", cdb, 16); 2872 2873 task = spdk_iscsi_task_get(conn, NULL, spdk_iscsi_task_cpl); 2874 if (!task) { 2875 SPDK_ERRLOG("Unable to acquire task\n"); 2876 return SPDK_ISCSI_CONNECTION_FATAL; 2877 } 2878 2879 spdk_iscsi_task_associate_pdu(task, pdu); 2880 lun_i = spdk_islun2lun(lun); 2881 task->lun_id = lun_i; 2882 dev = conn->dev; 2883 task->scsi.lun = spdk_scsi_dev_get_lun(dev, lun_i); 2884 2885 if ((R_bit != 0) && (W_bit != 0)) { 2886 SPDK_ERRLOG("Bidirectional CDB is not supported\n"); 2887 spdk_iscsi_task_put(task); 2888 return SPDK_ISCSI_CONNECTION_FATAL; 2889 } 2890 2891 task->scsi.cdb = cdb; 2892 task->tag = task_tag; 2893 task->scsi.transfer_len = transfer_len; 2894 task->scsi.target_port = conn->target_port; 2895 task->scsi.initiator_port = conn->initiator_port; 2896 task->parent = NULL; 2897 task->rsp_scsi_status = SPDK_SCSI_STATUS_GOOD; 2898 2899 if (task->scsi.lun == NULL) { 2900 spdk_scsi_task_process_null_lun(&task->scsi); 2901 spdk_iscsi_task_cpl(&task->scsi); 2902 return 0; 2903 } 2904 2905 /* no bi-directional support */ 2906 if (R_bit) { 2907 return spdk_iscsi_op_scsi_read(conn, task); 2908 } else if (W_bit) { 2909 task->scsi.dxfer_dir = SPDK_SCSI_DIR_TO_DEV; 2910 2911 if ((conn->sess->ErrorRecoveryLevel >= 1) && 2912 (spdk_iscsi_compare_pdu_bhs_within_existed_r2t_tasks(conn, pdu))) { 2913 spdk_iscsi_task_response(conn, task); 2914 spdk_iscsi_task_put(task); 2915 return 0; 2916 } 2917 2918 if (pdu->data_segment_len > transfer_len) { 2919 SPDK_ERRLOG("data segment len(=%d) > task transfer len(=%d)\n", 2920 (int)pdu->data_segment_len, transfer_len); 2921 spdk_iscsi_task_put(task); 2922 return spdk_iscsi_reject(conn, pdu, ISCSI_REASON_PROTOCOL_ERROR); 2923 } 2924 2925 /* check the ImmediateData and also pdu->data_segment_len */ 2926 if ((!conn->sess->ImmediateData && (pdu->data_segment_len > 0)) || 2927 (pdu->data_segment_len > conn->sess->FirstBurstLength)) { 2928 spdk_iscsi_task_put(task); 2929 return spdk_iscsi_reject(conn, pdu, ISCSI_REASON_PROTOCOL_ERROR); 2930 } 2931 2932 if (F_bit && pdu->data_segment_len < transfer_len) { 2933 /* needs R2T */ 2934 rc = spdk_add_transfer_task(conn, task); 2935 if (rc < 0) { 2936 SPDK_ERRLOG("add_transfer_task() failed\n"); 2937 spdk_iscsi_task_put(task); 2938 return SPDK_ISCSI_CONNECTION_FATAL; 2939 } 2940 2941 /* Non-immediate writes */ 2942 if (pdu->data_segment_len == 0) { 2943 return 0; 2944 } else { 2945 /* we are doing the first partial write task */ 2946 task->scsi.ref++; 2947 spdk_scsi_task_set_data(&task->scsi, pdu->data, pdu->data_segment_len); 2948 task->scsi.length = pdu->data_segment_len; 2949 } 2950 } 2951 2952 if (pdu->data_segment_len == transfer_len) { 2953 /* we are doing small writes with no R2T */ 2954 spdk_scsi_task_set_data(&task->scsi, pdu->data, transfer_len); 2955 task->scsi.length = transfer_len; 2956 } 2957 } else { 2958 /* neither R nor W bit set */ 2959 task->scsi.dxfer_dir = SPDK_SCSI_DIR_NONE; 2960 if (transfer_len > 0) { 2961 spdk_iscsi_task_put(task); 2962 SPDK_ERRLOG("Reject scsi cmd with EDTL > 0 but (R | W) == 0\n"); 2963 return spdk_iscsi_reject(conn, pdu, ISCSI_REASON_INVALID_PDU_FIELD); 2964 } 2965 } 2966 2967 spdk_iscsi_queue_task(conn, task); 2968 return 0; 2969 } 2970 2971 static void 2972 spdk_abort_transfer_task_in_task_mgmt_resp(struct spdk_iscsi_conn *conn, 2973 struct spdk_iscsi_task *task) 2974 { 2975 struct spdk_iscsi_pdu *pdu; 2976 2977 pdu = spdk_iscsi_task_get_pdu(task); 2978 2979 switch (task->scsi.function) { 2980 /* abort task identified by Reference Task Tag field */ 2981 case ISCSI_TASK_FUNC_ABORT_TASK: 2982 spdk_del_transfer_task(conn, task->scsi.abort_id); 2983 break; 2984 2985 /* abort all tasks issued via this session on the LUN */ 2986 case ISCSI_TASK_FUNC_ABORT_TASK_SET: 2987 spdk_clear_all_transfer_task(conn, task->scsi.lun, pdu); 2988 break; 2989 2990 case ISCSI_TASK_FUNC_LOGICAL_UNIT_RESET: 2991 spdk_clear_all_transfer_task(conn, task->scsi.lun, pdu); 2992 break; 2993 } 2994 } 2995 2996 void 2997 spdk_iscsi_task_mgmt_response(struct spdk_iscsi_conn *conn, 2998 struct spdk_iscsi_task *task) 2999 { 3000 struct spdk_iscsi_pdu *rsp_pdu; 3001 struct iscsi_bhs_task_req *reqh; 3002 struct iscsi_bhs_task_resp *rsph; 3003 3004 if (task->pdu == NULL) { 3005 /* 3006 * This was an internally generated task management command, 3007 * usually from LUN cleanup when a connection closes. 3008 */ 3009 return; 3010 } 3011 3012 reqh = (struct iscsi_bhs_task_req *)&task->pdu->bhs; 3013 /* response PDU */ 3014 rsp_pdu = spdk_get_pdu(); 3015 rsph = (struct iscsi_bhs_task_resp *)&rsp_pdu->bhs; 3016 rsph->opcode = ISCSI_OP_TASK_RSP; 3017 rsph->flags |= 0x80; /* bit 0 default to 1 */ 3018 switch (task->scsi.response) { 3019 case SPDK_SCSI_TASK_MGMT_RESP_COMPLETE: 3020 spdk_abort_transfer_task_in_task_mgmt_resp(conn, task); 3021 rsph->response = ISCSI_TASK_FUNC_RESP_COMPLETE; 3022 break; 3023 case SPDK_SCSI_TASK_MGMT_RESP_SUCCESS: 3024 spdk_abort_transfer_task_in_task_mgmt_resp(conn, task); 3025 rsph->response = ISCSI_TASK_FUNC_RESP_COMPLETE; 3026 break; 3027 case SPDK_SCSI_TASK_MGMT_RESP_REJECT: 3028 rsph->response = ISCSI_TASK_FUNC_REJECTED; 3029 break; 3030 case SPDK_SCSI_TASK_MGMT_RESP_INVALID_LUN: 3031 rsph->response = ISCSI_TASK_FUNC_RESP_LUN_NOT_EXIST; 3032 break; 3033 case SPDK_SCSI_TASK_MGMT_RESP_TARGET_FAILURE: 3034 rsph->response = ISCSI_TASK_FUNC_REJECTED; 3035 break; 3036 case SPDK_SCSI_TASK_MGMT_RESP_REJECT_FUNC_NOT_SUPPORTED: 3037 rsph->response = ISCSI_TASK_FUNC_RESP_FUNC_NOT_SUPPORTED; 3038 break; 3039 } 3040 rsph->itt = reqh->itt; 3041 3042 to_be32(&rsph->stat_sn, conn->StatSN); 3043 conn->StatSN++; 3044 3045 if (reqh->immediate == 0) { 3046 conn->sess->MaxCmdSN++; 3047 } 3048 3049 to_be32(&rsph->exp_cmd_sn, conn->sess->ExpCmdSN); 3050 to_be32(&rsph->max_cmd_sn, conn->sess->MaxCmdSN); 3051 3052 spdk_iscsi_conn_write_pdu(conn, rsp_pdu); 3053 } 3054 3055 void spdk_iscsi_task_response(struct spdk_iscsi_conn *conn, 3056 struct spdk_iscsi_task *task) 3057 { 3058 struct spdk_iscsi_pdu *rsp_pdu; 3059 struct iscsi_bhs_scsi_resp *rsph; 3060 uint32_t task_tag; 3061 uint32_t transfer_len; 3062 size_t residual_len; 3063 size_t data_len; 3064 int O_bit, U_bit; 3065 int rc; 3066 struct spdk_iscsi_task *primary; 3067 3068 primary = spdk_iscsi_task_get_primary(task); 3069 3070 transfer_len = primary->scsi.transfer_len; 3071 task_tag = task->tag; 3072 3073 /* transfer data from logical unit */ 3074 /* (direction is view of initiator side) */ 3075 if (spdk_iscsi_task_is_read(primary)) { 3076 rc = spdk_iscsi_transfer_in(conn, task); 3077 if (rc > 0) { 3078 /* sent status by last DATAIN PDU */ 3079 return; 3080 } 3081 3082 if (primary->bytes_completed != primary->scsi.transfer_len) { 3083 return; 3084 } 3085 } 3086 3087 O_bit = U_bit = 0; 3088 residual_len = 0; 3089 data_len = primary->scsi.data_transferred; 3090 3091 if ((transfer_len != 0) && 3092 (task->scsi.status == SPDK_SCSI_STATUS_GOOD)) { 3093 if (data_len < transfer_len) { 3094 /* underflow */ 3095 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Underflow %zu/%u\n", data_len, transfer_len); 3096 residual_len = transfer_len - data_len; 3097 U_bit = 1; 3098 } else if (data_len > transfer_len) { 3099 /* overflow */ 3100 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Overflow %zu/%u\n", data_len, transfer_len); 3101 residual_len = data_len - transfer_len; 3102 O_bit = 1; 3103 } else { 3104 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Transfer %u\n", transfer_len); 3105 } 3106 } 3107 3108 /* response PDU */ 3109 rsp_pdu = spdk_get_pdu(); 3110 assert(rsp_pdu != NULL); 3111 rsph = (struct iscsi_bhs_scsi_resp *)&rsp_pdu->bhs; 3112 assert(task->scsi.sense_data_len <= sizeof(rsp_pdu->sense.data)); 3113 memcpy(rsp_pdu->sense.data, task->scsi.sense_data, task->scsi.sense_data_len); 3114 to_be16(&rsp_pdu->sense.length, task->scsi.sense_data_len); 3115 rsp_pdu->data = (uint8_t *)&rsp_pdu->sense; 3116 rsp_pdu->data_from_mempool = true; 3117 3118 /* 3119 * we need to hold onto this task/cmd because until the 3120 * PDU has been written out 3121 */ 3122 rsp_pdu->task = task; 3123 task->scsi.ref++; 3124 3125 rsph->opcode = ISCSI_OP_SCSI_RSP; 3126 rsph->flags |= 0x80; /* bit 0 is default to 1 */ 3127 3128 if (O_bit) { 3129 rsph->flags |= ISCSI_SCSI_OVERFLOW; 3130 } 3131 3132 if (U_bit) { 3133 rsph->flags |= ISCSI_SCSI_UNDERFLOW; 3134 } 3135 3136 rsph->status = task->scsi.status; 3137 if (task->scsi.sense_data_len) { 3138 /* SenseLength (2 bytes) + SenseData */ 3139 DSET24(rsph->data_segment_len, 2 + task->scsi.sense_data_len); 3140 } 3141 to_be32(&rsph->itt, task_tag); 3142 3143 to_be32(&rsph->stat_sn, conn->StatSN); 3144 conn->StatSN++; 3145 3146 if (!spdk_iscsi_task_is_immediate(primary)) { 3147 conn->sess->MaxCmdSN++; 3148 } 3149 3150 to_be32(&rsph->exp_cmd_sn, conn->sess->ExpCmdSN); 3151 to_be32(&rsph->max_cmd_sn, conn->sess->MaxCmdSN); 3152 3153 to_be32(&rsph->bi_read_res_cnt, 0); 3154 to_be32(&rsph->res_cnt, residual_len); 3155 3156 spdk_iscsi_conn_write_pdu(conn, rsp_pdu); 3157 } 3158 3159 static struct spdk_iscsi_task * 3160 spdk_get_transfer_task(struct spdk_iscsi_conn *conn, uint32_t transfer_tag) 3161 { 3162 int i; 3163 3164 for (i = 0; i < conn->pending_r2t; i++) { 3165 if (conn->outstanding_r2t_tasks[i]->ttt == transfer_tag) { 3166 return (conn->outstanding_r2t_tasks[i]); 3167 } 3168 } 3169 3170 return NULL; 3171 } 3172 3173 static int 3174 _spdk_iscsi_conn_abort_queued_datain_task(struct spdk_iscsi_conn *conn, 3175 struct spdk_iscsi_task *task) 3176 { 3177 struct spdk_iscsi_task *subtask; 3178 uint32_t remaining_size; 3179 3180 while (conn->data_in_cnt < MAX_LARGE_DATAIN_PER_CONNECTION) { 3181 assert(task->current_datain_offset <= task->scsi.transfer_len); 3182 3183 /* If no IO is submitted yet, just abort the primary task. */ 3184 if (task->current_datain_offset == 0) { 3185 TAILQ_REMOVE(&conn->queued_datain_tasks, task, link); 3186 spdk_scsi_task_process_abort(&task->scsi); 3187 spdk_iscsi_task_cpl(&task->scsi); 3188 return 0; 3189 } 3190 3191 /* If any IO is submitted already, abort all subtasks by repetition. */ 3192 if (task->current_datain_offset < task->scsi.transfer_len) { 3193 remaining_size = task->scsi.transfer_len - task->current_datain_offset; 3194 subtask = spdk_iscsi_task_get(conn, task, spdk_iscsi_task_cpl); 3195 assert(subtask != NULL); 3196 subtask->scsi.offset = task->current_datain_offset; 3197 subtask->scsi.length = DMIN32(SPDK_BDEV_LARGE_BUF_MAX_SIZE, remaining_size); 3198 spdk_scsi_task_set_data(&subtask->scsi, NULL, 0); 3199 task->current_datain_offset += subtask->scsi.length; 3200 conn->data_in_cnt++; 3201 3202 subtask->scsi.transfer_len = subtask->scsi.length; 3203 spdk_scsi_task_process_abort(&subtask->scsi); 3204 spdk_iscsi_task_cpl(&subtask->scsi); 3205 3206 /* Remove the primary task from the list if this is the last subtask */ 3207 if (task->current_datain_offset == task->scsi.transfer_len) { 3208 TAILQ_REMOVE(&conn->queued_datain_tasks, task, link); 3209 return 0; 3210 } 3211 } 3212 } 3213 3214 return -1; 3215 } 3216 3217 static int 3218 spdk_iscsi_conn_abort_queued_datain_task(struct spdk_iscsi_conn *conn, 3219 uint32_t ref_task_tag) 3220 { 3221 struct spdk_iscsi_task *task; 3222 3223 TAILQ_FOREACH(task, &conn->queued_datain_tasks, link) { 3224 if (task->tag == ref_task_tag) { 3225 return _spdk_iscsi_conn_abort_queued_datain_task(conn, task); 3226 } 3227 } 3228 3229 return 0; 3230 } 3231 3232 static int 3233 spdk_iscsi_conn_abort_queued_datain_tasks(struct spdk_iscsi_conn *conn, 3234 struct spdk_scsi_lun *lun, 3235 struct spdk_iscsi_pdu *pdu) 3236 { 3237 struct spdk_iscsi_task *task, *task_tmp; 3238 struct spdk_iscsi_pdu *pdu_tmp; 3239 int rc; 3240 3241 TAILQ_FOREACH_SAFE(task, &conn->queued_datain_tasks, link, task_tmp) { 3242 pdu_tmp = spdk_iscsi_task_get_pdu(task); 3243 if ((lun == NULL || lun == task->scsi.lun) && 3244 (pdu == NULL || (SN32_LT(pdu_tmp->cmd_sn, pdu->cmd_sn)))) { 3245 rc = _spdk_iscsi_conn_abort_queued_datain_task(conn, task); 3246 if (rc != 0) { 3247 return rc; 3248 } 3249 } 3250 } 3251 3252 return 0; 3253 } 3254 3255 static int 3256 _spdk_iscsi_op_abort_task(void *arg) 3257 { 3258 struct spdk_iscsi_task *task = arg; 3259 int rc; 3260 3261 rc = spdk_iscsi_conn_abort_queued_datain_task(task->conn, 3262 task->scsi.abort_id); 3263 if (rc != 0) { 3264 return 1; 3265 } 3266 3267 spdk_poller_unregister(&task->mgmt_poller); 3268 spdk_iscsi_queue_mgmt_task(task->conn, task); 3269 return 1; 3270 } 3271 3272 static void 3273 spdk_iscsi_op_abort_task(struct spdk_iscsi_task *task, uint32_t ref_task_tag) 3274 { 3275 task->scsi.abort_id = ref_task_tag; 3276 task->scsi.function = SPDK_SCSI_TASK_FUNC_ABORT_TASK; 3277 task->mgmt_poller = spdk_poller_register(_spdk_iscsi_op_abort_task, task, 10); 3278 } 3279 3280 static int 3281 _spdk_iscsi_op_abort_task_set(void *arg) 3282 { 3283 struct spdk_iscsi_task *task = arg; 3284 int rc; 3285 3286 rc = spdk_iscsi_conn_abort_queued_datain_tasks(task->conn, task->scsi.lun, 3287 task->pdu); 3288 if (rc != 0) { 3289 return 1; 3290 } 3291 3292 spdk_poller_unregister(&task->mgmt_poller); 3293 spdk_iscsi_queue_mgmt_task(task->conn, task); 3294 return 1; 3295 } 3296 3297 void 3298 spdk_iscsi_op_abort_task_set(struct spdk_iscsi_task *task, uint8_t function) 3299 { 3300 task->scsi.function = function; 3301 task->mgmt_poller = spdk_poller_register(_spdk_iscsi_op_abort_task_set, task, 10); 3302 } 3303 3304 static int 3305 spdk_iscsi_op_task(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu) 3306 { 3307 struct iscsi_bhs_task_req *reqh; 3308 uint64_t lun; 3309 uint32_t task_tag; 3310 uint32_t ref_task_tag; 3311 uint8_t function; 3312 int lun_i; 3313 struct spdk_iscsi_task *task; 3314 struct spdk_scsi_dev *dev; 3315 3316 if (conn->sess->session_type != SESSION_TYPE_NORMAL) { 3317 SPDK_ERRLOG("ISCSI_OP_TASK not allowed in discovery and invalid session\n"); 3318 return SPDK_ISCSI_CONNECTION_FATAL; 3319 } 3320 3321 reqh = (struct iscsi_bhs_task_req *)&pdu->bhs; 3322 function = reqh->flags & ISCSI_TASK_FUNCTION_MASK; 3323 lun = from_be64(&reqh->lun); 3324 task_tag = from_be32(&reqh->itt); 3325 ref_task_tag = from_be32(&reqh->ref_task_tag); 3326 3327 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "I=%d, func=%d, ITT=%x, ref TT=%x, LUN=0x%16.16"PRIx64"\n", 3328 reqh->immediate, function, task_tag, ref_task_tag, lun); 3329 3330 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "StatSN=%u, ExpCmdSN=%u, MaxCmdSN=%u\n", 3331 conn->StatSN, conn->sess->ExpCmdSN, conn->sess->MaxCmdSN); 3332 3333 lun_i = spdk_islun2lun(lun); 3334 dev = conn->dev; 3335 3336 task = spdk_iscsi_task_get(conn, NULL, spdk_iscsi_task_mgmt_cpl); 3337 if (!task) { 3338 SPDK_ERRLOG("Unable to acquire task\n"); 3339 return SPDK_ISCSI_CONNECTION_FATAL; 3340 } 3341 3342 spdk_iscsi_task_associate_pdu(task, pdu); 3343 task->scsi.target_port = conn->target_port; 3344 task->scsi.initiator_port = conn->initiator_port; 3345 task->tag = task_tag; 3346 task->scsi.lun = spdk_scsi_dev_get_lun(dev, lun_i); 3347 3348 if (task->scsi.lun == NULL) { 3349 task->scsi.response = SPDK_SCSI_TASK_MGMT_RESP_INVALID_LUN; 3350 spdk_iscsi_task_mgmt_response(conn, task); 3351 spdk_iscsi_task_put(task); 3352 return 0; 3353 } 3354 3355 switch (function) { 3356 /* abort task identified by Referenced Task Tag field */ 3357 case ISCSI_TASK_FUNC_ABORT_TASK: 3358 SPDK_NOTICELOG("ABORT_TASK\n"); 3359 3360 spdk_iscsi_op_abort_task(task, ref_task_tag); 3361 3362 return SPDK_SUCCESS; 3363 3364 /* abort all tasks issued via this session on the LUN */ 3365 case ISCSI_TASK_FUNC_ABORT_TASK_SET: 3366 SPDK_NOTICELOG("ABORT_TASK_SET\n"); 3367 3368 spdk_iscsi_op_abort_task_set(task, SPDK_SCSI_TASK_FUNC_ABORT_TASK_SET); 3369 return SPDK_SUCCESS; 3370 3371 case ISCSI_TASK_FUNC_CLEAR_TASK_SET: 3372 task->scsi.response = SPDK_SCSI_TASK_MGMT_RESP_REJECT_FUNC_NOT_SUPPORTED; 3373 SPDK_NOTICELOG("CLEAR_TASK_SET (Unsupported)\n"); 3374 break; 3375 3376 case ISCSI_TASK_FUNC_CLEAR_ACA: 3377 task->scsi.response = SPDK_SCSI_TASK_MGMT_RESP_REJECT_FUNC_NOT_SUPPORTED; 3378 SPDK_NOTICELOG("CLEAR_ACA (Unsupported)\n"); 3379 break; 3380 3381 case ISCSI_TASK_FUNC_LOGICAL_UNIT_RESET: 3382 SPDK_NOTICELOG("LOGICAL_UNIT_RESET\n"); 3383 3384 spdk_iscsi_op_abort_task_set(task, SPDK_SCSI_TASK_FUNC_LUN_RESET); 3385 return SPDK_SUCCESS; 3386 3387 case ISCSI_TASK_FUNC_TARGET_WARM_RESET: 3388 SPDK_NOTICELOG("TARGET_WARM_RESET (Unsupported)\n"); 3389 3390 #if 0 3391 spdk_iscsi_drop_conns(conn, conn->initiator_name, 1 /* drop all */); 3392 rc = spdk_iscsi_tgt_node_reset(conn->sess->target, lun); 3393 if (rc < 0) { 3394 SPDK_ERRLOG("tgt_node reset failed\n"); 3395 } 3396 #else 3397 task->scsi.response = SPDK_SCSI_TASK_MGMT_RESP_REJECT_FUNC_NOT_SUPPORTED; 3398 #endif 3399 break; 3400 3401 case ISCSI_TASK_FUNC_TARGET_COLD_RESET: 3402 SPDK_NOTICELOG("TARGET_COLD_RESET\n"); 3403 3404 #if 0 3405 spdk_iscsi_drop_conns(conn, conn->initiator_name, 1 /* drop all */); 3406 3407 rc = spdk_iscsi_tgt_node_reset(conn->sess->target, lun); 3408 if (rc < 0) { 3409 SPDK_ERRLOG("tgt_node reset failed\n"); 3410 } 3411 3412 conn->state = ISCSI_CONN_STATE_EXITING; 3413 #else 3414 task->scsi.response = SPDK_SCSI_TASK_MGMT_RESP_REJECT_FUNC_NOT_SUPPORTED; 3415 #endif 3416 break; 3417 3418 case ISCSI_TASK_FUNC_TASK_REASSIGN: 3419 SPDK_NOTICELOG("TASK_REASSIGN (Unsupported)\n"); 3420 task->scsi.response = SPDK_SCSI_TASK_MGMT_RESP_REJECT_FUNC_NOT_SUPPORTED; 3421 break; 3422 3423 default: 3424 SPDK_ERRLOG("unsupported function %d\n", function); 3425 task->scsi.response = SPDK_SCSI_TASK_MGMT_RESP_REJECT; 3426 break; 3427 } 3428 3429 spdk_iscsi_task_mgmt_response(conn, task); 3430 spdk_iscsi_task_put(task); 3431 return 0; 3432 } 3433 3434 static int 3435 spdk_iscsi_op_nopout(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu) 3436 { 3437 struct spdk_iscsi_pdu *rsp_pdu; 3438 struct iscsi_bhs_nop_out *reqh; 3439 struct iscsi_bhs_nop_in *rsph; 3440 uint8_t *data; 3441 uint64_t lun; 3442 uint32_t task_tag; 3443 uint32_t transfer_tag; 3444 uint32_t CmdSN; 3445 int I_bit; 3446 int data_len; 3447 3448 if (conn->sess->session_type == SESSION_TYPE_DISCOVERY) { 3449 SPDK_ERRLOG("ISCSI_OP_NOPOUT not allowed in discovery session\n"); 3450 return SPDK_ISCSI_CONNECTION_FATAL; 3451 } 3452 3453 reqh = (struct iscsi_bhs_nop_out *)&pdu->bhs; 3454 I_bit = reqh->immediate; 3455 3456 data_len = DGET24(reqh->data_segment_len); 3457 if (data_len > conn->MaxRecvDataSegmentLength) { 3458 data_len = conn->MaxRecvDataSegmentLength; 3459 } 3460 3461 lun = from_be64(&reqh->lun); 3462 task_tag = from_be32(&reqh->itt); 3463 transfer_tag = from_be32(&reqh->ttt); 3464 CmdSN = from_be32(&reqh->cmd_sn); 3465 pdu->cmd_sn = CmdSN; 3466 3467 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "I=%d, ITT=%x, TTT=%x\n", 3468 I_bit, task_tag, transfer_tag); 3469 3470 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "CmdSN=%u, StatSN=%u, ExpCmdSN=%u, MaxCmdSN=%u\n", 3471 CmdSN, conn->StatSN, conn->sess->ExpCmdSN, 3472 conn->sess->MaxCmdSN); 3473 3474 if (transfer_tag != 0xFFFFFFFF && transfer_tag != (uint32_t)conn->id) { 3475 SPDK_ERRLOG("invalid transfer tag 0x%x\n", transfer_tag); 3476 /* 3477 * Technically we should probably fail the connection here, but for now 3478 * just print the error message and continue. 3479 */ 3480 } 3481 3482 /* 3483 * We don't actually check to see if this is a response to the NOP-In 3484 * that we sent. Our goal is to just verify that the initiator is 3485 * alive and responding to commands, not to verify that it tags 3486 * NOP-Outs correctly 3487 */ 3488 conn->nop_outstanding = false; 3489 3490 if (task_tag == 0xffffffffU) { 3491 if (I_bit == 1) { 3492 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "got NOPOUT ITT=0xffffffff\n"); 3493 return SPDK_SUCCESS; 3494 } else { 3495 SPDK_ERRLOG("got NOPOUT ITT=0xffffffff, I=0\n"); 3496 return SPDK_ISCSI_CONNECTION_FATAL; 3497 } 3498 } 3499 3500 data = calloc(1, data_len); 3501 if (!data) { 3502 SPDK_ERRLOG("calloc() failed for ping data\n"); 3503 return SPDK_ISCSI_CONNECTION_FATAL; 3504 } 3505 3506 /* response of NOPOUT */ 3507 if (data_len > 0) { 3508 /* copy ping data */ 3509 memcpy(data, pdu->data, data_len); 3510 } 3511 3512 transfer_tag = 0xffffffffU; 3513 3514 /* response PDU */ 3515 rsp_pdu = spdk_get_pdu(); 3516 if (rsp_pdu == NULL) { 3517 free(data); 3518 return SPDK_ISCSI_CONNECTION_FATAL; 3519 } 3520 rsph = (struct iscsi_bhs_nop_in *)&rsp_pdu->bhs; 3521 rsp_pdu->data = data; 3522 rsph->opcode = ISCSI_OP_NOPIN; 3523 rsph->flags |= 0x80; /* bit 0 default to 1 */ 3524 DSET24(rsph->data_segment_len, data_len); 3525 to_be64(&rsph->lun, lun); 3526 to_be32(&rsph->itt, task_tag); 3527 to_be32(&rsph->ttt, transfer_tag); 3528 3529 to_be32(&rsph->stat_sn, conn->StatSN); 3530 conn->StatSN++; 3531 3532 if (I_bit == 0) { 3533 conn->sess->MaxCmdSN++; 3534 } 3535 3536 to_be32(&rsph->exp_cmd_sn, conn->sess->ExpCmdSN); 3537 to_be32(&rsph->max_cmd_sn, conn->sess->MaxCmdSN); 3538 3539 spdk_iscsi_conn_write_pdu(conn, rsp_pdu); 3540 conn->last_nopin = spdk_get_ticks(); 3541 3542 return SPDK_SUCCESS; 3543 } 3544 3545 static int 3546 spdk_add_transfer_task(struct spdk_iscsi_conn *conn, 3547 struct spdk_iscsi_task *task) 3548 { 3549 uint32_t transfer_len; 3550 size_t max_burst_len; 3551 size_t segment_len; 3552 size_t data_len; 3553 int len; 3554 int idx; 3555 int rc; 3556 int data_out_req; 3557 3558 transfer_len = task->scsi.transfer_len; 3559 data_len = spdk_iscsi_task_get_pdu(task)->data_segment_len; 3560 max_burst_len = conn->sess->MaxBurstLength; 3561 segment_len = SPDK_ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH; 3562 data_out_req = 1 + (transfer_len - data_len - 1) / segment_len; 3563 task->data_out_cnt = data_out_req; 3564 3565 /* 3566 * If we already have too many tasks using R2T, then queue this task 3567 * and start sending R2T for it after some of the tasks using R2T/data 3568 * out buffers complete. 3569 */ 3570 if (conn->pending_r2t >= DEFAULT_MAXR2T) { 3571 TAILQ_INSERT_TAIL(&conn->queued_r2t_tasks, task, link); 3572 return SPDK_SUCCESS; 3573 } 3574 3575 conn->data_out_cnt += data_out_req; 3576 idx = conn->pending_r2t++; 3577 3578 conn->outstanding_r2t_tasks[idx] = task; 3579 task->next_expected_r2t_offset = data_len; 3580 task->current_r2t_length = 0; 3581 task->R2TSN = 0; 3582 /* According to RFC3720 10.8.5, 0xffffffff is 3583 * reserved for TTT in R2T. 3584 */ 3585 if (++conn->ttt == 0xffffffffu) { 3586 conn->ttt = 0; 3587 } 3588 task->ttt = conn->ttt; 3589 3590 while (data_len != transfer_len) { 3591 len = DMIN32(max_burst_len, (transfer_len - data_len)); 3592 rc = spdk_iscsi_send_r2t(conn, task, data_len, len, 3593 task->ttt, &task->R2TSN); 3594 if (rc < 0) { 3595 SPDK_ERRLOG("iscsi_send_r2t() failed\n"); 3596 return rc; 3597 } 3598 data_len += len; 3599 task->next_r2t_offset = data_len; 3600 task->outstanding_r2t++; 3601 if (conn->sess->MaxOutstandingR2T == task->outstanding_r2t) { 3602 break; 3603 } 3604 } 3605 3606 TAILQ_INSERT_TAIL(&conn->active_r2t_tasks, task, link); 3607 return SPDK_SUCCESS; 3608 } 3609 3610 /* If there are additional large writes queued for R2Ts, start them now. 3611 * This is called when a large write is just completed or when multiple LUNs 3612 * are attached and large write tasks for the specific LUN are cleared. 3613 */ 3614 static void 3615 spdk_start_queued_transfer_tasks(struct spdk_iscsi_conn *conn) 3616 { 3617 struct spdk_iscsi_task *task, *tmp; 3618 3619 TAILQ_FOREACH_SAFE(task, &conn->queued_r2t_tasks, link, tmp) { 3620 if (conn->pending_r2t < DEFAULT_MAXR2T) { 3621 TAILQ_REMOVE(&conn->queued_r2t_tasks, task, link); 3622 spdk_add_transfer_task(conn, task); 3623 } else { 3624 break; 3625 } 3626 } 3627 } 3628 3629 void spdk_del_transfer_task(struct spdk_iscsi_conn *conn, uint32_t task_tag) 3630 { 3631 struct spdk_iscsi_task *task; 3632 int i; 3633 3634 for (i = 0; i < conn->pending_r2t; i++) { 3635 if (conn->outstanding_r2t_tasks[i]->tag == task_tag) { 3636 task = conn->outstanding_r2t_tasks[i]; 3637 conn->data_out_cnt -= task->data_out_cnt; 3638 3639 conn->pending_r2t--; 3640 for (; i < conn->pending_r2t; i++) { 3641 conn->outstanding_r2t_tasks[i] = conn->outstanding_r2t_tasks[i + 1]; 3642 } 3643 conn->outstanding_r2t_tasks[conn->pending_r2t] = NULL; 3644 break; 3645 } 3646 } 3647 3648 spdk_start_queued_transfer_tasks(conn); 3649 } 3650 3651 static void 3652 spdk_del_connection_queued_task(struct spdk_iscsi_conn *conn, void *tailq, 3653 struct spdk_scsi_lun *lun, 3654 struct spdk_iscsi_pdu *pdu) 3655 { 3656 struct spdk_iscsi_task *task, *task_tmp; 3657 struct spdk_iscsi_pdu *pdu_tmp; 3658 3659 /* 3660 * Temporary used to index spdk_scsi_task related 3661 * queues of the connection. 3662 */ 3663 TAILQ_HEAD(queued_tasks, spdk_iscsi_task) *head; 3664 head = (struct queued_tasks *)tailq; 3665 3666 TAILQ_FOREACH_SAFE(task, head, link, task_tmp) { 3667 pdu_tmp = spdk_iscsi_task_get_pdu(task); 3668 if ((lun == NULL || lun == task->scsi.lun) && 3669 (pdu == NULL || SN32_LT(pdu_tmp->cmd_sn, pdu->cmd_sn))) { 3670 TAILQ_REMOVE(head, task, link); 3671 if (lun != NULL && spdk_scsi_lun_is_removing(lun)) { 3672 spdk_scsi_task_process_null_lun(&task->scsi); 3673 spdk_iscsi_task_response(conn, task); 3674 } 3675 spdk_iscsi_task_put(task); 3676 } 3677 } 3678 } 3679 3680 void spdk_clear_all_transfer_task(struct spdk_iscsi_conn *conn, 3681 struct spdk_scsi_lun *lun, 3682 struct spdk_iscsi_pdu *pdu) 3683 { 3684 int i, j, pending_r2t; 3685 struct spdk_iscsi_task *task; 3686 struct spdk_iscsi_pdu *pdu_tmp; 3687 3688 pending_r2t = conn->pending_r2t; 3689 for (i = 0; i < pending_r2t; i++) { 3690 task = conn->outstanding_r2t_tasks[i]; 3691 pdu_tmp = spdk_iscsi_task_get_pdu(task); 3692 if ((lun == NULL || lun == task->scsi.lun) && 3693 (pdu == NULL || SN32_LT(pdu_tmp->cmd_sn, pdu->cmd_sn))) { 3694 conn->outstanding_r2t_tasks[i] = NULL; 3695 task->outstanding_r2t = 0; 3696 task->next_r2t_offset = 0; 3697 task->next_expected_r2t_offset = 0; 3698 conn->data_out_cnt -= task->data_out_cnt; 3699 conn->pending_r2t--; 3700 } 3701 } 3702 3703 for (i = 0; i < pending_r2t; i++) { 3704 if (conn->outstanding_r2t_tasks[i] != NULL) { 3705 continue; 3706 } 3707 for (j = i + 1; j < pending_r2t; j++) { 3708 if (conn->outstanding_r2t_tasks[j] != NULL) { 3709 conn->outstanding_r2t_tasks[i] = conn->outstanding_r2t_tasks[j]; 3710 conn->outstanding_r2t_tasks[j] = NULL; 3711 break; 3712 } 3713 } 3714 } 3715 3716 spdk_del_connection_queued_task(conn, &conn->active_r2t_tasks, lun, pdu); 3717 spdk_del_connection_queued_task(conn, &conn->queued_r2t_tasks, lun, pdu); 3718 3719 spdk_start_queued_transfer_tasks(conn); 3720 } 3721 3722 /* This function is used to handle the r2t snack */ 3723 static int 3724 spdk_iscsi_handle_r2t_snack(struct spdk_iscsi_conn *conn, 3725 struct spdk_iscsi_task *task, 3726 struct spdk_iscsi_pdu *pdu, uint32_t beg_run, 3727 uint32_t run_length, int32_t task_tag) 3728 { 3729 int32_t last_r2tsn; 3730 int i; 3731 3732 if (beg_run < task->acked_r2tsn) { 3733 SPDK_ERRLOG("ITT: 0x%08x, R2T SNACK requests retransmission of" 3734 "R2TSN: from 0x%08x to 0x%08x. But it has already" 3735 "ack to R2TSN:0x%08x, protocol error.\n", 3736 task_tag, beg_run, (beg_run + run_length), 3737 (task->acked_r2tsn - 1)); 3738 return spdk_iscsi_reject(conn, pdu, ISCSI_REASON_PROTOCOL_ERROR); 3739 } 3740 3741 if (run_length) { 3742 if ((beg_run + run_length) > task->R2TSN) { 3743 SPDK_ERRLOG("ITT: 0x%08x, received R2T SNACK with" 3744 "BegRun: 0x%08x, RunLength: 0x%08x, exceeds" 3745 "current R2TSN: 0x%08x, protocol error.\n", 3746 task_tag, beg_run, run_length, 3747 task->R2TSN); 3748 3749 return spdk_iscsi_reject(conn, pdu, 3750 ISCSI_REASON_INVALID_PDU_FIELD); 3751 } 3752 last_r2tsn = (beg_run + run_length); 3753 } else { 3754 last_r2tsn = task->R2TSN; 3755 } 3756 3757 for (i = beg_run; i < last_r2tsn; i++) { 3758 if (spdk_iscsi_send_r2t_recovery(conn, task, i, false) < 0) { 3759 SPDK_ERRLOG("The r2t_sn=%d of r2t_task=%p is not sent\n", i, task); 3760 } 3761 } 3762 return 0; 3763 } 3764 3765 /* This function is used to recover the data in packet */ 3766 static int 3767 spdk_iscsi_handle_recovery_datain(struct spdk_iscsi_conn *conn, 3768 struct spdk_iscsi_task *task, 3769 struct spdk_iscsi_pdu *pdu, uint32_t beg_run, 3770 uint32_t run_length, uint32_t task_tag) 3771 { 3772 struct spdk_iscsi_pdu *old_pdu, *pdu_temp; 3773 uint32_t i; 3774 struct iscsi_bhs_data_in *datain_header; 3775 uint32_t last_statsn; 3776 3777 task = spdk_iscsi_task_get_primary(task); 3778 3779 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "spdk_iscsi_handle_recovery_datain\n"); 3780 3781 if (beg_run < task->acked_data_sn) { 3782 SPDK_ERRLOG("ITT: 0x%08x, DATA IN SNACK requests retransmission of" 3783 "DATASN: from 0x%08x to 0x%08x but already acked to " 3784 "DATASN: 0x%08x protocol error\n", 3785 task_tag, beg_run, 3786 (beg_run + run_length), (task->acked_data_sn - 1)); 3787 3788 return spdk_iscsi_reject(conn, pdu, ISCSI_REASON_PROTOCOL_ERROR); 3789 } 3790 3791 if (run_length == 0) { 3792 /* as the DataSN begins at 0 */ 3793 run_length = task->datain_datasn + 1; 3794 } 3795 3796 if ((beg_run + run_length - 1) > task->datain_datasn) { 3797 SPDK_ERRLOG("Initiator requests BegRun: 0x%08x, RunLength:" 3798 "0x%08x greater than maximum DataSN: 0x%08x.\n", 3799 beg_run, run_length, task->datain_datasn); 3800 3801 return -1; 3802 } else { 3803 last_statsn = beg_run + run_length - 1; 3804 } 3805 3806 for (i = beg_run; i <= last_statsn; i++) { 3807 TAILQ_FOREACH_SAFE(old_pdu, &conn->snack_pdu_list, tailq, pdu_temp) { 3808 if (old_pdu->bhs.opcode == ISCSI_OP_SCSI_DATAIN) { 3809 datain_header = (struct iscsi_bhs_data_in *)&old_pdu->bhs; 3810 if (from_be32(&datain_header->itt) == task_tag && 3811 from_be32(&datain_header->data_sn) == i) { 3812 TAILQ_REMOVE(&conn->snack_pdu_list, old_pdu, tailq); 3813 spdk_iscsi_conn_write_pdu(conn, old_pdu); 3814 break; 3815 } 3816 } 3817 } 3818 } 3819 return 0; 3820 } 3821 3822 /* This function is used to handle the status snack */ 3823 static int 3824 spdk_iscsi_handle_status_snack(struct spdk_iscsi_conn *conn, 3825 struct spdk_iscsi_pdu *pdu) 3826 { 3827 uint32_t beg_run; 3828 uint32_t run_length; 3829 struct iscsi_bhs_snack_req *reqh; 3830 uint32_t i; 3831 uint32_t last_statsn; 3832 bool found_pdu; 3833 struct spdk_iscsi_pdu *old_pdu; 3834 3835 reqh = (struct iscsi_bhs_snack_req *)&pdu->bhs; 3836 beg_run = from_be32(&reqh->beg_run); 3837 run_length = from_be32(&reqh->run_len); 3838 3839 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "beg_run=%d, run_length=%d, conn->StatSN=" 3840 "%d, conn->exp_statsn=%d\n", beg_run, run_length, 3841 conn->StatSN, conn->exp_statsn); 3842 3843 if (!beg_run) { 3844 beg_run = conn->exp_statsn; 3845 } else if (beg_run < conn->exp_statsn) { 3846 SPDK_ERRLOG("Got Status SNACK Begrun: 0x%08x, RunLength: 0x%08x " 3847 "but already got ExpStatSN: 0x%08x on CID:%hu.\n", 3848 beg_run, run_length, conn->StatSN, conn->cid); 3849 3850 return spdk_iscsi_reject(conn, pdu, ISCSI_REASON_INVALID_PDU_FIELD); 3851 } 3852 3853 last_statsn = (!run_length) ? conn->StatSN : (beg_run + run_length); 3854 3855 for (i = beg_run; i < last_statsn; i++) { 3856 found_pdu = false; 3857 TAILQ_FOREACH(old_pdu, &conn->snack_pdu_list, tailq) { 3858 if (from_be32(&old_pdu->bhs.stat_sn) == i) { 3859 found_pdu = true; 3860 break; 3861 } 3862 } 3863 3864 if (!found_pdu) { 3865 SPDK_ERRLOG("Unable to find StatSN: 0x%08x. For a Status" 3866 "SNACK, assuming this is a proactive SNACK " 3867 "for an untransmitted StatSN, ignoring.\n", 3868 beg_run); 3869 } else { 3870 TAILQ_REMOVE(&conn->snack_pdu_list, old_pdu, tailq); 3871 spdk_iscsi_conn_write_pdu(conn, old_pdu); 3872 } 3873 } 3874 3875 return 0; 3876 } 3877 3878 /* This function is used to handle the data ack snack */ 3879 static int 3880 spdk_iscsi_handle_data_ack(struct spdk_iscsi_conn *conn, 3881 struct spdk_iscsi_pdu *pdu) 3882 { 3883 uint32_t transfer_tag; 3884 uint32_t beg_run; 3885 uint32_t run_length; 3886 struct spdk_iscsi_pdu *old_pdu; 3887 uint32_t old_datasn; 3888 struct iscsi_bhs_snack_req *reqh; 3889 struct spdk_iscsi_task *task; 3890 struct iscsi_bhs_data_in *datain_header; 3891 struct spdk_iscsi_task *primary; 3892 3893 reqh = (struct iscsi_bhs_snack_req *)&pdu->bhs; 3894 transfer_tag = from_be32(&reqh->ttt); 3895 beg_run = from_be32(&reqh->beg_run); 3896 run_length = from_be32(&reqh->run_len); 3897 task = NULL; 3898 datain_header = NULL; 3899 3900 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "beg_run=%d,transfer_tag=%d,run_len=%d\n", 3901 beg_run, transfer_tag, run_length); 3902 3903 task = spdk_get_scsi_task_from_ttt(conn, transfer_tag); 3904 if (!task) { 3905 SPDK_ERRLOG("Data ACK SNACK for TTT: 0x%08x is invalid.\n", 3906 transfer_tag); 3907 goto reject_return; 3908 } 3909 3910 primary = spdk_iscsi_task_get_primary(task); 3911 if ((run_length != 0) || (beg_run < primary->acked_data_sn)) { 3912 SPDK_ERRLOG("TTT: 0x%08x Data ACK SNACK BegRUN: %d is less than " 3913 "the next expected acked DataSN: %d\n", 3914 transfer_tag, beg_run, primary->acked_data_sn); 3915 goto reject_return; 3916 } 3917 3918 primary->acked_data_sn = beg_run; 3919 3920 /* To free the pdu */ 3921 TAILQ_FOREACH(old_pdu, &conn->snack_pdu_list, tailq) { 3922 if (old_pdu->bhs.opcode == ISCSI_OP_SCSI_DATAIN) { 3923 datain_header = (struct iscsi_bhs_data_in *) &old_pdu->bhs; 3924 old_datasn = from_be32(&datain_header->data_sn); 3925 if ((from_be32(&datain_header->ttt) == transfer_tag) && 3926 (old_datasn == beg_run - 1)) { 3927 TAILQ_REMOVE(&conn->snack_pdu_list, old_pdu, tailq); 3928 if (old_pdu->task) { 3929 spdk_iscsi_task_put(old_pdu->task); 3930 } 3931 spdk_put_pdu(old_pdu); 3932 break; 3933 } 3934 } 3935 } 3936 3937 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Received Data ACK SNACK for TTT: 0x%08x," 3938 " updated acked DataSN to 0x%08x.\n", transfer_tag, 3939 (task->acked_data_sn - 1)); 3940 3941 return 0; 3942 3943 reject_return: 3944 return spdk_iscsi_reject(conn, pdu, ISCSI_REASON_INVALID_SNACK); 3945 } 3946 3947 /* This function is used to remove the r2t pdu from snack_pdu_list by < task, r2t_sn> info */ 3948 static struct spdk_iscsi_pdu * 3949 spdk_iscsi_remove_r2t_pdu_from_snack_list(struct spdk_iscsi_conn *conn, 3950 struct spdk_iscsi_task *task, 3951 uint32_t r2t_sn) 3952 { 3953 struct spdk_iscsi_pdu *pdu; 3954 struct iscsi_bhs_r2t *r2t_header; 3955 3956 TAILQ_FOREACH(pdu, &conn->snack_pdu_list, tailq) { 3957 if (pdu->bhs.opcode == ISCSI_OP_R2T) { 3958 r2t_header = (struct iscsi_bhs_r2t *)&pdu->bhs; 3959 if (pdu->task == task && 3960 from_be32(&r2t_header->r2t_sn) == r2t_sn) { 3961 TAILQ_REMOVE(&conn->snack_pdu_list, pdu, tailq); 3962 return pdu; 3963 } 3964 } 3965 } 3966 3967 return NULL; 3968 } 3969 3970 /* This function is used re-send the r2t packet */ 3971 static int 3972 spdk_iscsi_send_r2t_recovery(struct spdk_iscsi_conn *conn, 3973 struct spdk_iscsi_task *task, uint32_t r2t_sn, 3974 bool send_new_r2tsn) 3975 { 3976 struct spdk_iscsi_pdu *pdu; 3977 struct iscsi_bhs_r2t *rsph; 3978 uint32_t transfer_len; 3979 uint32_t len; 3980 int rc; 3981 3982 /* remove the r2t pdu from the snack_list */ 3983 pdu = spdk_iscsi_remove_r2t_pdu_from_snack_list(conn, task, r2t_sn); 3984 if (!pdu) { 3985 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "No pdu is found\n"); 3986 return -1; 3987 } 3988 3989 /* flag 3990 * false: only need to re-send the old r2t with changing statsn 3991 * true: we send a r2t with new r2tsn 3992 */ 3993 if (!send_new_r2tsn) { 3994 to_be32(&pdu->bhs.stat_sn, conn->StatSN); 3995 spdk_iscsi_conn_write_pdu(conn, pdu); 3996 } else { 3997 rsph = (struct iscsi_bhs_r2t *)&pdu->bhs; 3998 transfer_len = from_be32(&rsph->desired_xfer_len); 3999 4000 /* still need to increase the acked r2tsn */ 4001 task->acked_r2tsn++; 4002 len = DMIN32(conn->sess->MaxBurstLength, (transfer_len - 4003 task->next_expected_r2t_offset)); 4004 4005 /* remove the old_r2t_pdu */ 4006 if (pdu->task) { 4007 spdk_iscsi_task_put(pdu->task); 4008 } 4009 spdk_put_pdu(pdu); 4010 4011 /* re-send a new r2t pdu */ 4012 rc = spdk_iscsi_send_r2t(conn, task, task->next_expected_r2t_offset, 4013 len, task->ttt, &task->R2TSN); 4014 if (rc < 0) { 4015 return SPDK_ISCSI_CONNECTION_FATAL; 4016 } 4017 } 4018 4019 return 0; 4020 } 4021 4022 /* This function is used to handle the snack request from the initiator */ 4023 static int 4024 spdk_iscsi_op_snack(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu) 4025 { 4026 struct iscsi_bhs_snack_req *reqh; 4027 struct spdk_iscsi_task *task; 4028 int type; 4029 uint32_t task_tag; 4030 uint32_t beg_run; 4031 uint32_t run_length; 4032 int rc; 4033 4034 if (conn->sess->session_type == SESSION_TYPE_DISCOVERY) { 4035 SPDK_ERRLOG("ISCSI_OP_SNACK not allowed in discovery session\n"); 4036 return SPDK_ISCSI_CONNECTION_FATAL; 4037 } 4038 4039 reqh = (struct iscsi_bhs_snack_req *)&pdu->bhs; 4040 if (!conn->sess->ErrorRecoveryLevel) { 4041 SPDK_ERRLOG("Got a SNACK request in ErrorRecoveryLevel=0\n"); 4042 return spdk_iscsi_reject(conn, pdu, ISCSI_REASON_PROTOCOL_ERROR); 4043 } 4044 4045 type = reqh->flags & ISCSI_FLAG_SNACK_TYPE_MASK; 4046 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "The value of type is %d\n", type); 4047 4048 switch (type) { 4049 case 0: 4050 reqh = (struct iscsi_bhs_snack_req *)&pdu->bhs; 4051 task_tag = from_be32(&reqh->itt); 4052 beg_run = from_be32(&reqh->beg_run); 4053 run_length = from_be32(&reqh->run_len); 4054 4055 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "beg_run=%d, run_length=%d, " 4056 "task_tag=%x, transfer_tag=%u\n", beg_run, 4057 run_length, task_tag, from_be32(&reqh->ttt)); 4058 4059 task = spdk_get_scsi_task_from_itt(conn, task_tag, 4060 ISCSI_OP_SCSI_DATAIN); 4061 if (task) { 4062 return spdk_iscsi_handle_recovery_datain(conn, task, pdu, 4063 beg_run, run_length, task_tag); 4064 } 4065 task = spdk_get_scsi_task_from_itt(conn, task_tag, ISCSI_OP_R2T); 4066 if (task) { 4067 return spdk_iscsi_handle_r2t_snack(conn, task, pdu, beg_run, 4068 run_length, task_tag); 4069 } 4070 SPDK_ERRLOG("It is Neither datain nor r2t recovery request\n"); 4071 rc = -1; 4072 break; 4073 case ISCSI_FLAG_SNACK_TYPE_STATUS: 4074 rc = spdk_iscsi_handle_status_snack(conn, pdu); 4075 break; 4076 case ISCSI_FLAG_SNACK_TYPE_DATA_ACK: 4077 rc = spdk_iscsi_handle_data_ack(conn, pdu); 4078 break; 4079 case ISCSI_FLAG_SNACK_TYPE_RDATA: 4080 SPDK_ERRLOG("R-Data SNACK is Not Supported int spdk\n"); 4081 rc = spdk_iscsi_reject(conn, pdu, ISCSI_REASON_PROTOCOL_ERROR); 4082 break; 4083 default: 4084 SPDK_ERRLOG("Unknown SNACK type %d, protocol error\n", type); 4085 rc = spdk_iscsi_reject(conn, pdu, ISCSI_REASON_PROTOCOL_ERROR); 4086 break; 4087 } 4088 4089 return rc; 4090 } 4091 4092 /* This function is used to refree the pdu when it is acknowledged */ 4093 static void 4094 spdk_remove_acked_pdu(struct spdk_iscsi_conn *conn, 4095 uint32_t ExpStatSN) 4096 { 4097 struct spdk_iscsi_pdu *pdu, *pdu_temp; 4098 uint32_t stat_sn; 4099 4100 conn->exp_statsn = DMIN32(ExpStatSN, conn->StatSN); 4101 TAILQ_FOREACH_SAFE(pdu, &conn->snack_pdu_list, tailq, pdu_temp) { 4102 stat_sn = from_be32(&pdu->bhs.stat_sn); 4103 if (SN32_LT(stat_sn, conn->exp_statsn)) { 4104 TAILQ_REMOVE(&conn->snack_pdu_list, pdu, tailq); 4105 spdk_iscsi_conn_free_pdu(conn, pdu); 4106 } 4107 } 4108 } 4109 4110 static int spdk_iscsi_op_data(struct spdk_iscsi_conn *conn, 4111 struct spdk_iscsi_pdu *pdu) 4112 { 4113 struct spdk_iscsi_task *task, *subtask; 4114 struct iscsi_bhs_data_out *reqh; 4115 struct spdk_scsi_lun *lun_dev; 4116 uint32_t transfer_tag; 4117 uint32_t task_tag; 4118 uint32_t transfer_len; 4119 uint32_t DataSN; 4120 uint32_t buffer_offset; 4121 uint32_t len; 4122 int F_bit; 4123 int rc; 4124 int reject_reason = ISCSI_REASON_INVALID_PDU_FIELD; 4125 4126 if (conn->sess->session_type == SESSION_TYPE_DISCOVERY) { 4127 SPDK_ERRLOG("ISCSI_OP_SCSI_DATAOUT not allowed in discovery session\n"); 4128 return SPDK_ISCSI_CONNECTION_FATAL; 4129 } 4130 4131 reqh = (struct iscsi_bhs_data_out *)&pdu->bhs; 4132 F_bit = !!(reqh->flags & ISCSI_FLAG_FINAL); 4133 transfer_tag = from_be32(&reqh->ttt); 4134 task_tag = from_be32(&reqh->itt); 4135 DataSN = from_be32(&reqh->data_sn); 4136 buffer_offset = from_be32(&reqh->buffer_offset); 4137 4138 task = spdk_get_transfer_task(conn, transfer_tag); 4139 if (task == NULL) { 4140 SPDK_ERRLOG("Not found task for transfer_tag=%x\n", transfer_tag); 4141 goto reject_return; 4142 } 4143 4144 lun_dev = spdk_scsi_dev_get_lun(conn->dev, task->lun_id); 4145 4146 if (pdu->data_segment_len > task->desired_data_transfer_length) { 4147 SPDK_ERRLOG("the dataout pdu data length is larger than the value sent by R2T PDU\n"); 4148 return SPDK_ISCSI_CONNECTION_FATAL; 4149 } 4150 4151 if (task->tag != task_tag) { 4152 SPDK_ERRLOG("The r2t task tag is %u, and the dataout task tag is %u\n", 4153 task->tag, task_tag); 4154 goto reject_return; 4155 } 4156 4157 if (DataSN != task->r2t_datasn) { 4158 SPDK_ERRLOG("DataSN(%u) exp=%d error\n", DataSN, task->r2t_datasn); 4159 if (conn->sess->ErrorRecoveryLevel >= 1) { 4160 goto send_r2t_recovery_return; 4161 } else { 4162 reject_reason = ISCSI_REASON_PROTOCOL_ERROR; 4163 goto reject_return; 4164 } 4165 } 4166 4167 if (buffer_offset != task->next_expected_r2t_offset) { 4168 SPDK_ERRLOG("offset(%u) error\n", buffer_offset); 4169 return SPDK_ISCSI_CONNECTION_FATAL; 4170 } 4171 4172 transfer_len = task->scsi.transfer_len; 4173 task->current_r2t_length += pdu->data_segment_len; 4174 task->next_expected_r2t_offset += pdu->data_segment_len; 4175 task->r2t_datasn++; 4176 4177 if (task->current_r2t_length > conn->sess->MaxBurstLength) { 4178 SPDK_ERRLOG("R2T burst(%u) > MaxBurstLength(%u)\n", 4179 task->current_r2t_length, 4180 conn->sess->MaxBurstLength); 4181 return SPDK_ISCSI_CONNECTION_FATAL; 4182 } 4183 4184 if (F_bit) { 4185 /* 4186 * This R2T burst is done. Clear the length before we 4187 * receive a PDU for the next R2T burst. 4188 */ 4189 task->current_r2t_length = 0; 4190 } 4191 4192 subtask = spdk_iscsi_task_get(conn, task, spdk_iscsi_task_cpl); 4193 if (subtask == NULL) { 4194 SPDK_ERRLOG("Unable to acquire subtask\n"); 4195 return SPDK_ISCSI_CONNECTION_FATAL; 4196 } 4197 subtask->scsi.offset = buffer_offset; 4198 subtask->scsi.length = pdu->data_segment_len; 4199 spdk_scsi_task_set_data(&subtask->scsi, pdu->data, pdu->data_segment_len); 4200 spdk_iscsi_task_associate_pdu(subtask, pdu); 4201 4202 if (task->next_expected_r2t_offset == transfer_len) { 4203 task->acked_r2tsn++; 4204 } else if (F_bit && (task->next_r2t_offset < transfer_len)) { 4205 task->acked_r2tsn++; 4206 len = DMIN32(conn->sess->MaxBurstLength, (transfer_len - 4207 task->next_r2t_offset)); 4208 rc = spdk_iscsi_send_r2t(conn, task, task->next_r2t_offset, len, 4209 task->ttt, &task->R2TSN); 4210 if (rc < 0) { 4211 SPDK_ERRLOG("iscsi_send_r2t() failed\n"); 4212 } 4213 task->next_r2t_offset += len; 4214 } 4215 4216 if (lun_dev == NULL) { 4217 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "LUN %d is removed, complete the task immediately\n", 4218 task->lun_id); 4219 subtask->scsi.transfer_len = subtask->scsi.length; 4220 spdk_scsi_task_process_null_lun(&subtask->scsi); 4221 spdk_iscsi_task_cpl(&subtask->scsi); 4222 return 0; 4223 } 4224 4225 spdk_iscsi_queue_task(conn, subtask); 4226 return 0; 4227 4228 send_r2t_recovery_return: 4229 rc = spdk_iscsi_send_r2t_recovery(conn, task, task->acked_r2tsn, true); 4230 if (rc == 0) { 4231 return 0; 4232 } 4233 4234 reject_return: 4235 return spdk_iscsi_reject(conn, pdu, reject_reason); 4236 } 4237 4238 static int 4239 spdk_iscsi_send_r2t(struct spdk_iscsi_conn *conn, 4240 struct spdk_iscsi_task *task, int offset, 4241 int len, uint32_t transfer_tag, uint32_t *R2TSN) 4242 { 4243 struct spdk_iscsi_pdu *rsp_pdu; 4244 struct iscsi_bhs_r2t *rsph; 4245 4246 /* R2T PDU */ 4247 rsp_pdu = spdk_get_pdu(); 4248 if (rsp_pdu == NULL) { 4249 return SPDK_ISCSI_CONNECTION_FATAL; 4250 } 4251 rsph = (struct iscsi_bhs_r2t *)&rsp_pdu->bhs; 4252 rsp_pdu->data = NULL; 4253 rsph->opcode = ISCSI_OP_R2T; 4254 rsph->flags |= 0x80; /* bit 0 is default to 1 */ 4255 to_be64(&rsph->lun, task->lun_id); 4256 to_be32(&rsph->itt, task->tag); 4257 to_be32(&rsph->ttt, transfer_tag); 4258 4259 to_be32(&rsph->stat_sn, conn->StatSN); 4260 to_be32(&rsph->exp_cmd_sn, conn->sess->ExpCmdSN); 4261 to_be32(&rsph->max_cmd_sn, conn->sess->MaxCmdSN); 4262 4263 to_be32(&rsph->r2t_sn, *R2TSN); 4264 *R2TSN += 1; 4265 4266 task->r2t_datasn = 0; /* next expected datasn to ack */ 4267 4268 to_be32(&rsph->buffer_offset, (uint32_t)offset); 4269 to_be32(&rsph->desired_xfer_len, (uint32_t)len); 4270 task->desired_data_transfer_length = (size_t)len; 4271 4272 /* we need to hold onto this task/cmd because until the PDU has been 4273 * written out */ 4274 rsp_pdu->task = task; 4275 task->scsi.ref++; 4276 4277 spdk_iscsi_conn_write_pdu(conn, rsp_pdu); 4278 4279 return SPDK_SUCCESS; 4280 } 4281 4282 void spdk_iscsi_send_nopin(struct spdk_iscsi_conn *conn) 4283 { 4284 struct spdk_iscsi_pdu *rsp_pdu; 4285 struct iscsi_bhs_nop_in *rsp; 4286 4287 /* Only send nopin if we have logged in and are in a normal session. */ 4288 if (conn->sess == NULL || 4289 !conn->full_feature || 4290 !spdk_iscsi_param_eq_val(conn->sess->params, "SessionType", "Normal")) { 4291 return; 4292 } 4293 4294 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "send NOPIN isid=%"PRIx64", tsih=%u, cid=%u\n", 4295 conn->sess->isid, conn->sess->tsih, conn->cid); 4296 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "StatSN=%u, ExpCmdSN=%u, MaxCmdSN=%u\n", 4297 conn->StatSN, conn->sess->ExpCmdSN, 4298 conn->sess->MaxCmdSN); 4299 4300 rsp_pdu = spdk_get_pdu(); 4301 rsp = (struct iscsi_bhs_nop_in *) &rsp_pdu->bhs; 4302 rsp_pdu->data = NULL; 4303 4304 /* 4305 * spdk_get_pdu() memset's the PDU for us, so only fill out the needed 4306 * fields. 4307 */ 4308 rsp->opcode = ISCSI_OP_NOPIN; 4309 rsp->flags = 0x80; 4310 /* 4311 * Technically the to_be32() is not needed here, since 4312 * to_be32(0xFFFFFFFU) returns 0xFFFFFFFFU. 4313 */ 4314 to_be32(&rsp->itt, 0xFFFFFFFFU); 4315 to_be32(&rsp->ttt, conn->id); 4316 to_be32(&rsp->stat_sn, conn->StatSN); 4317 to_be32(&rsp->exp_cmd_sn, conn->sess->ExpCmdSN); 4318 to_be32(&rsp->max_cmd_sn, conn->sess->MaxCmdSN); 4319 4320 spdk_iscsi_conn_write_pdu(conn, rsp_pdu); 4321 conn->last_nopin = spdk_get_ticks(); 4322 conn->nop_outstanding = true; 4323 } 4324 4325 static void 4326 spdk_init_login_reject_response(struct spdk_iscsi_pdu *pdu, struct spdk_iscsi_pdu *rsp_pdu) 4327 { 4328 struct iscsi_bhs_login_rsp *rsph; 4329 4330 memset(rsp_pdu, 0, sizeof(struct spdk_iscsi_pdu)); 4331 rsph = (struct iscsi_bhs_login_rsp *)&rsp_pdu->bhs; 4332 rsph->version_max = ISCSI_VERSION; 4333 rsph->version_act = ISCSI_VERSION; 4334 rsph->opcode = ISCSI_OP_LOGIN_RSP; 4335 rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR; 4336 rsph->status_detail = ISCSI_LOGIN_INVALID_LOGIN_REQUEST; 4337 rsph->itt = pdu->bhs.itt; 4338 } 4339 4340 int 4341 spdk_iscsi_execute(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu) 4342 { 4343 int opcode; 4344 int rc; 4345 struct spdk_iscsi_pdu *rsp_pdu = NULL; 4346 uint32_t ExpStatSN; 4347 int I_bit; 4348 struct spdk_iscsi_sess *sess; 4349 struct iscsi_bhs_scsi_req *reqh; 4350 4351 if (pdu == NULL) { 4352 return -1; 4353 } 4354 4355 opcode = pdu->bhs.opcode; 4356 reqh = (struct iscsi_bhs_scsi_req *)&pdu->bhs; 4357 pdu->cmd_sn = from_be32(&reqh->cmd_sn); 4358 4359 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "opcode %x\n", opcode); 4360 4361 if (opcode == ISCSI_OP_LOGIN) { 4362 rc = spdk_iscsi_op_login(conn, pdu); 4363 if (rc < 0) { 4364 SPDK_ERRLOG("iscsi_op_login() failed\n"); 4365 } 4366 return rc; 4367 } 4368 4369 /* connection in login phase but receive non-login opcode 4370 * return response code 0x020b to initiator. 4371 * */ 4372 if (!conn->full_feature && conn->state == ISCSI_CONN_STATE_RUNNING) { 4373 rsp_pdu = spdk_get_pdu(); 4374 if (rsp_pdu == NULL) { 4375 return SPDK_ISCSI_CONNECTION_FATAL; 4376 } 4377 spdk_init_login_reject_response(pdu, rsp_pdu); 4378 spdk_iscsi_conn_write_pdu(conn, rsp_pdu); 4379 SPDK_ERRLOG("Received opcode %d in login phase\n", opcode); 4380 return SPDK_ISCSI_LOGIN_ERROR_RESPONSE; 4381 } else if (conn->state == ISCSI_CONN_STATE_INVALID) { 4382 SPDK_ERRLOG("before Full Feature\n"); 4383 return SPDK_ISCSI_CONNECTION_FATAL; 4384 } 4385 4386 sess = conn->sess; 4387 if (!sess) { 4388 SPDK_ERRLOG("Connection has no associated session!\n"); 4389 return SPDK_ISCSI_CONNECTION_FATAL; 4390 } 4391 I_bit = reqh->immediate; 4392 if (I_bit == 0) { 4393 if (SN32_LT(pdu->cmd_sn, sess->ExpCmdSN) || 4394 SN32_GT(pdu->cmd_sn, sess->MaxCmdSN)) { 4395 if (sess->session_type == SESSION_TYPE_NORMAL && 4396 opcode != ISCSI_OP_SCSI_DATAOUT) { 4397 SPDK_ERRLOG("CmdSN(%u) ignore (ExpCmdSN=%u, MaxCmdSN=%u)\n", 4398 pdu->cmd_sn, sess->ExpCmdSN, sess->MaxCmdSN); 4399 4400 if (sess->ErrorRecoveryLevel >= 1) { 4401 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Skip the error in ERL 1 and 2\n"); 4402 } else { 4403 return SPDK_PDU_FATAL; 4404 } 4405 } 4406 } 4407 } else if (pdu->cmd_sn != sess->ExpCmdSN) { 4408 SPDK_ERRLOG("CmdSN(%u) error ExpCmdSN=%u\n", pdu->cmd_sn, sess->ExpCmdSN); 4409 4410 if (sess->ErrorRecoveryLevel >= 1) { 4411 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Skip the error in ERL 1 and 2\n"); 4412 } else if (opcode != ISCSI_OP_NOPOUT) { 4413 /* 4414 * The Linux initiator does not send valid CmdSNs for 4415 * nopout under heavy load, so do not close the 4416 * connection in that case. 4417 */ 4418 return SPDK_ISCSI_CONNECTION_FATAL; 4419 } 4420 } 4421 4422 ExpStatSN = from_be32(&reqh->exp_stat_sn); 4423 if (SN32_GT(ExpStatSN, conn->StatSN)) { 4424 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "StatSN(%u) advanced\n", ExpStatSN); 4425 ExpStatSN = conn->StatSN; 4426 } 4427 4428 if (sess->ErrorRecoveryLevel >= 1) { 4429 spdk_remove_acked_pdu(conn, ExpStatSN); 4430 } 4431 4432 if (!I_bit && opcode != ISCSI_OP_SCSI_DATAOUT) { 4433 sess->ExpCmdSN++; 4434 } 4435 4436 switch (opcode) { 4437 case ISCSI_OP_NOPOUT: 4438 rc = spdk_iscsi_op_nopout(conn, pdu); 4439 if (rc < 0) { 4440 SPDK_ERRLOG("spdk_iscsi_op_nopout() failed\n"); 4441 return rc; 4442 } 4443 break; 4444 4445 case ISCSI_OP_SCSI: 4446 rc = spdk_iscsi_op_scsi(conn, pdu); 4447 if (rc < 0) { 4448 SPDK_ERRLOG("spdk_iscsi_op_scsi() failed\n"); 4449 return rc; 4450 } 4451 break; 4452 case ISCSI_OP_TASK: 4453 rc = spdk_iscsi_op_task(conn, pdu); 4454 if (rc < 0) { 4455 SPDK_ERRLOG("spdk_iscsi_op_task() failed\n"); 4456 return rc; 4457 } 4458 break; 4459 4460 case ISCSI_OP_TEXT: 4461 rc = spdk_iscsi_op_text(conn, pdu); 4462 if (rc < 0) { 4463 SPDK_ERRLOG("spdk_iscsi_op_text() failed\n"); 4464 return rc; 4465 } 4466 break; 4467 4468 case ISCSI_OP_LOGOUT: 4469 rc = spdk_iscsi_op_logout(conn, pdu); 4470 if (rc < 0) { 4471 SPDK_ERRLOG("spdk_iscsi_op_logout() failed\n"); 4472 return rc; 4473 } 4474 break; 4475 4476 case ISCSI_OP_SCSI_DATAOUT: 4477 rc = spdk_iscsi_op_data(conn, pdu); 4478 if (rc < 0) { 4479 SPDK_ERRLOG("spdk_iscsi_op_data() failed\n"); 4480 return rc; 4481 } 4482 break; 4483 4484 case ISCSI_OP_SNACK: 4485 rc = spdk_iscsi_op_snack(conn, pdu); 4486 if (rc < 0) { 4487 SPDK_ERRLOG("spdk_iscsi_op_snack() failed\n"); 4488 return rc; 4489 } 4490 break; 4491 4492 default: 4493 SPDK_ERRLOG("unsupported opcode %x\n", opcode); 4494 return spdk_iscsi_reject(conn, pdu, ISCSI_REASON_PROTOCOL_ERROR); 4495 } 4496 4497 return 0; 4498 } 4499 4500 void spdk_free_sess(struct spdk_iscsi_sess *sess) 4501 { 4502 if (sess == NULL) { 4503 return; 4504 } 4505 4506 sess->tag = 0; 4507 sess->target = NULL; 4508 sess->session_type = SESSION_TYPE_INVALID; 4509 spdk_iscsi_param_free(sess->params); 4510 free(sess->conns); 4511 spdk_scsi_port_free(&sess->initiator_port); 4512 spdk_mempool_put(g_spdk_iscsi.session_pool, (void *)sess); 4513 } 4514 4515 static int 4516 spdk_create_iscsi_sess(struct spdk_iscsi_conn *conn, 4517 struct spdk_iscsi_tgt_node *target, 4518 enum session_type session_type) 4519 { 4520 struct spdk_iscsi_sess *sess; 4521 int rc; 4522 4523 sess = spdk_mempool_get(g_spdk_iscsi.session_pool); 4524 if (!sess) { 4525 SPDK_ERRLOG("Unable to get session object\n"); 4526 SPDK_ERRLOG("MaxSessions set to %d\n", g_spdk_iscsi.MaxSessions); 4527 return -ENOMEM; 4528 } 4529 4530 /* configuration values */ 4531 pthread_mutex_lock(&g_spdk_iscsi.mutex); 4532 4533 sess->MaxConnections = g_spdk_iscsi.MaxConnectionsPerSession; 4534 sess->MaxOutstandingR2T = DEFAULT_MAXOUTSTANDINGR2T; 4535 4536 sess->DefaultTime2Wait = g_spdk_iscsi.DefaultTime2Wait; 4537 sess->DefaultTime2Retain = g_spdk_iscsi.DefaultTime2Retain; 4538 sess->FirstBurstLength = g_spdk_iscsi.FirstBurstLength; 4539 sess->MaxBurstLength = SPDK_ISCSI_MAX_BURST_LENGTH; 4540 sess->InitialR2T = DEFAULT_INITIALR2T; 4541 sess->ImmediateData = g_spdk_iscsi.ImmediateData; 4542 sess->DataPDUInOrder = DEFAULT_DATAPDUINORDER; 4543 sess->DataSequenceInOrder = DEFAULT_DATASEQUENCEINORDER; 4544 sess->ErrorRecoveryLevel = g_spdk_iscsi.ErrorRecoveryLevel; 4545 4546 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 4547 4548 sess->tag = conn->portal->group->tag; 4549 4550 sess->conns = calloc(sess->MaxConnections, sizeof(*sess->conns)); 4551 if (!sess->conns) { 4552 SPDK_ERRLOG("calloc() failed for connection array\n"); 4553 return -ENOMEM; 4554 } 4555 4556 sess->connections = 0; 4557 4558 sess->conns[sess->connections] = conn; 4559 sess->connections++; 4560 4561 sess->params = NULL; 4562 sess->target = NULL; 4563 sess->isid = 0; 4564 sess->session_type = session_type; 4565 sess->current_text_itt = 0xffffffffU; 4566 4567 /* set default params */ 4568 rc = spdk_iscsi_sess_params_init(&sess->params); 4569 if (rc < 0) { 4570 SPDK_ERRLOG("iscsi_sess_params_init() failed\n"); 4571 goto error_return; 4572 } 4573 /* replace with config value */ 4574 rc = spdk_iscsi_param_set_int(sess->params, "MaxConnections", 4575 sess->MaxConnections); 4576 if (rc < 0) { 4577 SPDK_ERRLOG("iscsi_param_set_int() failed\n"); 4578 goto error_return; 4579 } 4580 4581 rc = spdk_iscsi_param_set_int(sess->params, "MaxOutstandingR2T", 4582 sess->MaxOutstandingR2T); 4583 if (rc < 0) { 4584 SPDK_ERRLOG("iscsi_param_set_int() failed\n"); 4585 goto error_return; 4586 } 4587 4588 rc = spdk_iscsi_param_set_int(sess->params, "DefaultTime2Wait", 4589 sess->DefaultTime2Wait); 4590 if (rc < 0) { 4591 SPDK_ERRLOG("iscsi_param_set_int() failed\n"); 4592 goto error_return; 4593 } 4594 4595 rc = spdk_iscsi_param_set_int(sess->params, "DefaultTime2Retain", 4596 sess->DefaultTime2Retain); 4597 if (rc < 0) { 4598 SPDK_ERRLOG("iscsi_param_set_int() failed\n"); 4599 goto error_return; 4600 } 4601 4602 rc = spdk_iscsi_param_set_int(sess->params, "FirstBurstLength", 4603 sess->FirstBurstLength); 4604 if (rc < 0) { 4605 SPDK_ERRLOG("iscsi_param_set_int() failed\n"); 4606 goto error_return; 4607 } 4608 4609 rc = spdk_iscsi_param_set_int(sess->params, "MaxBurstLength", 4610 sess->MaxBurstLength); 4611 if (rc < 0) { 4612 SPDK_ERRLOG("iscsi_param_set_int() failed\n"); 4613 goto error_return; 4614 } 4615 4616 rc = spdk_iscsi_param_set(sess->params, "InitialR2T", 4617 sess->InitialR2T ? "Yes" : "No"); 4618 if (rc < 0) { 4619 SPDK_ERRLOG("iscsi_param_set() failed\n"); 4620 goto error_return; 4621 } 4622 4623 rc = spdk_iscsi_param_set(sess->params, "ImmediateData", 4624 sess->ImmediateData ? "Yes" : "No"); 4625 if (rc < 0) { 4626 SPDK_ERRLOG("iscsi_param_set() failed\n"); 4627 goto error_return; 4628 } 4629 4630 rc = spdk_iscsi_param_set(sess->params, "DataPDUInOrder", 4631 sess->DataPDUInOrder ? "Yes" : "No"); 4632 if (rc < 0) { 4633 SPDK_ERRLOG("iscsi_param_set() failed\n"); 4634 goto error_return; 4635 } 4636 4637 rc = spdk_iscsi_param_set(sess->params, "DataSequenceInOrder", 4638 sess->DataSequenceInOrder ? "Yes" : "No"); 4639 if (rc < 0) { 4640 SPDK_ERRLOG("iscsi_param_set() failed\n"); 4641 goto error_return; 4642 } 4643 4644 rc = spdk_iscsi_param_set_int(sess->params, "ErrorRecoveryLevel", 4645 sess->ErrorRecoveryLevel); 4646 if (rc < 0) { 4647 SPDK_ERRLOG("iscsi_param_set_int() failed\n"); 4648 goto error_return; 4649 } 4650 4651 /* realloc buffer */ 4652 rc = spdk_iscsi_param_set_int(conn->params, "MaxRecvDataSegmentLength", 4653 conn->MaxRecvDataSegmentLength); 4654 if (rc < 0) { 4655 SPDK_ERRLOG("iscsi_param_set_int() failed\n"); 4656 goto error_return; 4657 } 4658 4659 /* sess for first connection of session */ 4660 conn->sess = sess; 4661 return 0; 4662 4663 error_return: 4664 spdk_free_sess(sess); 4665 conn->sess = NULL; 4666 return -1; 4667 } 4668 4669 static struct spdk_iscsi_sess * 4670 spdk_get_iscsi_sess_by_tsih(uint16_t tsih) 4671 { 4672 struct spdk_iscsi_sess *session; 4673 4674 if (tsih == 0 || tsih > g_spdk_iscsi.MaxSessions) { 4675 return NULL; 4676 } 4677 4678 session = g_spdk_iscsi.session[tsih - 1]; 4679 assert(tsih == session->tsih); 4680 4681 return session; 4682 } 4683 4684 static int 4685 spdk_append_iscsi_sess(struct spdk_iscsi_conn *conn, 4686 const char *initiator_port_name, uint16_t tsih, uint16_t cid) 4687 { 4688 struct spdk_iscsi_sess *sess; 4689 4690 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "append session: init port name=%s, tsih=%u, cid=%u\n", 4691 initiator_port_name, tsih, cid); 4692 4693 sess = spdk_get_iscsi_sess_by_tsih(tsih); 4694 if (sess == NULL) { 4695 SPDK_ERRLOG("spdk_get_iscsi_sess_by_tsih failed\n"); 4696 return -1; 4697 } 4698 if ((conn->portal->group->tag != sess->tag) || 4699 (strcasecmp(initiator_port_name, spdk_scsi_port_get_name(sess->initiator_port)) != 0) || 4700 (conn->target != sess->target)) { 4701 /* no match */ 4702 SPDK_ERRLOG("no MCS session for init port name=%s, tsih=%d, cid=%d\n", 4703 initiator_port_name, tsih, cid); 4704 return -1; 4705 } 4706 4707 if (sess->connections >= sess->MaxConnections) { 4708 /* no slot for connection */ 4709 SPDK_ERRLOG("too many connections for init port name=%s, tsih=%d, cid=%d\n", 4710 initiator_port_name, tsih, cid); 4711 return -1; 4712 } 4713 4714 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Connections (tsih %d): %d\n", sess->tsih, sess->connections); 4715 conn->sess = sess; 4716 4717 /* 4718 * TODO: need a mutex or other sync mechanism to protect the session's 4719 * connection list. 4720 */ 4721 sess->conns[sess->connections] = conn; 4722 sess->connections++; 4723 4724 return 0; 4725 } 4726 4727 bool spdk_iscsi_is_deferred_free_pdu(struct spdk_iscsi_pdu *pdu) 4728 { 4729 if (pdu == NULL) { 4730 return false; 4731 } 4732 4733 if (pdu->bhs.opcode == ISCSI_OP_R2T || 4734 pdu->bhs.opcode == ISCSI_OP_SCSI_DATAIN) { 4735 return true; 4736 } 4737 4738 return false; 4739 } 4740