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