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