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. 910 */ 911 lh_resp->expcmdsn = htonl(ict->ict_login_sm.icl_cmdsn + 1); 912 lh_resp->maxcmdsn = htonl(ict->ict_login_sm.icl_cmdsn + 2); 913 914 idm_pdu_tx(ict->ict_login_sm.icl_login_resp); 915 } 916 917 } 918 919 static void 920 login_sm_process_request(iscsit_conn_t *ict) 921 { 922 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 923 uint8_t error_class = 0; 924 uint8_t error_detail = 0; 925 926 /* 927 * First walk all the PDU's that make up this login request 928 * and compile all the iSCSI key-value pairs into nvlist format. 929 */ 930 931 ASSERT(lsm->icl_request_nvlist == NULL); 932 /* create an nvlist for request key/value pairs */ 933 if (idm_pdu_list_to_nvlist(&lsm->icl_pdu_list, 934 &lsm->icl_request_nvlist, &error_detail) != IDM_STATUS_SUCCESS) { 935 error_class = ISCSI_STATUS_CLASS_TARGET_ERR; 936 SET_LOGIN_ERROR(ict, error_class, error_detail); 937 goto request_fail; 938 } 939 940 /* Allocate a new nvlist for response key/value pairs */ 941 ASSERT(lsm->icl_response_nvlist == NULL); 942 if (nvlist_alloc(&lsm->icl_response_nvlist, NV_UNIQUE_NAME, 943 KM_NOSLEEP) != 0) { 944 error_class = ISCSI_STATUS_CLASS_TARGET_ERR; 945 error_detail = ISCSI_LOGIN_STATUS_NO_RESOURCES; 946 SET_LOGIN_ERROR(ict, error_class, error_detail); 947 goto request_fail; 948 } 949 950 /* 951 * This would be a very good time to make sure we have 952 * negotiated the required values for the login phase. For 953 * example we definitely should have defined InitiatorName, 954 * and Target name regardless of our current login phase. 955 */ 956 if (!ict->ict_op.op_initial_params_set) { 957 if (login_sm_validate_initial_parameters(ict) != 958 IDM_STATUS_SUCCESS) { 959 goto request_fail; 960 } 961 962 /* 963 * Now setup our session association. This includes 964 * create a new session or looking up an existing session, 965 * and if this is not a discovery session then we will 966 * also register this session with STMF. 967 */ 968 if (login_sm_session_bind(ict) != IDM_STATUS_SUCCESS) { 969 goto request_fail; 970 } 971 972 if (login_sm_set_auth(ict) != IDM_STATUS_SUCCESS) { 973 goto request_fail; 974 } 975 976 /* 977 * Prepend TargetAlias and PortalGroupTag 978 */ 979 if (ict->ict_op.op_discovery_session == B_FALSE) { 980 if ((lsm->icl_auth.ca_tgt_alias[0]) != '\0') { 981 (void) iscsit_reply_string(ict, 982 "TargetAlias", 983 &lsm->icl_auth.ca_tgt_alias[0]); 984 } 985 (void) iscsit_reply_numerical(ict, 986 "TargetPortalGroupTag", 987 (uint64_t)lsm->icl_tpgt_tag); 988 } 989 990 ict->ict_op.op_initial_params_set = B_TRUE; 991 } 992 993 if (login_sm_process_nvlist(ict) != IDM_STATUS_SUCCESS) { 994 goto request_fail; 995 } 996 997 if (login_sm_check_security(ict) != IDM_STATUS_SUCCESS) { 998 goto request_fail; 999 } 1000 1001 request_fail: 1002 login_sm_build_login_response(ict); 1003 iscsit_login_sm_event(ict, ILE_LOGIN_RESP_READY, NULL); 1004 1005 /* clean up request_nvlist and response_nvlist */ 1006 if (lsm->icl_request_nvlist != NULL) { 1007 nvlist_free(lsm->icl_request_nvlist); 1008 lsm->icl_request_nvlist = NULL; 1009 } 1010 if (lsm->icl_response_nvlist != NULL) { 1011 nvlist_free(lsm->icl_response_nvlist); 1012 lsm->icl_response_nvlist = NULL; 1013 } 1014 } 1015 1016 1017 static void 1018 login_sm_ffp_actions(iscsit_conn_t *ict) 1019 { 1020 iscsit_process_negotiated_values(ict); 1021 } 1022 1023 static idm_status_t 1024 login_sm_validate_initial_parameters(iscsit_conn_t *ict) 1025 { 1026 int nvrc; 1027 char *string_val; 1028 uint8_t error_class = ISCSI_STATUS_CLASS_INITIATOR_ERR; 1029 uint8_t error_detail = ISCSI_LOGIN_STATUS_MISSING_FIELDS; 1030 idm_status_t status = IDM_STATUS_FAIL; 1031 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 1032 1033 /* 1034 * Make sure we received the required information from the initial 1035 * login. Add these declaratives to the negotiated list and 1036 * remove them from the request list as we go. If anything fails, 1037 * the caller will clean-up the nvlists. 1038 */ 1039 1040 /* 1041 * Initiator name 1042 */ 1043 if ((nvrc = nvlist_lookup_string(lsm->icl_request_nvlist, 1044 "InitiatorName", &string_val)) != 0) { 1045 goto initial_params_done; 1046 } 1047 if ((nvrc = nvlist_add_string(lsm->icl_negotiated_values, 1048 "InitiatorName", string_val)) != 0) { 1049 goto initial_params_done; 1050 } 1051 if ((nvrc = nvlist_lookup_string(lsm->icl_negotiated_values, 1052 "InitiatorName", &string_val)) != 0) { 1053 goto initial_params_done; 1054 } 1055 lsm->icl_initiator_name = string_val; 1056 if ((nvrc = nvlist_remove(lsm->icl_request_nvlist, 1057 "InitiatorName", DATA_TYPE_STRING)) != 0) { 1058 goto initial_params_done; 1059 } 1060 1061 /* 1062 * Session type 1063 */ 1064 ict->ict_op.op_discovery_session = B_FALSE; 1065 nvrc = nvlist_lookup_string(lsm->icl_request_nvlist, 1066 "SessionType", &string_val); 1067 if (nvrc != ENOENT && nvrc != 0) { 1068 goto initial_params_done; 1069 } 1070 if (nvrc == 0) { 1071 if (strcmp(string_val, "Discovery") == 0) { 1072 ict->ict_op.op_discovery_session = B_TRUE; 1073 } else if (strcmp(string_val, "Normal") != 0) { 1074 goto initial_params_done; 1075 } 1076 if ((nvrc = nvlist_add_string(lsm->icl_negotiated_values, 1077 "SessionType", string_val)) != 0) { 1078 goto initial_params_done; 1079 } 1080 if ((nvrc = nvlist_remove(lsm->icl_request_nvlist, 1081 "SessionType", DATA_TYPE_STRING)) != 0) { 1082 goto initial_params_done; 1083 } 1084 } 1085 1086 /* 1087 * Must have either TargetName or SessionType==Discovery 1088 */ 1089 lsm->icl_target_name = NULL; 1090 nvrc = nvlist_lookup_string(lsm->icl_request_nvlist, 1091 "TargetName", &string_val); 1092 if (nvrc != ENOENT && nvrc != 0) { 1093 goto initial_params_done; 1094 } 1095 if (nvrc == 0) { 1096 if ((nvrc = nvlist_add_string(lsm->icl_negotiated_values, 1097 "TargetName", string_val)) != 0) { 1098 goto initial_params_done; 1099 } 1100 if ((nvrc = nvlist_lookup_string(lsm->icl_negotiated_values, 1101 "TargetName", &string_val)) != 0) { 1102 goto initial_params_done; 1103 } 1104 lsm->icl_target_name = string_val; 1105 if ((nvrc = nvlist_remove(lsm->icl_request_nvlist, 1106 "TargetName", DATA_TYPE_STRING)) != 0) { 1107 goto initial_params_done; 1108 } 1109 } else if (ict->ict_op.op_discovery_session == B_FALSE) { 1110 /* 1111 * Missing target name 1112 */ 1113 goto initial_params_done; 1114 } 1115 1116 IDM_SM_LOG(CE_NOTE, "conn %p: initiator=%s", (void *)ict->ict_ic, 1117 (lsm->icl_initiator_name == NULL) ? "N/A" : 1118 lsm->icl_initiator_name); 1119 IDM_SM_LOG(CE_NOTE, "conn %p: target=%s", (void *)ict->ict_ic, 1120 (lsm->icl_target_name == NULL) ? "N/A" : 1121 lsm->icl_target_name); 1122 IDM_SM_LOG(CE_NOTE, "conn %p: sessiontype=%s", (void *)ict->ict_ic, 1123 ict->ict_op.op_discovery_session ? "Discovery" : "Normal"); 1124 1125 /* Sucess */ 1126 status = IDM_STATUS_SUCCESS; 1127 error_class = ISCSI_STATUS_CLASS_SUCCESS; 1128 error_detail = ISCSI_LOGIN_STATUS_ACCEPT; 1129 1130 initial_params_done: 1131 SET_LOGIN_ERROR(ict, error_class, error_detail); 1132 return (status); 1133 } 1134 1135 1136 /* 1137 * login_sm_session_bind 1138 * 1139 * This function looks at the data from the initial login request 1140 * of a new connection and either looks up and existing session, 1141 * creates a new session, or returns an error. RFC3720 section 5.3.1 1142 * defines these rules: 1143 * 1144 * +------------------------------------------------------------------+ 1145 * |ISID | TSIH | CID | Target action | 1146 * +------------------------------------------------------------------+ 1147 * |new | non-zero | any | fail the login | 1148 * | | | | ("session does not exist") | 1149 * +------------------------------------------------------------------+ 1150 * |new | zero | any | instantiate a new session | 1151 * +------------------------------------------------------------------+ 1152 * |existing | zero | any | do session reinstatement | 1153 * | | | | (see section 5.3.5) | 1154 * +------------------------------------------------------------------+ 1155 * |existing | non-zero | new | add a new connection to | 1156 * | | existing | | the session | 1157 * +------------------------------------------------------------------+ 1158 * |existing | non-zero |existing| do connection reinstatement| 1159 * | | existing | | (see section 5.3.4) | 1160 * +------------------------------------------------------------------+ 1161 * |existing | non-zero | any | fail the login | 1162 * | | new | | ("session does not exist") | 1163 * +------------------------------------------------------------------+ 1164 * 1165 */ 1166 1167 /* 1168 * Map an <ipv6,port> address to an <ipv4,port> address if possible. 1169 * Returns: 1170 * 1 - success 1171 * 0 - address not mapable 1172 */ 1173 1174 static int 1175 iscsit_is_v4_mapped(struct sockaddr_storage *sa, struct sockaddr_storage *v4sa) 1176 { 1177 struct sockaddr_in *sin; 1178 struct in_addr *in; 1179 struct sockaddr_in6 *sin6; 1180 struct in6_addr *in6; 1181 int ret = 0; 1182 1183 sin6 = (struct sockaddr_in6 *)sa; 1184 in6 = &sin6->sin6_addr; 1185 if ((sa->ss_family == AF_INET6) && 1186 (IN6_IS_ADDR_V4MAPPED(in6) || IN6_IS_ADDR_V4COMPAT(in6))) { 1187 sin = (struct sockaddr_in *)v4sa; 1188 in = &sin->sin_addr; 1189 v4sa->ss_family = AF_INET; 1190 sin->sin_port = sin6->sin6_port; 1191 IN6_V4MAPPED_TO_INADDR(in6, in); 1192 ret = 1; 1193 } 1194 return (ret); 1195 } 1196 1197 static idm_status_t 1198 login_sm_session_bind(iscsit_conn_t *ict) 1199 { 1200 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 1201 iscsit_tgt_t *tgt = NULL; 1202 iscsit_tpgt_t *tpgt = NULL; 1203 iscsit_portal_t *portal = NULL; 1204 iscsit_sess_t *existing_sess = NULL; 1205 iscsit_sess_t *new_sess = NULL; 1206 iscsit_conn_t *existing_ict = NULL; 1207 uint8_t error_class; 1208 uint8_t error_detail; 1209 1210 /* 1211 * Look up target and then check if there are sessions or connections 1212 * that match this request (see below). Any holds taken on objects 1213 * must be released at the end of the function (let's keep things 1214 * simple). 1215 * 1216 * If target name is set then we should have a corresponding target 1217 * context configured. 1218 */ 1219 if (lsm->icl_target_name != NULL) { 1220 /* 1221 * iscsit_tgt_lookup implicitly takes a ref on the target 1222 */ 1223 ISCSIT_GLOBAL_LOCK(RW_READER); 1224 tgt = iscsit_tgt_lookup_locked(lsm->icl_target_name); 1225 if (tgt == NULL) { 1226 ISCSIT_GLOBAL_UNLOCK(); 1227 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_INITIATOR_ERR, 1228 ISCSI_LOGIN_STATUS_TGT_NOT_FOUND); 1229 goto session_bind_error; 1230 } else { 1231 mutex_enter(&tgt->target_mutex); 1232 tpgt = avl_first(&tgt->target_tpgt_list); 1233 1234 if (IS_DEFAULT_TPGT(tpgt)) { 1235 lsm->icl_tpgt_tag = ISCSIT_DEFAULT_TPGT; 1236 } else { 1237 /* 1238 * Find the portal group tag for the 1239 * login response. 1240 */ 1241 struct sockaddr_storage v4sa, *sa; 1242 1243 sa = &ict->ict_ic->ic_laddr; 1244 portal = iscsit_tgt_lookup_portal(tgt, 1245 sa, &tpgt); 1246 if (portal == NULL && 1247 iscsit_is_v4_mapped(sa, &v4sa)) { 1248 /* 1249 * Try again if the local address 1250 * was v6 mappable to v4. 1251 */ 1252 portal = iscsit_tgt_lookup_portal(tgt, 1253 &v4sa, &tpgt); 1254 1255 } 1256 if (portal == NULL) { 1257 /* 1258 * Initiator came in on wrong address 1259 */ 1260 SET_LOGIN_ERROR(ict, 1261 ISCSI_STATUS_CLASS_INITIATOR_ERR, 1262 ISCSI_LOGIN_STATUS_TGT_NOT_FOUND); 1263 mutex_exit(&tgt->target_mutex); 1264 ISCSIT_GLOBAL_UNLOCK(); 1265 goto session_bind_error; 1266 } 1267 1268 /* 1269 * Need to release holds on the portal and 1270 * tpgt after processing is complete. 1271 */ 1272 lsm->icl_tpgt_tag = tpgt->tpgt_tag; 1273 iscsit_portal_rele(portal); 1274 iscsit_tpgt_rele(tpgt); 1275 } 1276 1277 if ((tgt->target_state != TS_STMF_ONLINE) || 1278 ((iscsit_global.global_svc_state != ISE_ENABLED) && 1279 ((iscsit_global.global_svc_state != ISE_BUSY)))) { 1280 SET_LOGIN_ERROR(ict, 1281 ISCSI_STATUS_CLASS_INITIATOR_ERR, 1282 ISCSI_LOGIN_STATUS_TGT_REMOVED); 1283 mutex_exit(&tgt->target_mutex); 1284 ISCSIT_GLOBAL_UNLOCK(); 1285 goto session_bind_error; 1286 } 1287 mutex_exit(&tgt->target_mutex); 1288 ISCSIT_GLOBAL_UNLOCK(); 1289 } 1290 } 1291 1292 ASSERT((tgt != NULL) || (ict->ict_op.op_discovery_session == B_TRUE)); 1293 1294 /* 1295 * Check if there is an existing session matching this ISID. If 1296 * tgt == NULL then we'll look for the session on the global list 1297 * of discovery session. If we find a session then the ISID 1298 * exists. 1299 */ 1300 existing_sess = iscsit_tgt_lookup_sess(tgt, lsm->icl_initiator_name, 1301 lsm->icl_isid, lsm->icl_tsih, lsm->icl_tpgt_tag); 1302 if (existing_sess != NULL) { 1303 existing_ict = iscsit_sess_lookup_conn(existing_sess, 1304 ict->ict_cid); 1305 } 1306 1307 /* 1308 * If this is a discovery session, make sure it has appropriate 1309 * parameters. 1310 */ 1311 if ((ict->ict_op.op_discovery_session == B_TRUE) && 1312 ((lsm->icl_tsih != ISCSI_UNSPEC_TSIH) || (existing_sess != NULL))) { 1313 /* XXX Do we need to check for existing ISID (sess != NULL)? */ 1314 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_INITIATOR_ERR, 1315 ISCSI_LOGIN_STATUS_INVALID_REQUEST); 1316 goto session_bind_error; 1317 } 1318 1319 /* 1320 * Check the two error conditions from the table. 1321 * 1322 * ISID=new, TSIH=non-zero 1323 */ 1324 if ((existing_sess == NULL) && (lsm->icl_tsih != ISCSI_UNSPEC_TSIH)) { 1325 /* fail the login */ 1326 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_INITIATOR_ERR, 1327 ISCSI_LOGIN_STATUS_NO_SESSION); 1328 goto session_bind_error; 1329 } 1330 1331 /* ISID=existing, TSIH=non-zero new */ 1332 if ((existing_sess != NULL) && (lsm->icl_tsih != 0) && 1333 (existing_sess->ist_tsih != lsm->icl_tsih)) { 1334 /* fail the login */ 1335 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_INITIATOR_ERR, 1336 ISCSI_LOGIN_STATUS_NO_SESSION); 1337 goto session_bind_error; 1338 } 1339 1340 /* 1341 * Handle the remaining table cases in order 1342 */ 1343 if (existing_sess == NULL) { 1344 /* Should have caught this above */ 1345 ASSERT(lsm->icl_tsih == ISCSI_UNSPEC_TSIH); 1346 /* 1347 * ISID=new, TSIH=zero --> instantiate a new session 1348 */ 1349 new_sess = iscsit_sess_create(tgt, ict, lsm->icl_cmdsn, 1350 lsm->icl_isid, lsm->icl_tpgt_tag, lsm->icl_initiator_name, 1351 lsm->icl_target_name, &error_class, &error_detail); 1352 ASSERT(new_sess != NULL); 1353 1354 /* Session create may have failed even if it returned a value */ 1355 if (error_class != ISCSI_STATUS_CLASS_SUCCESS) { 1356 SET_LOGIN_ERROR(ict, error_class, error_detail); 1357 goto session_bind_error; 1358 } 1359 1360 /* 1361 * If we don't already have an STMF session and this is not 1362 * a discovery session then we need to allocate and register 1363 * one. 1364 */ 1365 if (!ict->ict_op.op_discovery_session) { 1366 if (login_sm_session_register(ict) != 1367 IDM_STATUS_SUCCESS) { 1368 /* login_sm_session_register sets error codes */ 1369 goto session_bind_error; 1370 } 1371 } 1372 1373 } else { 1374 if (lsm->icl_tsih == ISCSI_UNSPEC_TSIH) { 1375 /* 1376 * ISID=existing, TSIH=zero --> Session reinstatement 1377 */ 1378 new_sess = iscsit_sess_reinstate(tgt, existing_sess, 1379 ict, &error_class, &error_detail); 1380 ASSERT(new_sess != NULL); 1381 1382 if (error_class != ISCSI_STATUS_CLASS_SUCCESS) { 1383 SET_LOGIN_ERROR(ict, error_class, error_detail); 1384 goto session_bind_error; 1385 } 1386 1387 /* 1388 * If we don't already have an STMF session and this is 1389 * not a discovery session then we need to allocate and 1390 * register one. 1391 */ 1392 if (!ict->ict_op.op_discovery_session) { 1393 if (login_sm_session_register(ict) != 1394 IDM_STATUS_SUCCESS) { 1395 /* 1396 * login_sm_session_register sets 1397 * error codes 1398 */ 1399 goto session_bind_error; 1400 } 1401 } 1402 } else { 1403 /* 1404 * The following code covers these two cases: 1405 * ISID=existing, TSIH=non-zero existing, CID=new 1406 * --> add new connection to MC/S session 1407 * ISID=existing, TSIH=non-zero existing, CID=existing 1408 * --> do connection reinstatement 1409 * 1410 * Session continuation uses this path as well 1411 */ 1412 cmn_err(CE_NOTE, "login_sm_session_bind: add new " 1413 "conn/sess continue"); 1414 if (existing_ict != NULL) { 1415 /* 1416 * ISID=existing, TSIH=non-zero existing, 1417 * CID=existing --> do connection reinstatement 1418 */ 1419 if (iscsit_conn_reinstate(existing_ict, ict) != 1420 IDM_STATUS_SUCCESS) { 1421 /* 1422 * Most likely this means the connection 1423 * the initiator is trying to reinstate 1424 * is not in an acceptable state. 1425 */ 1426 SET_LOGIN_ERROR(ict, 1427 ISCSI_STATUS_CLASS_INITIATOR_ERR, 1428 ISCSI_LOGIN_STATUS_INIT_ERR); 1429 goto session_bind_error; 1430 } 1431 } 1432 1433 iscsit_sess_sm_event(existing_sess, SE_CONN_IN_LOGIN, 1434 ict); 1435 } 1436 } 1437 1438 if (tgt != NULL) 1439 iscsit_tgt_rele(tgt); 1440 if (existing_sess != NULL) 1441 iscsit_sess_rele(existing_sess); 1442 if (existing_ict != NULL) 1443 iscsit_conn_rele(existing_ict); 1444 1445 return (IDM_STATUS_SUCCESS); 1446 1447 session_bind_error: 1448 if (tgt != NULL) 1449 iscsit_tgt_rele(tgt); 1450 if (existing_sess != NULL) 1451 iscsit_sess_rele(existing_sess); 1452 if (existing_ict != NULL) 1453 iscsit_conn_rele(existing_ict); 1454 1455 /* 1456 * If session bind fails we will fail the login but don't destroy 1457 * the session until later. 1458 */ 1459 return (IDM_STATUS_FAIL); 1460 } 1461 1462 1463 static idm_status_t 1464 login_sm_set_auth(iscsit_conn_t *ict) 1465 { 1466 idm_status_t idmrc = IDM_STATUS_SUCCESS; 1467 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 1468 iscsit_ini_t *ini; 1469 iscsit_tgt_t *tgt; 1470 char *auth = ""; 1471 char *radiusserver = ""; 1472 char *radiussecret = ""; 1473 char *chapuser = ""; 1474 char *chapsecret = ""; 1475 char *targetchapuser = ""; 1476 char *targetchapsecret = ""; 1477 char *targetalias = ""; 1478 int i; 1479 1480 ISCSIT_GLOBAL_LOCK(RW_READER); 1481 1482 /* 1483 * Set authentication method to none for discovery session. 1484 */ 1485 if (ict->ict_op.op_discovery_session == B_TRUE) { 1486 lsm->icl_auth.ca_method_valid_list[0] = AM_NONE; 1487 ISCSIT_GLOBAL_UNLOCK(); 1488 return (idmrc); 1489 } 1490 1491 /* 1492 * Get all the authentication parameters we need -- since we hold 1493 * the global config lock we guarantee that the parameters will 1494 * be consistent with each other. 1495 */ 1496 (void) nvlist_lookup_string(iscsit_global.global_props, 1497 PROP_AUTH, &auth); 1498 (void) nvlist_lookup_string(iscsit_global.global_props, 1499 PROP_RADIUS_SERVER, &radiusserver); 1500 (void) nvlist_lookup_string(iscsit_global.global_props, 1501 PROP_RADIUS_SECRET, &radiussecret); 1502 1503 ini = iscsit_ini_lookup_locked(lsm->icl_initiator_name); 1504 if (ini != NULL) { 1505 /* Get Initiator CHAP parameters */ 1506 (void) nvlist_lookup_string(ini->ini_props, PROP_CHAP_USER, 1507 &chapuser); 1508 (void) nvlist_lookup_string(ini->ini_props, PROP_CHAP_SECRET, 1509 &chapsecret); 1510 } 1511 1512 tgt = ict->ict_sess->ist_tgt; 1513 if (tgt != NULL) { 1514 /* See if we have a target-specific authentication setting */ 1515 (void) nvlist_lookup_string(tgt->target_props, PROP_AUTH, 1516 &auth); 1517 /* Get target CHAP parameters */ 1518 (void) nvlist_lookup_string(tgt->target_props, 1519 PROP_TARGET_CHAP_USER, &targetchapuser); 1520 (void) nvlist_lookup_string(tgt->target_props, 1521 PROP_TARGET_CHAP_SECRET, &targetchapsecret); 1522 /* Get alias */ 1523 (void) nvlist_lookup_string(tgt->target_props, 1524 PROP_ALIAS, &targetalias); 1525 } 1526 1527 /* Set authentication method */ 1528 i = 0; 1529 if (strcmp(auth, PA_AUTH_RADIUS) == 0) { 1530 /* CHAP authentication using RADIUS server */ 1531 lsm->icl_auth.ca_method_valid_list[i++] = AM_CHAP; 1532 lsm->icl_auth.ca_use_radius = B_TRUE; 1533 } else if (strcmp(auth, PA_AUTH_CHAP) == 0) { 1534 /* Local CHAP authentication */ 1535 lsm->icl_auth.ca_method_valid_list[i++] = AM_CHAP; 1536 lsm->icl_auth.ca_use_radius = B_FALSE; 1537 } else if ((strcmp(auth, PA_AUTH_NONE) == 0) || 1538 (strcmp(auth, "") == 0)) { 1539 /* No authentication */ 1540 lsm->icl_auth.ca_method_valid_list[i++] = AM_NONE; 1541 } 1542 1543 /* 1544 * If initiator/target CHAP username is not set then use the 1545 * node name. If lsm->icl_target_name == NULL then this is 1546 * a discovery session so we don't need to work about the target. 1547 */ 1548 if (strcmp(chapuser, "") == 0) { 1549 (void) strlcpy(lsm->icl_auth.ca_ini_chapuser, 1550 lsm->icl_initiator_name, 1551 min(iscsitAuthStringMaxLength, MAX_ISCSI_NODENAMELEN)); 1552 } else { 1553 (void) strlcpy(lsm->icl_auth.ca_ini_chapuser, chapuser, 1554 iscsitAuthStringMaxLength); 1555 } 1556 if ((lsm->icl_target_name != NULL) && 1557 (strcmp(targetchapuser, "") == 0)) { 1558 (void) strlcpy(lsm->icl_auth.ca_tgt_chapuser, 1559 lsm->icl_target_name, 1560 min(iscsitAuthStringMaxLength, MAX_ISCSI_NODENAMELEN)); 1561 } else { 1562 (void) strlcpy(lsm->icl_auth.ca_tgt_chapuser, 1563 targetchapuser, iscsitAuthStringMaxLength); 1564 } 1565 1566 /* 1567 * Secrets are stored in base64-encoded format so we need to 1568 * decode them into binary form 1569 */ 1570 if (strcmp(chapsecret, "") == 0) { 1571 lsm->icl_auth.ca_ini_chapsecretlen = 0; 1572 } else { 1573 if (iscsi_base64_str_to_binary(chapsecret, 1574 strnlen(chapsecret, iscsitAuthStringMaxLength), 1575 lsm->icl_auth.ca_ini_chapsecret, iscsitAuthStringMaxLength, 1576 &lsm->icl_auth.ca_ini_chapsecretlen) != 0) { 1577 cmn_err(CE_WARN, "Corrupted CHAP secret" 1578 " for initiator %s", lsm->icl_initiator_name); 1579 lsm->icl_auth.ca_ini_chapsecretlen = 0; 1580 } 1581 } 1582 if (strcmp(targetchapsecret, "") == 0) { 1583 lsm->icl_auth.ca_tgt_chapsecretlen = 0; 1584 } else { 1585 if (iscsi_base64_str_to_binary(targetchapsecret, 1586 strnlen(targetchapsecret, iscsitAuthStringMaxLength), 1587 lsm->icl_auth.ca_tgt_chapsecret, iscsitAuthStringMaxLength, 1588 &lsm->icl_auth.ca_tgt_chapsecretlen) != 0) { 1589 cmn_err(CE_WARN, "Corrupted CHAP secret" 1590 " for target %s", lsm->icl_target_name); 1591 lsm->icl_auth.ca_tgt_chapsecretlen = 0; 1592 } 1593 } 1594 if (strcmp(radiussecret, "") == 0) { 1595 lsm->icl_auth.ca_radius_secretlen = 0; 1596 } else { 1597 if (iscsi_base64_str_to_binary(radiussecret, 1598 strnlen(radiussecret, iscsitAuthStringMaxLength), 1599 lsm->icl_auth.ca_radius_secret, iscsitAuthStringMaxLength, 1600 &lsm->icl_auth.ca_radius_secretlen) != 0) { 1601 cmn_err(CE_WARN, "Corrupted RADIUS secret"); 1602 lsm->icl_auth.ca_radius_secretlen = 0; 1603 } 1604 } 1605 1606 /* 1607 * Set alias 1608 */ 1609 (void) strlcpy(lsm->icl_auth.ca_tgt_alias, targetalias, 1610 MAX_ISCSI_NODENAMELEN); 1611 1612 /* 1613 * Now that authentication parameters are setup, validate the parameters 1614 * against the authentication mode 1615 * Decode RADIUS server value int lsm->icl_auth.ca_radius_server 1616 */ 1617 if ((strcmp(auth, PA_AUTH_RADIUS) == 0) && 1618 ((lsm->icl_auth.ca_radius_secretlen == 0) || 1619 (strcmp(radiusserver, "") == 0) || 1620 it_common_convert_sa(radiusserver, 1621 &lsm->icl_auth.ca_radius_server, 1622 DEFAULT_RADIUS_PORT) == NULL)) { 1623 cmn_err(CE_WARN, "RADIUS authentication selected " 1624 "for target %s but RADIUS parameters are not " 1625 "configured.", lsm->icl_target_name); 1626 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_TARGET_ERR, 1627 ISCSI_LOGIN_STATUS_TARGET_ERROR); 1628 idmrc = IDM_STATUS_FAIL; 1629 } else if ((strcmp(auth, PA_AUTH_CHAP) == 0) && 1630 (lsm->icl_auth.ca_ini_chapsecretlen == 0)) { 1631 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_INITIATOR_ERR, 1632 ISCSI_LOGIN_STATUS_AUTH_FAILED); 1633 idmrc = IDM_STATUS_FAIL; 1634 } 1635 1636 ISCSIT_GLOBAL_UNLOCK(); 1637 1638 return (idmrc); 1639 } 1640 1641 1642 static idm_status_t 1643 login_sm_session_register(iscsit_conn_t *ict) 1644 { 1645 iscsit_sess_t *ist = ict->ict_sess; 1646 stmf_scsi_session_t *ss; 1647 1648 /* 1649 * Hold target mutex until we have finished registering with STMF 1650 */ 1651 mutex_enter(&ist->ist_tgt->target_mutex); 1652 if (ist->ist_tgt->target_state != TS_STMF_ONLINE) { 1653 mutex_exit(&ist->ist_tgt->target_mutex); 1654 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_INITIATOR_ERR, 1655 ISCSI_LOGIN_STATUS_TGT_REMOVED); 1656 return (IDM_STATUS_FAIL); 1657 } 1658 1659 ss = stmf_alloc(STMF_STRUCT_SCSI_SESSION, 0, 1660 0); 1661 if (ss == NULL) { 1662 mutex_exit(&ist->ist_tgt->target_mutex); 1663 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_TARGET_ERR, 1664 ISCSI_LOGIN_STATUS_NO_RESOURCES); 1665 return (IDM_STATUS_FAIL); 1666 } 1667 1668 ss->ss_rport_id = kmem_zalloc(sizeof (scsi_devid_desc_t) + 1669 strlen(ist->ist_initiator_name) + 1, KM_SLEEP); 1670 (void) strcpy((char *)ss->ss_rport_id->ident, ist->ist_initiator_name); 1671 ss->ss_rport_id->ident_length = strlen(ist->ist_initiator_name); 1672 ss->ss_rport_id->protocol_id = PROTOCOL_iSCSI; 1673 ss->ss_rport_id->piv = 1; 1674 ss->ss_rport_id->code_set = CODE_SET_ASCII; 1675 ss->ss_rport_id->association = ID_IS_TARGET_PORT; 1676 1677 ss->ss_lport = ist->ist_lport; 1678 1679 if (stmf_register_scsi_session(ict->ict_sess->ist_lport, ss) != 1680 STMF_SUCCESS) { 1681 mutex_exit(&ist->ist_tgt->target_mutex); 1682 kmem_free(ss->ss_rport_id, 1683 sizeof (scsi_devid_desc_t) + 1684 strlen(ist->ist_initiator_name) + 1); 1685 stmf_free(ss); 1686 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_TARGET_ERR, 1687 ISCSI_LOGIN_STATUS_TARGET_ERROR); 1688 return (IDM_STATUS_FAIL); 1689 } 1690 1691 ss->ss_port_private = ict->ict_sess; 1692 ict->ict_sess->ist_stmf_sess = ss; 1693 mutex_exit(&ist->ist_tgt->target_mutex); 1694 1695 return (IDM_STATUS_SUCCESS); 1696 } 1697 1698 1699 static idm_status_t 1700 login_sm_req_pdu_check(iscsit_conn_t *ict, idm_pdu_t *pdu) 1701 { 1702 uint8_t csg_req; 1703 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 1704 iscsi_login_hdr_t *lh = (iscsi_login_hdr_t *)pdu->isp_hdr; 1705 iscsi_login_rsp_hdr_t *lh_resp = lsm->icl_login_resp_tmpl; 1706 1707 /* 1708 * Check CSG 1709 */ 1710 csg_req = ISCSI_LOGIN_CURRENT_STAGE(lh->flags); 1711 switch (csg_req) { 1712 case ISCSI_SECURITY_NEGOTIATION_STAGE: 1713 case ISCSI_OP_PARMS_NEGOTIATION_STAGE: 1714 if ((csg_req != lsm->icl_login_csg) && 1715 (lsm->icl_login_state != ILS_LOGIN_INIT)) { 1716 /* 1717 * Inappropriate CSG change. Initiator can only 1718 * change CSG after we've responded with the 1719 * transit bit set. If we had responded with 1720 * a CSG change previous we would have updated 1721 * our copy of CSG. 1722 * 1723 * The exception is when we are in ILS_LOGIN_INIT 1724 * state since we haven't determined our initial 1725 * CSG value yet. 1726 */ 1727 goto pdu_check_fail; 1728 } 1729 break; 1730 case ISCSI_FULL_FEATURE_PHASE: 1731 default: 1732 goto pdu_check_fail; 1733 } 1734 1735 /* 1736 * If this is the first login PDU for a new connection then 1737 * the session will be NULL. 1738 */ 1739 if (ict->ict_sess != NULL) { 1740 /* 1741 * We've already created a session on a previous PDU. Make 1742 * sure this PDU is consistent with what we've already seen 1743 */ 1744 if ((ict->ict_cid != ntohs(lh->cid)) || 1745 (bcmp(ict->ict_sess->ist_isid, lh->isid, 1746 ISCSI_ISID_LEN) != 0)) { 1747 goto pdu_check_fail; 1748 } 1749 } 1750 1751 /* 1752 * Make sure we are compatible with the version range 1753 */ 1754 #if (ISCSIT_MAX_VERSION > 0) 1755 if ((lh->min_version > ISCSIT_MAX_VERSION) || 1756 (lh->max_version < ISCSIT_MIN_VERSION)) { 1757 goto pdu_check_fail; 1758 } 1759 #endif 1760 1761 /* 1762 * Just in case the initiator changes things up on us along the way 1763 * check against our active_version -- we can't change the active 1764 * version and the initiator is not *supposed* to change its 1765 * min_version and max_version values so this should never happen. 1766 * Of course we only do this if the response header template has 1767 * been built. 1768 */ 1769 if ((lh_resp->opcode == ISCSI_OP_LOGIN_RSP) && /* header valid */ 1770 ((lh->min_version > lh_resp->active_version) || 1771 (lh->max_version < lh_resp->active_version))) { 1772 goto pdu_check_fail; 1773 } 1774 1775 return (IDM_STATUS_SUCCESS); 1776 1777 pdu_check_fail: 1778 return (IDM_STATUS_FAIL); 1779 } 1780 1781 static idm_status_t 1782 login_sm_process_nvlist(iscsit_conn_t *ict) 1783 { 1784 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 1785 char *nvp_name; 1786 nvpair_t *nvp; 1787 nvpair_t *next_nvp; 1788 nvpair_t *negotiated_nvp; 1789 kv_status_t kvrc; 1790 uint8_t error_class; 1791 uint8_t error_detail; 1792 idm_status_t idm_status; 1793 1794 error_class = ISCSI_STATUS_CLASS_SUCCESS; 1795 error_detail = ISCSI_LOGIN_STATUS_ACCEPT; 1796 1797 /* First, request that the transport process the list */ 1798 kvrc = idm_negotiate_key_values(ict->ict_ic, lsm->icl_request_nvlist, 1799 lsm->icl_response_nvlist, lsm->icl_negotiated_values); 1800 idm_kvstat_to_error(kvrc, &error_class, &error_detail); 1801 if (error_class != ISCSI_STATUS_CLASS_SUCCESS) { 1802 SET_LOGIN_ERROR(ict, error_class, error_detail); 1803 idm_status = IDM_STATUS_FAIL; 1804 return (idm_status); 1805 } 1806 1807 /* Ensure we clear transit bit if the transport layer has countered */ 1808 if (kvrc == KV_HANDLED_NO_TRANSIT) { 1809 lsm->icl_login_transit = B_FALSE; 1810 } 1811 1812 /* Now, move on and process the rest of the pairs */ 1813 nvp = nvlist_next_nvpair(lsm->icl_request_nvlist, NULL); 1814 while (nvp != NULL) { 1815 next_nvp = nvlist_next_nvpair(lsm->icl_request_nvlist, nvp); 1816 nvp_name = nvpair_name(nvp); 1817 /* 1818 * If we've already agreed upon a value then make sure this 1819 * is not attempting to change that value. From RFC3270 1820 * section 5.3: 1821 * 1822 * "Neither the initiator nor the target should attempt to 1823 * declare or negotiate a parameter more than once during 1824 * login except for responses to specific keys that 1825 * explicitly allow repeated key declarations (e.g., 1826 * TargetAddress). An attempt to renegotiate/redeclare 1827 * parameters not specifically allowed MUST be detected 1828 * by the initiator and target. If such an attempt is 1829 * detected by the target, the target MUST respond 1830 * with Login reject (initiator error); ..." 1831 */ 1832 if (nvlist_lookup_nvpair(lsm->icl_negotiated_values, 1833 nvp_name, &negotiated_nvp) == 0) { 1834 kvrc = KV_HANDLED; 1835 } else { 1836 kvrc = iscsit_handle_key(ict, nvp, nvp_name); 1837 } 1838 1839 idm_kvstat_to_error(kvrc, &error_class, &error_detail); 1840 if (error_class != ISCSI_STATUS_CLASS_SUCCESS) { 1841 break; 1842 } 1843 1844 nvp = next_nvp; 1845 } 1846 1847 if (error_class == ISCSI_STATUS_CLASS_SUCCESS) { 1848 idm_status = IDM_STATUS_SUCCESS; 1849 } else { 1850 /* supply login class/detail for login errors */ 1851 SET_LOGIN_ERROR(ict, error_class, error_detail); 1852 idm_status = IDM_STATUS_FAIL; 1853 } 1854 1855 return (idm_status); 1856 } 1857 1858 static idm_status_t 1859 login_sm_check_security(iscsit_conn_t *ict) 1860 { 1861 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 1862 conn_auth_t *auth = &lsm->icl_auth; 1863 iscsit_auth_method_t *am_list = &auth->ca_method_valid_list[0]; 1864 kv_status_t kvrc; 1865 uint8_t error_class; 1866 uint8_t error_detail; 1867 idm_status_t idm_status; 1868 1869 error_class = ISCSI_STATUS_CLASS_SUCCESS; 1870 error_detail = ISCSI_LOGIN_STATUS_ACCEPT; 1871 1872 /* Check authentication status. */ 1873 if (lsm->icl_login_csg == ISCSI_SECURITY_NEGOTIATION_STAGE) { 1874 /* 1875 * We should have some authentication key/value pair(s) 1876 * received from initiator and the authentication phase 1877 * has been shifted when the key/value pair(s) are being 1878 * handled in the previous call iscsit_handle_security_key. 1879 * Now it turns to target to check the authentication phase 1880 * and shift it after taking some authentication action. 1881 */ 1882 kvrc = iscsit_reply_security_key(ict); 1883 idm_kvstat_to_error(kvrc, &error_class, &error_detail); 1884 } else if (!ict->ict_login_sm.icl_auth_pass) { 1885 /* 1886 * Check to see if the target allows initiators to bypass the 1887 * security check. If the target is configured to require 1888 * authentication, we reject the connection. 1889 */ 1890 if (am_list[0] == AM_NONE || am_list[0] == 0) { 1891 ict->ict_login_sm.icl_auth_pass = 1; 1892 } else { 1893 error_class = ISCSI_STATUS_CLASS_INITIATOR_ERR; 1894 error_detail = ISCSI_LOGIN_STATUS_AUTH_FAILED; 1895 } 1896 } 1897 1898 if (error_class == ISCSI_STATUS_CLASS_SUCCESS) { 1899 idm_status = IDM_STATUS_SUCCESS; 1900 } else { 1901 /* supply login class/detail for login errors */ 1902 SET_LOGIN_ERROR(ict, error_class, error_detail); 1903 idm_status = IDM_STATUS_FAIL; 1904 } 1905 1906 return (idm_status); 1907 } 1908 1909 static void 1910 login_sm_build_login_response(iscsit_conn_t *ict) 1911 { 1912 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 1913 iscsi_login_rsp_hdr_t *lh; 1914 int transit, text_transit = 1; 1915 1916 /* 1917 * 1. Convert response nvlist to an idm text buffer that holds 1918 * response key-value pairs. 1919 * 2. Build a PDU to transmit the first login response PDU 1920 * 3. If there is more data, wait for an ack then goto step 2. 1921 */ 1922 ASSERT(lsm->icl_login_resp != NULL); 1923 1924 if (lsm->icl_response_nvlist) { 1925 if (lsm->icl_login_resp_itb == NULL) { 1926 /* initialze the idm text buf to send pdus */ 1927 lsm->icl_login_resp_itb = idm_nvlist_to_itextbuf( 1928 lsm->icl_response_nvlist); 1929 if (lsm->icl_login_resp_itb == NULL) { 1930 SET_LOGIN_ERROR(ict, 1931 ISCSI_STATUS_CLASS_TARGET_ERR, 1932 ISCSI_LOGIN_STATUS_NO_RESOURCES); 1933 /* Still need to send the resp so continue */ 1934 } else { 1935 lsm->icl_login_resp_buf = 1936 idm_pdu_init_text_data(lsm->icl_login_resp, 1937 lsm->icl_login_resp_itb, 1938 ISCSI_DEFAULT_MAX_RECV_SEG_LEN, 1939 lsm->icl_login_resp_buf, &text_transit); 1940 } 1941 } else { 1942 lsm->icl_login_resp_buf = idm_pdu_init_text_data( 1943 lsm->icl_login_resp, lsm->icl_login_resp_itb, 1944 ISCSI_DEFAULT_MAX_RECV_SEG_LEN, 1945 lsm->icl_login_resp_buf, &text_transit); 1946 } 1947 } else { 1948 lsm->icl_login_resp->isp_data = NULL; 1949 lsm->icl_login_resp->isp_datalen = 0; 1950 } 1951 1952 /* 1953 * Use the BHS header values from the response template 1954 */ 1955 bcopy(lsm->icl_login_resp_tmpl, 1956 lsm->icl_login_resp->isp_hdr, sizeof (iscsi_login_rsp_hdr_t)); 1957 1958 lh = (iscsi_login_rsp_hdr_t *)lsm->icl_login_resp->isp_hdr; 1959 1960 /* Set error class/detail */ 1961 lh->status_class = lsm->icl_login_resp_err_class; 1962 lh->status_detail = lsm->icl_login_resp_err_detail; 1963 /* Set CSG, NSG and Transit */ 1964 lh->flags = 0; 1965 lh->flags |= lsm->icl_login_csg << 2; 1966 1967 1968 if (lh->status_class == ISCSI_STATUS_CLASS_SUCCESS) { 1969 if (lsm->icl_login_transit && 1970 lsm->icl_auth_pass != 0) { 1971 transit = 1; 1972 } else { 1973 transit = 0; 1974 } 1975 /* 1976 * inititalize the text data 1977 */ 1978 if (transit == 1 && text_transit == 1) { 1979 lh->flags |= lsm->icl_login_nsg; 1980 lsm->icl_login_csg = lsm->icl_login_nsg; 1981 lh->flags |= ISCSI_FLAG_LOGIN_TRANSIT; 1982 } else { 1983 lh->flags &= ~ISCSI_FLAG_LOGIN_TRANSIT; 1984 } 1985 1986 /* If we are transitioning to FFP then set TSIH */ 1987 if (transit && (lh->flags & ISCSI_FLAG_LOGIN_TRANSIT) && 1988 lsm->icl_login_csg == ISCSI_FULL_FEATURE_PHASE) { 1989 lh->tsid = htons(ict->ict_sess->ist_tsih); 1990 } 1991 } else { 1992 lsm->icl_login_resp->isp_data = 0; 1993 lsm->icl_login_resp->isp_datalen = 0; 1994 } 1995 } 1996 1997 static kv_status_t 1998 iscsit_handle_key(iscsit_conn_t *ict, nvpair_t *nvp, char *nvp_name) 1999 { 2000 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 2001 kv_status_t kvrc; 2002 const idm_kv_xlate_t *ikvx; 2003 2004 ikvx = idm_lookup_kv_xlate(nvp_name, strlen(nvp_name)); 2005 if (ikvx->ik_key_id == KI_MAX_KEY) { 2006 /* 2007 * Any key not understood by the acceptor may be igonred 2008 * by the acceptor without affecting the basic function. 2009 * However, the answer for a key not understood MUST be 2010 * key=NotUnderstood. 2011 */ 2012 kvrc = iscsit_reply_string(ict, nvp_name, 2013 ISCSI_TEXT_NOTUNDERSTOOD); 2014 } else { 2015 kvrc = iscsit_handle_common_key(ict, nvp, ikvx); 2016 if (kvrc == KV_UNHANDLED) { 2017 switch (lsm->icl_login_csg) { 2018 case ISCSI_SECURITY_NEGOTIATION_STAGE: 2019 kvrc = iscsit_handle_security_key( 2020 ict, nvp, ikvx); 2021 break; 2022 case ISCSI_OP_PARMS_NEGOTIATION_STAGE: 2023 kvrc = iscsit_handle_operational_key( 2024 ict, nvp, ikvx); 2025 break; 2026 case ISCSI_FULL_FEATURE_PHASE: 2027 default: 2028 /* What are we doing here? */ 2029 ASSERT(0); 2030 kvrc = KV_UNHANDLED; 2031 } 2032 } 2033 } 2034 2035 return (kvrc); 2036 } 2037 2038 static kv_status_t 2039 iscsit_handle_common_key(iscsit_conn_t *ict, nvpair_t *nvp, 2040 const idm_kv_xlate_t *ikvx) 2041 { 2042 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 2043 kv_status_t kvrc; 2044 char *string_val; 2045 int nvrc; 2046 2047 switch (ikvx->ik_key_id) { 2048 case KI_INITIATOR_NAME: 2049 case KI_INITIATOR_ALIAS: 2050 nvrc = nvlist_add_nvpair(lsm->icl_negotiated_values, nvp); 2051 kvrc = idm_nvstat_to_kvstat(nvrc); 2052 break; 2053 case KI_TARGET_NAME: 2054 /* We'll validate the target during login_sm_session_bind() */ 2055 nvrc = nvpair_value_string(nvp, &string_val); 2056 ASSERT(nvrc == 0); /* We built this nvlist */ 2057 2058 nvrc = nvlist_add_nvpair(lsm->icl_negotiated_values, nvp); 2059 kvrc = idm_nvstat_to_kvstat(nvrc); 2060 break; 2061 case KI_TARGET_ALIAS: 2062 case KI_TARGET_ADDRESS: 2063 case KI_TARGET_PORTAL_GROUP_TAG: 2064 kvrc = KV_TARGET_ONLY; /* Only the target can declare this */ 2065 break; 2066 case KI_SESSION_TYPE: 2067 /* 2068 * If we don't receive this key on the initial login 2069 * we assume this is a normal session. 2070 */ 2071 nvrc = nvlist_add_nvpair(lsm->icl_negotiated_values, nvp); 2072 kvrc = idm_nvstat_to_kvstat(nvrc); 2073 nvrc = nvpair_value_string(nvp, &string_val); 2074 ASSERT(nvrc == 0); /* We built this nvlist */ 2075 ict->ict_op.op_discovery_session = 2076 strcmp(string_val, "Discovery") == 0 ? B_TRUE : B_FALSE; 2077 break; 2078 default: 2079 /* 2080 * This is not really an error but we should 2081 * leave this nvpair on the list since we 2082 * didn't do anything with it. Either 2083 * the security or operational phase 2084 * handling functions should process it. 2085 */ 2086 kvrc = KV_UNHANDLED; 2087 break; 2088 } 2089 2090 return (kvrc); 2091 } 2092 2093 static kv_status_t 2094 iscsit_handle_security_key(iscsit_conn_t *ict, nvpair_t *nvp, 2095 const idm_kv_xlate_t *ikvx) 2096 { 2097 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 2098 iscsit_auth_client_t *client = &lsm->icl_auth_client; 2099 iscsikey_id_t kv_id; 2100 kv_status_t kvrc; 2101 iscsit_auth_handler_t handler; 2102 2103 /* 2104 * After all of security keys are handled, this function will 2105 * be called again to verify current authentication status 2106 * and perform some actual authentication work. At this time, 2107 * the nvp and ikvx will be passed in as NULLs. 2108 */ 2109 if (ikvx != NULL) { 2110 kv_id = ikvx->ik_key_id; 2111 } else { 2112 kv_id = 0; 2113 } 2114 2115 handler = iscsit_auth_get_handler(client, kv_id); 2116 if (handler) { 2117 kvrc = handler(ict, nvp, ikvx); 2118 } else { 2119 kvrc = KV_UNHANDLED; /* invalid request */ 2120 } 2121 2122 return (kvrc); 2123 } 2124 2125 static kv_status_t 2126 iscsit_reply_security_key(iscsit_conn_t *ict) 2127 { 2128 return (iscsit_handle_security_key(ict, NULL, NULL)); 2129 } 2130 2131 static kv_status_t 2132 iscsit_handle_operational_key(iscsit_conn_t *ict, nvpair_t *nvp, 2133 const idm_kv_xlate_t *ikvx) 2134 { 2135 kv_status_t kvrc = KV_UNHANDLED; 2136 boolean_t bool_val; 2137 uint64_t num_val; 2138 int nvrc; 2139 2140 /* 2141 * Retrieve values. All value lookups are expected to succeed 2142 * since we build the nvlist while decoding the text buffer. This 2143 * step is intended to eliminate some duplication of code (for example 2144 * we only need to code the numerical value lookup once). We will 2145 * handle the values (if necessary) below. 2146 */ 2147 switch (ikvx->ik_key_id) { 2148 /* Lists */ 2149 case KI_HEADER_DIGEST: 2150 case KI_DATA_DIGEST: 2151 break; 2152 /* Booleans */ 2153 case KI_INITIAL_R2T: 2154 case KI_IMMEDIATE_DATA: 2155 case KI_DATA_PDU_IN_ORDER: 2156 case KI_DATA_SEQUENCE_IN_ORDER: 2157 case KI_IFMARKER: 2158 case KI_OFMARKER: 2159 nvrc = nvpair_value_boolean_value(nvp, &bool_val); 2160 ASSERT(nvrc == 0); /* We built this nvlist */ 2161 break; 2162 /* Numericals */ 2163 case KI_MAX_CONNECTIONS: 2164 case KI_MAX_RECV_DATA_SEGMENT_LENGTH: 2165 case KI_MAX_BURST_LENGTH: 2166 case KI_FIRST_BURST_LENGTH: 2167 case KI_DEFAULT_TIME_2_WAIT: 2168 case KI_DEFAULT_TIME_2_RETAIN: 2169 case KI_MAX_OUTSTANDING_R2T: 2170 case KI_ERROR_RECOVERY_LEVEL: 2171 nvrc = nvpair_value_uint64(nvp, &num_val); 2172 ASSERT(nvrc == 0); 2173 break; 2174 /* Ranges */ 2175 case KI_OFMARKERINT: 2176 case KI_IFMARKERINT: 2177 break; 2178 default: 2179 break; 2180 } 2181 2182 /* 2183 * Now handle the values according to the key name. Sometimes we 2184 * don't care what the value is -- in that case we just add the nvpair 2185 * to the negotiated values list. 2186 */ 2187 switch (ikvx->ik_key_id) { 2188 case KI_HEADER_DIGEST: 2189 kvrc = iscsit_handle_digest(ict, nvp, ikvx); 2190 break; 2191 case KI_DATA_DIGEST: 2192 kvrc = iscsit_handle_digest(ict, nvp, ikvx); 2193 break; 2194 case KI_INITIAL_R2T: 2195 /* We *require* INITIAL_R2T=yes */ 2196 kvrc = iscsit_handle_boolean(ict, nvp, bool_val, ikvx, 2197 B_TRUE); 2198 break; 2199 case KI_IMMEDIATE_DATA: 2200 kvrc = iscsit_handle_boolean(ict, nvp, bool_val, ikvx, 2201 bool_val); 2202 break; 2203 case KI_DATA_PDU_IN_ORDER: 2204 kvrc = iscsit_handle_boolean(ict, nvp, bool_val, ikvx, 2205 B_TRUE); 2206 break; 2207 case KI_DATA_SEQUENCE_IN_ORDER: 2208 /* We allow any value for DATA_SEQUENCE_IN_ORDER */ 2209 kvrc = iscsit_handle_boolean(ict, nvp, bool_val, ikvx, 2210 bool_val); 2211 break; 2212 case KI_OFMARKER: 2213 case KI_IFMARKER: 2214 /* We don't support markers */ 2215 kvrc = iscsit_handle_boolean(ict, nvp, bool_val, ikvx, 2216 B_FALSE); 2217 break; 2218 case KI_MAX_CONNECTIONS: 2219 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx, 2220 ISCSI_MIN_CONNECTIONS, 2221 ISCSI_MAX_CONNECTIONS, 2222 ISCSIT_MAX_CONNECTIONS); 2223 break; 2224 case KI_MAX_RECV_DATA_SEGMENT_LENGTH: 2225 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx, 2226 ISCSI_MIN_RECV_DATA_SEGMENT_LENGTH, 2227 ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH, 2228 ISCSIT_MAX_RECV_DATA_SEGMENT_LENGTH); 2229 break; 2230 case KI_MAX_BURST_LENGTH: 2231 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx, 2232 ISCSI_MIN_MAX_BURST_LENGTH, 2233 ISCSI_MAX_BURST_LENGTH, 2234 ISCSIT_MAX_BURST_LENGTH); 2235 break; 2236 case KI_FIRST_BURST_LENGTH: 2237 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx, 2238 ISCSI_MIN_FIRST_BURST_LENGTH, 2239 ISCSI_MAX_FIRST_BURST_LENGTH, 2240 ISCSIT_MAX_FIRST_BURST_LENGTH); 2241 break; 2242 case KI_DEFAULT_TIME_2_WAIT: 2243 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx, 2244 ISCSI_MIN_TIME2WAIT, 2245 ISCSI_MAX_TIME2WAIT, 2246 ISCSIT_MAX_TIME2WAIT); 2247 break; 2248 case KI_DEFAULT_TIME_2_RETAIN: 2249 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx, 2250 ISCSI_MIN_TIME2RETAIN, 2251 ISCSI_MAX_TIME2RETAIN, 2252 ISCSIT_MAX_TIME2RETAIN); 2253 break; 2254 case KI_MAX_OUTSTANDING_R2T: 2255 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx, 2256 ISCSI_MIN_MAX_OUTSTANDING_R2T, 2257 ISCSI_MAX_OUTSTANDING_R2T, 2258 ISCSIT_MAX_OUTSTANDING_R2T); 2259 break; 2260 case KI_ERROR_RECOVERY_LEVEL: 2261 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx, 2262 ISCSI_MIN_ERROR_RECOVERY_LEVEL, 2263 ISCSI_MAX_ERROR_RECOVERY_LEVEL, 2264 ISCSIT_MAX_ERROR_RECOVERY_LEVEL); 2265 break; 2266 case KI_OFMARKERINT: 2267 case KI_IFMARKERINT: 2268 kvrc = iscsit_reply_string(ict, ikvx->ik_key_name, 2269 ISCSI_TEXT_IRRELEVANT); 2270 break; 2271 default: 2272 kvrc = KV_UNHANDLED; /* invalid request */ 2273 break; 2274 } 2275 2276 return (kvrc); 2277 } 2278 2279 static kv_status_t 2280 iscsit_reply_numerical(iscsit_conn_t *ict, 2281 const char *nvp_name, const uint64_t value) 2282 { 2283 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 2284 kv_status_t kvrc; 2285 int nvrc; 2286 2287 nvrc = nvlist_add_uint64(lsm->icl_response_nvlist, 2288 nvp_name, value); 2289 kvrc = idm_nvstat_to_kvstat(nvrc); 2290 2291 return (kvrc); 2292 } 2293 2294 static kv_status_t 2295 iscsit_reply_string(iscsit_conn_t *ict, 2296 const char *nvp_name, const char *text) 2297 { 2298 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 2299 kv_status_t kvrc; 2300 int nvrc; 2301 2302 nvrc = nvlist_add_string(lsm->icl_response_nvlist, 2303 nvp_name, text); 2304 kvrc = idm_nvstat_to_kvstat(nvrc); 2305 2306 return (kvrc); 2307 } 2308 2309 static kv_status_t 2310 iscsit_handle_digest(iscsit_conn_t *ict, nvpair_t *choices, 2311 const idm_kv_xlate_t *ikvx) 2312 { 2313 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 2314 kv_status_t kvrc = KV_VALUE_ERROR; 2315 int nvrc; 2316 nvpair_t *digest_choice; 2317 char *digest_choice_string; 2318 2319 /* 2320 * Need to add persistent config here if we want users to allow 2321 * disabling of digests on the target side. You could argue that 2322 * this makes things too complicated... just let the initiator state 2323 * what it wants and we'll take it. For now that's exactly what 2324 * we'll do. 2325 * 2326 * Basic digest negotiation happens here at iSCSI level. IDM 2327 * can override this during negotiate_key_values phase to 2328 * decline to set up any digest processing. 2329 */ 2330 digest_choice = idm_get_next_listvalue(choices, NULL); 2331 2332 /* 2333 * Loop through all choices. As soon as we find a choice 2334 * that we support add the value to our negotiated values list 2335 * and respond with that value in the login response. 2336 */ 2337 while (digest_choice != NULL) { 2338 nvrc = nvpair_value_string(digest_choice, 2339 &digest_choice_string); 2340 ASSERT(nvrc == 0); 2341 2342 if ((strcasecmp(digest_choice_string, "crc32c") == 0) || 2343 (strcasecmp(digest_choice_string, "none") == 0)) { 2344 /* Add to negotiated values list */ 2345 nvrc = nvlist_add_string(lsm->icl_negotiated_values, 2346 ikvx->ik_key_name, digest_choice_string); 2347 kvrc = idm_nvstat_to_kvstat(nvrc); 2348 if (nvrc == 0) { 2349 /* Add to login response list */ 2350 nvrc = nvlist_add_string( 2351 lsm->icl_response_nvlist, 2352 ikvx->ik_key_name, digest_choice_string); 2353 kvrc = idm_nvstat_to_kvstat(nvrc); 2354 } 2355 break; 2356 } 2357 digest_choice = idm_get_next_listvalue(choices, 2358 digest_choice); 2359 } 2360 2361 if (digest_choice == NULL) 2362 kvrc = KV_VALUE_ERROR; 2363 2364 return (kvrc); 2365 } 2366 2367 static kv_status_t 2368 iscsit_handle_boolean(iscsit_conn_t *ict, nvpair_t *nvp, boolean_t value, 2369 const idm_kv_xlate_t *ikvx, boolean_t iscsit_value) 2370 { 2371 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 2372 kv_status_t kvrc; 2373 int nvrc; 2374 2375 if (value != iscsit_value) { 2376 /* Respond back to initiator with our value */ 2377 value = iscsit_value; 2378 lsm->icl_login_transit = B_FALSE; 2379 nvrc = 0; 2380 } else { 2381 /* Add this to our negotiated values */ 2382 nvrc = nvlist_add_nvpair(lsm->icl_negotiated_values, 2383 nvp); 2384 } 2385 2386 /* Response of Simple-value Negotiation */ 2387 if (nvrc == 0 && !ikvx->ik_declarative) { 2388 nvrc = nvlist_add_boolean_value( 2389 lsm->icl_response_nvlist, ikvx->ik_key_name, value); 2390 } 2391 kvrc = idm_nvstat_to_kvstat(nvrc); 2392 2393 return (kvrc); 2394 } 2395 2396 static kv_status_t 2397 iscsit_handle_numerical(iscsit_conn_t *ict, nvpair_t *nvp, uint64_t value, 2398 const idm_kv_xlate_t *ikvx, 2399 uint64_t iscsi_min_value, uint64_t iscsi_max_value, 2400 uint64_t iscsit_max_value) 2401 { 2402 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 2403 kv_status_t kvrc; 2404 int nvrc; 2405 2406 /* Validate against standard */ 2407 if ((value < iscsi_min_value) || (value > iscsi_max_value)) { 2408 kvrc = KV_VALUE_ERROR; 2409 } else { 2410 if (value > iscsit_max_value) { 2411 /* Respond back to initiator with our value */ 2412 value = iscsit_max_value; 2413 lsm->icl_login_transit = B_FALSE; 2414 nvrc = 0; 2415 } else { 2416 /* Add this to our negotiated values */ 2417 nvrc = nvlist_add_nvpair(lsm->icl_negotiated_values, 2418 nvp); 2419 } 2420 2421 /* Response of Simple-value Negotiation */ 2422 if (nvrc == 0 && !ikvx->ik_declarative) { 2423 nvrc = nvlist_add_uint64(lsm->icl_response_nvlist, 2424 ikvx->ik_key_name, value); 2425 } 2426 kvrc = idm_nvstat_to_kvstat(nvrc); 2427 } 2428 2429 return (kvrc); 2430 } 2431 2432 2433 static void 2434 iscsit_process_negotiated_values(iscsit_conn_t *ict) 2435 { 2436 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 2437 char *string_val; 2438 boolean_t boolean_val; 2439 uint64_t uint64_val; 2440 int nvrc; 2441 2442 /* Let the IDM level activate its parameters first */ 2443 idm_notice_key_values(ict->ict_ic, lsm->icl_negotiated_values); 2444 2445 /* 2446 * Initiator alias and target alias 2447 */ 2448 if ((nvrc = nvlist_lookup_string(lsm->icl_negotiated_values, 2449 "InitiatorAlias", &string_val)) != ENOENT) { 2450 ASSERT(nvrc == 0); 2451 ict->ict_sess->ist_initiator_alias = 2452 kmem_alloc(strlen(string_val) + 1, KM_SLEEP); 2453 (void) strcpy(ict->ict_sess->ist_initiator_alias, string_val); 2454 } 2455 2456 if ((nvrc = nvlist_lookup_string(lsm->icl_negotiated_values, 2457 "TargetAlias", &string_val)) != ENOENT) { 2458 ASSERT(nvrc == 0); 2459 ict->ict_sess->ist_target_alias = 2460 kmem_alloc(strlen(string_val) + 1, KM_SLEEP); 2461 (void) strcpy(ict->ict_sess->ist_target_alias, string_val); 2462 } 2463 2464 /* 2465 * Operational parameters. We process SessionType when it is 2466 * initially received since it is required on the initial login. 2467 */ 2468 if ((nvrc = nvlist_lookup_boolean_value(lsm->icl_negotiated_values, 2469 "InitialR2T", &boolean_val)) != ENOENT) { 2470 ASSERT(nvrc == 0); 2471 ict->ict_op.op_initial_r2t = boolean_val; 2472 } 2473 2474 if ((nvrc = nvlist_lookup_boolean_value(lsm->icl_negotiated_values, 2475 "ImmediateData", &boolean_val)) != ENOENT) { 2476 ASSERT(nvrc == 0); 2477 ict->ict_op.op_immed_data = boolean_val; 2478 } 2479 2480 if ((nvrc = nvlist_lookup_boolean_value(lsm->icl_negotiated_values, 2481 "DataPDUInOrder", &boolean_val)) != ENOENT) { 2482 ASSERT(nvrc == 0); 2483 ict->ict_op.op_data_pdu_in_order = boolean_val; 2484 } 2485 2486 if ((nvrc = nvlist_lookup_boolean_value(lsm->icl_negotiated_values, 2487 "DataSequenceInOrder", &boolean_val)) != ENOENT) { 2488 ASSERT(nvrc == 0); 2489 ict->ict_op.op_data_sequence_in_order = boolean_val; 2490 } 2491 2492 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values, 2493 "MaxConnections", &uint64_val)) != ENOENT) { 2494 ASSERT(nvrc == 0); 2495 ict->ict_op.op_max_connections = uint64_val; 2496 } 2497 2498 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values, 2499 "MaxRecvDataSegmentLength", &uint64_val)) != ENOENT) { 2500 ASSERT(nvrc == 0); 2501 ict->ict_op.op_max_recv_data_segment_length = uint64_val; 2502 } 2503 2504 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values, 2505 "MaxBurstLength", &uint64_val)) != ENOENT) { 2506 ASSERT(nvrc == 0); 2507 ict->ict_op.op_max_burst_length = uint64_val; 2508 } 2509 2510 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values, 2511 "FirstBurstLength", &uint64_val)) != ENOENT) { 2512 ASSERT(nvrc == 0); 2513 ict->ict_op.op_first_burst_length = uint64_val; 2514 } 2515 2516 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values, 2517 "DefaultTime2Wait", &uint64_val)) != ENOENT) { 2518 ASSERT(nvrc == 0); 2519 ict->ict_op.op_default_time_2_wait = uint64_val; 2520 } 2521 2522 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values, 2523 "DefaultTime2Retain", &uint64_val)) != ENOENT) { 2524 ASSERT(nvrc == 0); 2525 ict->ict_op.op_default_time_2_retain = uint64_val; 2526 } 2527 2528 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values, 2529 "MaxOutstandingR2T", &uint64_val)) != ENOENT) { 2530 ASSERT(nvrc == 0); 2531 ict->ict_op.op_max_outstanding_r2t = uint64_val; 2532 } 2533 2534 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values, 2535 "ErrorRecoveryLevel", &uint64_val)) != ENOENT) { 2536 ASSERT(nvrc == 0); 2537 ict->ict_op.op_error_recovery_level = uint64_val; 2538 } 2539 } 2540