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