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