1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2012 The FreeBSD Foundation 5 * 6 * This software was developed by Edward Tomasz Napierala under sponsorship 7 * from the FreeBSD Foundation. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 */ 31 32 #include <sys/cdefs.h> 33 __FBSDID("$FreeBSD$"); 34 35 #include <sys/param.h> 36 #include <sys/condvar.h> 37 #include <sys/conf.h> 38 #include <sys/endian.h> 39 #include <sys/eventhandler.h> 40 #include <sys/file.h> 41 #include <sys/kernel.h> 42 #include <sys/kthread.h> 43 #include <sys/lock.h> 44 #include <sys/malloc.h> 45 #include <sys/mbuf.h> 46 #include <sys/mutex.h> 47 #include <sys/module.h> 48 #include <sys/socket.h> 49 #include <sys/sockopt.h> 50 #include <sys/sysctl.h> 51 #include <sys/systm.h> 52 #include <sys/sx.h> 53 #include <vm/uma.h> 54 55 #include <cam/cam.h> 56 #include <cam/cam_ccb.h> 57 #include <cam/cam_xpt.h> 58 #include <cam/cam_debug.h> 59 #include <cam/cam_sim.h> 60 #include <cam/cam_xpt_sim.h> 61 #include <cam/cam_xpt_periph.h> 62 #include <cam/cam_periph.h> 63 #include <cam/scsi/scsi_all.h> 64 #include <cam/scsi/scsi_message.h> 65 66 #include <dev/iscsi/icl.h> 67 #include <dev/iscsi/icl_wrappers.h> 68 #include <dev/iscsi/iscsi_ioctl.h> 69 #include <dev/iscsi/iscsi_proto.h> 70 #include <dev/iscsi/iscsi.h> 71 72 #ifdef ICL_KERNEL_PROXY 73 #include <sys/socketvar.h> 74 #endif 75 76 #ifdef ICL_KERNEL_PROXY 77 FEATURE(iscsi_kernel_proxy, "iSCSI initiator built with ICL_KERNEL_PROXY"); 78 #endif 79 80 /* 81 * XXX: This is global so the iscsi_unload() can access it. 82 * Think about how to do this properly. 83 */ 84 static struct iscsi_softc *sc; 85 86 SYSCTL_NODE(_kern, OID_AUTO, iscsi, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, 87 "iSCSI initiator"); 88 static int debug = 1; 89 SYSCTL_INT(_kern_iscsi, OID_AUTO, debug, CTLFLAG_RWTUN, 90 &debug, 0, "Enable debug messages"); 91 92 static int ping_timeout = 5; 93 SYSCTL_INT(_kern_iscsi, OID_AUTO, ping_timeout, CTLFLAG_RWTUN, &ping_timeout, 94 0, "Timeout for ping (NOP-Out) requests, in seconds"); 95 static int iscsid_timeout = 60; 96 SYSCTL_INT(_kern_iscsi, OID_AUTO, iscsid_timeout, CTLFLAG_RWTUN, &iscsid_timeout, 97 0, "Time to wait for iscsid(8) to handle reconnection, in seconds"); 98 static int login_timeout = 60; 99 SYSCTL_INT(_kern_iscsi, OID_AUTO, login_timeout, CTLFLAG_RWTUN, &login_timeout, 100 0, "Time to wait for iscsid(8) to finish Login Phase, in seconds"); 101 static int maxtags = 255; 102 SYSCTL_INT(_kern_iscsi, OID_AUTO, maxtags, CTLFLAG_RWTUN, &maxtags, 103 0, "Max number of IO requests queued"); 104 static int fail_on_disconnection = 0; 105 SYSCTL_INT(_kern_iscsi, OID_AUTO, fail_on_disconnection, CTLFLAG_RWTUN, 106 &fail_on_disconnection, 0, "Destroy CAM SIM on connection failure"); 107 static int fail_on_shutdown = 1; 108 SYSCTL_INT(_kern_iscsi, OID_AUTO, fail_on_shutdown, CTLFLAG_RWTUN, 109 &fail_on_shutdown, 0, "Fail disconnected sessions on shutdown"); 110 111 static MALLOC_DEFINE(M_ISCSI, "iSCSI", "iSCSI initiator"); 112 static uma_zone_t iscsi_outstanding_zone; 113 114 #define CONN_SESSION(X) ((struct iscsi_session *)X->ic_prv0) 115 #define PDU_SESSION(X) (CONN_SESSION(X->ip_conn)) 116 117 #define ISCSI_DEBUG(X, ...) \ 118 do { \ 119 if (debug > 1) \ 120 printf("%s: " X "\n", __func__, ## __VA_ARGS__);\ 121 } while (0) 122 123 #define ISCSI_WARN(X, ...) \ 124 do { \ 125 if (debug > 0) { \ 126 printf("WARNING: %s: " X "\n", \ 127 __func__, ## __VA_ARGS__); \ 128 } \ 129 } while (0) 130 131 #define ISCSI_SESSION_DEBUG(S, X, ...) \ 132 do { \ 133 if (debug > 1) { \ 134 printf("%s: %s (%s): " X "\n", \ 135 __func__, S->is_conf.isc_target_addr, \ 136 S->is_conf.isc_target, ## __VA_ARGS__); \ 137 } \ 138 } while (0) 139 140 #define ISCSI_SESSION_WARN(S, X, ...) \ 141 do { \ 142 if (debug > 0) { \ 143 printf("WARNING: %s (%s): " X "\n", \ 144 S->is_conf.isc_target_addr, \ 145 S->is_conf.isc_target, ## __VA_ARGS__); \ 146 } \ 147 } while (0) 148 149 #define ISCSI_SESSION_LOCK(X) mtx_lock(&X->is_lock) 150 #define ISCSI_SESSION_UNLOCK(X) mtx_unlock(&X->is_lock) 151 #define ISCSI_SESSION_LOCK_ASSERT(X) mtx_assert(&X->is_lock, MA_OWNED) 152 #define ISCSI_SESSION_LOCK_ASSERT_NOT(X) mtx_assert(&X->is_lock, MA_NOTOWNED) 153 154 static int iscsi_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, 155 int mode, struct thread *td); 156 157 static struct cdevsw iscsi_cdevsw = { 158 .d_version = D_VERSION, 159 .d_ioctl = iscsi_ioctl, 160 .d_name = "iscsi", 161 }; 162 163 static void iscsi_pdu_queue_locked(struct icl_pdu *request); 164 static void iscsi_pdu_queue(struct icl_pdu *request); 165 static void iscsi_pdu_update_statsn(const struct icl_pdu *response); 166 static void iscsi_pdu_handle_nop_in(struct icl_pdu *response); 167 static void iscsi_pdu_handle_scsi_response(struct icl_pdu *response); 168 static void iscsi_pdu_handle_task_response(struct icl_pdu *response); 169 static void iscsi_pdu_handle_data_in(struct icl_pdu *response); 170 static void iscsi_pdu_handle_logout_response(struct icl_pdu *response); 171 static void iscsi_pdu_handle_r2t(struct icl_pdu *response); 172 static void iscsi_pdu_handle_async_message(struct icl_pdu *response); 173 static void iscsi_pdu_handle_reject(struct icl_pdu *response); 174 static void iscsi_session_reconnect(struct iscsi_session *is); 175 static void iscsi_session_terminate(struct iscsi_session *is); 176 static void iscsi_action(struct cam_sim *sim, union ccb *ccb); 177 static struct iscsi_outstanding *iscsi_outstanding_find(struct iscsi_session *is, 178 uint32_t initiator_task_tag); 179 static struct iscsi_outstanding *iscsi_outstanding_add(struct iscsi_session *is, 180 struct icl_pdu *request, union ccb *ccb, 181 uint32_t *initiator_task_tagp); 182 static void iscsi_outstanding_remove(struct iscsi_session *is, 183 struct iscsi_outstanding *io); 184 185 static bool 186 iscsi_pdu_prepare(struct icl_pdu *request) 187 { 188 struct iscsi_session *is; 189 struct iscsi_bhs_scsi_command *bhssc; 190 191 is = PDU_SESSION(request); 192 193 ISCSI_SESSION_LOCK_ASSERT(is); 194 195 /* 196 * We're only using fields common for all the request 197 * (initiator -> target) PDUs. 198 */ 199 bhssc = (struct iscsi_bhs_scsi_command *)request->ip_bhs; 200 201 /* 202 * Data-Out PDU does not contain CmdSN. 203 */ 204 if (bhssc->bhssc_opcode != ISCSI_BHS_OPCODE_SCSI_DATA_OUT) { 205 if (ISCSI_SNGT(is->is_cmdsn, is->is_maxcmdsn) && 206 (bhssc->bhssc_opcode & ISCSI_BHS_OPCODE_IMMEDIATE) == 0) { 207 /* 208 * Current MaxCmdSN prevents us from sending any more 209 * SCSI Command PDUs to the target; postpone the PDU. 210 * It will get resent by either iscsi_pdu_queue(), 211 * or by maintenance thread. 212 */ 213 #if 0 214 ISCSI_SESSION_DEBUG(is, "postponing send, CmdSN %u, " 215 "ExpCmdSN %u, MaxCmdSN %u, opcode 0x%x", 216 is->is_cmdsn, is->is_expcmdsn, is->is_maxcmdsn, 217 bhssc->bhssc_opcode); 218 #endif 219 return (true); 220 } 221 bhssc->bhssc_cmdsn = htonl(is->is_cmdsn); 222 if ((bhssc->bhssc_opcode & ISCSI_BHS_OPCODE_IMMEDIATE) == 0) 223 is->is_cmdsn++; 224 } 225 bhssc->bhssc_expstatsn = htonl(is->is_statsn + 1); 226 227 return (false); 228 } 229 230 static void 231 iscsi_session_send_postponed(struct iscsi_session *is) 232 { 233 struct icl_pdu *request; 234 bool postpone; 235 236 ISCSI_SESSION_LOCK_ASSERT(is); 237 238 if (STAILQ_EMPTY(&is->is_postponed)) 239 return; 240 while ((request = STAILQ_FIRST(&is->is_postponed)) != NULL) { 241 postpone = iscsi_pdu_prepare(request); 242 if (postpone) 243 return; 244 STAILQ_REMOVE_HEAD(&is->is_postponed, ip_next); 245 icl_pdu_queue(request); 246 } 247 xpt_release_simq(is->is_sim, 1); 248 } 249 250 static void 251 iscsi_pdu_queue_locked(struct icl_pdu *request) 252 { 253 struct iscsi_session *is; 254 bool postpone; 255 256 is = PDU_SESSION(request); 257 ISCSI_SESSION_LOCK_ASSERT(is); 258 iscsi_session_send_postponed(is); 259 postpone = iscsi_pdu_prepare(request); 260 if (postpone) { 261 if (STAILQ_EMPTY(&is->is_postponed)) 262 xpt_freeze_simq(is->is_sim, 1); 263 STAILQ_INSERT_TAIL(&is->is_postponed, request, ip_next); 264 return; 265 } 266 icl_pdu_queue(request); 267 } 268 269 static void 270 iscsi_pdu_queue(struct icl_pdu *request) 271 { 272 struct iscsi_session *is; 273 274 is = PDU_SESSION(request); 275 ISCSI_SESSION_LOCK(is); 276 iscsi_pdu_queue_locked(request); 277 ISCSI_SESSION_UNLOCK(is); 278 } 279 280 static void 281 iscsi_session_logout(struct iscsi_session *is) 282 { 283 struct icl_pdu *request; 284 struct iscsi_bhs_logout_request *bhslr; 285 286 request = icl_pdu_new(is->is_conn, M_NOWAIT); 287 if (request == NULL) 288 return; 289 290 bhslr = (struct iscsi_bhs_logout_request *)request->ip_bhs; 291 bhslr->bhslr_opcode = ISCSI_BHS_OPCODE_LOGOUT_REQUEST; 292 bhslr->bhslr_reason = BHSLR_REASON_CLOSE_SESSION; 293 iscsi_pdu_queue_locked(request); 294 } 295 296 static void 297 iscsi_session_terminate_task(struct iscsi_session *is, 298 struct iscsi_outstanding *io, cam_status status) 299 { 300 301 ISCSI_SESSION_LOCK_ASSERT(is); 302 303 if (io->io_ccb != NULL) { 304 io->io_ccb->ccb_h.status &= ~(CAM_SIM_QUEUED | CAM_STATUS_MASK); 305 io->io_ccb->ccb_h.status |= status; 306 if ((io->io_ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { 307 io->io_ccb->ccb_h.status |= CAM_DEV_QFRZN; 308 xpt_freeze_devq(io->io_ccb->ccb_h.path, 1); 309 ISCSI_SESSION_DEBUG(is, "freezing devq"); 310 } 311 xpt_done(io->io_ccb); 312 } 313 iscsi_outstanding_remove(is, io); 314 } 315 316 static void 317 iscsi_session_terminate_tasks(struct iscsi_session *is, cam_status status) 318 { 319 struct iscsi_outstanding *io, *tmp; 320 321 ISCSI_SESSION_LOCK_ASSERT(is); 322 323 TAILQ_FOREACH_SAFE(io, &is->is_outstanding, io_next, tmp) { 324 iscsi_session_terminate_task(is, io, status); 325 } 326 } 327 328 static void 329 iscsi_session_cleanup(struct iscsi_session *is, bool destroy_sim) 330 { 331 struct icl_pdu *pdu; 332 333 ISCSI_SESSION_LOCK_ASSERT(is); 334 335 /* 336 * Don't queue any new PDUs. 337 */ 338 if (is->is_sim != NULL && is->is_simq_frozen == false) { 339 ISCSI_SESSION_DEBUG(is, "freezing"); 340 xpt_freeze_simq(is->is_sim, 1); 341 is->is_simq_frozen = true; 342 } 343 344 /* 345 * Remove postponed PDUs. 346 */ 347 if (!STAILQ_EMPTY(&is->is_postponed)) 348 xpt_release_simq(is->is_sim, 1); 349 while ((pdu = STAILQ_FIRST(&is->is_postponed)) != NULL) { 350 STAILQ_REMOVE_HEAD(&is->is_postponed, ip_next); 351 icl_pdu_free(pdu); 352 } 353 354 if (destroy_sim == false) { 355 /* 356 * Terminate SCSI tasks, asking CAM to requeue them. 357 */ 358 iscsi_session_terminate_tasks(is, CAM_REQUEUE_REQ); 359 return; 360 } 361 362 iscsi_session_terminate_tasks(is, CAM_DEV_NOT_THERE); 363 364 if (is->is_sim == NULL) 365 return; 366 367 ISCSI_SESSION_DEBUG(is, "deregistering SIM"); 368 xpt_async(AC_LOST_DEVICE, is->is_path, NULL); 369 370 if (is->is_simq_frozen) { 371 is->is_simq_frozen = false; 372 xpt_release_simq(is->is_sim, 1); 373 } 374 375 xpt_free_path(is->is_path); 376 is->is_path = NULL; 377 xpt_bus_deregister(cam_sim_path(is->is_sim)); 378 cam_sim_free(is->is_sim, TRUE /*free_devq*/); 379 is->is_sim = NULL; 380 is->is_devq = NULL; 381 } 382 383 static void 384 iscsi_maintenance_thread_reconnect(struct iscsi_session *is) 385 { 386 /* 387 * As we will be reconnecting shortly, 388 * discard outstanding data immediately on 389 * close(), also notify peer via RST if 390 * any packets come in. 391 */ 392 struct socket *so; 393 so = is->is_conn->ic_socket; 394 if (so != NULL) { 395 struct sockopt sopt; 396 struct linger sl; 397 sopt.sopt_dir = SOPT_SET; 398 sopt.sopt_level = SOL_SOCKET; 399 sopt.sopt_name = SO_LINGER; 400 sopt.sopt_val = &sl; 401 sopt.sopt_valsize = sizeof(sl); 402 sl.l_onoff = 1; /* non-zero value enables linger option in kernel */ 403 sl.l_linger = 0; /* timeout interval in seconds */ 404 sosetopt(is->is_conn->ic_socket, &sopt); 405 } 406 407 icl_conn_close(is->is_conn); 408 409 ISCSI_SESSION_LOCK(is); 410 411 is->is_connected = false; 412 is->is_reconnecting = false; 413 is->is_login_phase = false; 414 415 #ifdef ICL_KERNEL_PROXY 416 if (is->is_login_pdu != NULL) { 417 icl_pdu_free(is->is_login_pdu); 418 is->is_login_pdu = NULL; 419 } 420 cv_signal(&is->is_login_cv); 421 #endif 422 423 if (fail_on_disconnection) { 424 ISCSI_SESSION_DEBUG(is, "connection failed, destroying devices"); 425 iscsi_session_cleanup(is, true); 426 } else { 427 iscsi_session_cleanup(is, false); 428 } 429 430 KASSERT(TAILQ_EMPTY(&is->is_outstanding), 431 ("destroying session with active tasks")); 432 KASSERT(STAILQ_EMPTY(&is->is_postponed), 433 ("destroying session with postponed PDUs")); 434 435 if (is->is_conf.isc_enable == 0 && is->is_conf.isc_discovery == 0) { 436 ISCSI_SESSION_UNLOCK(is); 437 return; 438 } 439 440 /* 441 * Request immediate reconnection from iscsid(8). 442 */ 443 //ISCSI_SESSION_DEBUG(is, "waking up iscsid(8)"); 444 is->is_waiting_for_iscsid = true; 445 strlcpy(is->is_reason, "Waiting for iscsid(8)", sizeof(is->is_reason)); 446 is->is_timeout = 0; 447 ISCSI_SESSION_UNLOCK(is); 448 cv_signal(&is->is_softc->sc_cv); 449 } 450 451 static void 452 iscsi_maintenance_thread_terminate(struct iscsi_session *is) 453 { 454 struct iscsi_softc *sc; 455 456 sc = is->is_softc; 457 sx_xlock(&sc->sc_lock); 458 TAILQ_REMOVE(&sc->sc_sessions, is, is_next); 459 sx_xunlock(&sc->sc_lock); 460 461 icl_conn_close(is->is_conn); 462 callout_drain(&is->is_callout); 463 464 ISCSI_SESSION_LOCK(is); 465 466 KASSERT(is->is_terminating, ("is_terminating == false")); 467 468 #ifdef ICL_KERNEL_PROXY 469 if (is->is_login_pdu != NULL) { 470 icl_pdu_free(is->is_login_pdu); 471 is->is_login_pdu = NULL; 472 } 473 cv_signal(&is->is_login_cv); 474 #endif 475 476 iscsi_session_cleanup(is, true); 477 478 KASSERT(TAILQ_EMPTY(&is->is_outstanding), 479 ("destroying session with active tasks")); 480 KASSERT(STAILQ_EMPTY(&is->is_postponed), 481 ("destroying session with postponed PDUs")); 482 483 ISCSI_SESSION_UNLOCK(is); 484 485 icl_conn_free(is->is_conn); 486 mtx_destroy(&is->is_lock); 487 cv_destroy(&is->is_maintenance_cv); 488 #ifdef ICL_KERNEL_PROXY 489 cv_destroy(&is->is_login_cv); 490 #endif 491 492 ISCSI_SESSION_DEBUG(is, "terminated"); 493 free(is, M_ISCSI); 494 495 /* 496 * The iscsi_unload() routine might be waiting. 497 */ 498 cv_signal(&sc->sc_cv); 499 } 500 501 static void 502 iscsi_maintenance_thread(void *arg) 503 { 504 struct iscsi_session *is = arg; 505 506 ISCSI_SESSION_LOCK(is); 507 for (;;) { 508 if (is->is_reconnecting == false && 509 is->is_terminating == false && 510 (STAILQ_EMPTY(&is->is_postponed) || 511 ISCSI_SNGT(is->is_cmdsn, is->is_maxcmdsn))) 512 cv_wait(&is->is_maintenance_cv, &is->is_lock); 513 514 /* Terminate supersedes reconnect. */ 515 if (is->is_terminating) { 516 ISCSI_SESSION_UNLOCK(is); 517 iscsi_maintenance_thread_terminate(is); 518 kthread_exit(); 519 return; 520 } 521 522 if (is->is_reconnecting) { 523 ISCSI_SESSION_UNLOCK(is); 524 iscsi_maintenance_thread_reconnect(is); 525 ISCSI_SESSION_LOCK(is); 526 continue; 527 } 528 529 iscsi_session_send_postponed(is); 530 } 531 ISCSI_SESSION_UNLOCK(is); 532 } 533 534 static void 535 iscsi_session_reconnect(struct iscsi_session *is) 536 { 537 538 /* 539 * XXX: We can't use locking here, because 540 * it's being called from various contexts. 541 * Hope it doesn't break anything. 542 */ 543 if (is->is_reconnecting) 544 return; 545 546 is->is_reconnecting = true; 547 cv_signal(&is->is_maintenance_cv); 548 } 549 550 static void 551 iscsi_session_terminate(struct iscsi_session *is) 552 { 553 554 if (is->is_terminating) 555 return; 556 557 is->is_terminating = true; 558 559 #if 0 560 iscsi_session_logout(is); 561 #endif 562 cv_signal(&is->is_maintenance_cv); 563 } 564 565 static void 566 iscsi_callout(void *context) 567 { 568 struct icl_pdu *request; 569 struct iscsi_bhs_nop_out *bhsno; 570 struct iscsi_session *is; 571 bool reconnect_needed = false; 572 sbintime_t sbt, pr; 573 574 is = context; 575 576 ISCSI_SESSION_LOCK(is); 577 if (is->is_terminating) { 578 ISCSI_SESSION_UNLOCK(is); 579 return; 580 } 581 582 sbt = mstosbt(995); 583 pr = mstosbt(10); 584 callout_schedule_sbt(&is->is_callout, sbt, pr, 0); 585 586 if (is->is_conf.isc_enable == 0) 587 goto out; 588 589 is->is_timeout++; 590 591 if (is->is_waiting_for_iscsid) { 592 if (iscsid_timeout > 0 && is->is_timeout > iscsid_timeout) { 593 ISCSI_SESSION_WARN(is, "timed out waiting for iscsid(8) " 594 "for %d seconds; reconnecting", 595 is->is_timeout); 596 reconnect_needed = true; 597 } 598 goto out; 599 } 600 601 if (is->is_login_phase) { 602 if (is->is_login_timeout > 0 && is->is_timeout > is->is_login_timeout) { 603 ISCSI_SESSION_WARN(is, "login timed out after %d seconds; " 604 "reconnecting", is->is_timeout); 605 reconnect_needed = true; 606 } 607 goto out; 608 } 609 610 if (is->is_ping_timeout <= 0) { 611 /* 612 * Pings are disabled. Don't send NOP-Out in this case. 613 * Reset the timeout, to avoid triggering reconnection, 614 * should the user decide to reenable them. 615 */ 616 is->is_timeout = 0; 617 goto out; 618 } 619 620 if (is->is_timeout >= is->is_ping_timeout) { 621 ISCSI_SESSION_WARN(is, "no ping reply (NOP-In) after %d seconds; " 622 "reconnecting", is->is_ping_timeout); 623 reconnect_needed = true; 624 goto out; 625 } 626 627 ISCSI_SESSION_UNLOCK(is); 628 629 /* 630 * If the ping was reset less than one second ago - which means 631 * that we've received some PDU during the last second - assume 632 * the traffic flows correctly and don't bother sending a NOP-Out. 633 * 634 * (It's 2 - one for one second, and one for incrementing is_timeout 635 * earlier in this routine.) 636 */ 637 if (is->is_timeout < 2) 638 return; 639 640 request = icl_pdu_new(is->is_conn, M_NOWAIT); 641 if (request == NULL) { 642 ISCSI_SESSION_WARN(is, "failed to allocate PDU"); 643 return; 644 } 645 bhsno = (struct iscsi_bhs_nop_out *)request->ip_bhs; 646 bhsno->bhsno_opcode = ISCSI_BHS_OPCODE_NOP_OUT | 647 ISCSI_BHS_OPCODE_IMMEDIATE; 648 bhsno->bhsno_flags = 0x80; 649 bhsno->bhsno_target_transfer_tag = 0xffffffff; 650 iscsi_pdu_queue(request); 651 return; 652 653 out: 654 if (is->is_terminating) { 655 ISCSI_SESSION_UNLOCK(is); 656 return; 657 } 658 659 ISCSI_SESSION_UNLOCK(is); 660 661 if (reconnect_needed) 662 iscsi_session_reconnect(is); 663 } 664 665 static void 666 iscsi_pdu_update_statsn(const struct icl_pdu *response) 667 { 668 const struct iscsi_bhs_data_in *bhsdi; 669 struct iscsi_session *is; 670 uint32_t expcmdsn, maxcmdsn, statsn; 671 672 is = PDU_SESSION(response); 673 674 ISCSI_SESSION_LOCK_ASSERT(is); 675 676 /* 677 * We're only using fields common for all the response 678 * (target -> initiator) PDUs. 679 */ 680 bhsdi = (const struct iscsi_bhs_data_in *)response->ip_bhs; 681 /* 682 * Ok, I lied. In case of Data-In, "The fields StatSN, Status, 683 * and Residual Count only have meaningful content if the S bit 684 * is set to 1", so we also need to check the bit specific for 685 * Data-In PDU. 686 */ 687 if (bhsdi->bhsdi_opcode != ISCSI_BHS_OPCODE_SCSI_DATA_IN || 688 (bhsdi->bhsdi_flags & BHSDI_FLAGS_S) != 0) { 689 statsn = ntohl(bhsdi->bhsdi_statsn); 690 if (statsn != is->is_statsn && statsn != (is->is_statsn + 1)) { 691 /* XXX: This is normal situation for MCS */ 692 ISCSI_SESSION_WARN(is, "PDU 0x%x StatSN %u != " 693 "session ExpStatSN %u (or + 1); reconnecting", 694 bhsdi->bhsdi_opcode, statsn, is->is_statsn); 695 iscsi_session_reconnect(is); 696 } 697 if (ISCSI_SNGT(statsn, is->is_statsn)) 698 is->is_statsn = statsn; 699 } 700 701 expcmdsn = ntohl(bhsdi->bhsdi_expcmdsn); 702 maxcmdsn = ntohl(bhsdi->bhsdi_maxcmdsn); 703 704 if (ISCSI_SNLT(maxcmdsn + 1, expcmdsn)) { 705 ISCSI_SESSION_DEBUG(is, 706 "PDU MaxCmdSN %u + 1 < PDU ExpCmdSN %u; ignoring", 707 maxcmdsn, expcmdsn); 708 } else { 709 if (ISCSI_SNGT(maxcmdsn, is->is_maxcmdsn)) { 710 is->is_maxcmdsn = maxcmdsn; 711 712 /* 713 * Command window increased; kick the maintanance thread 714 * to send out postponed commands. 715 */ 716 if (!STAILQ_EMPTY(&is->is_postponed)) 717 cv_signal(&is->is_maintenance_cv); 718 } else if (ISCSI_SNLT(maxcmdsn, is->is_maxcmdsn)) { 719 /* XXX: This is normal situation for MCS */ 720 ISCSI_SESSION_DEBUG(is, 721 "PDU MaxCmdSN %u < session MaxCmdSN %u; ignoring", 722 maxcmdsn, is->is_maxcmdsn); 723 } 724 725 if (ISCSI_SNGT(expcmdsn, is->is_expcmdsn)) { 726 is->is_expcmdsn = expcmdsn; 727 } else if (ISCSI_SNLT(expcmdsn, is->is_expcmdsn)) { 728 /* XXX: This is normal situation for MCS */ 729 ISCSI_SESSION_DEBUG(is, 730 "PDU ExpCmdSN %u < session ExpCmdSN %u; ignoring", 731 expcmdsn, is->is_expcmdsn); 732 } 733 } 734 735 /* 736 * Every incoming PDU - not just NOP-In - resets the ping timer. 737 * The purpose of the timeout is to reset the connection when it stalls; 738 * we don't want this to happen when NOP-In or NOP-Out ends up delayed 739 * in some queue. 740 */ 741 is->is_timeout = 0; 742 } 743 744 static void 745 iscsi_receive_callback(struct icl_pdu *response) 746 { 747 struct iscsi_session *is; 748 749 is = PDU_SESSION(response); 750 751 ISCSI_SESSION_LOCK(is); 752 753 iscsi_pdu_update_statsn(response); 754 755 #ifdef ICL_KERNEL_PROXY 756 if (is->is_login_phase) { 757 if (is->is_login_pdu == NULL) 758 is->is_login_pdu = response; 759 else 760 icl_pdu_free(response); 761 ISCSI_SESSION_UNLOCK(is); 762 cv_signal(&is->is_login_cv); 763 return; 764 } 765 #endif 766 767 /* 768 * The handling routine is responsible for freeing the PDU 769 * when it's no longer needed. 770 */ 771 switch (response->ip_bhs->bhs_opcode) { 772 case ISCSI_BHS_OPCODE_NOP_IN: 773 iscsi_pdu_handle_nop_in(response); 774 ISCSI_SESSION_UNLOCK(is); 775 break; 776 case ISCSI_BHS_OPCODE_SCSI_RESPONSE: 777 iscsi_pdu_handle_scsi_response(response); 778 /* Session lock dropped inside. */ 779 ISCSI_SESSION_LOCK_ASSERT_NOT(is); 780 break; 781 case ISCSI_BHS_OPCODE_TASK_RESPONSE: 782 iscsi_pdu_handle_task_response(response); 783 ISCSI_SESSION_UNLOCK(is); 784 break; 785 case ISCSI_BHS_OPCODE_SCSI_DATA_IN: 786 iscsi_pdu_handle_data_in(response); 787 /* Session lock dropped inside. */ 788 ISCSI_SESSION_LOCK_ASSERT_NOT(is); 789 break; 790 case ISCSI_BHS_OPCODE_LOGOUT_RESPONSE: 791 iscsi_pdu_handle_logout_response(response); 792 ISCSI_SESSION_UNLOCK(is); 793 break; 794 case ISCSI_BHS_OPCODE_R2T: 795 iscsi_pdu_handle_r2t(response); 796 ISCSI_SESSION_UNLOCK(is); 797 break; 798 case ISCSI_BHS_OPCODE_ASYNC_MESSAGE: 799 iscsi_pdu_handle_async_message(response); 800 ISCSI_SESSION_UNLOCK(is); 801 break; 802 case ISCSI_BHS_OPCODE_REJECT: 803 iscsi_pdu_handle_reject(response); 804 ISCSI_SESSION_UNLOCK(is); 805 break; 806 default: 807 ISCSI_SESSION_WARN(is, "received PDU with unsupported " 808 "opcode 0x%x; reconnecting", 809 response->ip_bhs->bhs_opcode); 810 iscsi_session_reconnect(is); 811 ISCSI_SESSION_UNLOCK(is); 812 icl_pdu_free(response); 813 } 814 } 815 816 static void 817 iscsi_error_callback(struct icl_conn *ic) 818 { 819 struct iscsi_session *is; 820 821 is = CONN_SESSION(ic); 822 823 ISCSI_SESSION_WARN(is, "connection error; reconnecting"); 824 iscsi_session_reconnect(is); 825 } 826 827 static void 828 iscsi_pdu_handle_nop_in(struct icl_pdu *response) 829 { 830 struct iscsi_session *is; 831 struct iscsi_bhs_nop_out *bhsno; 832 struct iscsi_bhs_nop_in *bhsni; 833 struct icl_pdu *request; 834 void *data = NULL; 835 size_t datasize; 836 int error; 837 838 is = PDU_SESSION(response); 839 bhsni = (struct iscsi_bhs_nop_in *)response->ip_bhs; 840 841 if (bhsni->bhsni_target_transfer_tag == 0xffffffff) { 842 /* 843 * Nothing to do; iscsi_pdu_update_statsn() already 844 * zeroed the timeout. 845 */ 846 icl_pdu_free(response); 847 return; 848 } 849 850 datasize = icl_pdu_data_segment_length(response); 851 if (datasize > 0) { 852 data = malloc(datasize, M_ISCSI, M_NOWAIT | M_ZERO); 853 if (data == NULL) { 854 ISCSI_SESSION_WARN(is, "failed to allocate memory; " 855 "reconnecting"); 856 icl_pdu_free(response); 857 iscsi_session_reconnect(is); 858 return; 859 } 860 icl_pdu_get_data(response, 0, data, datasize); 861 } 862 863 request = icl_pdu_new(response->ip_conn, M_NOWAIT); 864 if (request == NULL) { 865 ISCSI_SESSION_WARN(is, "failed to allocate memory; " 866 "reconnecting"); 867 free(data, M_ISCSI); 868 icl_pdu_free(response); 869 iscsi_session_reconnect(is); 870 return; 871 } 872 bhsno = (struct iscsi_bhs_nop_out *)request->ip_bhs; 873 bhsno->bhsno_opcode = ISCSI_BHS_OPCODE_NOP_OUT | 874 ISCSI_BHS_OPCODE_IMMEDIATE; 875 bhsno->bhsno_flags = 0x80; 876 bhsno->bhsno_initiator_task_tag = 0xffffffff; 877 bhsno->bhsno_target_transfer_tag = bhsni->bhsni_target_transfer_tag; 878 if (datasize > 0) { 879 error = icl_pdu_append_data(request, data, datasize, M_NOWAIT); 880 if (error != 0) { 881 ISCSI_SESSION_WARN(is, "failed to allocate memory; " 882 "reconnecting"); 883 free(data, M_ISCSI); 884 icl_pdu_free(request); 885 icl_pdu_free(response); 886 iscsi_session_reconnect(is); 887 return; 888 } 889 free(data, M_ISCSI); 890 } 891 892 icl_pdu_free(response); 893 iscsi_pdu_queue_locked(request); 894 } 895 896 static void 897 iscsi_pdu_handle_scsi_response(struct icl_pdu *response) 898 { 899 struct iscsi_bhs_scsi_response *bhssr; 900 struct iscsi_outstanding *io; 901 struct iscsi_session *is; 902 union ccb *ccb; 903 struct ccb_scsiio *csio; 904 size_t data_segment_len, received; 905 uint16_t sense_len; 906 uint32_t resid; 907 908 is = PDU_SESSION(response); 909 910 bhssr = (struct iscsi_bhs_scsi_response *)response->ip_bhs; 911 io = iscsi_outstanding_find(is, bhssr->bhssr_initiator_task_tag); 912 if (io == NULL || io->io_ccb == NULL) { 913 ISCSI_SESSION_WARN(is, "bad itt 0x%x", bhssr->bhssr_initiator_task_tag); 914 icl_pdu_free(response); 915 iscsi_session_reconnect(is); 916 ISCSI_SESSION_UNLOCK(is); 917 return; 918 } 919 920 ccb = io->io_ccb; 921 if (bhssr->bhssr_response == BHSSR_RESPONSE_COMMAND_COMPLETED) { 922 if (ntohl(bhssr->bhssr_expdatasn) != io->io_datasn) { 923 ISCSI_SESSION_WARN(is, 924 "ExpDataSN mismatch in SCSI Response (%u vs %u)", 925 ntohl(bhssr->bhssr_expdatasn), io->io_datasn); 926 927 /* 928 * XXX: Permit an ExpDataSN of zero for errors. 929 * 930 * This doesn't conform to RFC 7143, but some 931 * targets seem to do this. 932 */ 933 if (bhssr->bhssr_status != 0 && 934 bhssr->bhssr_expdatasn == htonl(0)) 935 goto skip_expdatasn; 936 937 icl_pdu_free(response); 938 iscsi_session_reconnect(is); 939 ISCSI_SESSION_UNLOCK(is); 940 return; 941 } 942 } else { 943 if (bhssr->bhssr_expdatasn != htonl(0)) { 944 ISCSI_SESSION_WARN(is, 945 "ExpDataSN mismatch in SCSI Response (%u vs 0)", 946 ntohl(bhssr->bhssr_expdatasn)); 947 icl_pdu_free(response); 948 iscsi_session_reconnect(is); 949 ISCSI_SESSION_UNLOCK(is); 950 return; 951 } 952 } 953 skip_expdatasn: 954 955 /* 956 * With iSER, after getting good response we can be sure 957 * that all the data has been successfully transferred. 958 */ 959 if (is->is_conn->ic_iser) { 960 resid = ntohl(bhssr->bhssr_residual_count); 961 if (bhssr->bhssr_flags & BHSSR_FLAGS_RESIDUAL_UNDERFLOW) { 962 io->io_received = ccb->csio.dxfer_len - resid; 963 } else if (bhssr->bhssr_flags & BHSSR_FLAGS_RESIDUAL_OVERFLOW) { 964 ISCSI_SESSION_WARN(is, "overflow: target indicates %d", resid); 965 } else { 966 io->io_received = ccb->csio.dxfer_len; 967 } 968 } 969 970 received = io->io_received; 971 iscsi_outstanding_remove(is, io); 972 ISCSI_SESSION_UNLOCK(is); 973 974 if (bhssr->bhssr_response != BHSSR_RESPONSE_COMMAND_COMPLETED) { 975 ISCSI_SESSION_WARN(is, "service response 0x%x", bhssr->bhssr_response); 976 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { 977 xpt_freeze_devq(ccb->ccb_h.path, 1); 978 ISCSI_SESSION_DEBUG(is, "freezing devq"); 979 } 980 ccb->ccb_h.status = CAM_REQ_CMP_ERR | CAM_DEV_QFRZN; 981 } else if (bhssr->bhssr_status == 0) { 982 ccb->ccb_h.status = CAM_REQ_CMP; 983 } else { 984 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { 985 xpt_freeze_devq(ccb->ccb_h.path, 1); 986 ISCSI_SESSION_DEBUG(is, "freezing devq"); 987 } 988 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR | CAM_DEV_QFRZN; 989 ccb->csio.scsi_status = bhssr->bhssr_status; 990 } 991 992 csio = &ccb->csio; 993 data_segment_len = icl_pdu_data_segment_length(response); 994 if (data_segment_len > 0) { 995 if (data_segment_len < sizeof(sense_len)) { 996 ISCSI_SESSION_WARN(is, "truncated data segment (%zd bytes)", 997 data_segment_len); 998 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { 999 xpt_freeze_devq(ccb->ccb_h.path, 1); 1000 ISCSI_SESSION_DEBUG(is, "freezing devq"); 1001 } 1002 ccb->ccb_h.status = CAM_REQ_CMP_ERR | CAM_DEV_QFRZN; 1003 goto out; 1004 } 1005 icl_pdu_get_data(response, 0, &sense_len, sizeof(sense_len)); 1006 sense_len = ntohs(sense_len); 1007 #if 0 1008 ISCSI_SESSION_DEBUG(is, "sense_len %d, data len %zd", 1009 sense_len, data_segment_len); 1010 #endif 1011 if (sizeof(sense_len) + sense_len > data_segment_len) { 1012 ISCSI_SESSION_WARN(is, "truncated data segment " 1013 "(%zd bytes, should be %zd)", 1014 data_segment_len, sizeof(sense_len) + sense_len); 1015 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { 1016 xpt_freeze_devq(ccb->ccb_h.path, 1); 1017 ISCSI_SESSION_DEBUG(is, "freezing devq"); 1018 } 1019 ccb->ccb_h.status = CAM_REQ_CMP_ERR | CAM_DEV_QFRZN; 1020 goto out; 1021 } else if (sizeof(sense_len) + sense_len < data_segment_len) 1022 ISCSI_SESSION_WARN(is, "oversize data segment " 1023 "(%zd bytes, should be %zd)", 1024 data_segment_len, sizeof(sense_len) + sense_len); 1025 if (sense_len > csio->sense_len) { 1026 ISCSI_SESSION_DEBUG(is, "truncating sense from %d to %d", 1027 sense_len, csio->sense_len); 1028 sense_len = csio->sense_len; 1029 } 1030 icl_pdu_get_data(response, sizeof(sense_len), &csio->sense_data, sense_len); 1031 csio->sense_resid = csio->sense_len - sense_len; 1032 ccb->ccb_h.status |= CAM_AUTOSNS_VALID; 1033 } 1034 1035 out: 1036 if (bhssr->bhssr_flags & BHSSR_FLAGS_RESIDUAL_UNDERFLOW) 1037 csio->resid = ntohl(bhssr->bhssr_residual_count); 1038 1039 if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 1040 KASSERT(received <= csio->dxfer_len, 1041 ("received > csio->dxfer_len")); 1042 if (received < csio->dxfer_len) { 1043 if (csio->resid != csio->dxfer_len - received) { 1044 ISCSI_SESSION_WARN(is, "underflow mismatch: " 1045 "target indicates %d, we calculated %zd", 1046 csio->resid, csio->dxfer_len - received); 1047 } 1048 csio->resid = csio->dxfer_len - received; 1049 } 1050 } 1051 1052 xpt_done(ccb); 1053 icl_pdu_free(response); 1054 } 1055 1056 static void 1057 iscsi_pdu_handle_task_response(struct icl_pdu *response) 1058 { 1059 struct iscsi_bhs_task_management_response *bhstmr; 1060 struct iscsi_outstanding *io, *aio; 1061 struct iscsi_session *is; 1062 1063 is = PDU_SESSION(response); 1064 1065 bhstmr = (struct iscsi_bhs_task_management_response *)response->ip_bhs; 1066 io = iscsi_outstanding_find(is, bhstmr->bhstmr_initiator_task_tag); 1067 if (io == NULL || io->io_ccb != NULL) { 1068 ISCSI_SESSION_WARN(is, "bad itt 0x%x", 1069 bhstmr->bhstmr_initiator_task_tag); 1070 icl_pdu_free(response); 1071 iscsi_session_reconnect(is); 1072 return; 1073 } 1074 1075 if (bhstmr->bhstmr_response != BHSTMR_RESPONSE_FUNCTION_COMPLETE) { 1076 ISCSI_SESSION_WARN(is, "task response 0x%x", 1077 bhstmr->bhstmr_response); 1078 } else { 1079 aio = iscsi_outstanding_find(is, io->io_referenced_task_tag); 1080 if (aio != NULL && aio->io_ccb != NULL) 1081 iscsi_session_terminate_task(is, aio, CAM_REQ_ABORTED); 1082 } 1083 1084 iscsi_outstanding_remove(is, io); 1085 icl_pdu_free(response); 1086 } 1087 1088 static void 1089 iscsi_pdu_handle_data_in(struct icl_pdu *response) 1090 { 1091 struct iscsi_bhs_data_in *bhsdi; 1092 struct iscsi_outstanding *io; 1093 struct iscsi_session *is; 1094 union ccb *ccb; 1095 struct ccb_scsiio *csio; 1096 size_t data_segment_len, received, oreceived; 1097 1098 is = PDU_SESSION(response); 1099 bhsdi = (struct iscsi_bhs_data_in *)response->ip_bhs; 1100 io = iscsi_outstanding_find(is, bhsdi->bhsdi_initiator_task_tag); 1101 if (io == NULL || io->io_ccb == NULL) { 1102 ISCSI_SESSION_WARN(is, "bad itt 0x%x", bhsdi->bhsdi_initiator_task_tag); 1103 icl_pdu_free(response); 1104 iscsi_session_reconnect(is); 1105 ISCSI_SESSION_UNLOCK(is); 1106 return; 1107 } 1108 1109 if (io->io_datasn != ntohl(bhsdi->bhsdi_datasn)) { 1110 ISCSI_SESSION_WARN(is, "received Data-In PDU with " 1111 "DataSN %u, while expected %u; dropping connection", 1112 ntohl(bhsdi->bhsdi_datasn), io->io_datasn); 1113 icl_pdu_free(response); 1114 iscsi_session_reconnect(is); 1115 ISCSI_SESSION_UNLOCK(is); 1116 return; 1117 } 1118 io->io_datasn += response->ip_additional_pdus + 1; 1119 1120 data_segment_len = icl_pdu_data_segment_length(response); 1121 if (data_segment_len == 0) { 1122 /* 1123 * "The sending of 0 length data segments should be avoided, 1124 * but initiators and targets MUST be able to properly receive 1125 * 0 length data segments." 1126 */ 1127 ISCSI_SESSION_UNLOCK(is); 1128 icl_pdu_free(response); 1129 return; 1130 } 1131 1132 /* 1133 * We need to track this for security reasons - without it, malicious target 1134 * could respond to SCSI READ without sending Data-In PDUs, which would result 1135 * in read operation on the initiator side returning random kernel data. 1136 */ 1137 if (ntohl(bhsdi->bhsdi_buffer_offset) != io->io_received) { 1138 ISCSI_SESSION_WARN(is, "data out of order; expected offset %zd, got %zd", 1139 io->io_received, (size_t)ntohl(bhsdi->bhsdi_buffer_offset)); 1140 icl_pdu_free(response); 1141 iscsi_session_reconnect(is); 1142 ISCSI_SESSION_UNLOCK(is); 1143 return; 1144 } 1145 1146 ccb = io->io_ccb; 1147 csio = &ccb->csio; 1148 1149 if (io->io_received + data_segment_len > csio->dxfer_len) { 1150 ISCSI_SESSION_WARN(is, "oversize data segment (%zd bytes " 1151 "at offset %zd, buffer is %d)", 1152 data_segment_len, io->io_received, csio->dxfer_len); 1153 icl_pdu_free(response); 1154 iscsi_session_reconnect(is); 1155 ISCSI_SESSION_UNLOCK(is); 1156 return; 1157 } 1158 1159 oreceived = io->io_received; 1160 io->io_received += data_segment_len; 1161 received = io->io_received; 1162 if ((bhsdi->bhsdi_flags & BHSDI_FLAGS_S) != 0) 1163 iscsi_outstanding_remove(is, io); 1164 ISCSI_SESSION_UNLOCK(is); 1165 1166 icl_pdu_get_data(response, 0, csio->data_ptr + oreceived, data_segment_len); 1167 1168 /* 1169 * XXX: Check F. 1170 */ 1171 if ((bhsdi->bhsdi_flags & BHSDI_FLAGS_S) == 0) { 1172 /* 1173 * Nothing more to do. 1174 */ 1175 icl_pdu_free(response); 1176 return; 1177 } 1178 1179 //ISCSI_SESSION_DEBUG(is, "got S flag; status 0x%x", bhsdi->bhsdi_status); 1180 if (bhsdi->bhsdi_status == 0) { 1181 ccb->ccb_h.status = CAM_REQ_CMP; 1182 } else { 1183 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { 1184 xpt_freeze_devq(ccb->ccb_h.path, 1); 1185 ISCSI_SESSION_DEBUG(is, "freezing devq"); 1186 } 1187 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR | CAM_DEV_QFRZN; 1188 csio->scsi_status = bhsdi->bhsdi_status; 1189 } 1190 1191 if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 1192 KASSERT(received <= csio->dxfer_len, 1193 ("received > csio->dxfer_len")); 1194 if (received < csio->dxfer_len) { 1195 csio->resid = ntohl(bhsdi->bhsdi_residual_count); 1196 if (csio->resid != csio->dxfer_len - received) { 1197 ISCSI_SESSION_WARN(is, "underflow mismatch: " 1198 "target indicates %d, we calculated %zd", 1199 csio->resid, csio->dxfer_len - received); 1200 } 1201 csio->resid = csio->dxfer_len - received; 1202 } 1203 } 1204 1205 xpt_done(ccb); 1206 icl_pdu_free(response); 1207 } 1208 1209 static void 1210 iscsi_pdu_handle_logout_response(struct icl_pdu *response) 1211 { 1212 1213 ISCSI_SESSION_DEBUG(PDU_SESSION(response), "logout response"); 1214 icl_pdu_free(response); 1215 } 1216 1217 static void 1218 iscsi_pdu_handle_r2t(struct icl_pdu *response) 1219 { 1220 struct icl_pdu *request; 1221 struct iscsi_session *is; 1222 struct iscsi_bhs_r2t *bhsr2t; 1223 struct iscsi_bhs_data_out *bhsdo; 1224 struct iscsi_outstanding *io; 1225 struct ccb_scsiio *csio; 1226 size_t off, len, max_send_data_segment_length, total_len; 1227 int error; 1228 uint32_t datasn = 0; 1229 1230 is = PDU_SESSION(response); 1231 1232 bhsr2t = (struct iscsi_bhs_r2t *)response->ip_bhs; 1233 io = iscsi_outstanding_find(is, bhsr2t->bhsr2t_initiator_task_tag); 1234 if (io == NULL || io->io_ccb == NULL) { 1235 ISCSI_SESSION_WARN(is, "bad itt 0x%x; reconnecting", 1236 bhsr2t->bhsr2t_initiator_task_tag); 1237 icl_pdu_free(response); 1238 iscsi_session_reconnect(is); 1239 return; 1240 } 1241 1242 csio = &io->io_ccb->csio; 1243 1244 if ((csio->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_OUT) { 1245 ISCSI_SESSION_WARN(is, "received R2T for read command; reconnecting"); 1246 icl_pdu_free(response); 1247 iscsi_session_reconnect(is); 1248 return; 1249 } 1250 1251 /* 1252 * XXX: Verify R2TSN. 1253 */ 1254 1255 off = ntohl(bhsr2t->bhsr2t_buffer_offset); 1256 if (off > csio->dxfer_len) { 1257 ISCSI_SESSION_WARN(is, "target requested invalid offset " 1258 "%zd, buffer is is %d; reconnecting", off, csio->dxfer_len); 1259 icl_pdu_free(response); 1260 iscsi_session_reconnect(is); 1261 return; 1262 } 1263 1264 total_len = ntohl(bhsr2t->bhsr2t_desired_data_transfer_length); 1265 if (total_len == 0 || total_len > csio->dxfer_len) { 1266 ISCSI_SESSION_WARN(is, "target requested invalid length " 1267 "%zd, buffer is %d; reconnecting", total_len, csio->dxfer_len); 1268 icl_pdu_free(response); 1269 iscsi_session_reconnect(is); 1270 return; 1271 } 1272 1273 //ISCSI_SESSION_DEBUG(is, "r2t; off %zd, len %zd", off, total_len); 1274 1275 if (is->is_conn->ic_hw_isomax != 0) 1276 max_send_data_segment_length = is->is_conn->ic_hw_isomax; 1277 else 1278 max_send_data_segment_length = 1279 is->is_conn->ic_max_send_data_segment_length; 1280 for (;;) { 1281 len = total_len; 1282 1283 if (len > max_send_data_segment_length) 1284 len = max_send_data_segment_length; 1285 1286 if (off + len > csio->dxfer_len) { 1287 ISCSI_SESSION_WARN(is, "target requested invalid " 1288 "length/offset %zd, buffer is %d; reconnecting", 1289 off + len, csio->dxfer_len); 1290 icl_pdu_free(response); 1291 iscsi_session_reconnect(is); 1292 return; 1293 } 1294 1295 request = icl_pdu_new(response->ip_conn, M_NOWAIT); 1296 if (request == NULL) { 1297 icl_pdu_free(response); 1298 iscsi_session_reconnect(is); 1299 return; 1300 } 1301 1302 bhsdo = (struct iscsi_bhs_data_out *)request->ip_bhs; 1303 bhsdo->bhsdo_opcode = ISCSI_BHS_OPCODE_SCSI_DATA_OUT; 1304 bhsdo->bhsdo_lun = bhsr2t->bhsr2t_lun; 1305 bhsdo->bhsdo_initiator_task_tag = 1306 bhsr2t->bhsr2t_initiator_task_tag; 1307 bhsdo->bhsdo_target_transfer_tag = 1308 bhsr2t->bhsr2t_target_transfer_tag; 1309 bhsdo->bhsdo_datasn = htonl(datasn); 1310 bhsdo->bhsdo_buffer_offset = htonl(off); 1311 error = icl_pdu_append_data(request, csio->data_ptr + off, len, 1312 M_NOWAIT); 1313 if (error != 0) { 1314 ISCSI_SESSION_WARN(is, "failed to allocate memory; " 1315 "reconnecting"); 1316 icl_pdu_free(request); 1317 icl_pdu_free(response); 1318 iscsi_session_reconnect(is); 1319 return; 1320 } 1321 1322 datasn += howmany(len, 1323 is->is_conn->ic_max_send_data_segment_length); 1324 off += len; 1325 total_len -= len; 1326 1327 if (total_len == 0) { 1328 bhsdo->bhsdo_flags |= BHSDO_FLAGS_F; 1329 //ISCSI_SESSION_DEBUG(is, "setting F, off %zd", off); 1330 } else { 1331 //ISCSI_SESSION_DEBUG(is, "not finished, off %zd", off); 1332 } 1333 1334 iscsi_pdu_queue_locked(request); 1335 1336 if (total_len == 0) 1337 break; 1338 } 1339 1340 icl_pdu_free(response); 1341 } 1342 1343 static void 1344 iscsi_pdu_handle_async_message(struct icl_pdu *response) 1345 { 1346 struct iscsi_bhs_asynchronous_message *bhsam; 1347 struct iscsi_session *is; 1348 1349 is = PDU_SESSION(response); 1350 bhsam = (struct iscsi_bhs_asynchronous_message *)response->ip_bhs; 1351 switch (bhsam->bhsam_async_event) { 1352 case BHSAM_EVENT_TARGET_REQUESTS_LOGOUT: 1353 ISCSI_SESSION_WARN(is, "target requests logout; removing session"); 1354 iscsi_session_logout(is); 1355 iscsi_session_terminate(is); 1356 break; 1357 case BHSAM_EVENT_TARGET_TERMINATES_CONNECTION: 1358 ISCSI_SESSION_WARN(is, "target indicates it will drop the connection"); 1359 break; 1360 case BHSAM_EVENT_TARGET_TERMINATES_SESSION: 1361 ISCSI_SESSION_WARN(is, "target indicates it will drop the session"); 1362 break; 1363 default: 1364 /* 1365 * XXX: Technically, we're obligated to also handle 1366 * parameter renegotiation. 1367 */ 1368 ISCSI_SESSION_WARN(is, "ignoring AsyncEvent %d", bhsam->bhsam_async_event); 1369 break; 1370 } 1371 1372 icl_pdu_free(response); 1373 } 1374 1375 static void 1376 iscsi_pdu_handle_reject(struct icl_pdu *response) 1377 { 1378 struct iscsi_bhs_reject *bhsr; 1379 struct iscsi_session *is; 1380 1381 is = PDU_SESSION(response); 1382 bhsr = (struct iscsi_bhs_reject *)response->ip_bhs; 1383 ISCSI_SESSION_WARN(is, "received Reject PDU, reason 0x%x; protocol error?", 1384 bhsr->bhsr_reason); 1385 1386 icl_pdu_free(response); 1387 } 1388 1389 static int 1390 iscsi_ioctl_daemon_wait(struct iscsi_softc *sc, 1391 struct iscsi_daemon_request *request) 1392 { 1393 struct iscsi_session *is; 1394 struct icl_drv_limits idl; 1395 int error; 1396 1397 sx_slock(&sc->sc_lock); 1398 for (;;) { 1399 TAILQ_FOREACH(is, &sc->sc_sessions, is_next) { 1400 ISCSI_SESSION_LOCK(is); 1401 if (is->is_conf.isc_enable == 0 && 1402 is->is_conf.isc_discovery == 0) { 1403 ISCSI_SESSION_UNLOCK(is); 1404 continue; 1405 } 1406 if (is->is_waiting_for_iscsid) 1407 break; 1408 ISCSI_SESSION_UNLOCK(is); 1409 } 1410 1411 if (is == NULL) { 1412 if (sc->sc_unloading) { 1413 sx_sunlock(&sc->sc_lock); 1414 return (ENXIO); 1415 } 1416 1417 /* 1418 * No session requires attention from iscsid(8); wait. 1419 */ 1420 error = cv_wait_sig(&sc->sc_cv, &sc->sc_lock); 1421 if (error != 0) { 1422 sx_sunlock(&sc->sc_lock); 1423 return (error); 1424 } 1425 continue; 1426 } 1427 1428 is->is_waiting_for_iscsid = false; 1429 is->is_login_phase = true; 1430 is->is_reason[0] = '\0'; 1431 ISCSI_SESSION_UNLOCK(is); 1432 1433 request->idr_session_id = is->is_id; 1434 memcpy(&request->idr_isid, &is->is_isid, 1435 sizeof(request->idr_isid)); 1436 request->idr_tsih = 0; /* New or reinstated session. */ 1437 memcpy(&request->idr_conf, &is->is_conf, 1438 sizeof(request->idr_conf)); 1439 1440 error = icl_limits(is->is_conf.isc_offload, 1441 is->is_conf.isc_iser, &idl); 1442 if (error != 0) { 1443 ISCSI_SESSION_WARN(is, "icl_limits for offload \"%s\" " 1444 "failed with error %d", is->is_conf.isc_offload, 1445 error); 1446 sx_sunlock(&sc->sc_lock); 1447 return (error); 1448 } 1449 request->idr_limits.isl_max_recv_data_segment_length = 1450 idl.idl_max_recv_data_segment_length; 1451 request->idr_limits.isl_max_send_data_segment_length = 1452 idl.idl_max_send_data_segment_length; 1453 request->idr_limits.isl_max_burst_length = 1454 idl.idl_max_burst_length; 1455 request->idr_limits.isl_first_burst_length = 1456 idl.idl_first_burst_length; 1457 1458 sx_sunlock(&sc->sc_lock); 1459 return (0); 1460 } 1461 } 1462 1463 static int 1464 iscsi_ioctl_daemon_handoff(struct iscsi_softc *sc, 1465 struct iscsi_daemon_handoff *handoff) 1466 { 1467 struct iscsi_session *is; 1468 struct icl_conn *ic; 1469 int error; 1470 1471 sx_slock(&sc->sc_lock); 1472 1473 /* 1474 * Find the session to hand off socket to. 1475 */ 1476 TAILQ_FOREACH(is, &sc->sc_sessions, is_next) { 1477 if (is->is_id == handoff->idh_session_id) 1478 break; 1479 } 1480 if (is == NULL) { 1481 sx_sunlock(&sc->sc_lock); 1482 return (ESRCH); 1483 } 1484 ISCSI_SESSION_LOCK(is); 1485 ic = is->is_conn; 1486 if (is->is_conf.isc_discovery || is->is_terminating) { 1487 ISCSI_SESSION_UNLOCK(is); 1488 sx_sunlock(&sc->sc_lock); 1489 return (EINVAL); 1490 } 1491 if (is->is_connected) { 1492 /* 1493 * This might have happened because another iscsid(8) 1494 * instance handed off the connection in the meantime. 1495 * Just return. 1496 */ 1497 ISCSI_SESSION_WARN(is, "handoff on already connected " 1498 "session"); 1499 ISCSI_SESSION_UNLOCK(is); 1500 sx_sunlock(&sc->sc_lock); 1501 return (EBUSY); 1502 } 1503 1504 strlcpy(is->is_target_alias, handoff->idh_target_alias, 1505 sizeof(is->is_target_alias)); 1506 is->is_tsih = handoff->idh_tsih; 1507 is->is_statsn = handoff->idh_statsn; 1508 is->is_protocol_level = handoff->idh_protocol_level; 1509 is->is_initial_r2t = handoff->idh_initial_r2t; 1510 is->is_immediate_data = handoff->idh_immediate_data; 1511 1512 ic->ic_max_recv_data_segment_length = 1513 handoff->idh_max_recv_data_segment_length; 1514 ic->ic_max_send_data_segment_length = 1515 handoff->idh_max_send_data_segment_length; 1516 is->is_max_burst_length = handoff->idh_max_burst_length; 1517 is->is_first_burst_length = handoff->idh_first_burst_length; 1518 1519 if (handoff->idh_header_digest == ISCSI_DIGEST_CRC32C) 1520 ic->ic_header_crc32c = true; 1521 else 1522 ic->ic_header_crc32c = false; 1523 if (handoff->idh_data_digest == ISCSI_DIGEST_CRC32C) 1524 ic->ic_data_crc32c = true; 1525 else 1526 ic->ic_data_crc32c = false; 1527 ic->ic_maxtags = maxtags; 1528 1529 is->is_cmdsn = 0; 1530 is->is_expcmdsn = 0; 1531 is->is_maxcmdsn = 0; 1532 is->is_waiting_for_iscsid = false; 1533 is->is_login_phase = false; 1534 is->is_timeout = 0; 1535 is->is_ping_timeout = is->is_conf.isc_ping_timeout; 1536 if (is->is_ping_timeout < 0) 1537 is->is_ping_timeout = ping_timeout; 1538 is->is_login_timeout = is->is_conf.isc_login_timeout; 1539 if (is->is_login_timeout < 0) 1540 is->is_login_timeout = login_timeout; 1541 is->is_connected = true; 1542 is->is_reason[0] = '\0'; 1543 1544 ISCSI_SESSION_UNLOCK(is); 1545 1546 /* 1547 * If we're going through the proxy, the idh_socket will be 0, 1548 * and the ICL module can simply ignore this call. It can also 1549 * use it to determine it's no longer in the Login phase. 1550 */ 1551 error = icl_conn_handoff(ic, handoff->idh_socket); 1552 if (error != 0) { 1553 sx_sunlock(&sc->sc_lock); 1554 iscsi_session_terminate(is); 1555 return (error); 1556 } 1557 1558 sx_sunlock(&sc->sc_lock); 1559 1560 if (is->is_sim != NULL) { 1561 /* 1562 * When reconnecting, there already is SIM allocated for the session. 1563 */ 1564 KASSERT(is->is_simq_frozen, ("reconnect without frozen simq")); 1565 ISCSI_SESSION_LOCK(is); 1566 ISCSI_SESSION_DEBUG(is, "releasing"); 1567 is->is_simq_frozen = false; 1568 xpt_release_simq(is->is_sim, 1); 1569 ISCSI_SESSION_UNLOCK(is); 1570 1571 } else { 1572 ISCSI_SESSION_LOCK(is); 1573 is->is_devq = cam_simq_alloc(ic->ic_maxtags); 1574 if (is->is_devq == NULL) { 1575 ISCSI_SESSION_UNLOCK(is); 1576 ISCSI_SESSION_WARN(is, "failed to allocate simq"); 1577 iscsi_session_terminate(is); 1578 return (ENOMEM); 1579 } 1580 1581 is->is_sim = cam_sim_alloc(iscsi_action, NULL, "iscsi", 1582 is, is->is_id /* unit */, &is->is_lock, 1583 1, ic->ic_maxtags, is->is_devq); 1584 if (is->is_sim == NULL) { 1585 ISCSI_SESSION_UNLOCK(is); 1586 ISCSI_SESSION_WARN(is, "failed to allocate SIM"); 1587 cam_simq_free(is->is_devq); 1588 iscsi_session_terminate(is); 1589 return (ENOMEM); 1590 } 1591 1592 if (xpt_bus_register(is->is_sim, NULL, 0) != 0) { 1593 ISCSI_SESSION_UNLOCK(is); 1594 ISCSI_SESSION_WARN(is, "failed to register bus"); 1595 iscsi_session_terminate(is); 1596 return (ENOMEM); 1597 } 1598 1599 error = xpt_create_path(&is->is_path, /*periph*/NULL, 1600 cam_sim_path(is->is_sim), CAM_TARGET_WILDCARD, 1601 CAM_LUN_WILDCARD); 1602 if (error != CAM_REQ_CMP) { 1603 ISCSI_SESSION_UNLOCK(is); 1604 ISCSI_SESSION_WARN(is, "failed to create path"); 1605 iscsi_session_terminate(is); 1606 return (ENOMEM); 1607 } 1608 ISCSI_SESSION_UNLOCK(is); 1609 } 1610 1611 return (0); 1612 } 1613 1614 static int 1615 iscsi_ioctl_daemon_fail(struct iscsi_softc *sc, 1616 struct iscsi_daemon_fail *fail) 1617 { 1618 struct iscsi_session *is; 1619 1620 sx_slock(&sc->sc_lock); 1621 1622 TAILQ_FOREACH(is, &sc->sc_sessions, is_next) { 1623 if (is->is_id == fail->idf_session_id) 1624 break; 1625 } 1626 if (is == NULL) { 1627 sx_sunlock(&sc->sc_lock); 1628 return (ESRCH); 1629 } 1630 ISCSI_SESSION_LOCK(is); 1631 ISCSI_SESSION_DEBUG(is, "iscsid(8) failed: %s", 1632 fail->idf_reason); 1633 strlcpy(is->is_reason, fail->idf_reason, sizeof(is->is_reason)); 1634 //is->is_waiting_for_iscsid = false; 1635 //is->is_login_phase = true; 1636 //iscsi_session_reconnect(is); 1637 ISCSI_SESSION_UNLOCK(is); 1638 sx_sunlock(&sc->sc_lock); 1639 1640 return (0); 1641 } 1642 1643 #ifdef ICL_KERNEL_PROXY 1644 static int 1645 iscsi_ioctl_daemon_connect(struct iscsi_softc *sc, 1646 struct iscsi_daemon_connect *idc) 1647 { 1648 struct iscsi_session *is; 1649 struct sockaddr *from_sa, *to_sa; 1650 int error; 1651 1652 sx_slock(&sc->sc_lock); 1653 TAILQ_FOREACH(is, &sc->sc_sessions, is_next) { 1654 if (is->is_id == idc->idc_session_id) 1655 break; 1656 } 1657 if (is == NULL) { 1658 sx_sunlock(&sc->sc_lock); 1659 return (ESRCH); 1660 } 1661 sx_sunlock(&sc->sc_lock); 1662 1663 if (idc->idc_from_addrlen > 0) { 1664 error = getsockaddr(&from_sa, (void *)idc->idc_from_addr, idc->idc_from_addrlen); 1665 if (error != 0) { 1666 ISCSI_SESSION_WARN(is, 1667 "getsockaddr failed with error %d", error); 1668 return (error); 1669 } 1670 } else { 1671 from_sa = NULL; 1672 } 1673 error = getsockaddr(&to_sa, (void *)idc->idc_to_addr, idc->idc_to_addrlen); 1674 if (error != 0) { 1675 ISCSI_SESSION_WARN(is, "getsockaddr failed with error %d", 1676 error); 1677 free(from_sa, M_SONAME); 1678 return (error); 1679 } 1680 1681 ISCSI_SESSION_LOCK(is); 1682 is->is_statsn = 0; 1683 is->is_cmdsn = 0; 1684 is->is_expcmdsn = 0; 1685 is->is_maxcmdsn = 0; 1686 is->is_waiting_for_iscsid = false; 1687 is->is_login_phase = true; 1688 is->is_timeout = 0; 1689 ISCSI_SESSION_UNLOCK(is); 1690 1691 error = icl_conn_connect(is->is_conn, idc->idc_domain, 1692 idc->idc_socktype, idc->idc_protocol, from_sa, to_sa); 1693 free(from_sa, M_SONAME); 1694 free(to_sa, M_SONAME); 1695 1696 /* 1697 * Digests are always disabled during login phase. 1698 */ 1699 is->is_conn->ic_header_crc32c = false; 1700 is->is_conn->ic_data_crc32c = false; 1701 1702 return (error); 1703 } 1704 1705 static int 1706 iscsi_ioctl_daemon_send(struct iscsi_softc *sc, 1707 struct iscsi_daemon_send *ids) 1708 { 1709 struct iscsi_session *is; 1710 struct icl_pdu *ip; 1711 size_t datalen; 1712 void *data; 1713 int error; 1714 1715 sx_slock(&sc->sc_lock); 1716 TAILQ_FOREACH(is, &sc->sc_sessions, is_next) { 1717 if (is->is_id == ids->ids_session_id) 1718 break; 1719 } 1720 if (is == NULL) { 1721 sx_sunlock(&sc->sc_lock); 1722 return (ESRCH); 1723 } 1724 sx_sunlock(&sc->sc_lock); 1725 1726 if (is->is_login_phase == false) 1727 return (EBUSY); 1728 1729 if (is->is_terminating || is->is_reconnecting) 1730 return (EIO); 1731 1732 datalen = ids->ids_data_segment_len; 1733 if (datalen > is->is_conn->ic_max_send_data_segment_length) 1734 return (EINVAL); 1735 if (datalen > 0) { 1736 data = malloc(datalen, M_ISCSI, M_WAITOK); 1737 error = copyin(ids->ids_data_segment, data, datalen); 1738 if (error != 0) { 1739 free(data, M_ISCSI); 1740 return (error); 1741 } 1742 } 1743 1744 ip = icl_pdu_new(is->is_conn, M_WAITOK); 1745 memcpy(ip->ip_bhs, ids->ids_bhs, sizeof(*ip->ip_bhs)); 1746 if (datalen > 0) { 1747 error = icl_pdu_append_data(ip, data, datalen, M_WAITOK); 1748 KASSERT(error == 0, ("icl_pdu_append_data(..., M_WAITOK) failed")); 1749 free(data, M_ISCSI); 1750 } 1751 iscsi_pdu_queue(ip); 1752 1753 return (0); 1754 } 1755 1756 static int 1757 iscsi_ioctl_daemon_receive(struct iscsi_softc *sc, 1758 struct iscsi_daemon_receive *idr) 1759 { 1760 struct iscsi_session *is; 1761 struct icl_pdu *ip; 1762 void *data; 1763 int error; 1764 1765 sx_slock(&sc->sc_lock); 1766 TAILQ_FOREACH(is, &sc->sc_sessions, is_next) { 1767 if (is->is_id == idr->idr_session_id) 1768 break; 1769 } 1770 if (is == NULL) { 1771 sx_sunlock(&sc->sc_lock); 1772 return (ESRCH); 1773 } 1774 sx_sunlock(&sc->sc_lock); 1775 1776 if (is->is_login_phase == false) 1777 return (EBUSY); 1778 1779 ISCSI_SESSION_LOCK(is); 1780 while (is->is_login_pdu == NULL && 1781 is->is_terminating == false && 1782 is->is_reconnecting == false) { 1783 error = cv_wait_sig(&is->is_login_cv, &is->is_lock); 1784 if (error != 0) { 1785 ISCSI_SESSION_UNLOCK(is); 1786 return (error); 1787 } 1788 } 1789 if (is->is_terminating || is->is_reconnecting) { 1790 ISCSI_SESSION_UNLOCK(is); 1791 return (EIO); 1792 } 1793 ip = is->is_login_pdu; 1794 is->is_login_pdu = NULL; 1795 ISCSI_SESSION_UNLOCK(is); 1796 1797 if (ip->ip_data_len > idr->idr_data_segment_len) { 1798 icl_pdu_free(ip); 1799 return (EMSGSIZE); 1800 } 1801 1802 copyout(ip->ip_bhs, idr->idr_bhs, sizeof(*ip->ip_bhs)); 1803 if (ip->ip_data_len > 0) { 1804 data = malloc(ip->ip_data_len, M_ISCSI, M_WAITOK); 1805 icl_pdu_get_data(ip, 0, data, ip->ip_data_len); 1806 copyout(data, idr->idr_data_segment, ip->ip_data_len); 1807 free(data, M_ISCSI); 1808 } 1809 1810 icl_pdu_free(ip); 1811 1812 return (0); 1813 } 1814 #endif /* ICL_KERNEL_PROXY */ 1815 1816 static void 1817 iscsi_sanitize_session_conf(struct iscsi_session_conf *isc) 1818 { 1819 /* 1820 * Just make sure all the fields are null-terminated. 1821 * 1822 * XXX: This is not particularly secure. We should 1823 * create our own conf and then copy in relevant 1824 * fields. 1825 */ 1826 isc->isc_initiator[ISCSI_NAME_LEN - 1] = '\0'; 1827 isc->isc_initiator_addr[ISCSI_ADDR_LEN - 1] = '\0'; 1828 isc->isc_initiator_alias[ISCSI_ALIAS_LEN - 1] = '\0'; 1829 isc->isc_target[ISCSI_NAME_LEN - 1] = '\0'; 1830 isc->isc_target_addr[ISCSI_ADDR_LEN - 1] = '\0'; 1831 isc->isc_user[ISCSI_NAME_LEN - 1] = '\0'; 1832 isc->isc_secret[ISCSI_SECRET_LEN - 1] = '\0'; 1833 isc->isc_mutual_user[ISCSI_NAME_LEN - 1] = '\0'; 1834 isc->isc_mutual_secret[ISCSI_SECRET_LEN - 1] = '\0'; 1835 } 1836 1837 static bool 1838 iscsi_valid_session_conf(const struct iscsi_session_conf *isc) 1839 { 1840 1841 if (isc->isc_initiator[0] == '\0') { 1842 ISCSI_DEBUG("empty isc_initiator"); 1843 return (false); 1844 } 1845 1846 if (isc->isc_target_addr[0] == '\0') { 1847 ISCSI_DEBUG("empty isc_target_addr"); 1848 return (false); 1849 } 1850 1851 if (isc->isc_discovery != 0 && isc->isc_target[0] != 0) { 1852 ISCSI_DEBUG("non-empty isc_target for discovery session"); 1853 return (false); 1854 } 1855 1856 if (isc->isc_discovery == 0 && isc->isc_target[0] == 0) { 1857 ISCSI_DEBUG("empty isc_target for non-discovery session"); 1858 return (false); 1859 } 1860 1861 return (true); 1862 } 1863 1864 static int 1865 iscsi_ioctl_session_add(struct iscsi_softc *sc, struct iscsi_session_add *isa) 1866 { 1867 struct iscsi_session *is; 1868 const struct iscsi_session *is2; 1869 int error; 1870 sbintime_t sbt, pr; 1871 1872 iscsi_sanitize_session_conf(&isa->isa_conf); 1873 if (iscsi_valid_session_conf(&isa->isa_conf) == false) 1874 return (EINVAL); 1875 1876 is = malloc(sizeof(*is), M_ISCSI, M_ZERO | M_WAITOK); 1877 memcpy(&is->is_conf, &isa->isa_conf, sizeof(is->is_conf)); 1878 1879 sx_xlock(&sc->sc_lock); 1880 1881 /* 1882 * Prevent duplicates. 1883 */ 1884 TAILQ_FOREACH(is2, &sc->sc_sessions, is_next) { 1885 if (!!is->is_conf.isc_discovery != 1886 !!is2->is_conf.isc_discovery) 1887 continue; 1888 1889 if (strcmp(is->is_conf.isc_target_addr, 1890 is2->is_conf.isc_target_addr) != 0) 1891 continue; 1892 1893 if (is->is_conf.isc_discovery == 0 && 1894 strcmp(is->is_conf.isc_target, 1895 is2->is_conf.isc_target) != 0) 1896 continue; 1897 1898 sx_xunlock(&sc->sc_lock); 1899 free(is, M_ISCSI); 1900 return (EBUSY); 1901 } 1902 1903 is->is_conn = icl_new_conn(is->is_conf.isc_offload, 1904 is->is_conf.isc_iser, "iscsi", &is->is_lock); 1905 if (is->is_conn == NULL) { 1906 sx_xunlock(&sc->sc_lock); 1907 free(is, M_ISCSI); 1908 return (EINVAL); 1909 } 1910 is->is_conn->ic_receive = iscsi_receive_callback; 1911 is->is_conn->ic_error = iscsi_error_callback; 1912 is->is_conn->ic_prv0 = is; 1913 TAILQ_INIT(&is->is_outstanding); 1914 STAILQ_INIT(&is->is_postponed); 1915 mtx_init(&is->is_lock, "iscsi_lock", NULL, MTX_DEF); 1916 cv_init(&is->is_maintenance_cv, "iscsi_mt"); 1917 #ifdef ICL_KERNEL_PROXY 1918 cv_init(&is->is_login_cv, "iscsi_login"); 1919 #endif 1920 1921 /* 1922 * Set some default values, from RFC 3720, section 12. 1923 * 1924 * These values are updated by the handoff IOCTL, but are 1925 * needed prior to the handoff to support sending the ISER 1926 * login PDU. 1927 */ 1928 is->is_conn->ic_max_recv_data_segment_length = 8192; 1929 is->is_conn->ic_max_send_data_segment_length = 8192; 1930 is->is_max_burst_length = 262144; 1931 is->is_first_burst_length = 65536; 1932 1933 is->is_softc = sc; 1934 sc->sc_last_session_id++; 1935 is->is_id = sc->sc_last_session_id; 1936 is->is_isid[0] = 0x80; /* RFC 3720, 10.12.5: 10b, "Random" ISID. */ 1937 arc4rand(&is->is_isid[1], 5, 0); 1938 is->is_tsih = 0; 1939 callout_init(&is->is_callout, 1); 1940 1941 error = kthread_add(iscsi_maintenance_thread, is, NULL, NULL, 0, 0, "iscsimt"); 1942 if (error != 0) { 1943 ISCSI_SESSION_WARN(is, "kthread_add(9) failed with error %d", error); 1944 sx_xunlock(&sc->sc_lock); 1945 return (error); 1946 } 1947 is->is_ping_timeout = is->is_conf.isc_ping_timeout; 1948 if (is->is_ping_timeout < 0) 1949 is->is_ping_timeout = ping_timeout; 1950 is->is_login_timeout = is->is_conf.isc_login_timeout; 1951 if (is->is_login_timeout < 0) 1952 is->is_login_timeout = login_timeout; 1953 1954 sbt = mstosbt(995); 1955 pr = mstosbt(10); 1956 callout_reset_sbt(&is->is_callout, sbt, pr, iscsi_callout, is, 0); 1957 TAILQ_INSERT_TAIL(&sc->sc_sessions, is, is_next); 1958 1959 ISCSI_SESSION_LOCK(is); 1960 /* 1961 * Don't notify iscsid(8) if the session is disabled and it's not 1962 * a discovery session, 1963 */ 1964 if (is->is_conf.isc_enable == 0 && is->is_conf.isc_discovery == 0) { 1965 ISCSI_SESSION_UNLOCK(is); 1966 sx_xunlock(&sc->sc_lock); 1967 return (0); 1968 } 1969 1970 is->is_waiting_for_iscsid = true; 1971 strlcpy(is->is_reason, "Waiting for iscsid(8)", sizeof(is->is_reason)); 1972 ISCSI_SESSION_UNLOCK(is); 1973 cv_signal(&sc->sc_cv); 1974 sx_xunlock(&sc->sc_lock); 1975 return (0); 1976 } 1977 1978 static bool 1979 iscsi_session_conf_matches(unsigned int id1, const struct iscsi_session_conf *c1, 1980 unsigned int id2, const struct iscsi_session_conf *c2) 1981 { 1982 1983 if (id2 != 0 && id2 != id1) 1984 return (false); 1985 if (c2->isc_target[0] != '\0' && 1986 strcmp(c1->isc_target, c2->isc_target) != 0) 1987 return (false); 1988 if (c2->isc_target_addr[0] != '\0' && 1989 strcmp(c1->isc_target_addr, c2->isc_target_addr) != 0) 1990 return (false); 1991 return (true); 1992 } 1993 1994 static int 1995 iscsi_ioctl_session_remove(struct iscsi_softc *sc, 1996 struct iscsi_session_remove *isr) 1997 { 1998 struct iscsi_session *is, *tmp; 1999 bool found = false; 2000 2001 iscsi_sanitize_session_conf(&isr->isr_conf); 2002 2003 sx_xlock(&sc->sc_lock); 2004 TAILQ_FOREACH_SAFE(is, &sc->sc_sessions, is_next, tmp) { 2005 ISCSI_SESSION_LOCK(is); 2006 if (iscsi_session_conf_matches(is->is_id, &is->is_conf, 2007 isr->isr_session_id, &isr->isr_conf)) { 2008 found = true; 2009 iscsi_session_logout(is); 2010 iscsi_session_terminate(is); 2011 } 2012 ISCSI_SESSION_UNLOCK(is); 2013 } 2014 sx_xunlock(&sc->sc_lock); 2015 2016 if (!found) 2017 return (ESRCH); 2018 2019 return (0); 2020 } 2021 2022 static int 2023 iscsi_ioctl_session_list(struct iscsi_softc *sc, struct iscsi_session_list *isl) 2024 { 2025 int error; 2026 unsigned int i = 0; 2027 struct iscsi_session *is; 2028 struct iscsi_session_state iss; 2029 2030 sx_slock(&sc->sc_lock); 2031 TAILQ_FOREACH(is, &sc->sc_sessions, is_next) { 2032 if (i >= isl->isl_nentries) { 2033 sx_sunlock(&sc->sc_lock); 2034 return (EMSGSIZE); 2035 } 2036 memset(&iss, 0, sizeof(iss)); 2037 memcpy(&iss.iss_conf, &is->is_conf, sizeof(iss.iss_conf)); 2038 iss.iss_id = is->is_id; 2039 strlcpy(iss.iss_target_alias, is->is_target_alias, sizeof(iss.iss_target_alias)); 2040 strlcpy(iss.iss_reason, is->is_reason, sizeof(iss.iss_reason)); 2041 strlcpy(iss.iss_offload, is->is_conn->ic_offload, sizeof(iss.iss_offload)); 2042 2043 if (is->is_conn->ic_header_crc32c) 2044 iss.iss_header_digest = ISCSI_DIGEST_CRC32C; 2045 else 2046 iss.iss_header_digest = ISCSI_DIGEST_NONE; 2047 2048 if (is->is_conn->ic_data_crc32c) 2049 iss.iss_data_digest = ISCSI_DIGEST_CRC32C; 2050 else 2051 iss.iss_data_digest = ISCSI_DIGEST_NONE; 2052 2053 iss.iss_max_send_data_segment_length = 2054 is->is_conn->ic_max_send_data_segment_length; 2055 iss.iss_max_recv_data_segment_length = 2056 is->is_conn->ic_max_recv_data_segment_length; 2057 iss.iss_max_burst_length = is->is_max_burst_length; 2058 iss.iss_first_burst_length = is->is_first_burst_length; 2059 iss.iss_immediate_data = is->is_immediate_data; 2060 iss.iss_connected = is->is_connected; 2061 2062 error = copyout(&iss, isl->isl_pstates + i, sizeof(iss)); 2063 if (error != 0) { 2064 sx_sunlock(&sc->sc_lock); 2065 return (error); 2066 } 2067 i++; 2068 } 2069 sx_sunlock(&sc->sc_lock); 2070 2071 isl->isl_nentries = i; 2072 2073 return (0); 2074 } 2075 2076 static int 2077 iscsi_ioctl_session_modify(struct iscsi_softc *sc, 2078 struct iscsi_session_modify *ism) 2079 { 2080 struct iscsi_session *is; 2081 const struct iscsi_session *is2; 2082 2083 iscsi_sanitize_session_conf(&ism->ism_conf); 2084 if (iscsi_valid_session_conf(&ism->ism_conf) == false) 2085 return (EINVAL); 2086 2087 sx_xlock(&sc->sc_lock); 2088 TAILQ_FOREACH(is, &sc->sc_sessions, is_next) { 2089 ISCSI_SESSION_LOCK(is); 2090 if (is->is_id == ism->ism_session_id) { 2091 /* Note that the session remains locked. */ 2092 break; 2093 } 2094 ISCSI_SESSION_UNLOCK(is); 2095 } 2096 if (is == NULL) { 2097 sx_xunlock(&sc->sc_lock); 2098 return (ESRCH); 2099 } 2100 2101 /* 2102 * Prevent duplicates. 2103 */ 2104 TAILQ_FOREACH(is2, &sc->sc_sessions, is_next) { 2105 if (is == is2) 2106 continue; 2107 2108 if (!!ism->ism_conf.isc_discovery != 2109 !!is2->is_conf.isc_discovery) 2110 continue; 2111 2112 if (strcmp(ism->ism_conf.isc_target_addr, 2113 is2->is_conf.isc_target_addr) != 0) 2114 continue; 2115 2116 if (ism->ism_conf.isc_discovery == 0 && 2117 strcmp(ism->ism_conf.isc_target, 2118 is2->is_conf.isc_target) != 0) 2119 continue; 2120 2121 ISCSI_SESSION_UNLOCK(is); 2122 sx_xunlock(&sc->sc_lock); 2123 return (EBUSY); 2124 } 2125 2126 sx_xunlock(&sc->sc_lock); 2127 2128 memcpy(&is->is_conf, &ism->ism_conf, sizeof(is->is_conf)); 2129 ISCSI_SESSION_UNLOCK(is); 2130 2131 iscsi_session_reconnect(is); 2132 2133 return (0); 2134 } 2135 2136 static int 2137 iscsi_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int mode, 2138 struct thread *td) 2139 { 2140 struct iscsi_softc *sc; 2141 2142 sc = dev->si_drv1; 2143 2144 switch (cmd) { 2145 case ISCSIDWAIT: 2146 return (iscsi_ioctl_daemon_wait(sc, 2147 (struct iscsi_daemon_request *)arg)); 2148 case ISCSIDHANDOFF: 2149 return (iscsi_ioctl_daemon_handoff(sc, 2150 (struct iscsi_daemon_handoff *)arg)); 2151 case ISCSIDFAIL: 2152 return (iscsi_ioctl_daemon_fail(sc, 2153 (struct iscsi_daemon_fail *)arg)); 2154 #ifdef ICL_KERNEL_PROXY 2155 case ISCSIDCONNECT: 2156 return (iscsi_ioctl_daemon_connect(sc, 2157 (struct iscsi_daemon_connect *)arg)); 2158 case ISCSIDSEND: 2159 return (iscsi_ioctl_daemon_send(sc, 2160 (struct iscsi_daemon_send *)arg)); 2161 case ISCSIDRECEIVE: 2162 return (iscsi_ioctl_daemon_receive(sc, 2163 (struct iscsi_daemon_receive *)arg)); 2164 #endif /* ICL_KERNEL_PROXY */ 2165 case ISCSISADD: 2166 return (iscsi_ioctl_session_add(sc, 2167 (struct iscsi_session_add *)arg)); 2168 case ISCSISREMOVE: 2169 return (iscsi_ioctl_session_remove(sc, 2170 (struct iscsi_session_remove *)arg)); 2171 case ISCSISLIST: 2172 return (iscsi_ioctl_session_list(sc, 2173 (struct iscsi_session_list *)arg)); 2174 case ISCSISMODIFY: 2175 return (iscsi_ioctl_session_modify(sc, 2176 (struct iscsi_session_modify *)arg)); 2177 default: 2178 return (EINVAL); 2179 } 2180 } 2181 2182 static struct iscsi_outstanding * 2183 iscsi_outstanding_find(struct iscsi_session *is, uint32_t initiator_task_tag) 2184 { 2185 struct iscsi_outstanding *io; 2186 2187 ISCSI_SESSION_LOCK_ASSERT(is); 2188 2189 TAILQ_FOREACH(io, &is->is_outstanding, io_next) { 2190 if (io->io_initiator_task_tag == initiator_task_tag) 2191 return (io); 2192 } 2193 return (NULL); 2194 } 2195 2196 static struct iscsi_outstanding * 2197 iscsi_outstanding_find_ccb(struct iscsi_session *is, union ccb *ccb) 2198 { 2199 struct iscsi_outstanding *io; 2200 2201 ISCSI_SESSION_LOCK_ASSERT(is); 2202 2203 TAILQ_FOREACH(io, &is->is_outstanding, io_next) { 2204 if (io->io_ccb == ccb) 2205 return (io); 2206 } 2207 return (NULL); 2208 } 2209 2210 static struct iscsi_outstanding * 2211 iscsi_outstanding_add(struct iscsi_session *is, struct icl_pdu *request, 2212 union ccb *ccb, uint32_t *initiator_task_tagp) 2213 { 2214 struct iscsi_outstanding *io; 2215 int error; 2216 2217 ISCSI_SESSION_LOCK_ASSERT(is); 2218 2219 io = uma_zalloc(iscsi_outstanding_zone, M_NOWAIT | M_ZERO); 2220 if (io == NULL) { 2221 ISCSI_SESSION_WARN(is, "failed to allocate %zd bytes", 2222 sizeof(*io)); 2223 return (NULL); 2224 } 2225 2226 error = icl_conn_task_setup(is->is_conn, request, &ccb->csio, 2227 initiator_task_tagp, &io->io_icl_prv); 2228 if (error != 0) { 2229 ISCSI_SESSION_WARN(is, 2230 "icl_conn_task_setup() failed with error %d", error); 2231 uma_zfree(iscsi_outstanding_zone, io); 2232 return (NULL); 2233 } 2234 2235 KASSERT(iscsi_outstanding_find(is, *initiator_task_tagp) == NULL, 2236 ("initiator_task_tag 0x%x already added", *initiator_task_tagp)); 2237 2238 io->io_initiator_task_tag = *initiator_task_tagp; 2239 io->io_ccb = ccb; 2240 TAILQ_INSERT_TAIL(&is->is_outstanding, io, io_next); 2241 return (io); 2242 } 2243 2244 static void 2245 iscsi_outstanding_remove(struct iscsi_session *is, struct iscsi_outstanding *io) 2246 { 2247 2248 ISCSI_SESSION_LOCK_ASSERT(is); 2249 2250 icl_conn_task_done(is->is_conn, io->io_icl_prv); 2251 TAILQ_REMOVE(&is->is_outstanding, io, io_next); 2252 uma_zfree(iscsi_outstanding_zone, io); 2253 } 2254 2255 static void 2256 iscsi_action_abort(struct iscsi_session *is, union ccb *ccb) 2257 { 2258 struct icl_pdu *request; 2259 struct iscsi_bhs_task_management_request *bhstmr; 2260 struct ccb_abort *cab = &ccb->cab; 2261 struct iscsi_outstanding *io, *aio; 2262 uint32_t initiator_task_tag; 2263 2264 ISCSI_SESSION_LOCK_ASSERT(is); 2265 2266 #if 0 2267 KASSERT(is->is_login_phase == false, ("%s called during Login Phase", __func__)); 2268 #else 2269 if (is->is_login_phase) { 2270 ccb->ccb_h.status = CAM_REQ_ABORTED; 2271 xpt_done(ccb); 2272 return; 2273 } 2274 #endif 2275 2276 aio = iscsi_outstanding_find_ccb(is, cab->abort_ccb); 2277 if (aio == NULL) { 2278 ccb->ccb_h.status = CAM_REQ_CMP; 2279 xpt_done(ccb); 2280 return; 2281 } 2282 2283 request = icl_pdu_new(is->is_conn, M_NOWAIT); 2284 if (request == NULL) { 2285 ccb->ccb_h.status = CAM_RESRC_UNAVAIL; 2286 xpt_done(ccb); 2287 return; 2288 } 2289 2290 initiator_task_tag = is->is_initiator_task_tag++; 2291 if (initiator_task_tag == 0xffffffff) 2292 initiator_task_tag = is->is_initiator_task_tag++; 2293 2294 io = iscsi_outstanding_add(is, request, NULL, &initiator_task_tag); 2295 if (io == NULL) { 2296 icl_pdu_free(request); 2297 ccb->ccb_h.status = CAM_RESRC_UNAVAIL; 2298 xpt_done(ccb); 2299 return; 2300 } 2301 io->io_referenced_task_tag = aio->io_initiator_task_tag; 2302 2303 bhstmr = (struct iscsi_bhs_task_management_request *)request->ip_bhs; 2304 bhstmr->bhstmr_opcode = ISCSI_BHS_OPCODE_TASK_REQUEST; 2305 bhstmr->bhstmr_function = 0x80 | BHSTMR_FUNCTION_ABORT_TASK; 2306 bhstmr->bhstmr_lun = htobe64(CAM_EXTLUN_BYTE_SWIZZLE(ccb->ccb_h.target_lun)); 2307 bhstmr->bhstmr_initiator_task_tag = initiator_task_tag; 2308 bhstmr->bhstmr_referenced_task_tag = aio->io_initiator_task_tag; 2309 2310 iscsi_pdu_queue_locked(request); 2311 } 2312 2313 static void 2314 iscsi_action_scsiio(struct iscsi_session *is, union ccb *ccb) 2315 { 2316 struct icl_pdu *request; 2317 struct iscsi_bhs_scsi_command *bhssc; 2318 struct ccb_scsiio *csio; 2319 struct iscsi_outstanding *io; 2320 size_t len; 2321 uint32_t initiator_task_tag; 2322 int error; 2323 2324 ISCSI_SESSION_LOCK_ASSERT(is); 2325 2326 #if 0 2327 KASSERT(is->is_login_phase == false, ("%s called during Login Phase", __func__)); 2328 #else 2329 if (is->is_login_phase) { 2330 ISCSI_SESSION_DEBUG(is, "called during login phase"); 2331 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { 2332 xpt_freeze_devq(ccb->ccb_h.path, 1); 2333 ISCSI_SESSION_DEBUG(is, "freezing devq"); 2334 } 2335 ccb->ccb_h.status = CAM_REQ_ABORTED | CAM_DEV_QFRZN; 2336 xpt_done(ccb); 2337 return; 2338 } 2339 #endif 2340 2341 request = icl_pdu_new(is->is_conn, M_NOWAIT); 2342 if (request == NULL) { 2343 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { 2344 xpt_freeze_devq(ccb->ccb_h.path, 1); 2345 ISCSI_SESSION_DEBUG(is, "freezing devq"); 2346 } 2347 ccb->ccb_h.status = CAM_RESRC_UNAVAIL | CAM_DEV_QFRZN; 2348 xpt_done(ccb); 2349 return; 2350 } 2351 2352 initiator_task_tag = is->is_initiator_task_tag++; 2353 if (initiator_task_tag == 0xffffffff) 2354 initiator_task_tag = is->is_initiator_task_tag++; 2355 2356 io = iscsi_outstanding_add(is, request, ccb, &initiator_task_tag); 2357 if (io == NULL) { 2358 icl_pdu_free(request); 2359 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { 2360 xpt_freeze_devq(ccb->ccb_h.path, 1); 2361 ISCSI_SESSION_DEBUG(is, "freezing devq"); 2362 } 2363 ccb->ccb_h.status = CAM_RESRC_UNAVAIL | CAM_DEV_QFRZN; 2364 xpt_done(ccb); 2365 return; 2366 } 2367 2368 csio = &ccb->csio; 2369 bhssc = (struct iscsi_bhs_scsi_command *)request->ip_bhs; 2370 bhssc->bhssc_opcode = ISCSI_BHS_OPCODE_SCSI_COMMAND; 2371 bhssc->bhssc_flags |= BHSSC_FLAGS_F; 2372 switch (csio->ccb_h.flags & CAM_DIR_MASK) { 2373 case CAM_DIR_IN: 2374 bhssc->bhssc_flags |= BHSSC_FLAGS_R; 2375 break; 2376 case CAM_DIR_OUT: 2377 bhssc->bhssc_flags |= BHSSC_FLAGS_W; 2378 break; 2379 } 2380 2381 if ((ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0) { 2382 switch (csio->tag_action) { 2383 case MSG_HEAD_OF_Q_TAG: 2384 bhssc->bhssc_flags |= BHSSC_FLAGS_ATTR_HOQ; 2385 break; 2386 case MSG_ORDERED_Q_TAG: 2387 bhssc->bhssc_flags |= BHSSC_FLAGS_ATTR_ORDERED; 2388 break; 2389 case MSG_ACA_TASK: 2390 bhssc->bhssc_flags |= BHSSC_FLAGS_ATTR_ACA; 2391 break; 2392 case MSG_SIMPLE_Q_TAG: 2393 default: 2394 bhssc->bhssc_flags |= BHSSC_FLAGS_ATTR_SIMPLE; 2395 break; 2396 } 2397 } else 2398 bhssc->bhssc_flags |= BHSSC_FLAGS_ATTR_UNTAGGED; 2399 2400 if (is->is_protocol_level >= 2) { 2401 bhssc->bhssc_pri = (csio->priority << BHSSC_PRI_SHIFT) & 2402 BHSSC_PRI_MASK; 2403 } 2404 2405 bhssc->bhssc_lun = htobe64(CAM_EXTLUN_BYTE_SWIZZLE(ccb->ccb_h.target_lun)); 2406 bhssc->bhssc_initiator_task_tag = initiator_task_tag; 2407 bhssc->bhssc_expected_data_transfer_length = htonl(csio->dxfer_len); 2408 KASSERT(csio->cdb_len <= sizeof(bhssc->bhssc_cdb), 2409 ("unsupported CDB size %zd", (size_t)csio->cdb_len)); 2410 2411 if (csio->ccb_h.flags & CAM_CDB_POINTER) 2412 memcpy(&bhssc->bhssc_cdb, csio->cdb_io.cdb_ptr, csio->cdb_len); 2413 else 2414 memcpy(&bhssc->bhssc_cdb, csio->cdb_io.cdb_bytes, csio->cdb_len); 2415 2416 if (is->is_immediate_data && 2417 (csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) { 2418 len = csio->dxfer_len; 2419 //ISCSI_SESSION_DEBUG(is, "adding %zd of immediate data", len); 2420 if (len > is->is_first_burst_length) { 2421 ISCSI_SESSION_DEBUG(is, "len %zd -> %d", len, is->is_first_burst_length); 2422 len = is->is_first_burst_length; 2423 } 2424 if (len > is->is_conn->ic_max_send_data_segment_length) { 2425 ISCSI_SESSION_DEBUG(is, "len %zd -> %d", len, 2426 is->is_conn->ic_max_send_data_segment_length); 2427 len = is->is_conn->ic_max_send_data_segment_length; 2428 } 2429 2430 error = icl_pdu_append_data(request, csio->data_ptr, len, M_NOWAIT); 2431 if (error != 0) { 2432 iscsi_outstanding_remove(is, io); 2433 icl_pdu_free(request); 2434 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { 2435 xpt_freeze_devq(ccb->ccb_h.path, 1); 2436 ISCSI_SESSION_DEBUG(is, "freezing devq"); 2437 } 2438 ccb->ccb_h.status = CAM_RESRC_UNAVAIL | CAM_DEV_QFRZN; 2439 xpt_done(ccb); 2440 return; 2441 } 2442 } 2443 iscsi_pdu_queue_locked(request); 2444 } 2445 2446 static void 2447 iscsi_action(struct cam_sim *sim, union ccb *ccb) 2448 { 2449 struct iscsi_session *is; 2450 2451 is = cam_sim_softc(sim); 2452 2453 ISCSI_SESSION_LOCK_ASSERT(is); 2454 2455 if (is->is_terminating || 2456 (is->is_connected == false && fail_on_disconnection)) { 2457 ccb->ccb_h.status = CAM_DEV_NOT_THERE; 2458 xpt_done(ccb); 2459 return; 2460 } 2461 2462 /* 2463 * Make sure CAM doesn't sneak in a CCB just after freezing the queue. 2464 */ 2465 if (is->is_simq_frozen == true) { 2466 ccb->ccb_h.status &= ~(CAM_SIM_QUEUED | CAM_STATUS_MASK); 2467 ccb->ccb_h.status |= CAM_REQUEUE_REQ; 2468 /* Don't freeze the devq - the SIM queue is already frozen. */ 2469 xpt_done(ccb); 2470 return; 2471 } 2472 2473 switch (ccb->ccb_h.func_code) { 2474 case XPT_PATH_INQ: 2475 { 2476 struct ccb_pathinq *cpi = &ccb->cpi; 2477 2478 cpi->version_num = 1; 2479 cpi->hba_inquiry = PI_TAG_ABLE; 2480 cpi->target_sprt = 0; 2481 cpi->hba_misc = PIM_EXTLUNS; 2482 /* 2483 * XXX: It shouldn't ever be NULL; this could be turned 2484 * into a KASSERT eventually. 2485 */ 2486 if (is->is_conn == NULL) 2487 ISCSI_WARN("NULL conn"); 2488 else if (is->is_conn->ic_unmapped) 2489 cpi->hba_misc |= PIM_UNMAPPED; 2490 cpi->hba_eng_cnt = 0; 2491 cpi->max_target = 0; 2492 /* 2493 * Note that the variable below is only relevant for targets 2494 * that don't claim compliance with anything above SPC2, which 2495 * means they don't support REPORT_LUNS. 2496 */ 2497 cpi->max_lun = 255; 2498 cpi->initiator_id = ~0; 2499 strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 2500 strlcpy(cpi->hba_vid, "iSCSI", HBA_IDLEN); 2501 strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 2502 cpi->unit_number = cam_sim_unit(sim); 2503 cpi->bus_id = cam_sim_bus(sim); 2504 cpi->base_transfer_speed = 150000; /* XXX */ 2505 cpi->transport = XPORT_ISCSI; 2506 cpi->transport_version = 0; 2507 cpi->protocol = PROTO_SCSI; 2508 cpi->protocol_version = SCSI_REV_SPC3; 2509 cpi->maxio = maxphys; 2510 cpi->ccb_h.status = CAM_REQ_CMP; 2511 break; 2512 } 2513 case XPT_GET_TRAN_SETTINGS: 2514 { 2515 struct ccb_trans_settings *cts; 2516 struct ccb_trans_settings_scsi *scsi; 2517 2518 cts = &ccb->cts; 2519 scsi = &cts->proto_specific.scsi; 2520 2521 cts->protocol = PROTO_SCSI; 2522 cts->protocol_version = SCSI_REV_SPC3; 2523 cts->transport = XPORT_ISCSI; 2524 cts->transport_version = 0; 2525 scsi->valid = CTS_SCSI_VALID_TQ; 2526 scsi->flags = CTS_SCSI_FLAGS_TAG_ENB; 2527 cts->ccb_h.status = CAM_REQ_CMP; 2528 break; 2529 } 2530 case XPT_CALC_GEOMETRY: 2531 cam_calc_geometry(&ccb->ccg, /*extended*/1); 2532 ccb->ccb_h.status = CAM_REQ_CMP; 2533 break; 2534 #if 0 2535 /* 2536 * XXX: What's the point? 2537 */ 2538 case XPT_RESET_BUS: 2539 case XPT_TERM_IO: 2540 ISCSI_SESSION_DEBUG(is, "faking success for reset, abort, or term_io"); 2541 ccb->ccb_h.status = CAM_REQ_CMP; 2542 break; 2543 #endif 2544 case XPT_ABORT: 2545 iscsi_action_abort(is, ccb); 2546 return; 2547 case XPT_SCSI_IO: 2548 iscsi_action_scsiio(is, ccb); 2549 return; 2550 default: 2551 #if 0 2552 ISCSI_SESSION_DEBUG(is, "got unsupported code 0x%x", ccb->ccb_h.func_code); 2553 #endif 2554 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; 2555 break; 2556 } 2557 xpt_done(ccb); 2558 } 2559 2560 static void 2561 iscsi_terminate_sessions(struct iscsi_softc *sc) 2562 { 2563 struct iscsi_session *is; 2564 2565 sx_slock(&sc->sc_lock); 2566 TAILQ_FOREACH(is, &sc->sc_sessions, is_next) 2567 iscsi_session_terminate(is); 2568 while(!TAILQ_EMPTY(&sc->sc_sessions)) { 2569 ISCSI_DEBUG("waiting for sessions to terminate"); 2570 cv_wait(&sc->sc_cv, &sc->sc_lock); 2571 } 2572 ISCSI_DEBUG("all sessions terminated"); 2573 sx_sunlock(&sc->sc_lock); 2574 } 2575 2576 static void 2577 iscsi_shutdown_pre(struct iscsi_softc *sc) 2578 { 2579 struct iscsi_session *is; 2580 2581 if (!fail_on_shutdown) 2582 return; 2583 2584 /* 2585 * If we have any sessions waiting for reconnection, request 2586 * maintenance thread to fail them immediately instead of waiting 2587 * for reconnect timeout. 2588 * 2589 * This prevents LUNs with mounted filesystems that are supported 2590 * by disconnected iSCSI sessions from hanging, however it will 2591 * fail all queued BIOs. 2592 */ 2593 ISCSI_DEBUG("forcing failing all disconnected sessions due to shutdown"); 2594 2595 fail_on_disconnection = 1; 2596 2597 sx_slock(&sc->sc_lock); 2598 TAILQ_FOREACH(is, &sc->sc_sessions, is_next) { 2599 ISCSI_SESSION_LOCK(is); 2600 if (!is->is_connected) { 2601 ISCSI_SESSION_DEBUG(is, "force failing disconnected session early"); 2602 iscsi_session_reconnect(is); 2603 } 2604 ISCSI_SESSION_UNLOCK(is); 2605 } 2606 sx_sunlock(&sc->sc_lock); 2607 } 2608 2609 static void 2610 iscsi_shutdown_post(struct iscsi_softc *sc) 2611 { 2612 2613 if (!KERNEL_PANICKED()) { 2614 ISCSI_DEBUG("removing all sessions due to shutdown"); 2615 iscsi_terminate_sessions(sc); 2616 } 2617 } 2618 2619 static int 2620 iscsi_load(void) 2621 { 2622 int error; 2623 2624 sc = malloc(sizeof(*sc), M_ISCSI, M_ZERO | M_WAITOK); 2625 sx_init(&sc->sc_lock, "iscsi"); 2626 TAILQ_INIT(&sc->sc_sessions); 2627 cv_init(&sc->sc_cv, "iscsi_cv"); 2628 2629 iscsi_outstanding_zone = uma_zcreate("iscsi_outstanding", 2630 sizeof(struct iscsi_outstanding), NULL, NULL, NULL, NULL, 2631 UMA_ALIGN_PTR, 0); 2632 2633 error = make_dev_p(MAKEDEV_CHECKNAME, &sc->sc_cdev, &iscsi_cdevsw, 2634 NULL, UID_ROOT, GID_WHEEL, 0600, "iscsi"); 2635 if (error != 0) { 2636 ISCSI_WARN("failed to create device node, error %d", error); 2637 return (error); 2638 } 2639 sc->sc_cdev->si_drv1 = sc; 2640 2641 sc->sc_shutdown_pre_eh = EVENTHANDLER_REGISTER(shutdown_pre_sync, 2642 iscsi_shutdown_pre, sc, SHUTDOWN_PRI_FIRST); 2643 /* 2644 * shutdown_post_sync needs to run after filesystem shutdown and before 2645 * CAM shutdown - otherwise when rebooting with an iSCSI session that is 2646 * disconnected but has outstanding requests, dashutdown() will hang on 2647 * cam_periph_runccb(). 2648 */ 2649 sc->sc_shutdown_post_eh = EVENTHANDLER_REGISTER(shutdown_post_sync, 2650 iscsi_shutdown_post, sc, SHUTDOWN_PRI_DEFAULT - 1); 2651 2652 return (0); 2653 } 2654 2655 static int 2656 iscsi_unload(void) 2657 { 2658 2659 /* Awaken any threads asleep in iscsi_ioctl(). */ 2660 sx_xlock(&sc->sc_lock); 2661 sc->sc_unloading = true; 2662 cv_signal(&sc->sc_cv); 2663 sx_xunlock(&sc->sc_lock); 2664 2665 if (sc->sc_cdev != NULL) { 2666 ISCSI_DEBUG("removing device node"); 2667 destroy_dev(sc->sc_cdev); 2668 ISCSI_DEBUG("device node removed"); 2669 } 2670 2671 if (sc->sc_shutdown_pre_eh != NULL) 2672 EVENTHANDLER_DEREGISTER(shutdown_pre_sync, sc->sc_shutdown_pre_eh); 2673 if (sc->sc_shutdown_post_eh != NULL) 2674 EVENTHANDLER_DEREGISTER(shutdown_post_sync, sc->sc_shutdown_post_eh); 2675 2676 iscsi_terminate_sessions(sc); 2677 2678 uma_zdestroy(iscsi_outstanding_zone); 2679 sx_destroy(&sc->sc_lock); 2680 cv_destroy(&sc->sc_cv); 2681 free(sc, M_ISCSI); 2682 return (0); 2683 } 2684 2685 static int 2686 iscsi_quiesce(void) 2687 { 2688 sx_slock(&sc->sc_lock); 2689 if (!TAILQ_EMPTY(&sc->sc_sessions)) { 2690 sx_sunlock(&sc->sc_lock); 2691 return (EBUSY); 2692 } 2693 sx_sunlock(&sc->sc_lock); 2694 return (0); 2695 } 2696 2697 static int 2698 iscsi_modevent(module_t mod, int what, void *arg) 2699 { 2700 int error; 2701 2702 switch (what) { 2703 case MOD_LOAD: 2704 error = iscsi_load(); 2705 break; 2706 case MOD_UNLOAD: 2707 error = iscsi_unload(); 2708 break; 2709 case MOD_QUIESCE: 2710 error = iscsi_quiesce(); 2711 break; 2712 default: 2713 error = EINVAL; 2714 break; 2715 } 2716 return (error); 2717 } 2718 2719 moduledata_t iscsi_data = { 2720 "iscsi", 2721 iscsi_modevent, 2722 0 2723 }; 2724 2725 DECLARE_MODULE(iscsi, iscsi_data, SI_SUB_DRIVERS, SI_ORDER_MIDDLE); 2726 MODULE_DEPEND(iscsi, cam, 1, 1, 1); 2727 MODULE_DEPEND(iscsi, icl, 1, 1, 1); 2728