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