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