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