1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 23 */ 24 25 #include <sys/cpuvar.h> 26 #include <sys/types.h> 27 #include <sys/conf.h> 28 #include <sys/file.h> 29 #include <sys/ddi.h> 30 #include <sys/sunddi.h> 31 #include <sys/modctl.h> 32 #include <sys/scsi/generic/persist.h> 33 34 #include <sys/socket.h> 35 #include <sys/strsubr.h> 36 #include <sys/sysmacros.h> 37 #include <sys/note.h> 38 #include <sys/sdt.h> 39 40 #include <sys/stmf.h> 41 #include <sys/stmf_ioctl.h> 42 #include <sys/portif.h> 43 #include <sys/idm/idm.h> 44 #include <sys/idm/idm_text.h> 45 46 #define ISCSIT_LOGIN_SM_STRINGS 47 #include "iscsit.h" 48 #include "iscsit_auth.h" 49 50 typedef struct { 51 list_node_t le_ctx_node; 52 iscsit_login_event_t le_ctx_event; 53 idm_pdu_t *le_pdu; 54 } login_event_ctx_t; 55 56 #ifndef TRUE 57 #define TRUE B_TRUE 58 #endif 59 60 #ifndef FALSE 61 #define FALSE B_FALSE 62 #endif 63 64 #define DEFAULT_RADIUS_PORT 1812 65 66 static void 67 login_sm_complete(void *ict_void); 68 69 static void 70 login_sm_event_dispatch(iscsit_conn_login_t *lsm, iscsit_conn_t *ict, 71 login_event_ctx_t *ctx); 72 73 static void 74 login_sm_init(iscsit_conn_t *ict, login_event_ctx_t *ctx); 75 76 static void 77 login_sm_waiting(iscsit_conn_t *ict, login_event_ctx_t *ctx); 78 79 static void 80 login_sm_processing(iscsit_conn_t *ict, login_event_ctx_t *ctx); 81 82 static void 83 login_sm_responding(iscsit_conn_t *ict, login_event_ctx_t *ctx); 84 85 static void 86 login_sm_responded(iscsit_conn_t *ict, login_event_ctx_t *ctx); 87 88 static void 89 login_sm_ffp(iscsit_conn_t *ict, login_event_ctx_t *ctx); 90 91 static void 92 login_sm_done(iscsit_conn_t *ict, login_event_ctx_t *ctx); 93 94 static void 95 login_sm_error(iscsit_conn_t *ict, login_event_ctx_t *ctx); 96 97 static void 98 login_sm_new_state(iscsit_conn_t *ict, login_event_ctx_t *ctx, 99 iscsit_login_state_t new_state); 100 101 static void 102 login_sm_send_ack(iscsit_conn_t *ict, idm_pdu_t *pdu); 103 104 static idm_status_t 105 login_sm_validate_ack(iscsit_conn_t *ict, idm_pdu_t *pdu); 106 107 static boolean_t 108 login_sm_is_last_response(idm_pdu_t *pdu); 109 110 static void 111 login_sm_handle_initial_login(iscsit_conn_t *ict, idm_pdu_t *pdu); 112 113 static void 114 login_sm_send_next_response(iscsit_conn_t *ict, idm_pdu_t *pdu); 115 116 static void 117 login_sm_process_request(iscsit_conn_t *ict); 118 119 static idm_status_t 120 login_sm_req_pdu_check(iscsit_conn_t *ict, idm_pdu_t *pdu); 121 122 static idm_status_t 123 login_sm_process_nvlist(iscsit_conn_t *ict); 124 125 static idm_status_t 126 login_sm_check_security(iscsit_conn_t *ict); 127 128 static idm_pdu_t * 129 login_sm_build_login_response(iscsit_conn_t *ict); 130 131 static void 132 login_sm_ffp_actions(iscsit_conn_t *ict); 133 134 static idm_status_t 135 login_sm_validate_initial_parameters(iscsit_conn_t *ict); 136 137 static idm_status_t 138 login_sm_session_bind(iscsit_conn_t *ict); 139 140 static idm_status_t 141 login_sm_set_auth(iscsit_conn_t *ict); 142 143 static idm_status_t 144 login_sm_session_register(iscsit_conn_t *ict); 145 146 static kv_status_t 147 iscsit_handle_key(iscsit_conn_t *ict, nvpair_t *nvp, char *nvp_name); 148 149 static kv_status_t 150 iscsit_handle_common_key(iscsit_conn_t *ict, nvpair_t *nvp, 151 const idm_kv_xlate_t *ikvx); 152 153 static kv_status_t 154 iscsit_handle_security_key(iscsit_conn_t *ict, nvpair_t *nvp, 155 const idm_kv_xlate_t *ikvx); 156 157 static kv_status_t 158 iscsit_reply_security_key(iscsit_conn_t *ict); 159 160 static kv_status_t 161 iscsit_handle_operational_key(iscsit_conn_t *ict, nvpair_t *nvp, 162 const idm_kv_xlate_t *ikvx); 163 164 static kv_status_t 165 iscsit_reply_numerical(iscsit_conn_t *ict, 166 const char *nvp_name, const uint64_t value); 167 168 static kv_status_t 169 iscsit_reply_string(iscsit_conn_t *ict, 170 const char *nvp_name, const char *text); 171 172 static kv_status_t 173 iscsit_handle_digest(iscsit_conn_t *ict, nvpair_t *choices, 174 const idm_kv_xlate_t *ikvx); 175 176 static kv_status_t 177 iscsit_handle_boolean(iscsit_conn_t *ict, nvpair_t *nvp, boolean_t value, 178 const idm_kv_xlate_t *ikvx, boolean_t iscsit_value); 179 180 static kv_status_t 181 iscsit_handle_numerical(iscsit_conn_t *ict, nvpair_t *nvp, uint64_t value, 182 const idm_kv_xlate_t *ikvx, 183 uint64_t iscsi_min_value, uint64_t iscsi_max_value, 184 uint64_t iscsit_max_value); 185 186 static void 187 iscsit_process_negotiated_values(iscsit_conn_t *ict); 188 189 static void 190 login_resp_complete_cb(idm_pdu_t *pdu, idm_status_t status); 191 192 static idm_status_t 193 iscsit_add_declarative_keys(iscsit_conn_t *ict); 194 195 uint64_t max_dataseglen_target = ISCSIT_MAX_RECV_DATA_SEGMENT_LENGTH; 196 197 /* 198 * global mutex defined in iscsit.c to enforce 199 * login_sm_session_bind as a critical section 200 */ 201 extern kmutex_t login_sm_session_mutex; 202 203 idm_status_t 204 iscsit_login_sm_init(iscsit_conn_t *ict) 205 { 206 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 207 208 bzero(lsm, sizeof (iscsit_conn_login_t)); 209 210 (void) nvlist_alloc(&lsm->icl_negotiated_values, NV_UNIQUE_NAME, 211 KM_SLEEP); 212 213 /* 214 * Hold connection until the login state machine completes 215 */ 216 iscsit_conn_hold(ict); 217 218 /* 219 * Pre-allocating a login response PDU means we will always be 220 * able to respond to a login request -- even if we can't allocate 221 * a data buffer to hold the text responses we can at least send 222 * a login failure. 223 */ 224 lsm->icl_login_resp_tmpl = kmem_zalloc(sizeof (iscsi_login_rsp_hdr_t), 225 KM_SLEEP); 226 227 idm_sm_audit_init(&lsm->icl_state_audit); 228 mutex_init(&lsm->icl_mutex, NULL, MUTEX_DEFAULT, NULL); 229 list_create(&lsm->icl_login_events, sizeof (login_event_ctx_t), 230 offsetof(login_event_ctx_t, le_ctx_node)); 231 list_create(&lsm->icl_pdu_list, sizeof (idm_pdu_t), 232 offsetof(idm_pdu_t, isp_client_lnd)); 233 234 lsm->icl_login_state = ILS_LOGIN_INIT; 235 lsm->icl_login_last_state = ILS_LOGIN_INIT; 236 237 /* 238 * Initialize operational parameters to default values. Anything 239 * we don't specifically negotiate stays at the default. 240 */ 241 ict->ict_op.op_discovery_session = B_FALSE; 242 ict->ict_op.op_initial_r2t = ISCSI_DEFAULT_INITIALR2T; 243 ict->ict_op.op_immed_data = ISCSI_DEFAULT_IMMEDIATE_DATA; 244 ict->ict_op.op_data_pdu_in_order = ISCSI_DEFAULT_DATA_PDU_IN_ORDER; 245 ict->ict_op.op_data_sequence_in_order = 246 ISCSI_DEFAULT_DATA_SEQUENCE_IN_ORDER; 247 ict->ict_op.op_max_connections = ISCSI_DEFAULT_MAX_CONNECTIONS; 248 ict->ict_op.op_max_recv_data_segment_length = 249 ISCSI_DEFAULT_MAX_RECV_SEG_LEN; 250 ict->ict_op.op_max_burst_length = ISCSI_DEFAULT_MAX_BURST_LENGTH; 251 ict->ict_op.op_first_burst_length = ISCSI_DEFAULT_FIRST_BURST_LENGTH; 252 ict->ict_op.op_default_time_2_wait = ISCSI_DEFAULT_TIME_TO_WAIT; 253 ict->ict_op.op_default_time_2_retain = ISCSI_DEFAULT_TIME_TO_RETAIN; 254 ict->ict_op.op_max_outstanding_r2t = ISCSI_DEFAULT_MAX_OUT_R2T; 255 ict->ict_op.op_error_recovery_level = 256 ISCSI_DEFAULT_ERROR_RECOVERY_LEVEL; 257 258 return (IDM_STATUS_SUCCESS); 259 } 260 261 static void 262 login_resp_complete_cb(idm_pdu_t *pdu, idm_status_t status) 263 { 264 iscsit_conn_t *ict = pdu->isp_private; 265 266 /* 267 * Check that this is a login pdu 268 */ 269 ASSERT((pdu->isp_flags & IDM_PDU_LOGIN_TX) != 0); 270 idm_pdu_free(pdu); 271 272 if ((status != IDM_STATUS_SUCCESS) || 273 (ict->ict_login_sm.icl_login_resp_err_class != 0)) { 274 /* 275 * Transport or login error occurred. 276 */ 277 iscsit_login_sm_event(ict, ILE_LOGIN_ERROR, NULL); 278 } 279 iscsit_conn_rele(ict); 280 } 281 282 void 283 iscsit_login_sm_fini(iscsit_conn_t *ict) 284 { 285 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 286 287 mutex_enter(&lsm->icl_mutex); 288 list_destroy(&lsm->icl_pdu_list); 289 list_destroy(&lsm->icl_login_events); 290 291 kmem_free(lsm->icl_login_resp_tmpl, sizeof (iscsi_login_rsp_hdr_t)); 292 293 /* clean up the login response idm text buffer */ 294 if (lsm->icl_login_resp_itb != NULL) { 295 idm_itextbuf_free(lsm->icl_login_resp_itb); 296 lsm->icl_login_resp_itb = NULL; 297 } 298 299 nvlist_free(lsm->icl_negotiated_values); 300 mutex_destroy(&lsm->icl_mutex); 301 } 302 303 void 304 iscsit_login_sm_event(iscsit_conn_t *ict, iscsit_login_event_t event, 305 idm_pdu_t *pdu) 306 { 307 /* 308 * This is a bit ugly but if we're already in ILS_LOGIN_ERROR 309 * or ILS_LOGIN_DONE then just drop any additional events. They 310 * won't change the state and it's possible we've already called 311 * iscsit_login_sm_fini in which case the mutex is destroyed. 312 */ 313 if ((ict->ict_login_sm.icl_login_state == ILS_LOGIN_ERROR) || 314 (ict->ict_login_sm.icl_login_state == ILS_LOGIN_DONE)) 315 return; 316 317 mutex_enter(&ict->ict_login_sm.icl_mutex); 318 iscsit_login_sm_event_locked(ict, event, pdu); 319 mutex_exit(&ict->ict_login_sm.icl_mutex); 320 } 321 void 322 iscsit_login_sm_event_locked(iscsit_conn_t *ict, iscsit_login_event_t event, 323 idm_pdu_t *pdu) 324 { 325 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 326 login_event_ctx_t *ctx; 327 328 ASSERT(mutex_owned(&lsm->icl_mutex)); 329 ctx = kmem_zalloc(sizeof (*ctx), KM_SLEEP); 330 331 ctx->le_ctx_event = event; 332 ctx->le_pdu = pdu; 333 334 list_insert_tail(&lsm->icl_login_events, ctx); 335 336 /* 337 * Use the icl_busy flag to keep the state machine single threaded. 338 * This also serves as recursion avoidance since this flag will 339 * always be set if we call login_sm_event from within the 340 * state machine code. 341 */ 342 if (!lsm->icl_busy) { 343 lsm->icl_busy = B_TRUE; 344 while (!list_is_empty(&lsm->icl_login_events)) { 345 ctx = list_head(&lsm->icl_login_events); 346 list_remove(&lsm->icl_login_events, ctx); 347 idm_sm_audit_event(&lsm->icl_state_audit, 348 SAS_ISCSIT_LOGIN, (int)lsm->icl_login_state, 349 (int)ctx->le_ctx_event, (uintptr_t)pdu); 350 351 /* 352 * If the lsm is in a terminal state, just drain 353 * any remaining events. 354 */ 355 if ((lsm->icl_login_state == ILS_LOGIN_ERROR) || 356 (lsm->icl_login_state == ILS_LOGIN_DONE)) { 357 kmem_free(ctx, sizeof (*ctx)); 358 continue; 359 } 360 mutex_exit(&lsm->icl_mutex); 361 login_sm_event_dispatch(lsm, ict, ctx); 362 mutex_enter(&lsm->icl_mutex); 363 } 364 lsm->icl_busy = B_FALSE; 365 366 /* 367 * When the state machine reaches ILS_LOGIN_DONE or 368 * ILS_LOGIN_ERROR state the login process has completed 369 * and it's time to cleanup. The state machine code will 370 * mark itself "complete" when this happens. 371 * 372 * To protect against spurious events (which shouldn't 373 * happen) set icl_busy again. 374 */ 375 if (lsm->icl_login_complete) { 376 lsm->icl_busy = B_TRUE; 377 if (taskq_dispatch(iscsit_global.global_dispatch_taskq, 378 login_sm_complete, ict, DDI_SLEEP) == NULL) { 379 cmn_err(CE_WARN, "iscsit_login_sm_event_locked:" 380 " Failed to dispatch task"); 381 } 382 } 383 } 384 } 385 386 static void 387 login_sm_complete(void *ict_void) 388 { 389 iscsit_conn_t *ict = ict_void; 390 391 /* 392 * State machine has run to completion, resources 393 * will be cleaned up when connection is destroyed. 394 */ 395 iscsit_conn_rele(ict); 396 } 397 398 static void 399 login_sm_event_dispatch(iscsit_conn_login_t *lsm, iscsit_conn_t *ict, 400 login_event_ctx_t *ctx) 401 { 402 idm_pdu_t *pdu = ctx->le_pdu; /* Only valid for some events */ 403 404 DTRACE_PROBE2(login__event, iscsit_conn_t *, ict, 405 login_event_ctx_t *, ctx); 406 407 IDM_SM_LOG(CE_NOTE, "login_sm_event_dispatch: ict %p event %s(%d)", 408 (void *)ict, 409 iscsit_ile_name[ctx->le_ctx_event], ctx->le_ctx_event); 410 411 /* State independent actions */ 412 switch (ctx->le_ctx_event) { 413 case ILE_LOGIN_RCV: 414 /* Perform basic sanity checks on the header */ 415 if (login_sm_req_pdu_check(ict, pdu) != IDM_STATUS_SUCCESS) { 416 idm_pdu_t *rpdu; 417 418 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_INITIATOR_ERR, 419 ISCSI_LOGIN_STATUS_INVALID_REQUEST); 420 /* 421 * If we haven't processed any PDU's yet then use 422 * this one as a template for the response 423 */ 424 if (ict->ict_login_sm.icl_login_resp_tmpl->opcode == 0) 425 login_sm_handle_initial_login(ict, pdu); 426 rpdu = login_sm_build_login_response(ict); 427 login_sm_send_next_response(ict, rpdu); 428 idm_pdu_complete(pdu, IDM_STATUS_SUCCESS); 429 kmem_free(ctx, sizeof (*ctx)); 430 return; 431 } 432 break; 433 default: 434 break; 435 } 436 437 /* State dependent actions */ 438 switch (lsm->icl_login_state) { 439 case ILS_LOGIN_INIT: 440 login_sm_init(ict, ctx); 441 break; 442 case ILS_LOGIN_WAITING: 443 login_sm_waiting(ict, ctx); 444 break; 445 case ILS_LOGIN_PROCESSING: 446 login_sm_processing(ict, ctx); 447 break; 448 case ILS_LOGIN_RESPONDING: 449 login_sm_responding(ict, ctx); 450 break; 451 case ILS_LOGIN_RESPONDED: 452 login_sm_responded(ict, ctx); 453 break; 454 case ILS_LOGIN_FFP: 455 login_sm_ffp(ict, ctx); 456 break; 457 case ILS_LOGIN_DONE: 458 login_sm_done(ict, ctx); 459 break; 460 case ILS_LOGIN_ERROR: 461 login_sm_error(ict, ctx); 462 break; 463 } 464 465 kmem_free(ctx, sizeof (*ctx)); 466 } 467 468 static void 469 login_sm_init(iscsit_conn_t *ict, login_event_ctx_t *ctx) 470 { 471 idm_pdu_t *pdu; 472 473 switch (ctx->le_ctx_event) { 474 case ILE_LOGIN_RCV: 475 pdu = ctx->le_pdu; 476 477 /* 478 * This is the first login PDU we've received so use 479 * it to build the login response template and set our CSG. 480 */ 481 login_sm_handle_initial_login(ict, pdu); 482 483 /* 484 * Accumulate all the login PDU's that make up this 485 * request on a queue. 486 */ 487 mutex_enter(&ict->ict_login_sm.icl_mutex); 488 list_insert_tail(&ict->ict_login_sm.icl_pdu_list, pdu); 489 mutex_exit(&ict->ict_login_sm.icl_mutex); 490 491 if (pdu->isp_hdr->flags & ISCSI_FLAG_LOGIN_CONTINUE) { 492 login_sm_send_ack(ict, pdu); 493 login_sm_new_state(ict, ctx, ILS_LOGIN_WAITING); 494 } else { 495 login_sm_new_state(ict, ctx, ILS_LOGIN_PROCESSING); 496 } 497 break; 498 case ILE_LOGIN_CONN_ERROR: 499 case ILE_LOGIN_ERROR: 500 login_sm_new_state(ict, ctx, ILS_LOGIN_ERROR); 501 break; 502 default: 503 ASSERT(0); 504 } 505 } 506 507 static void 508 login_sm_waiting(iscsit_conn_t *ict, login_event_ctx_t *ctx) 509 { 510 idm_pdu_t *pdu; 511 512 switch (ctx->le_ctx_event) { 513 case ILE_LOGIN_RCV: 514 pdu = ctx->le_pdu; 515 mutex_enter(&ict->ict_login_sm.icl_mutex); 516 list_insert_tail(&ict->ict_login_sm.icl_pdu_list, pdu); 517 mutex_exit(&ict->ict_login_sm.icl_mutex); 518 if (!(pdu->isp_hdr->flags & ISCSI_FLAG_LOGIN_CONTINUE)) { 519 login_sm_new_state(ict, ctx, ILS_LOGIN_PROCESSING); 520 } else { 521 login_sm_send_ack(ict, pdu); 522 } 523 break; 524 case ILE_LOGIN_ERROR: 525 login_sm_new_state(ict, ctx, ILS_LOGIN_ERROR); 526 break; 527 case ILE_LOGIN_RESP_COMPLETE: 528 break; 529 default: 530 ASSERT(0); 531 } 532 } 533 534 static void 535 login_sm_processing(iscsit_conn_t *ict, login_event_ctx_t *ctx) 536 { 537 switch (ctx->le_ctx_event) { 538 case ILE_LOGIN_RESP_READY: 539 login_sm_new_state(ict, ctx, ILS_LOGIN_RESPONDING); 540 break; 541 case ILE_LOGIN_RCV: 542 idm_pdu_complete(ctx->le_pdu, IDM_STATUS_SUCCESS); 543 /*FALLTHROUGH*/ 544 case ILE_LOGIN_CONN_ERROR: 545 case ILE_LOGIN_ERROR: 546 login_sm_new_state(ict, ctx, ILS_LOGIN_ERROR); 547 break; 548 default: 549 ASSERT(0); 550 } 551 } 552 553 static void 554 login_sm_responding(iscsit_conn_t *ict, login_event_ctx_t *ctx) 555 { 556 idm_pdu_t *pdu, *rpdu; 557 558 switch (ctx->le_ctx_event) { 559 case ILE_LOGIN_RCV: 560 pdu = ctx->le_pdu; 561 /* 562 * We should only be in "responding" state if we have not 563 * sent the last PDU of a multi-PDU login response sequence. 564 * In that case we expect this received PDU to be an 565 * acknowledgement from the initiator (login PDU with C 566 * bit cleared and no data). If it's the acknowledgement 567 * we are expecting then we send the next PDU in the login 568 * response sequence. Otherwise it's a protocol error and 569 * the login fails. 570 */ 571 if (login_sm_validate_ack(ict, pdu) == IDM_STATUS_SUCCESS) { 572 rpdu = login_sm_build_login_response(ict); 573 login_sm_send_next_response(ict, rpdu); 574 } else { 575 login_sm_new_state(ict, ctx, ILS_LOGIN_ERROR); 576 } 577 idm_pdu_complete(pdu, IDM_STATUS_SUCCESS); 578 break; 579 case ILE_LOGIN_FFP: 580 login_sm_new_state(ict, ctx, ILS_LOGIN_FFP); 581 break; 582 case ILE_LOGIN_RESP_COMPLETE: 583 login_sm_new_state(ict, ctx, ILS_LOGIN_RESPONDED); 584 break; 585 case ILE_LOGIN_CONN_ERROR: 586 case ILE_LOGIN_ERROR: 587 login_sm_new_state(ict, ctx, ILS_LOGIN_ERROR); 588 break; 589 default: 590 ASSERT(0); 591 } 592 } 593 594 static void 595 login_sm_responded(iscsit_conn_t *ict, login_event_ctx_t *ctx) 596 { 597 idm_pdu_t *pdu; 598 iscsi_login_hdr_t *lh; 599 600 switch (ctx->le_ctx_event) { 601 case ILE_LOGIN_RCV: 602 pdu = ctx->le_pdu; 603 lh = (iscsi_login_hdr_t *)pdu->isp_hdr; 604 /* 605 * Set the CSG, NSG and Transit bits based on the this PDU. 606 * The CSG already validated in login_sm_req_pdu_check(). 607 * We'll clear the transit bit if we encounter any login 608 * parameters in the request that required an additional 609 * login transfer (i.e. no acceptable 610 * choices in range or we needed to change a boolean 611 * value from "Yes" to "No"). 612 */ 613 ict->ict_login_sm.icl_login_csg = 614 ISCSI_LOGIN_CURRENT_STAGE(lh->flags); 615 ict->ict_login_sm.icl_login_nsg = 616 ISCSI_LOGIN_NEXT_STAGE(lh->flags); 617 ict->ict_login_sm.icl_login_transit = 618 lh->flags & ISCSI_FLAG_LOGIN_TRANSIT; 619 mutex_enter(&ict->ict_login_sm.icl_mutex); 620 list_insert_tail(&ict->ict_login_sm.icl_pdu_list, pdu); 621 mutex_exit(&ict->ict_login_sm.icl_mutex); 622 if (pdu->isp_hdr->flags & ISCSI_FLAG_LOGIN_CONTINUE) { 623 login_sm_send_ack(ict, pdu); 624 login_sm_new_state(ict, ctx, ILS_LOGIN_WAITING); 625 } else { 626 login_sm_new_state(ict, ctx, ILS_LOGIN_PROCESSING); 627 } 628 break; 629 case ILE_LOGIN_CONN_ERROR: 630 case ILE_LOGIN_ERROR: 631 login_sm_new_state(ict, ctx, ILS_LOGIN_ERROR); 632 break; 633 default: 634 ASSERT(0); 635 } 636 } 637 638 static void 639 login_sm_ffp(iscsit_conn_t *ict, login_event_ctx_t *ctx) 640 { 641 switch (ctx->le_ctx_event) { 642 case ILE_LOGIN_RESP_COMPLETE: 643 login_sm_new_state(ict, ctx, ILS_LOGIN_DONE); 644 break; 645 case ILE_LOGIN_CONN_ERROR: 646 case ILE_LOGIN_ERROR: 647 login_sm_new_state(ict, ctx, ILS_LOGIN_ERROR); 648 break; 649 default: 650 ASSERT(0); 651 } 652 653 } 654 655 /*ARGSUSED*/ 656 static void 657 login_sm_done(iscsit_conn_t *ict, login_event_ctx_t *ctx) 658 { 659 /* Terminal state, we should get no events */ 660 switch (ctx->le_ctx_event) { 661 case ILE_LOGIN_RCV: 662 /* 663 * We've already processed everything we're going to 664 * process. Drop any additional login PDU's. 665 */ 666 idm_pdu_complete(ctx->le_pdu, IDM_STATUS_SUCCESS); 667 break; 668 case ILE_LOGIN_CONN_ERROR: 669 /* Don't care */ 670 break; 671 default: 672 ASSERT(0); 673 } 674 } 675 676 /*ARGSUSED*/ 677 static void 678 login_sm_error(iscsit_conn_t *ict, login_event_ctx_t *ctx) 679 { 680 switch (ctx->le_ctx_event) { 681 case ILE_LOGIN_RCV: 682 /* 683 * We've already processed everything we're going to 684 * process. Drop any additional login PDU's. 685 */ 686 idm_pdu_complete(ctx->le_pdu, IDM_STATUS_SUCCESS); 687 break; 688 case ILE_LOGIN_CONN_ERROR: 689 /* Don't care */ 690 break; 691 default: 692 ASSERT(0); 693 } 694 } 695 696 static void 697 login_sm_new_state(iscsit_conn_t *ict, login_event_ctx_t *ctx, 698 iscsit_login_state_t new_state) 699 { 700 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 701 idm_pdu_t *rpdu; 702 703 /* 704 * Validate new state 705 */ 706 ASSERT(new_state != ILS_UNDEFINED); 707 ASSERT3U(new_state, <, ILS_MAX_STATE); 708 709 new_state = (new_state < ILS_MAX_STATE) ? 710 new_state : ILS_UNDEFINED; 711 712 IDM_SM_LOG(CE_NOTE, "login_sm_new_state: conn %p " 713 "%s (%d) --> %s (%d)\n", (void *)ict->ict_ic, 714 iscsit_ils_name[lsm->icl_login_state], lsm->icl_login_state, 715 iscsit_ils_name[new_state], new_state); 716 717 DTRACE_PROBE3(login__state__change, 718 iscsit_conn_t *, ict, login_event_ctx_t *, ctx, 719 iscsit_login_state_t, new_state); 720 721 mutex_enter(&lsm->icl_mutex); 722 idm_sm_audit_state_change(&lsm->icl_state_audit, SAS_ISCSIT_LOGIN, 723 (int)lsm->icl_login_state, (int)new_state); 724 lsm->icl_login_last_state = lsm->icl_login_state; 725 lsm->icl_login_state = new_state; 726 mutex_exit(&lsm->icl_mutex); 727 728 switch (lsm->icl_login_state) { 729 case ILS_LOGIN_WAITING: 730 /* Do nothing, waiting for more login PDU's */ 731 break; 732 case ILS_LOGIN_PROCESSING: 733 /* All login PDU's received, process login request */ 734 login_sm_process_request(ict); 735 break; 736 case ILS_LOGIN_RESPONDING: 737 rpdu = login_sm_build_login_response(ict); 738 login_sm_send_next_response(ict, rpdu); 739 break; 740 case ILS_LOGIN_RESPONDED: 741 /* clean up the login response idm text buffer */ 742 if (lsm->icl_login_resp_itb != NULL) { 743 idm_itextbuf_free(lsm->icl_login_resp_itb); 744 lsm->icl_login_resp_itb = NULL; 745 } 746 break; 747 case ILS_LOGIN_FFP: 748 login_sm_ffp_actions(ict); 749 break; 750 case ILS_LOGIN_DONE: 751 case ILS_LOGIN_ERROR: 752 /* 753 * Flag the terminal state for the dispatcher 754 */ 755 lsm->icl_login_complete = B_TRUE; 756 break; 757 case ILS_LOGIN_INIT: /* Initial state, can't return */ 758 default: 759 ASSERT(0); 760 /*NOTREACHED*/ 761 } 762 } 763 764 /*ARGSUSED*/ 765 static void 766 login_sm_send_ack(iscsit_conn_t *ict, idm_pdu_t *pdu) 767 { 768 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 769 idm_pdu_t *lack; 770 771 /* 772 * allocate the response pdu 773 */ 774 lack = idm_pdu_alloc(sizeof (iscsi_hdr_t), 0); 775 idm_pdu_init(lack, ict->ict_ic, ict, login_resp_complete_cb); 776 lack->isp_flags |= IDM_PDU_LOGIN_TX; 777 778 /* 779 * copy the response template into the response pdu 780 */ 781 bcopy(lsm->icl_login_resp_tmpl, lack->isp_hdr, sizeof (iscsi_hdr_t)); 782 783 iscsit_conn_hold(ict); 784 idm_pdu_tx(lack); 785 } 786 787 /*ARGSUSED*/ 788 static idm_status_t 789 login_sm_validate_ack(iscsit_conn_t *ict, idm_pdu_t *pdu) 790 { 791 iscsi_hdr_t *ihp = pdu->isp_hdr; 792 if (ihp->flags & ISCSI_FLAG_TEXT_CONTINUE) { 793 return (IDM_STATUS_FAIL); 794 } 795 if (ntoh24(ihp->dlength) != 0) { 796 return (IDM_STATUS_FAIL); 797 } 798 return (IDM_STATUS_SUCCESS); 799 } 800 801 static boolean_t 802 login_sm_is_last_response(idm_pdu_t *pdu) 803 { 804 805 if (pdu->isp_hdr->flags & ISCSI_FLAG_LOGIN_CONTINUE) { 806 return (B_FALSE); 807 } 808 return (B_TRUE); 809 } 810 811 812 static void 813 login_sm_handle_initial_login(iscsit_conn_t *ict, idm_pdu_t *pdu) 814 { 815 iscsi_login_hdr_t *lh_req = (iscsi_login_hdr_t *)pdu->isp_hdr; 816 iscsi_login_rsp_hdr_t *lh_resp = 817 ict->ict_login_sm.icl_login_resp_tmpl; 818 819 /* 820 * First login PDU, this connection should not have a sesssion 821 * associated. 822 */ 823 ASSERT(ict->ict_sess == NULL); 824 825 /* 826 * Save off TSIH and ISID for later use in finding a session 827 */ 828 ict->ict_login_sm.icl_cmdsn = ntohl(lh_req->cmdsn); 829 ict->ict_login_sm.icl_tsih = ntohs(lh_req->tsid); 830 bcopy(lh_req->isid, ict->ict_login_sm.icl_isid, ISCSI_ISID_LEN); 831 832 /* 833 * We'll need the CID as well 834 */ 835 ict->ict_cid = ntohs(lh_req->cid); 836 837 /* 838 * Set the CSG, NSG and Transit bits based on the first PDU 839 * in the login sequence. The CSG already validated in 840 * login_sm_req_pdu_check(). We'll clear the transit bit if 841 * we encounter any login parameters in the request that 842 * required an additional login transfer (i.e. no acceptable 843 * choices in range or we needed to change a boolean 844 * value from "Yes" to "No"). 845 */ 846 ict->ict_login_sm.icl_login_csg = 847 ISCSI_LOGIN_CURRENT_STAGE(lh_req->flags); 848 ict->ict_login_sm.icl_login_nsg = 849 ISCSI_LOGIN_NEXT_STAGE(lh_req->flags); 850 ict->ict_login_sm.icl_login_transit = 851 lh_req->flags & ISCSI_FLAG_LOGIN_TRANSIT; 852 853 /* 854 * Initialize header for login reject response. This will also 855 * be copied for use as a template for other login responses 856 */ 857 lh_resp->opcode = ISCSI_OP_LOGIN_RSP; 858 lh_resp->max_version = ISCSIT_MAX_VERSION; 859 860 /* 861 * We already validated that we can support one of the initiator's 862 * versions in login_sm_req_pdu_check(). 863 */ 864 #if (ISCSIT_MAX_VERSION > 0) 865 if (ISCSIT_MAX_VERSION >= lh_req->min_version) { 866 lh_resp->active_version = 867 MIN(lh_req->max_version, ISCSIT_MAX_VERSION); 868 } else { 869 ASSERT(ISCSIT_MAX_VERSION <= lh_req->max_version); 870 lh_resp->active_version = ISCSIT_MAX_VERSION; 871 } 872 #endif 873 874 lh_resp->hlength = 0; /* No AHS */ 875 bcopy(lh_req->isid, lh_resp->isid, ISCSI_ISID_LEN); 876 lh_resp->tsid = lh_req->tsid; 877 lh_resp->itt = lh_req->itt; 878 879 /* 880 * StatSn, ExpCmdSn and MaxCmdSn will be set immediately before 881 * transmission 882 */ 883 } 884 885 static void 886 login_sm_send_next_response(iscsit_conn_t *ict, idm_pdu_t *pdu) 887 { 888 iscsi_login_rsp_hdr_t *lh_resp = (iscsi_login_rsp_hdr_t *)pdu->isp_hdr; 889 890 /* Make sure this PDU is part of the login phase */ 891 ASSERT((pdu->isp_flags & IDM_PDU_LOGIN_TX) != 0); 892 893 /* 894 * Fill in header values 895 */ 896 hton24(lh_resp->dlength, pdu->isp_datalen); 897 898 /* 899 * If the login is successful, this login response will contain 900 * the next StatSN and advance the StatSN for the connection. 901 */ 902 if (lh_resp->status_class == ISCSI_STATUS_CLASS_SUCCESS) { 903 ASSERT(ict->ict_sess != NULL); 904 905 if ((lh_resp->flags & ISCSI_FLAG_LOGIN_TRANSIT) && 906 (ISCSI_LOGIN_NEXT_STAGE(lh_resp->flags) == 907 ISCSI_FULL_FEATURE_PHASE) && 908 !(lh_resp->flags & ISCSI_FLAG_LOGIN_CONTINUE)) { 909 iscsit_login_sm_event(ict, ILE_LOGIN_FFP, NULL); 910 } 911 if (login_sm_is_last_response(pdu) == B_TRUE) { 912 /* 913 * The last of a potentially mult-PDU response finished. 914 */ 915 iscsit_login_sm_event(ict, ILE_LOGIN_RESP_COMPLETE, 916 NULL); 917 } 918 919 iscsit_conn_hold(ict); 920 pdu->isp_flags |= IDM_PDU_SET_STATSN | IDM_PDU_ADVANCE_STATSN; 921 iscsit_pdu_tx(pdu); 922 } else { 923 /* 924 * If status_class != ISCSI_STATUS_CLASS_SUCCESS then 925 * StatSN is not valid and we can call idm_pdu_tx instead 926 * of iscsit_pdu_tx. This is very good thing since in 927 * some cases of login failure we may not have a session. 928 * Since iscsit_calc_rspsn grabs the session mutex while 929 * it is retrieving values for expcmdsn and maxcmdsn this 930 * would cause a panic. 931 * 932 * Since we still want a value for expcmdsn, fill in an 933 * appropriate value based on the login request before 934 * sending the response. Cmdsn/expcmdsn do not advance during 935 * login phase. 936 */ 937 lh_resp->expcmdsn = htonl(ict->ict_login_sm.icl_cmdsn); 938 lh_resp->maxcmdsn = htonl(ict->ict_login_sm.icl_cmdsn + 1); 939 940 iscsit_conn_hold(ict); 941 idm_pdu_tx(pdu); 942 } 943 944 } 945 946 static void 947 login_sm_process_request(iscsit_conn_t *ict) 948 { 949 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 950 uint8_t error_class = 0; 951 uint8_t error_detail = 0; 952 953 /* 954 * First walk all the PDU's that make up this login request 955 * and compile all the iSCSI key-value pairs into nvlist format. 956 */ 957 958 ASSERT(lsm->icl_request_nvlist == NULL); 959 /* create an nvlist for request key/value pairs */ 960 if (idm_pdu_list_to_nvlist(&lsm->icl_pdu_list, 961 &lsm->icl_request_nvlist, &error_detail) != IDM_STATUS_SUCCESS) { 962 error_class = ISCSI_STATUS_CLASS_TARGET_ERR; 963 SET_LOGIN_ERROR(ict, error_class, error_detail); 964 goto request_fail; 965 } 966 967 /* Allocate a new nvlist for response key/value pairs */ 968 ASSERT(lsm->icl_response_nvlist == NULL); 969 if (nvlist_alloc(&lsm->icl_response_nvlist, NV_UNIQUE_NAME, 970 KM_NOSLEEP) != 0) { 971 error_class = ISCSI_STATUS_CLASS_TARGET_ERR; 972 error_detail = ISCSI_LOGIN_STATUS_NO_RESOURCES; 973 SET_LOGIN_ERROR(ict, error_class, error_detail); 974 goto request_fail; 975 } 976 977 /* 978 * This would be a very good time to make sure we have 979 * negotiated the required values for the login phase. For 980 * example we definitely should have defined InitiatorName, 981 * and Target name regardless of our current login phase. 982 */ 983 if (!ict->ict_op.op_initial_params_set) { 984 if (login_sm_validate_initial_parameters(ict) != 985 IDM_STATUS_SUCCESS) { 986 goto request_fail; 987 } 988 989 /* 990 * Now setup our session association. This includes 991 * create a new session or looking up an existing session, 992 * and if this is not a discovery session then we will 993 * also register this session with STMF. 994 */ 995 if (login_sm_session_bind(ict) != IDM_STATUS_SUCCESS) { 996 goto request_fail; 997 } 998 999 if (login_sm_set_auth(ict) != IDM_STATUS_SUCCESS) { 1000 goto request_fail; 1001 } 1002 1003 /* 1004 * Prepend TargetAlias and PortalGroupTag 1005 */ 1006 if (ict->ict_op.op_discovery_session == B_FALSE) { 1007 if ((lsm->icl_auth.ca_tgt_alias[0]) != '\0') { 1008 (void) iscsit_reply_string(ict, 1009 "TargetAlias", 1010 &lsm->icl_auth.ca_tgt_alias[0]); 1011 } 1012 (void) iscsit_reply_numerical(ict, 1013 "TargetPortalGroupTag", 1014 (uint64_t)lsm->icl_tpgt_tag); 1015 } 1016 1017 ict->ict_op.op_initial_params_set = B_TRUE; 1018 } 1019 1020 if (login_sm_process_nvlist(ict) != IDM_STATUS_SUCCESS) { 1021 goto request_fail; 1022 } 1023 1024 if (login_sm_check_security(ict) != IDM_STATUS_SUCCESS) { 1025 goto request_fail; 1026 } 1027 1028 /* clean up request_nvlist */ 1029 if (lsm->icl_request_nvlist != NULL) { 1030 nvlist_free(lsm->icl_request_nvlist); 1031 lsm->icl_request_nvlist = NULL; 1032 } 1033 1034 /* convert any responses to textbuf form */ 1035 ASSERT(lsm->icl_login_resp_itb == NULL); 1036 if (lsm->icl_response_nvlist) { 1037 lsm->icl_login_resp_itb = idm_nvlist_to_itextbuf( 1038 lsm->icl_response_nvlist); 1039 if (lsm->icl_login_resp_itb == NULL) { 1040 /* Still need to send the resp so continue */ 1041 SET_LOGIN_ERROR(ict, 1042 ISCSI_STATUS_CLASS_TARGET_ERR, 1043 ISCSI_LOGIN_STATUS_NO_RESOURCES); 1044 } 1045 /* clean up response_nvlist */ 1046 nvlist_free(lsm->icl_response_nvlist); 1047 lsm->icl_response_nvlist = NULL; 1048 } 1049 1050 /* tell the state machine to send the textbuf */ 1051 iscsit_login_sm_event(ict, ILE_LOGIN_RESP_READY, NULL); 1052 return; 1053 1054 request_fail: 1055 1056 /* clean up request_nvlist and response_nvlist */ 1057 if (lsm->icl_request_nvlist != NULL) { 1058 nvlist_free(lsm->icl_request_nvlist); 1059 lsm->icl_request_nvlist = NULL; 1060 } 1061 if (lsm->icl_response_nvlist != NULL) { 1062 nvlist_free(lsm->icl_response_nvlist); 1063 lsm->icl_response_nvlist = NULL; 1064 } 1065 /* Make sure we already set the login error */ 1066 if (ict->ict_login_sm.icl_login_resp_err_class == 1067 ISCSI_STATUS_CLASS_SUCCESS) { 1068 SET_LOGIN_ERROR(ict, 1069 ISCSI_STATUS_CLASS_TARGET_ERR, 1070 ISCSI_LOGIN_STATUS_TARGET_ERROR); 1071 } 1072 iscsit_login_sm_event(ict, ILE_LOGIN_RESP_READY, NULL); 1073 } 1074 1075 1076 static void 1077 login_sm_ffp_actions(iscsit_conn_t *ict) 1078 { 1079 iscsit_process_negotiated_values(ict); 1080 } 1081 1082 static idm_status_t 1083 login_sm_validate_initial_parameters(iscsit_conn_t *ict) 1084 { 1085 int nvrc; 1086 char *string_val; 1087 uint8_t error_class = ISCSI_STATUS_CLASS_INITIATOR_ERR; 1088 uint8_t error_detail = ISCSI_LOGIN_STATUS_MISSING_FIELDS; 1089 idm_status_t status = IDM_STATUS_FAIL; 1090 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 1091 1092 /* 1093 * Make sure we received the required information from the initial 1094 * login. Add these declaratives to the negotiated list and 1095 * remove them from the request list as we go. If anything fails, 1096 * the caller will clean-up the nvlists. 1097 */ 1098 1099 /* 1100 * Initiator name 1101 */ 1102 if ((nvrc = nvlist_lookup_string(lsm->icl_request_nvlist, 1103 "InitiatorName", &string_val)) != 0) { 1104 goto initial_params_done; 1105 } 1106 if ((nvrc = nvlist_add_string(lsm->icl_negotiated_values, 1107 "InitiatorName", string_val)) != 0) { 1108 goto initial_params_done; 1109 } 1110 if ((nvrc = nvlist_lookup_string(lsm->icl_negotiated_values, 1111 "InitiatorName", &string_val)) != 0) { 1112 goto initial_params_done; 1113 } 1114 lsm->icl_initiator_name = string_val; 1115 idm_conn_set_initiator_name(ict->ict_ic, lsm->icl_initiator_name); 1116 if ((nvrc = nvlist_remove(lsm->icl_request_nvlist, 1117 "InitiatorName", DATA_TYPE_STRING)) != 0) { 1118 goto initial_params_done; 1119 } 1120 1121 /* 1122 * Session type 1123 */ 1124 ict->ict_op.op_discovery_session = B_FALSE; 1125 nvrc = nvlist_lookup_string(lsm->icl_request_nvlist, 1126 "SessionType", &string_val); 1127 if (nvrc != ENOENT && nvrc != 0) { 1128 goto initial_params_done; 1129 } 1130 if (nvrc == 0) { 1131 if (strcmp(string_val, "Discovery") == 0) { 1132 ict->ict_op.op_discovery_session = B_TRUE; 1133 } else if (strcmp(string_val, "Normal") != 0) { 1134 goto initial_params_done; 1135 } 1136 if ((nvrc = nvlist_add_string(lsm->icl_negotiated_values, 1137 "SessionType", string_val)) != 0) { 1138 goto initial_params_done; 1139 } 1140 if ((nvrc = nvlist_remove(lsm->icl_request_nvlist, 1141 "SessionType", DATA_TYPE_STRING)) != 0) { 1142 goto initial_params_done; 1143 } 1144 } 1145 1146 /* 1147 * Must have either TargetName or SessionType==Discovery 1148 */ 1149 lsm->icl_target_name = NULL; 1150 nvrc = nvlist_lookup_string(lsm->icl_request_nvlist, 1151 "TargetName", &string_val); 1152 if (nvrc != ENOENT && nvrc != 0) { 1153 goto initial_params_done; 1154 } 1155 if (nvrc == 0) { 1156 if ((nvrc = nvlist_add_string(lsm->icl_negotiated_values, 1157 "TargetName", string_val)) != 0) { 1158 goto initial_params_done; 1159 } 1160 if ((nvrc = nvlist_lookup_string(lsm->icl_negotiated_values, 1161 "TargetName", &string_val)) != 0) { 1162 goto initial_params_done; 1163 } 1164 lsm->icl_target_name = string_val; 1165 idm_conn_set_target_name(ict->ict_ic, lsm->icl_target_name); 1166 if ((nvrc = nvlist_remove(lsm->icl_request_nvlist, 1167 "TargetName", DATA_TYPE_STRING)) != 0) { 1168 goto initial_params_done; 1169 } 1170 } else if (ict->ict_op.op_discovery_session == B_FALSE) { 1171 /* 1172 * Missing target name 1173 */ 1174 goto initial_params_done; 1175 } 1176 1177 idm_conn_set_isid(ict->ict_ic, lsm->icl_isid); 1178 (void) snprintf(ict->ict_ic->ic_tsih, ISCSI_MAX_TSIH_LEN + 1, "0x%04x", 1179 lsm->icl_tsih); 1180 1181 IDM_SM_LOG(CE_NOTE, "conn %p: initiator=%s", (void *)ict->ict_ic, 1182 (lsm->icl_initiator_name == NULL) ? "N/A" : 1183 lsm->icl_initiator_name); 1184 IDM_SM_LOG(CE_NOTE, "conn %p: target=%s", (void *)ict->ict_ic, 1185 (lsm->icl_target_name == NULL) ? "N/A" : 1186 lsm->icl_target_name); 1187 IDM_SM_LOG(CE_NOTE, "conn %p: sessiontype=%s", (void *)ict->ict_ic, 1188 ict->ict_op.op_discovery_session ? "Discovery" : "Normal"); 1189 1190 /* Sucess */ 1191 status = IDM_STATUS_SUCCESS; 1192 error_class = ISCSI_STATUS_CLASS_SUCCESS; 1193 error_detail = ISCSI_LOGIN_STATUS_ACCEPT; 1194 1195 initial_params_done: 1196 SET_LOGIN_ERROR(ict, error_class, error_detail); 1197 return (status); 1198 } 1199 1200 1201 /* 1202 * login_sm_session_bind 1203 * 1204 * This function looks at the data from the initial login request 1205 * of a new connection and either looks up and existing session, 1206 * creates a new session, or returns an error. RFC3720 section 5.3.1 1207 * defines these rules: 1208 * 1209 * +------------------------------------------------------------------+ 1210 * |ISID | TSIH | CID | Target action | 1211 * +------------------------------------------------------------------+ 1212 * |new | non-zero | any | fail the login | 1213 * | | | | ("session does not exist") | 1214 * +------------------------------------------------------------------+ 1215 * |new | zero | any | instantiate a new session | 1216 * +------------------------------------------------------------------+ 1217 * |existing | zero | any | do session reinstatement | 1218 * | | | | (see section 5.3.5) | 1219 * +------------------------------------------------------------------+ 1220 * |existing | non-zero | new | add a new connection to | 1221 * | | existing | | the session | 1222 * +------------------------------------------------------------------+ 1223 * |existing | non-zero |existing| do connection reinstatement| 1224 * | | existing | | (see section 5.3.4) | 1225 * +------------------------------------------------------------------+ 1226 * |existing | non-zero | any | fail the login | 1227 * | | new | | ("session does not exist") | 1228 * +------------------------------------------------------------------+ 1229 * 1230 */ 1231 1232 /* 1233 * Map an <ipv6,port> address to an <ipv4,port> address if possible. 1234 * Returns: 1235 * 1 - success 1236 * 0 - address not mapable 1237 */ 1238 1239 static int 1240 iscsit_is_v4_mapped(struct sockaddr_storage *sa, struct sockaddr_storage *v4sa) 1241 { 1242 struct sockaddr_in *sin; 1243 struct in_addr *in; 1244 struct sockaddr_in6 *sin6; 1245 struct in6_addr *in6; 1246 int ret = 0; 1247 1248 sin6 = (struct sockaddr_in6 *)sa; 1249 in6 = &sin6->sin6_addr; 1250 if ((sa->ss_family == AF_INET6) && 1251 (IN6_IS_ADDR_V4MAPPED(in6) || IN6_IS_ADDR_V4COMPAT(in6))) { 1252 sin = (struct sockaddr_in *)v4sa; 1253 in = &sin->sin_addr; 1254 v4sa->ss_family = AF_INET; 1255 sin->sin_port = sin6->sin6_port; 1256 IN6_V4MAPPED_TO_INADDR(in6, in); 1257 ret = 1; 1258 } 1259 return (ret); 1260 } 1261 1262 static idm_status_t 1263 login_sm_session_bind(iscsit_conn_t *ict) 1264 { 1265 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 1266 iscsit_tgt_t *tgt = NULL; 1267 iscsit_tpgt_t *tpgt = NULL; 1268 iscsit_portal_t *portal = NULL; 1269 iscsit_sess_t *existing_sess = NULL; 1270 iscsit_sess_t *new_sess = NULL; 1271 iscsit_conn_t *existing_ict = NULL; 1272 uint8_t error_class; 1273 uint8_t error_detail; 1274 1275 /* 1276 * The multi-threaded execution of binding login sessions to target 1277 * introduced race conditions in the session creation/binding and 1278 * allowed duplicate sessions to tbe created. The addition of the 1279 * global mutex login_sm_session_mutex makes this function single 1280 * threaded to avoid such race conditions. Although this causes 1281 * a small portion of the login to be serialized, it is unlikely 1282 * that there would be numerous simultaneous logins to become a 1283 * performance issue. 1284 */ 1285 mutex_enter(&login_sm_session_mutex); 1286 1287 /* 1288 * Look up target and then check if there are sessions or connections 1289 * that match this request (see below). Any holds taken on objects 1290 * must be released at the end of the function (let's keep things 1291 * simple). 1292 * 1293 * If target name is set then we should have a corresponding target 1294 * context configured. 1295 */ 1296 if (lsm->icl_target_name != NULL) { 1297 /* 1298 * iscsit_tgt_lookup implicitly takes a ref on the target 1299 */ 1300 ISCSIT_GLOBAL_LOCK(RW_READER); 1301 tgt = iscsit_tgt_lookup_locked(lsm->icl_target_name); 1302 if (tgt == NULL) { 1303 ISCSIT_GLOBAL_UNLOCK(); 1304 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_INITIATOR_ERR, 1305 ISCSI_LOGIN_STATUS_TGT_NOT_FOUND); 1306 goto session_bind_error; 1307 } else { 1308 mutex_enter(&tgt->target_mutex); 1309 tpgt = avl_first(&tgt->target_tpgt_list); 1310 1311 if (IS_DEFAULT_TPGT(tpgt)) { 1312 lsm->icl_tpgt_tag = ISCSIT_DEFAULT_TPGT; 1313 } else { 1314 /* 1315 * Find the portal group tag for the 1316 * login response. 1317 */ 1318 struct sockaddr_storage v4sa, *sa; 1319 1320 sa = &ict->ict_ic->ic_laddr; 1321 portal = iscsit_tgt_lookup_portal(tgt, 1322 sa, &tpgt); 1323 if (portal == NULL && 1324 iscsit_is_v4_mapped(sa, &v4sa)) { 1325 /* 1326 * Try again if the local address 1327 * was v6 mappable to v4. 1328 */ 1329 portal = iscsit_tgt_lookup_portal(tgt, 1330 &v4sa, &tpgt); 1331 1332 } 1333 if (portal == NULL) { 1334 /* 1335 * Initiator came in on wrong address 1336 */ 1337 SET_LOGIN_ERROR(ict, 1338 ISCSI_STATUS_CLASS_INITIATOR_ERR, 1339 ISCSI_LOGIN_STATUS_TGT_NOT_FOUND); 1340 mutex_exit(&tgt->target_mutex); 1341 ISCSIT_GLOBAL_UNLOCK(); 1342 goto session_bind_error; 1343 } 1344 1345 /* 1346 * Need to release holds on the portal and 1347 * tpgt after processing is complete. 1348 */ 1349 lsm->icl_tpgt_tag = tpgt->tpgt_tag; 1350 iscsit_portal_rele(portal); 1351 iscsit_tpgt_rele(tpgt); 1352 } 1353 1354 mutex_enter(&iscsit_global.global_state_mutex); 1355 if ((tgt->target_state != TS_STMF_ONLINE) || 1356 ((iscsit_global.global_svc_state != ISE_ENABLED) && 1357 ((iscsit_global.global_svc_state != ISE_BUSY)))) { 1358 mutex_exit(&iscsit_global.global_state_mutex); 1359 SET_LOGIN_ERROR(ict, 1360 ISCSI_STATUS_CLASS_TARGET_ERR, 1361 ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE); 1362 mutex_exit(&tgt->target_mutex); 1363 ISCSIT_GLOBAL_UNLOCK(); 1364 goto session_bind_error; 1365 } 1366 mutex_exit(&iscsit_global.global_state_mutex); 1367 mutex_exit(&tgt->target_mutex); 1368 ISCSIT_GLOBAL_UNLOCK(); 1369 } 1370 } 1371 1372 ASSERT((tgt != NULL) || (ict->ict_op.op_discovery_session == B_TRUE)); 1373 1374 /* 1375 * Check if there is an existing session matching this ISID. If 1376 * tgt == NULL then we'll look for the session on the global list 1377 * of discovery session. If we find a session then the ISID 1378 * exists. 1379 */ 1380 existing_sess = iscsit_tgt_lookup_sess(tgt, lsm->icl_initiator_name, 1381 lsm->icl_isid, lsm->icl_tsih, lsm->icl_tpgt_tag); 1382 if (existing_sess != NULL) { 1383 existing_ict = iscsit_sess_lookup_conn(existing_sess, 1384 ict->ict_cid); 1385 } 1386 1387 /* 1388 * If this is a discovery session, make sure it has appropriate 1389 * parameters. 1390 */ 1391 if ((ict->ict_op.op_discovery_session == B_TRUE) && 1392 ((lsm->icl_tsih != ISCSI_UNSPEC_TSIH) || (existing_sess != NULL))) { 1393 /* XXX Do we need to check for existing ISID (sess != NULL)? */ 1394 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_INITIATOR_ERR, 1395 ISCSI_LOGIN_STATUS_INVALID_REQUEST); 1396 goto session_bind_error; 1397 } 1398 1399 /* 1400 * Check the two error conditions from the table. 1401 * 1402 * ISID=new, TSIH=non-zero 1403 */ 1404 if ((existing_sess == NULL) && (lsm->icl_tsih != ISCSI_UNSPEC_TSIH)) { 1405 /* fail the login */ 1406 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_INITIATOR_ERR, 1407 ISCSI_LOGIN_STATUS_NO_SESSION); 1408 goto session_bind_error; 1409 } 1410 1411 /* ISID=existing, TSIH=non-zero new */ 1412 if ((existing_sess != NULL) && (lsm->icl_tsih != 0) && 1413 (existing_sess->ist_tsih != lsm->icl_tsih)) { 1414 /* fail the login */ 1415 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_INITIATOR_ERR, 1416 ISCSI_LOGIN_STATUS_NO_SESSION); 1417 goto session_bind_error; 1418 } 1419 1420 /* 1421 * Handle the remaining table cases in order 1422 */ 1423 if (existing_sess == NULL) { 1424 /* Should have caught this above */ 1425 ASSERT(lsm->icl_tsih == ISCSI_UNSPEC_TSIH); 1426 /* 1427 * ISID=new, TSIH=zero --> instantiate a new session 1428 */ 1429 new_sess = iscsit_sess_create(tgt, ict, lsm->icl_cmdsn, 1430 lsm->icl_isid, lsm->icl_tpgt_tag, lsm->icl_initiator_name, 1431 lsm->icl_target_name, &error_class, &error_detail); 1432 ASSERT(new_sess != NULL); 1433 1434 /* Session create may have failed even if it returned a value */ 1435 if (error_class != ISCSI_STATUS_CLASS_SUCCESS) { 1436 SET_LOGIN_ERROR(ict, error_class, error_detail); 1437 goto session_bind_error; 1438 } 1439 1440 /* 1441 * If we don't already have an STMF session and this is not 1442 * a discovery session then we need to allocate and register 1443 * one. 1444 */ 1445 if (!ict->ict_op.op_discovery_session) { 1446 if (login_sm_session_register(ict) != 1447 IDM_STATUS_SUCCESS) { 1448 /* login_sm_session_register sets error codes */ 1449 goto session_bind_error; 1450 } 1451 } 1452 1453 } else { 1454 if (lsm->icl_tsih == ISCSI_UNSPEC_TSIH) { 1455 /* 1456 * ISID=existing, TSIH=zero --> Session reinstatement 1457 */ 1458 new_sess = iscsit_sess_reinstate(tgt, existing_sess, 1459 ict, &error_class, &error_detail); 1460 ASSERT(new_sess != NULL); 1461 1462 if (error_class != ISCSI_STATUS_CLASS_SUCCESS) { 1463 SET_LOGIN_ERROR(ict, error_class, error_detail); 1464 goto session_bind_error; 1465 } 1466 1467 /* 1468 * If we don't already have an STMF session and this is 1469 * not a discovery session then we need to allocate and 1470 * register one. 1471 */ 1472 if (!ict->ict_op.op_discovery_session) { 1473 if (login_sm_session_register(ict) != 1474 IDM_STATUS_SUCCESS) { 1475 /* 1476 * login_sm_session_register sets 1477 * error codes 1478 */ 1479 goto session_bind_error; 1480 } 1481 } 1482 } else { 1483 /* 1484 * The following code covers these two cases: 1485 * ISID=existing, TSIH=non-zero existing, CID=new 1486 * --> add new connection to MC/S session 1487 * ISID=existing, TSIH=non-zero existing, CID=existing 1488 * --> do connection reinstatement 1489 * 1490 * Session continuation uses this path as well 1491 */ 1492 cmn_err(CE_NOTE, "login_sm_session_bind: add new " 1493 "conn/sess continue"); 1494 if (existing_ict != NULL) { 1495 /* 1496 * ISID=existing, TSIH=non-zero existing, 1497 * CID=existing --> do connection reinstatement 1498 */ 1499 if (iscsit_conn_reinstate(existing_ict, ict) != 1500 IDM_STATUS_SUCCESS) { 1501 /* 1502 * Most likely this means the connection 1503 * the initiator is trying to reinstate 1504 * is not in an acceptable state. 1505 */ 1506 SET_LOGIN_ERROR(ict, 1507 ISCSI_STATUS_CLASS_INITIATOR_ERR, 1508 ISCSI_LOGIN_STATUS_INIT_ERR); 1509 goto session_bind_error; 1510 } 1511 } 1512 1513 iscsit_sess_sm_event(existing_sess, SE_CONN_IN_LOGIN, 1514 ict); 1515 } 1516 } 1517 1518 if (tgt != NULL) 1519 iscsit_tgt_rele(tgt); 1520 if (existing_sess != NULL) 1521 iscsit_sess_rele(existing_sess); 1522 if (existing_ict != NULL) 1523 iscsit_conn_rele(existing_ict); 1524 1525 mutex_exit(&login_sm_session_mutex); 1526 return (IDM_STATUS_SUCCESS); 1527 1528 session_bind_error: 1529 if (tgt != NULL) 1530 iscsit_tgt_rele(tgt); 1531 if (existing_sess != NULL) 1532 iscsit_sess_rele(existing_sess); 1533 if (existing_ict != NULL) 1534 iscsit_conn_rele(existing_ict); 1535 1536 /* 1537 * If session bind fails we will fail the login but don't destroy 1538 * the session until later. 1539 */ 1540 mutex_exit(&login_sm_session_mutex); 1541 return (IDM_STATUS_FAIL); 1542 } 1543 1544 1545 static idm_status_t 1546 login_sm_set_auth(iscsit_conn_t *ict) 1547 { 1548 idm_status_t idmrc = IDM_STATUS_SUCCESS; 1549 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 1550 iscsit_ini_t *ini; 1551 iscsit_tgt_t *tgt; 1552 char *auth = ""; 1553 char *radiusserver = ""; 1554 char *radiussecret = ""; 1555 char *chapuser = ""; 1556 char *chapsecret = ""; 1557 char *targetchapuser = ""; 1558 char *targetchapsecret = ""; 1559 char *targetalias = ""; 1560 int i; 1561 1562 ISCSIT_GLOBAL_LOCK(RW_READER); 1563 1564 /* 1565 * Set authentication method to none for discovery session. 1566 */ 1567 if (ict->ict_op.op_discovery_session == B_TRUE) { 1568 lsm->icl_auth.ca_method_valid_list[0] = AM_NONE; 1569 ISCSIT_GLOBAL_UNLOCK(); 1570 return (idmrc); 1571 } 1572 1573 /* 1574 * Get all the authentication parameters we need -- since we hold 1575 * the global config lock we guarantee that the parameters will 1576 * be consistent with each other. 1577 */ 1578 (void) nvlist_lookup_string(iscsit_global.global_props, 1579 PROP_AUTH, &auth); 1580 (void) nvlist_lookup_string(iscsit_global.global_props, 1581 PROP_RADIUS_SERVER, &radiusserver); 1582 (void) nvlist_lookup_string(iscsit_global.global_props, 1583 PROP_RADIUS_SECRET, &radiussecret); 1584 1585 ini = iscsit_ini_lookup_locked(lsm->icl_initiator_name); 1586 if (ini != NULL) { 1587 /* Get Initiator CHAP parameters */ 1588 (void) nvlist_lookup_string(ini->ini_props, PROP_CHAP_USER, 1589 &chapuser); 1590 (void) nvlist_lookup_string(ini->ini_props, PROP_CHAP_SECRET, 1591 &chapsecret); 1592 } 1593 1594 tgt = ict->ict_sess->ist_tgt; 1595 if (tgt != NULL) { 1596 /* See if we have a target-specific authentication setting */ 1597 (void) nvlist_lookup_string(tgt->target_props, PROP_AUTH, 1598 &auth); 1599 /* Get target CHAP parameters */ 1600 (void) nvlist_lookup_string(tgt->target_props, 1601 PROP_TARGET_CHAP_USER, &targetchapuser); 1602 (void) nvlist_lookup_string(tgt->target_props, 1603 PROP_TARGET_CHAP_SECRET, &targetchapsecret); 1604 /* Get alias */ 1605 (void) nvlist_lookup_string(tgt->target_props, 1606 PROP_ALIAS, &targetalias); 1607 } 1608 1609 /* Set authentication method */ 1610 i = 0; 1611 if (strcmp(auth, PA_AUTH_RADIUS) == 0) { 1612 /* CHAP authentication using RADIUS server */ 1613 lsm->icl_auth.ca_method_valid_list[i++] = AM_CHAP; 1614 lsm->icl_auth.ca_use_radius = B_TRUE; 1615 } else if (strcmp(auth, PA_AUTH_CHAP) == 0) { 1616 /* Local CHAP authentication */ 1617 lsm->icl_auth.ca_method_valid_list[i++] = AM_CHAP; 1618 lsm->icl_auth.ca_use_radius = B_FALSE; 1619 } else if ((strcmp(auth, PA_AUTH_NONE) == 0) || 1620 (strcmp(auth, "") == 0)) { 1621 /* No authentication */ 1622 lsm->icl_auth.ca_method_valid_list[i++] = AM_NONE; 1623 } 1624 1625 /* 1626 * If initiator/target CHAP username is not set then use the 1627 * node name. If lsm->icl_target_name == NULL then this is 1628 * a discovery session so we don't need to work about the target. 1629 */ 1630 if (strcmp(chapuser, "") == 0) { 1631 (void) strlcpy(lsm->icl_auth.ca_ini_chapuser, 1632 lsm->icl_initiator_name, 1633 min(iscsitAuthStringMaxLength, MAX_ISCSI_NODENAMELEN)); 1634 } else { 1635 (void) strlcpy(lsm->icl_auth.ca_ini_chapuser, chapuser, 1636 iscsitAuthStringMaxLength); 1637 } 1638 if ((lsm->icl_target_name != NULL) && 1639 (strcmp(targetchapuser, "") == 0)) { 1640 (void) strlcpy(lsm->icl_auth.ca_tgt_chapuser, 1641 lsm->icl_target_name, 1642 min(iscsitAuthStringMaxLength, MAX_ISCSI_NODENAMELEN)); 1643 } else { 1644 (void) strlcpy(lsm->icl_auth.ca_tgt_chapuser, 1645 targetchapuser, iscsitAuthStringMaxLength); 1646 } 1647 1648 /* 1649 * Secrets are stored in base64-encoded format so we need to 1650 * decode them into binary form 1651 */ 1652 if (strcmp(chapsecret, "") == 0) { 1653 lsm->icl_auth.ca_ini_chapsecretlen = 0; 1654 } else { 1655 if (iscsi_base64_str_to_binary(chapsecret, 1656 strnlen(chapsecret, iscsitAuthStringMaxLength), 1657 lsm->icl_auth.ca_ini_chapsecret, iscsitAuthStringMaxLength, 1658 &lsm->icl_auth.ca_ini_chapsecretlen) != 0) { 1659 cmn_err(CE_WARN, "Corrupted CHAP secret" 1660 " for initiator %s", lsm->icl_initiator_name); 1661 lsm->icl_auth.ca_ini_chapsecretlen = 0; 1662 } 1663 } 1664 if (strcmp(targetchapsecret, "") == 0) { 1665 lsm->icl_auth.ca_tgt_chapsecretlen = 0; 1666 } else { 1667 if (iscsi_base64_str_to_binary(targetchapsecret, 1668 strnlen(targetchapsecret, iscsitAuthStringMaxLength), 1669 lsm->icl_auth.ca_tgt_chapsecret, iscsitAuthStringMaxLength, 1670 &lsm->icl_auth.ca_tgt_chapsecretlen) != 0) { 1671 cmn_err(CE_WARN, "Corrupted CHAP secret" 1672 " for target %s", lsm->icl_target_name); 1673 lsm->icl_auth.ca_tgt_chapsecretlen = 0; 1674 } 1675 } 1676 if (strcmp(radiussecret, "") == 0) { 1677 lsm->icl_auth.ca_radius_secretlen = 0; 1678 } else { 1679 if (iscsi_base64_str_to_binary(radiussecret, 1680 strnlen(radiussecret, iscsitAuthStringMaxLength), 1681 lsm->icl_auth.ca_radius_secret, iscsitAuthStringMaxLength, 1682 &lsm->icl_auth.ca_radius_secretlen) != 0) { 1683 cmn_err(CE_WARN, "Corrupted RADIUS secret"); 1684 lsm->icl_auth.ca_radius_secretlen = 0; 1685 } 1686 } 1687 1688 /* 1689 * Set alias 1690 */ 1691 (void) strlcpy(lsm->icl_auth.ca_tgt_alias, targetalias, 1692 MAX_ISCSI_NODENAMELEN); 1693 1694 /* 1695 * Now that authentication parameters are setup, validate the parameters 1696 * against the authentication mode 1697 * Decode RADIUS server value int lsm->icl_auth.ca_radius_server 1698 */ 1699 if ((strcmp(auth, PA_AUTH_RADIUS) == 0) && 1700 ((lsm->icl_auth.ca_radius_secretlen == 0) || 1701 (strcmp(radiusserver, "") == 0) || 1702 it_common_convert_sa(radiusserver, 1703 &lsm->icl_auth.ca_radius_server, 1704 DEFAULT_RADIUS_PORT) == NULL)) { 1705 cmn_err(CE_WARN, "RADIUS authentication selected " 1706 "for target %s but RADIUS parameters are not " 1707 "configured.", lsm->icl_target_name); 1708 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_TARGET_ERR, 1709 ISCSI_LOGIN_STATUS_TARGET_ERROR); 1710 idmrc = IDM_STATUS_FAIL; 1711 } else if ((strcmp(auth, PA_AUTH_CHAP) == 0) && 1712 (lsm->icl_auth.ca_ini_chapsecretlen == 0)) { 1713 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_INITIATOR_ERR, 1714 ISCSI_LOGIN_STATUS_AUTH_FAILED); 1715 idmrc = IDM_STATUS_FAIL; 1716 } 1717 1718 ISCSIT_GLOBAL_UNLOCK(); 1719 1720 return (idmrc); 1721 } 1722 1723 1724 static idm_status_t 1725 login_sm_session_register(iscsit_conn_t *ict) 1726 { 1727 iscsit_sess_t *ist = ict->ict_sess; 1728 stmf_scsi_session_t *ss; 1729 iscsi_transport_id_t *iscsi_tptid; 1730 uint16_t ident_len, adn_len, tptid_sz; 1731 1732 /* 1733 * Hold target mutex until we have finished registering with STMF 1734 */ 1735 mutex_enter(&ist->ist_tgt->target_mutex); 1736 if (ist->ist_tgt->target_state != TS_STMF_ONLINE) { 1737 mutex_exit(&ist->ist_tgt->target_mutex); 1738 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_INITIATOR_ERR, 1739 ISCSI_LOGIN_STATUS_TGT_REMOVED); 1740 return (IDM_STATUS_FAIL); 1741 } 1742 1743 ss = stmf_alloc(STMF_STRUCT_SCSI_SESSION, 0, 1744 0); 1745 if (ss == NULL) { 1746 mutex_exit(&ist->ist_tgt->target_mutex); 1747 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_TARGET_ERR, 1748 ISCSI_LOGIN_STATUS_NO_RESOURCES); 1749 return (IDM_STATUS_FAIL); 1750 } 1751 1752 ident_len = strlen(ist->ist_initiator_name) + 1; 1753 ss->ss_rport_id = kmem_zalloc(sizeof (scsi_devid_desc_t) + 1754 ident_len, KM_SLEEP); 1755 (void) strcpy((char *)ss->ss_rport_id->ident, ist->ist_initiator_name); 1756 ss->ss_rport_id->ident_length = ident_len - 1; 1757 ss->ss_rport_id->protocol_id = PROTOCOL_iSCSI; 1758 ss->ss_rport_id->piv = 1; 1759 ss->ss_rport_id->code_set = CODE_SET_ASCII; 1760 ss->ss_rport_id->association = ID_IS_TARGET_PORT; 1761 1762 /* adn_len should be 4 byte aligned, SPC3 rev 23, section 7.54.6 */ 1763 adn_len = (ident_len + 3) & ~ 3; 1764 tptid_sz = sizeof (iscsi_transport_id_t) - 1 + adn_len; 1765 ss->ss_rport = stmf_remote_port_alloc(tptid_sz); 1766 ss->ss_rport->rport_tptid->protocol_id = PROTOCOL_iSCSI; 1767 ss->ss_rport->rport_tptid->format_code = 0; 1768 iscsi_tptid = (iscsi_transport_id_t *)ss->ss_rport->rport_tptid; 1769 SCSI_WRITE16(&iscsi_tptid->add_len, adn_len); 1770 (void) strlcpy((char *)iscsi_tptid->iscsi_name, 1771 ist->ist_initiator_name, ident_len); 1772 1773 ss->ss_lport = ist->ist_lport; 1774 1775 if (stmf_register_scsi_session(ict->ict_sess->ist_lport, ss) != 1776 STMF_SUCCESS) { 1777 mutex_exit(&ist->ist_tgt->target_mutex); 1778 kmem_free(ss->ss_rport_id, 1779 sizeof (scsi_devid_desc_t) + 1780 strlen(ist->ist_initiator_name) + 1); 1781 stmf_remote_port_free(ss->ss_rport); 1782 stmf_free(ss); 1783 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_TARGET_ERR, 1784 ISCSI_LOGIN_STATUS_TARGET_ERROR); 1785 return (IDM_STATUS_FAIL); 1786 } 1787 1788 ss->ss_port_private = ict->ict_sess; 1789 ict->ict_sess->ist_stmf_sess = ss; 1790 mutex_exit(&ist->ist_tgt->target_mutex); 1791 1792 return (IDM_STATUS_SUCCESS); 1793 } 1794 1795 1796 static idm_status_t 1797 login_sm_req_pdu_check(iscsit_conn_t *ict, idm_pdu_t *pdu) 1798 { 1799 uint8_t csg_req; 1800 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 1801 iscsi_login_hdr_t *lh = (iscsi_login_hdr_t *)pdu->isp_hdr; 1802 iscsi_login_rsp_hdr_t *lh_resp = lsm->icl_login_resp_tmpl; 1803 1804 /* 1805 * Check CSG 1806 */ 1807 csg_req = ISCSI_LOGIN_CURRENT_STAGE(lh->flags); 1808 switch (csg_req) { 1809 case ISCSI_SECURITY_NEGOTIATION_STAGE: 1810 case ISCSI_OP_PARMS_NEGOTIATION_STAGE: 1811 if ((csg_req != lsm->icl_login_csg) && 1812 (lsm->icl_login_state != ILS_LOGIN_INIT)) { 1813 /* 1814 * Inappropriate CSG change. Initiator can only 1815 * change CSG after we've responded with the 1816 * transit bit set. If we had responded with 1817 * a CSG change previous we would have updated 1818 * our copy of CSG. 1819 * 1820 * The exception is when we are in ILS_LOGIN_INIT 1821 * state since we haven't determined our initial 1822 * CSG value yet. 1823 */ 1824 goto pdu_check_fail; 1825 } 1826 break; 1827 case ISCSI_FULL_FEATURE_PHASE: 1828 default: 1829 goto pdu_check_fail; 1830 } 1831 1832 /* 1833 * If this is the first login PDU for a new connection then 1834 * the session will be NULL. 1835 */ 1836 if (ict->ict_sess != NULL) { 1837 /* 1838 * We've already created a session on a previous PDU. Make 1839 * sure this PDU is consistent with what we've already seen 1840 */ 1841 if ((ict->ict_cid != ntohs(lh->cid)) || 1842 (bcmp(ict->ict_sess->ist_isid, lh->isid, 1843 ISCSI_ISID_LEN) != 0)) { 1844 goto pdu_check_fail; 1845 } 1846 } 1847 1848 /* 1849 * Make sure we are compatible with the version range 1850 */ 1851 #if (ISCSIT_MAX_VERSION > 0) 1852 if ((lh->min_version > ISCSIT_MAX_VERSION) || 1853 (lh->max_version < ISCSIT_MIN_VERSION)) { 1854 goto pdu_check_fail; 1855 } 1856 #endif 1857 1858 /* 1859 * Just in case the initiator changes things up on us along the way 1860 * check against our active_version -- we can't change the active 1861 * version and the initiator is not *supposed* to change its 1862 * min_version and max_version values so this should never happen. 1863 * Of course we only do this if the response header template has 1864 * been built. 1865 */ 1866 if ((lh_resp->opcode == ISCSI_OP_LOGIN_RSP) && /* header valid */ 1867 ((lh->min_version > lh_resp->active_version) || 1868 (lh->max_version < lh_resp->active_version))) { 1869 goto pdu_check_fail; 1870 } 1871 1872 return (IDM_STATUS_SUCCESS); 1873 1874 pdu_check_fail: 1875 return (IDM_STATUS_FAIL); 1876 } 1877 1878 static idm_status_t 1879 login_sm_process_nvlist(iscsit_conn_t *ict) 1880 { 1881 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 1882 char *nvp_name; 1883 nvpair_t *nvp; 1884 nvpair_t *next_nvp; 1885 nvpair_t *negotiated_nvp; 1886 kv_status_t kvrc; 1887 uint8_t error_class; 1888 uint8_t error_detail; 1889 idm_status_t idm_status; 1890 1891 error_class = ISCSI_STATUS_CLASS_SUCCESS; 1892 error_detail = ISCSI_LOGIN_STATUS_ACCEPT; 1893 1894 /* First, request that the transport process the list */ 1895 kvrc = idm_negotiate_key_values(ict->ict_ic, lsm->icl_request_nvlist, 1896 lsm->icl_response_nvlist, lsm->icl_negotiated_values); 1897 idm_kvstat_to_error(kvrc, &error_class, &error_detail); 1898 if (error_class != ISCSI_STATUS_CLASS_SUCCESS) { 1899 SET_LOGIN_ERROR(ict, error_class, error_detail); 1900 idm_status = IDM_STATUS_FAIL; 1901 return (idm_status); 1902 } 1903 1904 /* Ensure we clear transit bit if the transport layer has countered */ 1905 if (kvrc == KV_HANDLED_NO_TRANSIT) { 1906 lsm->icl_login_transit = B_FALSE; 1907 } 1908 1909 /* Prepend the declarative params */ 1910 if (!ict->ict_op.op_declarative_params_set && 1911 lsm->icl_login_csg == ISCSI_OP_PARMS_NEGOTIATION_STAGE) { 1912 if (iscsit_add_declarative_keys(ict) != IDM_STATUS_SUCCESS) { 1913 idm_status = IDM_STATUS_FAIL; 1914 return (idm_status); 1915 } 1916 ict->ict_op.op_declarative_params_set = B_TRUE; 1917 } 1918 1919 /* Now, move on and process the rest of the pairs */ 1920 nvp = nvlist_next_nvpair(lsm->icl_request_nvlist, NULL); 1921 while (nvp != NULL) { 1922 next_nvp = nvlist_next_nvpair(lsm->icl_request_nvlist, nvp); 1923 nvp_name = nvpair_name(nvp); 1924 /* 1925 * If we've already agreed upon a value then make sure this 1926 * is not attempting to change that value. From RFC3270 1927 * section 5.3: 1928 * 1929 * "Neither the initiator nor the target should attempt to 1930 * declare or negotiate a parameter more than once during 1931 * login except for responses to specific keys that 1932 * explicitly allow repeated key declarations (e.g., 1933 * TargetAddress). An attempt to renegotiate/redeclare 1934 * parameters not specifically allowed MUST be detected 1935 * by the initiator and target. If such an attempt is 1936 * detected by the target, the target MUST respond 1937 * with Login reject (initiator error); ..." 1938 */ 1939 if (nvlist_lookup_nvpair(lsm->icl_negotiated_values, 1940 nvp_name, &negotiated_nvp) == 0) { 1941 kvrc = KV_HANDLED; 1942 } else { 1943 kvrc = iscsit_handle_key(ict, nvp, nvp_name); 1944 } 1945 1946 idm_kvstat_to_error(kvrc, &error_class, &error_detail); 1947 if (error_class != ISCSI_STATUS_CLASS_SUCCESS) { 1948 break; 1949 } 1950 1951 nvp = next_nvp; 1952 } 1953 1954 if (error_class == ISCSI_STATUS_CLASS_SUCCESS) { 1955 idm_status = IDM_STATUS_SUCCESS; 1956 } else { 1957 /* supply login class/detail for login errors */ 1958 SET_LOGIN_ERROR(ict, error_class, error_detail); 1959 idm_status = IDM_STATUS_FAIL; 1960 } 1961 1962 return (idm_status); 1963 } 1964 1965 static idm_status_t 1966 login_sm_check_security(iscsit_conn_t *ict) 1967 { 1968 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 1969 conn_auth_t *auth = &lsm->icl_auth; 1970 iscsit_auth_method_t *am_list = &auth->ca_method_valid_list[0]; 1971 kv_status_t kvrc; 1972 uint8_t error_class; 1973 uint8_t error_detail; 1974 idm_status_t idm_status; 1975 1976 error_class = ISCSI_STATUS_CLASS_SUCCESS; 1977 error_detail = ISCSI_LOGIN_STATUS_ACCEPT; 1978 1979 /* Check authentication status. */ 1980 if (lsm->icl_login_csg == ISCSI_SECURITY_NEGOTIATION_STAGE) { 1981 /* 1982 * We should have some authentication key/value pair(s) 1983 * received from initiator and the authentication phase 1984 * has been shifted when the key/value pair(s) are being 1985 * handled in the previous call iscsit_handle_security_key. 1986 * Now it turns to target to check the authentication phase 1987 * and shift it after taking some authentication action. 1988 */ 1989 kvrc = iscsit_reply_security_key(ict); 1990 idm_kvstat_to_error(kvrc, &error_class, &error_detail); 1991 } else if (!ict->ict_login_sm.icl_auth_pass) { 1992 /* 1993 * Check to see if the target allows initiators to bypass the 1994 * security check. If the target is configured to require 1995 * authentication, we reject the connection. 1996 */ 1997 if (am_list[0] == AM_NONE || am_list[0] == 0) { 1998 ict->ict_login_sm.icl_auth_pass = 1; 1999 } else { 2000 error_class = ISCSI_STATUS_CLASS_INITIATOR_ERR; 2001 error_detail = ISCSI_LOGIN_STATUS_AUTH_FAILED; 2002 } 2003 } 2004 2005 if (error_class == ISCSI_STATUS_CLASS_SUCCESS) { 2006 idm_status = IDM_STATUS_SUCCESS; 2007 } else { 2008 /* supply login class/detail for login errors */ 2009 SET_LOGIN_ERROR(ict, error_class, error_detail); 2010 idm_status = IDM_STATUS_FAIL; 2011 } 2012 2013 return (idm_status); 2014 } 2015 2016 static idm_pdu_t * 2017 login_sm_build_login_response(iscsit_conn_t *ict) 2018 { 2019 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 2020 iscsi_login_rsp_hdr_t *lh; 2021 int transit, text_transit = 1; 2022 idm_pdu_t *login_resp; 2023 2024 /* 2025 * Create a response PDU and fill it with as much of 2026 * the response text that will fit. 2027 */ 2028 2029 if (lsm->icl_login_resp_itb) { 2030 /* allocate a pdu with space for text */ 2031 login_resp = idm_pdu_alloc(sizeof (iscsi_hdr_t), 2032 ISCSI_DEFAULT_MAX_RECV_SEG_LEN); 2033 /* copy a chunk of text into the pdu */ 2034 lsm->icl_login_resp_buf = idm_pdu_init_text_data( 2035 login_resp, lsm->icl_login_resp_itb, 2036 ISCSI_DEFAULT_MAX_RECV_SEG_LEN, 2037 lsm->icl_login_resp_buf, &text_transit); 2038 if (text_transit) { 2039 /* text buf has been consumed */ 2040 idm_itextbuf_free(lsm->icl_login_resp_itb); 2041 lsm->icl_login_resp_itb = NULL; 2042 lsm->icl_login_resp_buf = NULL; 2043 } 2044 } else { 2045 /* allocate a pdu for just a header */ 2046 login_resp = idm_pdu_alloc(sizeof (iscsi_hdr_t), 0); 2047 } 2048 /* finish initializing the pdu */ 2049 idm_pdu_init(login_resp, 2050 ict->ict_ic, ict, login_resp_complete_cb); 2051 login_resp->isp_flags |= IDM_PDU_LOGIN_TX; 2052 2053 /* 2054 * Use the BHS header values from the response template 2055 */ 2056 bcopy(lsm->icl_login_resp_tmpl, 2057 login_resp->isp_hdr, sizeof (iscsi_login_rsp_hdr_t)); 2058 2059 lh = (iscsi_login_rsp_hdr_t *)login_resp->isp_hdr; 2060 2061 /* Set error class/detail */ 2062 lh->status_class = lsm->icl_login_resp_err_class; 2063 lh->status_detail = lsm->icl_login_resp_err_detail; 2064 /* Set CSG, NSG and Transit */ 2065 lh->flags = 0; 2066 lh->flags |= lsm->icl_login_csg << 2; 2067 2068 2069 if (lh->status_class == ISCSI_STATUS_CLASS_SUCCESS) { 2070 if (lsm->icl_login_transit && 2071 lsm->icl_auth_pass != 0) { 2072 transit = 1; 2073 } else { 2074 transit = 0; 2075 } 2076 /* 2077 * inititalize the text data 2078 */ 2079 if (transit == 1 && text_transit == 1) { 2080 lh->flags |= lsm->icl_login_nsg; 2081 lsm->icl_login_csg = lsm->icl_login_nsg; 2082 lh->flags |= ISCSI_FLAG_LOGIN_TRANSIT; 2083 } else { 2084 lh->flags &= ~ISCSI_FLAG_LOGIN_TRANSIT; 2085 } 2086 2087 /* If we are transitioning to FFP then set TSIH */ 2088 if (transit && (lh->flags & ISCSI_FLAG_LOGIN_TRANSIT) && 2089 lsm->icl_login_csg == ISCSI_FULL_FEATURE_PHASE) { 2090 lh->tsid = htons(ict->ict_sess->ist_tsih); 2091 } 2092 } else { 2093 login_resp->isp_data = 0; 2094 login_resp->isp_datalen = 0; 2095 } 2096 return (login_resp); 2097 } 2098 2099 static kv_status_t 2100 iscsit_handle_key(iscsit_conn_t *ict, nvpair_t *nvp, char *nvp_name) 2101 { 2102 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 2103 kv_status_t kvrc; 2104 const idm_kv_xlate_t *ikvx; 2105 2106 ikvx = idm_lookup_kv_xlate(nvp_name, strlen(nvp_name)); 2107 if (ikvx->ik_key_id == KI_MAX_KEY) { 2108 /* 2109 * Any key not understood by the acceptor may be igonred 2110 * by the acceptor without affecting the basic function. 2111 * However, the answer for a key not understood MUST be 2112 * key=NotUnderstood. 2113 */ 2114 kvrc = iscsit_reply_string(ict, nvp_name, 2115 ISCSI_TEXT_NOTUNDERSTOOD); 2116 } else { 2117 kvrc = iscsit_handle_common_key(ict, nvp, ikvx); 2118 if (kvrc == KV_UNHANDLED) { 2119 switch (lsm->icl_login_csg) { 2120 case ISCSI_SECURITY_NEGOTIATION_STAGE: 2121 kvrc = iscsit_handle_security_key( 2122 ict, nvp, ikvx); 2123 break; 2124 case ISCSI_OP_PARMS_NEGOTIATION_STAGE: 2125 kvrc = iscsit_handle_operational_key( 2126 ict, nvp, ikvx); 2127 break; 2128 case ISCSI_FULL_FEATURE_PHASE: 2129 default: 2130 /* What are we doing here? */ 2131 ASSERT(0); 2132 kvrc = KV_UNHANDLED; 2133 } 2134 } 2135 } 2136 2137 return (kvrc); 2138 } 2139 2140 static kv_status_t 2141 iscsit_handle_common_key(iscsit_conn_t *ict, nvpair_t *nvp, 2142 const idm_kv_xlate_t *ikvx) 2143 { 2144 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 2145 kv_status_t kvrc; 2146 char *string_val; 2147 int nvrc; 2148 2149 switch (ikvx->ik_key_id) { 2150 case KI_INITIATOR_NAME: 2151 case KI_INITIATOR_ALIAS: 2152 nvrc = nvlist_add_nvpair(lsm->icl_negotiated_values, nvp); 2153 kvrc = idm_nvstat_to_kvstat(nvrc); 2154 break; 2155 case KI_TARGET_NAME: 2156 /* We'll validate the target during login_sm_session_bind() */ 2157 nvrc = nvpair_value_string(nvp, &string_val); 2158 ASSERT(nvrc == 0); /* We built this nvlist */ 2159 2160 nvrc = nvlist_add_nvpair(lsm->icl_negotiated_values, nvp); 2161 kvrc = idm_nvstat_to_kvstat(nvrc); 2162 break; 2163 case KI_TARGET_ALIAS: 2164 case KI_TARGET_ADDRESS: 2165 case KI_TARGET_PORTAL_GROUP_TAG: 2166 kvrc = KV_TARGET_ONLY; /* Only the target can declare this */ 2167 break; 2168 case KI_SESSION_TYPE: 2169 /* 2170 * If we don't receive this key on the initial login 2171 * we assume this is a normal session. 2172 */ 2173 nvrc = nvlist_add_nvpair(lsm->icl_negotiated_values, nvp); 2174 kvrc = idm_nvstat_to_kvstat(nvrc); 2175 nvrc = nvpair_value_string(nvp, &string_val); 2176 ASSERT(nvrc == 0); /* We built this nvlist */ 2177 ict->ict_op.op_discovery_session = 2178 strcmp(string_val, "Discovery") == 0 ? B_TRUE : B_FALSE; 2179 break; 2180 default: 2181 /* 2182 * This is not really an error but we should 2183 * leave this nvpair on the list since we 2184 * didn't do anything with it. Either 2185 * the security or operational phase 2186 * handling functions should process it. 2187 */ 2188 kvrc = KV_UNHANDLED; 2189 break; 2190 } 2191 2192 return (kvrc); 2193 } 2194 2195 static kv_status_t 2196 iscsit_handle_security_key(iscsit_conn_t *ict, nvpair_t *nvp, 2197 const idm_kv_xlate_t *ikvx) 2198 { 2199 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 2200 iscsit_auth_client_t *client = &lsm->icl_auth_client; 2201 iscsikey_id_t kv_id; 2202 kv_status_t kvrc; 2203 iscsit_auth_handler_t handler; 2204 2205 /* 2206 * After all of security keys are handled, this function will 2207 * be called again to verify current authentication status 2208 * and perform some actual authentication work. At this time, 2209 * the nvp and ikvx will be passed in as NULLs. 2210 */ 2211 if (ikvx != NULL) { 2212 kv_id = ikvx->ik_key_id; 2213 } else { 2214 kv_id = 0; 2215 } 2216 2217 handler = iscsit_auth_get_handler(client, kv_id); 2218 if (handler) { 2219 kvrc = handler(ict, nvp, ikvx); 2220 } else { 2221 kvrc = KV_UNHANDLED; /* invalid request */ 2222 } 2223 2224 return (kvrc); 2225 } 2226 2227 static kv_status_t 2228 iscsit_reply_security_key(iscsit_conn_t *ict) 2229 { 2230 return (iscsit_handle_security_key(ict, NULL, NULL)); 2231 } 2232 2233 static kv_status_t 2234 iscsit_handle_operational_key(iscsit_conn_t *ict, nvpair_t *nvp, 2235 const idm_kv_xlate_t *ikvx) 2236 { 2237 kv_status_t kvrc = KV_UNHANDLED; 2238 boolean_t bool_val; 2239 uint64_t num_val; 2240 int nvrc; 2241 2242 /* 2243 * Retrieve values. All value lookups are expected to succeed 2244 * since we build the nvlist while decoding the text buffer. This 2245 * step is intended to eliminate some duplication of code (for example 2246 * we only need to code the numerical value lookup once). We will 2247 * handle the values (if necessary) below. 2248 */ 2249 switch (ikvx->ik_key_id) { 2250 /* Lists */ 2251 case KI_HEADER_DIGEST: 2252 case KI_DATA_DIGEST: 2253 break; 2254 /* Booleans */ 2255 case KI_INITIAL_R2T: 2256 case KI_IMMEDIATE_DATA: 2257 case KI_DATA_PDU_IN_ORDER: 2258 case KI_DATA_SEQUENCE_IN_ORDER: 2259 case KI_IFMARKER: 2260 case KI_OFMARKER: 2261 nvrc = nvpair_value_boolean_value(nvp, &bool_val); 2262 ASSERT(nvrc == 0); /* We built this nvlist */ 2263 break; 2264 /* Numericals */ 2265 case KI_MAX_CONNECTIONS: 2266 case KI_MAX_RECV_DATA_SEGMENT_LENGTH: 2267 case KI_MAX_BURST_LENGTH: 2268 case KI_FIRST_BURST_LENGTH: 2269 case KI_DEFAULT_TIME_2_WAIT: 2270 case KI_DEFAULT_TIME_2_RETAIN: 2271 case KI_MAX_OUTSTANDING_R2T: 2272 case KI_ERROR_RECOVERY_LEVEL: 2273 nvrc = nvpair_value_uint64(nvp, &num_val); 2274 ASSERT(nvrc == 0); 2275 break; 2276 /* Ranges */ 2277 case KI_OFMARKERINT: 2278 case KI_IFMARKERINT: 2279 break; 2280 default: 2281 break; 2282 } 2283 2284 /* 2285 * Now handle the values according to the key name. Sometimes we 2286 * don't care what the value is -- in that case we just add the nvpair 2287 * to the negotiated values list. 2288 */ 2289 switch (ikvx->ik_key_id) { 2290 case KI_HEADER_DIGEST: 2291 kvrc = iscsit_handle_digest(ict, nvp, ikvx); 2292 break; 2293 case KI_DATA_DIGEST: 2294 kvrc = iscsit_handle_digest(ict, nvp, ikvx); 2295 break; 2296 case KI_INITIAL_R2T: 2297 /* We *require* INITIAL_R2T=yes */ 2298 kvrc = iscsit_handle_boolean(ict, nvp, bool_val, ikvx, 2299 B_TRUE); 2300 break; 2301 case KI_IMMEDIATE_DATA: 2302 kvrc = iscsit_handle_boolean(ict, nvp, bool_val, ikvx, 2303 bool_val); 2304 break; 2305 case KI_DATA_PDU_IN_ORDER: 2306 kvrc = iscsit_handle_boolean(ict, nvp, bool_val, ikvx, 2307 B_TRUE); 2308 break; 2309 case KI_DATA_SEQUENCE_IN_ORDER: 2310 /* We allow any value for DATA_SEQUENCE_IN_ORDER */ 2311 kvrc = iscsit_handle_boolean(ict, nvp, bool_val, ikvx, 2312 bool_val); 2313 break; 2314 case KI_OFMARKER: 2315 case KI_IFMARKER: 2316 /* We don't support markers */ 2317 kvrc = iscsit_handle_boolean(ict, nvp, bool_val, ikvx, 2318 B_FALSE); 2319 break; 2320 case KI_MAX_CONNECTIONS: 2321 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx, 2322 ISCSI_MIN_CONNECTIONS, 2323 ISCSI_MAX_CONNECTIONS, 2324 ISCSIT_MAX_CONNECTIONS); 2325 break; 2326 /* this is a declartive param */ 2327 case KI_MAX_RECV_DATA_SEGMENT_LENGTH: 2328 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx, 2329 ISCSI_MIN_RECV_DATA_SEGMENT_LENGTH, 2330 ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH, 2331 ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH); 2332 break; 2333 case KI_MAX_BURST_LENGTH: 2334 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx, 2335 ISCSI_MIN_MAX_BURST_LENGTH, 2336 ISCSI_MAX_BURST_LENGTH, 2337 ISCSIT_MAX_BURST_LENGTH); 2338 break; 2339 case KI_FIRST_BURST_LENGTH: 2340 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx, 2341 ISCSI_MIN_FIRST_BURST_LENGTH, 2342 ISCSI_MAX_FIRST_BURST_LENGTH, 2343 ISCSIT_MAX_FIRST_BURST_LENGTH); 2344 break; 2345 case KI_DEFAULT_TIME_2_WAIT: 2346 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx, 2347 ISCSI_MIN_TIME2WAIT, 2348 ISCSI_MAX_TIME2WAIT, 2349 ISCSIT_MAX_TIME2WAIT); 2350 break; 2351 case KI_DEFAULT_TIME_2_RETAIN: 2352 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx, 2353 ISCSI_MIN_TIME2RETAIN, 2354 ISCSI_MAX_TIME2RETAIN, 2355 ISCSIT_MAX_TIME2RETAIN); 2356 break; 2357 case KI_MAX_OUTSTANDING_R2T: 2358 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx, 2359 ISCSI_MIN_MAX_OUTSTANDING_R2T, 2360 ISCSI_MAX_OUTSTANDING_R2T, 2361 ISCSIT_MAX_OUTSTANDING_R2T); 2362 break; 2363 case KI_ERROR_RECOVERY_LEVEL: 2364 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx, 2365 ISCSI_MIN_ERROR_RECOVERY_LEVEL, 2366 ISCSI_MAX_ERROR_RECOVERY_LEVEL, 2367 ISCSIT_MAX_ERROR_RECOVERY_LEVEL); 2368 break; 2369 case KI_OFMARKERINT: 2370 case KI_IFMARKERINT: 2371 kvrc = iscsit_reply_string(ict, ikvx->ik_key_name, 2372 ISCSI_TEXT_IRRELEVANT); 2373 break; 2374 default: 2375 kvrc = KV_UNHANDLED; /* invalid request */ 2376 break; 2377 } 2378 2379 return (kvrc); 2380 } 2381 2382 static kv_status_t 2383 iscsit_reply_numerical(iscsit_conn_t *ict, 2384 const char *nvp_name, const uint64_t value) 2385 { 2386 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 2387 kv_status_t kvrc; 2388 int nvrc; 2389 2390 nvrc = nvlist_add_uint64(lsm->icl_response_nvlist, 2391 nvp_name, value); 2392 kvrc = idm_nvstat_to_kvstat(nvrc); 2393 2394 return (kvrc); 2395 } 2396 2397 static kv_status_t 2398 iscsit_reply_string(iscsit_conn_t *ict, 2399 const char *nvp_name, const char *text) 2400 { 2401 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 2402 kv_status_t kvrc; 2403 int nvrc; 2404 2405 nvrc = nvlist_add_string(lsm->icl_response_nvlist, 2406 nvp_name, text); 2407 kvrc = idm_nvstat_to_kvstat(nvrc); 2408 2409 return (kvrc); 2410 } 2411 2412 static kv_status_t 2413 iscsit_handle_digest(iscsit_conn_t *ict, nvpair_t *choices, 2414 const idm_kv_xlate_t *ikvx) 2415 { 2416 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 2417 kv_status_t kvrc = KV_VALUE_ERROR; 2418 int nvrc; 2419 nvpair_t *digest_choice; 2420 char *digest_choice_string; 2421 2422 /* 2423 * Need to add persistent config here if we want users to allow 2424 * disabling of digests on the target side. You could argue that 2425 * this makes things too complicated... just let the initiator state 2426 * what it wants and we'll take it. For now that's exactly what 2427 * we'll do. 2428 * 2429 * Basic digest negotiation happens here at iSCSI level. IDM 2430 * can override this during negotiate_key_values phase to 2431 * decline to set up any digest processing. 2432 */ 2433 digest_choice = idm_get_next_listvalue(choices, NULL); 2434 2435 /* 2436 * Loop through all choices. As soon as we find a choice 2437 * that we support add the value to our negotiated values list 2438 * and respond with that value in the login response. 2439 */ 2440 while (digest_choice != NULL) { 2441 nvrc = nvpair_value_string(digest_choice, 2442 &digest_choice_string); 2443 ASSERT(nvrc == 0); 2444 2445 if ((strcasecmp(digest_choice_string, "crc32c") == 0) || 2446 (strcasecmp(digest_choice_string, "none") == 0)) { 2447 /* Add to negotiated values list */ 2448 nvrc = nvlist_add_string(lsm->icl_negotiated_values, 2449 ikvx->ik_key_name, digest_choice_string); 2450 kvrc = idm_nvstat_to_kvstat(nvrc); 2451 if (nvrc == 0) { 2452 /* Add to login response list */ 2453 nvrc = nvlist_add_string( 2454 lsm->icl_response_nvlist, 2455 ikvx->ik_key_name, digest_choice_string); 2456 kvrc = idm_nvstat_to_kvstat(nvrc); 2457 } 2458 break; 2459 } 2460 digest_choice = idm_get_next_listvalue(choices, 2461 digest_choice); 2462 } 2463 2464 if (digest_choice == NULL) 2465 kvrc = KV_VALUE_ERROR; 2466 2467 return (kvrc); 2468 } 2469 2470 static kv_status_t 2471 iscsit_handle_boolean(iscsit_conn_t *ict, nvpair_t *nvp, boolean_t value, 2472 const idm_kv_xlate_t *ikvx, boolean_t iscsit_value) 2473 { 2474 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 2475 kv_status_t kvrc; 2476 int nvrc; 2477 2478 if (ikvx->ik_declarative) { 2479 nvrc = nvlist_add_nvpair(lsm->icl_negotiated_values, nvp); 2480 } else { 2481 if (value != iscsit_value) { 2482 /* Respond back to initiator with our value */ 2483 value = iscsit_value; 2484 nvrc = nvlist_add_boolean_value( 2485 lsm->icl_negotiated_values, 2486 ikvx->ik_key_name, value); 2487 lsm->icl_login_transit = B_FALSE; 2488 } else { 2489 /* Add this to our negotiated values */ 2490 nvrc = nvlist_add_nvpair(lsm->icl_negotiated_values, 2491 nvp); 2492 } 2493 2494 /* Response of Simple-value Negotiation */ 2495 if (nvrc == 0) { 2496 nvrc = nvlist_add_boolean_value( 2497 lsm->icl_response_nvlist, ikvx->ik_key_name, value); 2498 } 2499 } 2500 2501 kvrc = idm_nvstat_to_kvstat(nvrc); 2502 2503 return (kvrc); 2504 } 2505 2506 static kv_status_t 2507 iscsit_handle_numerical(iscsit_conn_t *ict, nvpair_t *nvp, uint64_t value, 2508 const idm_kv_xlate_t *ikvx, 2509 uint64_t iscsi_min_value, uint64_t iscsi_max_value, 2510 uint64_t iscsit_max_value) 2511 { 2512 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 2513 kv_status_t kvrc; 2514 int nvrc; 2515 2516 /* Validate against standard */ 2517 if ((value < iscsi_min_value) || (value > iscsi_max_value)) { 2518 kvrc = KV_VALUE_ERROR; 2519 } else if (ikvx->ik_declarative) { 2520 nvrc = nvlist_add_nvpair(lsm->icl_negotiated_values, nvp); 2521 kvrc = idm_nvstat_to_kvstat(nvrc); 2522 } else { 2523 if (value > iscsit_max_value) { 2524 /* Respond back to initiator with our value */ 2525 value = iscsit_max_value; 2526 nvrc = nvlist_add_uint64(lsm->icl_negotiated_values, 2527 ikvx->ik_key_name, value); 2528 lsm->icl_login_transit = B_FALSE; 2529 } else { 2530 /* Add this to our negotiated values */ 2531 nvrc = nvlist_add_nvpair(lsm->icl_negotiated_values, 2532 nvp); 2533 } 2534 2535 /* Response of Simple-value Negotiation */ 2536 if (nvrc == 0) { 2537 nvrc = nvlist_add_uint64(lsm->icl_response_nvlist, 2538 ikvx->ik_key_name, value); 2539 } 2540 kvrc = idm_nvstat_to_kvstat(nvrc); 2541 } 2542 2543 return (kvrc); 2544 } 2545 2546 2547 static void 2548 iscsit_process_negotiated_values(iscsit_conn_t *ict) 2549 { 2550 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 2551 char *string_val; 2552 boolean_t boolean_val; 2553 uint64_t uint64_val; 2554 int nvrc; 2555 2556 /* Let the IDM level activate its parameters first */ 2557 idm_notice_key_values(ict->ict_ic, lsm->icl_negotiated_values); 2558 2559 /* 2560 * Initiator alias and target alias 2561 */ 2562 if ((nvrc = nvlist_lookup_string(lsm->icl_negotiated_values, 2563 "InitiatorAlias", &string_val)) != ENOENT) { 2564 ASSERT(nvrc == 0); 2565 ict->ict_sess->ist_initiator_alias = 2566 kmem_alloc(strlen(string_val) + 1, KM_SLEEP); 2567 (void) strcpy(ict->ict_sess->ist_initiator_alias, string_val); 2568 } 2569 2570 if ((nvrc = nvlist_lookup_string(lsm->icl_negotiated_values, 2571 "TargetAlias", &string_val)) != ENOENT) { 2572 ASSERT(nvrc == 0); 2573 ict->ict_sess->ist_target_alias = 2574 kmem_alloc(strlen(string_val) + 1, KM_SLEEP); 2575 (void) strcpy(ict->ict_sess->ist_target_alias, string_val); 2576 } 2577 2578 /* 2579 * Operational parameters. We process SessionType when it is 2580 * initially received since it is required on the initial login. 2581 */ 2582 if ((nvrc = nvlist_lookup_boolean_value(lsm->icl_negotiated_values, 2583 "InitialR2T", &boolean_val)) != ENOENT) { 2584 ASSERT(nvrc == 0); 2585 ict->ict_op.op_initial_r2t = boolean_val; 2586 } 2587 2588 if ((nvrc = nvlist_lookup_boolean_value(lsm->icl_negotiated_values, 2589 "ImmediateData", &boolean_val)) != ENOENT) { 2590 ASSERT(nvrc == 0); 2591 ict->ict_op.op_immed_data = boolean_val; 2592 } 2593 2594 if ((nvrc = nvlist_lookup_boolean_value(lsm->icl_negotiated_values, 2595 "DataPDUInOrder", &boolean_val)) != ENOENT) { 2596 ASSERT(nvrc == 0); 2597 ict->ict_op.op_data_pdu_in_order = boolean_val; 2598 } 2599 2600 if ((nvrc = nvlist_lookup_boolean_value(lsm->icl_negotiated_values, 2601 "DataSequenceInOrder", &boolean_val)) != ENOENT) { 2602 ASSERT(nvrc == 0); 2603 ict->ict_op.op_data_sequence_in_order = boolean_val; 2604 } 2605 2606 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values, 2607 "MaxConnections", &uint64_val)) != ENOENT) { 2608 ASSERT(nvrc == 0); 2609 ict->ict_op.op_max_connections = uint64_val; 2610 } 2611 2612 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values, 2613 "MaxRecvDataSegmentLength", &uint64_val)) != ENOENT) { 2614 ASSERT(nvrc == 0); 2615 ict->ict_op.op_max_recv_data_segment_length = uint64_val; 2616 } 2617 2618 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values, 2619 "MaxBurstLength", &uint64_val)) != ENOENT) { 2620 ASSERT(nvrc == 0); 2621 ict->ict_op.op_max_burst_length = uint64_val; 2622 } 2623 2624 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values, 2625 "FirstBurstLength", &uint64_val)) != ENOENT) { 2626 ASSERT(nvrc == 0); 2627 ict->ict_op.op_first_burst_length = uint64_val; 2628 } 2629 2630 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values, 2631 "DefaultTime2Wait", &uint64_val)) != ENOENT) { 2632 ASSERT(nvrc == 0); 2633 ict->ict_op.op_default_time_2_wait = uint64_val; 2634 } 2635 2636 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values, 2637 "DefaultTime2Retain", &uint64_val)) != ENOENT) { 2638 ASSERT(nvrc == 0); 2639 ict->ict_op.op_default_time_2_retain = uint64_val; 2640 } 2641 2642 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values, 2643 "MaxOutstandingR2T", &uint64_val)) != ENOENT) { 2644 ASSERT(nvrc == 0); 2645 ict->ict_op.op_max_outstanding_r2t = uint64_val; 2646 } 2647 2648 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values, 2649 "ErrorRecoveryLevel", &uint64_val)) != ENOENT) { 2650 ASSERT(nvrc == 0); 2651 ict->ict_op.op_error_recovery_level = uint64_val; 2652 } 2653 } 2654 2655 static idm_status_t 2656 iscsit_add_declarative_keys(iscsit_conn_t *ict) 2657 { 2658 nvlist_t *cfg_nv = NULL; 2659 kv_status_t kvrc; 2660 int nvrc; 2661 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 2662 uint8_t error_class; 2663 uint8_t error_detail; 2664 idm_status_t idm_status; 2665 2666 if ((nvrc = nvlist_alloc(&cfg_nv, NV_UNIQUE_NAME, KM_NOSLEEP)) != 0) { 2667 kvrc = idm_nvstat_to_kvstat(nvrc); 2668 goto alloc_fail; 2669 } 2670 if ((nvrc = nvlist_add_uint64(cfg_nv, "MaxRecvDataSegmentLength", 2671 max_dataseglen_target)) != 0) { 2672 kvrc = idm_nvstat_to_kvstat(nvrc); 2673 goto done; 2674 } 2675 2676 kvrc = idm_declare_key_values(ict->ict_ic, cfg_nv, 2677 lsm->icl_response_nvlist); 2678 done: 2679 nvlist_free(cfg_nv); 2680 alloc_fail: 2681 idm_kvstat_to_error(kvrc, &error_class, &error_detail); 2682 if (error_class == ISCSI_STATUS_CLASS_SUCCESS) { 2683 idm_status = IDM_STATUS_SUCCESS; 2684 } else { 2685 SET_LOGIN_ERROR(ict, error_class, error_detail); 2686 idm_status = IDM_STATUS_FAIL; 2687 } 2688 return (idm_status); 2689 } 2690