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