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