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