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