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