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