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