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