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