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