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 src/sun_nws/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 src/sun_nws/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #pragma ident "@(#)iscsit_login.c 1.15 08/03/25 SMI"
27
28 #include <sys/cpuvar.h>
29 #include <sys/types.h>
30 #include <sys/conf.h>
31 #include <sys/stat.h>
32 #include <sys/file.h>
33 #include <sys/ddi.h>
34 #include <sys/sunddi.h>
35 #include <sys/modctl.h>
36
37 #include <sys/socket.h> /* networking stuff */
38 #include <sys/strsubr.h> /* networking stuff */
39 #include <sys/sysmacros.h> /* offsetof */
40 #include <sys/note.h> /* ASSERT3U */
41 #include <sys/sdt.h>
42
43 #include <stmf.h>
44 #include <stmf_ioctl.h>
45 #include <portif.h>
46 #include <idm.h>
47 #include <iscsit.h>
48 #include <iscsit_util.h>
49 #include <iscsit_auth.h>
50
51 typedef struct {
52 list_node_t le_ctx_node;
53 iscsit_login_event_t le_ctx_event;
54 idm_pdu_t *le_pdu;
55 } login_event_ctx_t;
56
57 #ifndef TRUE
58 #define TRUE B_TRUE
59 #endif
60
61 #ifndef FALSE
62 #define FALSE B_FALSE
63 #endif
64
65 extern char *iscsit_ils_name[];
66 extern char *iscsit_ile_name[];
67
68 static void
69 login_sm_complete(void *ict_void);
70
71 static void
72 login_sm_event_dispatch(iscsit_conn_login_t *lsm, iscsit_conn_t *ict,
73 login_event_ctx_t *ctx);
74
75 static void
76 login_sm_init(iscsit_conn_t *ict, login_event_ctx_t *ctx);
77
78 static void
79 login_sm_waiting(iscsit_conn_t *ict, login_event_ctx_t *ctx);
80
81 static void
82 login_sm_processing(iscsit_conn_t *ict, login_event_ctx_t *ctx);
83
84 static void
85 login_sm_responding(iscsit_conn_t *ict, login_event_ctx_t *ctx);
86
87 static void
88 login_sm_responded(iscsit_conn_t *ict, login_event_ctx_t *ctx);
89
90 static void
91 login_sm_ffp(iscsit_conn_t *ict, login_event_ctx_t *ctx);
92
93 static void
94 login_sm_done(iscsit_conn_t *ict, login_event_ctx_t *ctx);
95
96 static void
97 login_sm_error(iscsit_conn_t *ict, login_event_ctx_t *ctx);
98
99 static void
100 login_sm_new_state(iscsit_conn_t *ict, login_event_ctx_t *ctx,
101 iscsit_login_state_t new_state);
102
103 static void
104 login_sm_abort(iscsit_conn_t *ict);
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(iscsit_conn_t *ict);
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);
120
121 static void
122 login_rej_resp_cb(idm_pdu_t *pdu, idm_status_t status);
123
124 static void
125 login_sm_process_request(iscsit_conn_t *ict);
126
127 static idm_status_t
128 login_sm_req_pdu_check(iscsit_conn_t *ict, idm_pdu_t *pdu);
129
130 static idm_status_t
131 login_sm_pdu_list_to_nvlist(iscsit_conn_t *ict);
132
133 static idm_status_t
134 login_sm_process_nvlist(iscsit_conn_t *ict);
135
136 static idm_status_t
137 login_sm_check_security(iscsit_conn_t *ict);
138
139 static idm_status_t
140 login_sm_build_login_response(iscsit_conn_t *ict);
141
142 static void
143 login_sm_ffp_actions(iscsit_conn_t *ict);
144
145 static idm_status_t
146 login_sm_validate_initial_parameters(iscsit_conn_t *ict);
147
148 static idm_status_t
149 login_sm_session_bind(iscsit_conn_t *ict);
150
151 static idm_status_t
152 login_sm_session_register(iscsit_conn_t *ict);
153
154 static kv_status_t
155 iscsit_handle_key(iscsit_conn_t *ict, nvpair_t *nvp, char *nvp_name);
156
157 static kv_status_t
158 iscsit_handle_common_key(iscsit_conn_t *ict, nvpair_t *nvp,
159 const iscsi_kv_xlate_t *ikvx);
160
161 static kv_status_t
162 iscsit_handle_security_key(iscsit_conn_t *ict, nvpair_t *nvp,
163 const iscsi_kv_xlate_t *ikvx);
164
165 static kv_status_t
166 iscsit_reply_security_key(iscsit_conn_t *ict);
167
168 static kv_status_t
169 iscsit_handle_operational_key(iscsit_conn_t *ict, nvpair_t *nvp,
170 const iscsi_kv_xlate_t *ikvx);
171
172 static kv_status_t
173 iscsit_reply_constant(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 iscsi_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 iscsi_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 iscsi_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 idm_status_t
194 iscsit_login_sm_init(iscsit_conn_t *ict)
195 {
196 iscsit_conn_login_t *lsm = &ict->ict_login_sm;
197 int rc;
198
199 bzero(lsm, sizeof (iscsit_conn_login_t));
200
201 rc = nvlist_alloc(&lsm->icl_negotiated_values, NV_UNIQUE_NAME,
202 KM_NOSLEEP);
203 if (rc != 0) {
204 return (IDM_STATUS_FAIL);
205 }
206
207 /*
208 * Pre-allocating a login response PDU means we will always be
209 * able to respond to a login request -- even if we can't allocate
210 * a data buffer to hold the text responses we can at least send
211 * a login failure.
212 */
213 lsm->icl_login_rej_resp = idm_pdu_alloc(sizeof (iscsi_hdr_t), 0);
214 idm_pdu_init(lsm->icl_login_rej_resp, ict->ict_ic, NULL,
215 &login_rej_resp_cb);
216 bzero(lsm->icl_login_rej_resp->isp_hdr, sizeof (iscsi_hdr_t));
217
218 mutex_init(&lsm->icl_mutex, NULL, MUTEX_DEFAULT, NULL);
219 list_create(&lsm->icl_login_events, sizeof (login_event_ctx_t),
220 offsetof(login_event_ctx_t, le_ctx_node));
221 list_create(&lsm->icl_pdu_list, sizeof (idm_pdu_t),
222 offsetof(idm_pdu_t, isp_client_lnd));
223
224 lsm->icl_login_state = ILS_LOGIN_INIT;
225 lsm->icl_login_last_state = ILS_LOGIN_INIT;
226
227 /*
228 * Initialize operational parameters to default values. Anything
229 * we don't specifically negotiate stays at the default.
230 */
231 ict->ict_op.op_discovery_session = B_FALSE;
232 ict->ict_op.op_initial_r2t = ISCSI_DEFAULT_INITIALR2T;
233 ict->ict_op.op_immed_data = ISCSI_DEFAULT_IMMEDIATE_DATA;
234 ict->ict_op.op_data_pdu_in_order = ISCSI_DEFAULT_DATA_PDU_IN_ORDER;
235 ict->ict_op.op_data_sequence_in_order =
236 ISCSI_DEFAULT_DATA_SEQUENCE_IN_ORDER;
237 ict->ict_op.op_max_connections = ISCSI_DEFAULT_MAX_CONNECTIONS;
238 ict->ict_op.op_max_recv_data_segment_length =
239 ISCSI_DEFAULT_MAX_RECV_SEG_LEN;
240 ict->ict_op.op_max_burst_length = ISCSI_DEFAULT_MAX_BURST_LENGTH;
241 ict->ict_op.op_first_burst_length = ISCSI_DEFAULT_FIRST_BURST_LENGTH;
242 ict->ict_op.op_default_time_2_wait = ISCSI_DEFAULT_TIME_TO_WAIT;
243 ict->ict_op.op_default_time_2_retain = ISCSI_DEFAULT_TIME_TO_RETAIN;
244 ict->ict_op.op_max_outstanding_r2t = ISCSI_DEFAULT_MAX_OUT_R2T;
245 ict->ict_op.op_error_recovery_level =
246 ISCSI_DEFAULT_ERROR_RECOVERY_LEVEL;
247
248 return (IDM_STATUS_SUCCESS);
249 }
250
251 static void
252 login_rej_resp_cb(idm_pdu_t *pdu, idm_status_t status)
253 {
254 /* XXX Not sure what we need to do here, if anything. Login event? */
255 }
256
257 static void
258 login_resp_complete_cb(idm_pdu_t *pdu, idm_status_t status)
259 {
260 iscsit_conn_t *ict = pdu->isp_private;
261
262 /* XXX Not sure what we need to do here, if anything. */
263 if (login_sm_is_last_response(ict) == B_TRUE) {
264 iscsit_login_sm_event(ict, ILE_LOGIN_RESP_COMPLETE, NULL);
265 }
266 }
267
268 void
269 iscsit_login_sm_fini(iscsit_conn_t *ict)
270 {
271 iscsit_conn_login_t *lsm = &ict->ict_login_sm;
272
273 list_destroy(&lsm->icl_pdu_list);
274 list_destroy(&lsm->icl_login_events);
275 mutex_destroy(&lsm->icl_mutex);
276
277 idm_pdu_free(lsm->icl_login_rej_resp);
278 if (lsm->icl_login_resp != NULL) {
279 idm_pdu_free(lsm->icl_login_resp);
280 }
281
282 nvlist_free(lsm->icl_negotiated_values);
283 }
284
285 void
286 iscsit_login_sm_event(iscsit_conn_t *ict, iscsit_login_event_t event,
287 idm_pdu_t *pdu)
288 {
289 mutex_enter(&ict->ict_login_sm.icl_mutex);
290 iscsit_login_sm_event_locked(ict, event, pdu);
291 mutex_exit(&ict->ict_login_sm.icl_mutex);
292 }
293
294 void
295 iscsit_login_sm_event_locked(iscsit_conn_t *ict, iscsit_login_event_t event,
296 idm_pdu_t *pdu)
297 {
298 iscsit_conn_login_t *lsm = &ict->ict_login_sm;
299 login_event_ctx_t *ctx;
300
301 ctx = kmem_zalloc(sizeof (*ctx), KM_NOSLEEP);
302
303 if (ctx == NULL) {
304 /*
305 * Cleanup any resources associated with our current login
306 * process and send a login reject.
307 */
308 login_sm_abort(ict);
309 return;
310 }
311
312 ctx->le_ctx_event = event;
313 ctx->le_pdu = pdu;
314
315 list_insert_tail(&lsm->icl_login_events, ctx);
316 /*
317 * Use the icl_busy flag to keep the state machine single threaded.
318 * This also serves as recursion avoidance since this flag will
319 * always be set if we call login_sm_event from within the
320 * state machine code.
321 */
322 if (!lsm->icl_busy) {
323 lsm->icl_busy = B_TRUE;
324 while (!list_is_empty(&lsm->icl_login_events)) {
325 ctx = list_head(&lsm->icl_login_events);
326 list_remove(&lsm->icl_login_events, ctx);
327 mutex_exit(&lsm->icl_mutex);
328 login_sm_event_dispatch(lsm, ict, ctx);
329 mutex_enter(&lsm->icl_mutex);
330 }
331 lsm->icl_busy = B_FALSE;
332
333 /*
334 * When the state machine reaches ILS_LOGIN_DONE or
335 * ILS_LOGIN_ERROR state the login process has completed
336 * and it's time to cleanup. The state machine code will
337 * mark itself "complete" when this happens.
338 *
339 * To protect against spurious events (which shouldn't
340 * happen) set icl_busy again.
341 */
342 if (lsm->icl_login_complete) {
343 lsm->icl_busy = B_TRUE;
344 (void) taskq_dispatch(
345 iscsit_global.global_dispatch_taskq,
346 login_sm_complete, ict, DDI_SLEEP);
347 }
348 }
349 }
350
351 static void
352 login_sm_complete(void *ict_void)
353 {
354 iscsit_conn_t *ict = ict_void;
355
356 /*
357 * State machine has run to completion, release state machine resources
358 */
359 iscsit_login_sm_fini(ict);
360 }
361
362 static void
363 login_sm_event_dispatch(iscsit_conn_login_t *lsm, iscsit_conn_t *ict,
364 login_event_ctx_t *ctx)
365 {
366 idm_pdu_t *pdu = ctx->le_pdu; /* Only valid for some events */
367
368 /* State independent actions */
369 switch (ctx->le_ctx_event) {
370 case ILE_LOGIN_RCV:
371 /* Perform basic sanity checks on the header */
372 if (login_sm_req_pdu_check(ict, pdu) != IDM_STATUS_SUCCESS) {
373 iscsit_login_sm_event_locked(ict, ILE_LOGIN_ERROR,
374 NULL);
375 idm_pdu_complete(pdu, IDM_STATUS_SUCCESS);
376 return;
377 }
378 break;
379 default:
380 break;
381 }
382
383 /* State dependent actions */
384 switch (lsm->icl_login_state) {
385 case ILS_LOGIN_INIT:
386 login_sm_init(ict, ctx);
387 break;
388 case ILS_LOGIN_WAITING:
389 login_sm_waiting(ict, ctx);
390 break;
391 case ILS_LOGIN_PROCESSING:
392 login_sm_processing(ict, ctx);
393 break;
394 case ILS_LOGIN_RESPONDING:
395 login_sm_responding(ict, ctx);
396 break;
397 case ILS_LOGIN_RESPONDED:
398 login_sm_responded(ict, ctx);
399 break;
400 case ILS_LOGIN_FFP:
401 login_sm_ffp(ict, ctx);
402 break;
403 case ILS_LOGIN_DONE:
404 login_sm_done(ict, ctx);
405 break;
406 case ILS_LOGIN_ERROR:
407 login_sm_error(ict, ctx);
408 break;
409 }
410
411 kmem_free(ctx, sizeof (*ctx));
412 }
413
414 static void
415 login_sm_init(iscsit_conn_t *ict, login_event_ctx_t *ctx)
416 {
417 idm_pdu_t *pdu;
418
419 switch (ctx->le_ctx_event) {
420 case ILE_LOGIN_RCV:
421 pdu = ctx->le_pdu;
422
423 /*
424 * This is the first login PDU we've received so use
425 * it to build the login response template and set our CSG.
426 */
427 login_sm_handle_initial_login(ict, pdu);
428
429 /*
430 * Accumulate all the login PDU's that make up this
431 * request on a queue.
432 */
433 mutex_enter(&ict->ict_login_sm.icl_mutex);
434 list_insert_tail(&ict->ict_login_sm.icl_pdu_list, pdu);
435 mutex_exit(&ict->ict_login_sm.icl_mutex);
436
437 if (pdu->isp_hdr->flags & ISCSI_FLAG_LOGIN_CONTINUE) {
438 login_sm_send_ack(ict, pdu);
439 login_sm_new_state(ict, ctx, ILS_LOGIN_WAITING);
440 } else {
441 login_sm_new_state(ict, ctx, ILS_LOGIN_PROCESSING);
442 }
443 break;
444 case ILE_LOGIN_CONN_ERROR:
445 case ILE_LOGIN_ERROR:
446 login_sm_new_state(ict, ctx, ILS_LOGIN_ERROR);
447 break;
448 default:
449 ASSERT(0);
450 }
451 }
452
453 static void
454 login_sm_waiting(iscsit_conn_t *ict, login_event_ctx_t *ctx)
455 {
456 idm_pdu_t *pdu;
457
458 switch (ctx->le_ctx_event) {
459 case ILE_LOGIN_RCV:
460 pdu = ctx->le_pdu;
461 mutex_enter(&ict->ict_login_sm.icl_mutex);
462 list_insert_tail(&ict->ict_login_sm.icl_pdu_list, pdu);
463 mutex_exit(&ict->ict_login_sm.icl_mutex);
464 if (!(pdu->isp_hdr->flags & ISCSI_FLAG_LOGIN_CONTINUE)) {
465 login_sm_new_state(ict, ctx, ILS_LOGIN_PROCESSING);
466 } else {
467 login_sm_send_ack(ict, pdu);
468 }
469 break;
470 case ILE_LOGIN_ERROR:
471 login_sm_new_state(ict, ctx, ILS_LOGIN_ERROR);
472 break;
473 default:
474 ASSERT(0);
475 }
476 }
477
478 static void
479 login_sm_processing(iscsit_conn_t *ict, login_event_ctx_t *ctx)
480 {
481 switch (ctx->le_ctx_event) {
482 case ILE_LOGIN_RESP_READY:
483 login_sm_new_state(ict, ctx, ILS_LOGIN_RESPONDING);
484 break;
485 case ILE_LOGIN_RCV:
486 idm_pdu_complete(ctx->le_pdu, IDM_STATUS_SUCCESS);
487 /*FALLTHROUGH*/
488 case ILE_LOGIN_CONN_ERROR:
489 case ILE_LOGIN_ERROR:
490 login_sm_new_state(ict, ctx, ILS_LOGIN_ERROR);
491 break;
492 default:
493 ASSERT(0);
494 }
495 }
496
497 static void
498 login_sm_responding(iscsit_conn_t *ict, login_event_ctx_t *ctx)
499 {
500 idm_pdu_t *pdu;
501
502 switch (ctx->le_ctx_event) {
503 case ILE_LOGIN_RCV:
504 pdu = ctx->le_pdu;
505 /*
506 * We should only be in "responding" state if we have not
507 * sent the last PDU of a multi-PDU login response sequence.
508 * In that case we expect this received PDU to be an
509 * acknowledgement from the initiator (login PDU with C
510 * bit cleared and no data). If it's the acknowledgement
511 * we are expecting then we send the next PDU in the login
512 * response sequence. Otherwise it's a protocol error and
513 * the login fails.
514 */
515 if (login_sm_validate_ack(ict, pdu) == IDM_STATUS_SUCCESS) {
516 login_sm_send_next_response(ict);
517 } else {
518 login_sm_new_state(ict, ctx, ILS_LOGIN_ERROR);
519 }
520 idm_pdu_complete(pdu, IDM_STATUS_SUCCESS);
521 break;
522 case ILE_LOGIN_FFP:
523 login_sm_new_state(ict, ctx, ILS_LOGIN_FFP);
524 break;
525 case ILE_LOGIN_RESP_COMPLETE:
526 login_sm_new_state(ict, ctx, ILS_LOGIN_RESPONDED);
527 break;
528 case ILE_LOGIN_CONN_ERROR:
529 case ILE_LOGIN_ERROR:
530 login_sm_new_state(ict, ctx, ILS_LOGIN_ERROR);
531 break;
532 default:
533 ASSERT(0);
534 }
535 }
536
537 static void
538 login_sm_responded(iscsit_conn_t *ict, login_event_ctx_t *ctx)
539 {
540 idm_pdu_t *pdu;
541
542 switch (ctx->le_ctx_event) {
543 case ILE_LOGIN_RCV:
544 pdu = ctx->le_pdu;
545 mutex_enter(&ict->ict_login_sm.icl_mutex);
546 list_insert_tail(&ict->ict_login_sm.icl_pdu_list, pdu);
547 mutex_exit(&ict->ict_login_sm.icl_mutex);
548 if (pdu->isp_hdr->flags & ISCSI_FLAG_LOGIN_CONTINUE) {
549 login_sm_send_ack(ict, pdu);
550 login_sm_new_state(ict, ctx, ILS_LOGIN_WAITING);
551 } else {
552 login_sm_new_state(ict, ctx, ILS_LOGIN_PROCESSING);
553 }
554 break;
555 case ILE_LOGIN_CONN_ERROR:
556 case ILE_LOGIN_ERROR:
557 login_sm_new_state(ict, ctx, ILS_LOGIN_ERROR);
558 break;
559 default:
560 ASSERT(0);
561 }
562 }
563
564 static void
565 login_sm_ffp(iscsit_conn_t *ict, login_event_ctx_t *ctx)
566 {
567 switch (ctx->le_ctx_event) {
568 case ILE_LOGIN_RESP_COMPLETE:
569 login_sm_new_state(ict, ctx, ILS_LOGIN_DONE);
570 break;
571 case ILE_LOGIN_CONN_ERROR:
572 login_sm_new_state(ict, ctx, ILS_LOGIN_ERROR);
573 break;
574 default:
575 ASSERT(0);
576 }
577
578 }
579
580 static void
581 login_sm_done(iscsit_conn_t *ict, login_event_ctx_t *ctx)
582 {
583 /* Terminal state, we should get no events */
584 switch (ctx->le_ctx_event) {
585 case ILE_LOGIN_RCV:
586 /*
587 * We've already processed everything we're going to
588 * process. Drop any additional login PDU's.
589 */
590 idm_pdu_complete(ctx->le_pdu, IDM_STATUS_SUCCESS);
591 break;
592 case ILE_LOGIN_CONN_ERROR:
593 /* Don't care */
594 break;
595 default:
596 ASSERT(0);
597 }
598
599 }
600
601 static void
602 login_sm_error(iscsit_conn_t *ict, login_event_ctx_t *ctx)
603 {
604 switch (ctx->le_ctx_event) {
605 case ILE_LOGIN_RCV:
606 /*
607 * We've already processed everything we're going to
608 * process. Drop any additional login PDU's.
609 */
610 idm_pdu_complete(ctx->le_pdu, IDM_STATUS_SUCCESS);
611 break;
612 case ILE_LOGIN_CONN_ERROR:
613 /* Don't care */
614 break;
615 default:
616 ASSERT(0);
617 }
618 }
619
620 static void
621 login_sm_new_state(iscsit_conn_t *ict, login_event_ctx_t *ctx,
622 iscsit_login_state_t new_state)
623 {
624 iscsit_conn_login_t *lsm = &ict->ict_login_sm;
625
626 /*
627 * Validate new state
628 */
629 ASSERT(new_state != ILS_UNDEFINED);
630 ASSERT3U(new_state, <, ILS_MAX_STATE);
631
632 new_state = (new_state < ILS_MAX_STATE) ?
633 new_state : ILS_UNDEFINED;
634
635 cmn_err(CE_NOTE, "login_sm_new_state: conn %p, evt %s (%d), "
636 "%s (%d) --> %s (%d)\n",
637 ict->ict_ic, iscsit_ile_name[ctx->le_ctx_event], ctx->le_ctx_event,
638 iscsit_ils_name[lsm->icl_login_state], lsm->icl_login_state,
639 iscsit_ils_name[new_state], new_state);
640 DTRACE_PROBE3(login__state__change,
641 iscsit_conn_t *, ict, login_event_ctx_t *, ctx,
642 iscsit_login_state_t, new_state);
643
644 mutex_enter(&lsm->icl_mutex);
645 lsm->icl_login_last_state = lsm->icl_login_state;
646 lsm->icl_login_state = new_state;
647 mutex_exit(&lsm->icl_mutex);
648
649 switch (lsm->icl_login_state) {
650 case ILS_LOGIN_WAITING:
651 /* Do nothing, waiting for more login PDU's */
652 break;
653 case ILS_LOGIN_PROCESSING:
654 /* All login PDU's received, process login request */
655 login_sm_process_request(ict);
656 break;
657 case ILS_LOGIN_RESPONDING:
658 login_sm_send_next_response(ict);
659 break;
660 case ILS_LOGIN_RESPONDED:
661 /* Do nothing, waiting for another login request */
662 break;
663 case ILS_LOGIN_FFP:
664 login_sm_ffp_actions(ict);
665 break;
666 case ILS_LOGIN_DONE:
667 case ILS_LOGIN_ERROR:
668 /* Free login SM resources */
669 lsm->icl_login_complete = B_TRUE;
670 break;
671 case ILS_LOGIN_INIT: /* Initial state, can't return */
672 default:
673 ASSERT(0);
674 /*NOTREACHED*/
675 }
676 }
677
678 static void
679 login_sm_abort(iscsit_conn_t *ict)
680 {
681 ASSERT(0); /* XXX */
682 }
683
684 static void
685 login_sm_send_ack(iscsit_conn_t *ict, idm_pdu_t *pdu)
686 {
687 ASSERT(0); /* XXX */
688 }
689
690 static idm_status_t
691 login_sm_validate_ack(iscsit_conn_t *ict, idm_pdu_t *pdu)
692 {
693 ASSERT(0); /* XXX */
694 return (IDM_STATUS_FAIL);
695 }
696
697 static boolean_t
698 login_sm_is_last_response(iscsit_conn_t *ict)
699 {
700 /*
701 * XXX For the prototype we insist that responses fit in a single
702 * PDU so this is always true
703 */
704 return (B_TRUE);
705 }
706
707
708 static void
709 login_sm_handle_initial_login(iscsit_conn_t *ict, idm_pdu_t *pdu)
710 {
711 iscsi_login_hdr_t *lh_req = (iscsi_login_hdr_t *)pdu->isp_hdr;
712 iscsi_login_rsp_hdr_t *lh_resp = (iscsi_login_rsp_hdr_t *)
713 ict->ict_login_sm.icl_login_rej_resp->isp_hdr;
714
715 /*
716 * First login PDU, this connection should not have a sesssion
717 * associated.
718 */
719 ASSERT(ict->ict_sess == NULL);
720
721 /*
722 * Save off TSIH and ISID for later use in finding a session
723 */
724 ict->ict_login_sm.icl_cmdsn = ntohl(lh_req->cmdsn);
725 ict->ict_login_sm.icl_tsih = ntohs(lh_req->tsid);
726 bcopy(lh_req->isid, ict->ict_login_sm.icl_isid, ISCSI_ISID_LEN);
727
728 /*
729 * We'll need the CID as well
730 */
731 ict->ict_cid = ntohs(lh_req->cid);
732
733 /*
734 * Set CSG based on the login PDU. We already validated that
735 * the CSG value is acceptable (for example we're not trying
736 * to go directly to FFP) in login_sm_req_pdu_check().
737 */
738 ict->ict_login_sm.icl_login_csg =
739 ISCSI_LOGIN_CURRENT_STAGE(lh_req->flags);
740 ict->ict_login_sm.icl_login_nsg =
741 ISCSI_LOGIN_NEXT_STAGE(lh_req->flags);
742
743 /*
744 * Initialize header for login reject response. This will also
745 * be copied for use as a template for other login responses
746 */
747 lh_resp->opcode = ISCSI_OP_LOGIN_RSP;
748 lh_resp->max_version = ISCSIT_MAX_VERSION;
749
750 /*
751 * We already validated that we can support one of the initiator's
752 * versions in login_sm_req_pdu_check().
753 */
754 if (ISCSIT_MAX_VERSION >= lh_req->min_version) {
755 lh_resp->active_version =
756 MIN(lh_req->max_version, ISCSIT_MAX_VERSION);
757 } else {
758 ASSERT(ISCSIT_MAX_VERSION <= lh_req->max_version);
759 lh_resp->active_version = ISCSIT_MAX_VERSION;
760 }
761
762 lh_resp->hlength = 0; /* No AHS */
763 bcopy(lh_req->isid, lh_resp->isid, ISCSI_ISID_LEN);
764 lh_resp->tsid = lh_req->tsid;
765 lh_resp->itt = lh_req->itt;
766
767 /*
768 * StatSn, ExpCmdSn and MaxCmdSn will be set immediately before
769 * transmission
770 */
771 }
772
773 static void
774 login_sm_send_next_response(iscsit_conn_t *ict)
775 {
776 idm_pdu_t *pdu = ict->ict_login_sm.icl_login_resp;
777 iscsi_login_rsp_hdr_t *lh_resp = (iscsi_login_rsp_hdr_t *)pdu->isp_hdr;
778
779 /*
780 * XXX For the prototype we insist that responses fit in a single
781 * PDU so "next response" is the only response. What we probably
782 * should do in the final product is to have a single text buffer
783 * that contains the entire formatted response, then use a PDU
784 * to send one segment of that response at a time. The PDU will
785 * be used like a sliding window into the text buffer.
786 */
787
788 /*
789 * Fill in header values
790 */
791 hton24(lh_resp->dlength, pdu->isp_datalen);
792
793 /*
794 * If this is going to be the last PDU of a login response
795 * that moves us to FFP then generate the ILE_LOGIN_FFP event.
796 */
797 if ((lh_resp->flags & ISCSI_FLAG_LOGIN_TRANSIT) &&
798 (ISCSI_LOGIN_NEXT_STAGE(lh_resp->flags) ==
799 ISCSI_FULL_FEATURE_PHASE) &&
800 !(lh_resp->flags & ISCSI_FLAG_LOGIN_CONTINUE)) {
801 iscsit_login_sm_event_locked(ict, ILE_LOGIN_FFP, NULL);
802 }
803
804 iscsit_pdu_tx(ict->ict_login_sm.icl_login_resp);
805 }
806
807 static void
808 login_sm_process_request(iscsit_conn_t *ict)
809 {
810 iscsit_conn_login_t *lsm = &ict->ict_login_sm;
811
812 /*
813 * First walk all the PDU's that make up this login request
814 * and compile all the iSCSI key-value pairs into nvlist format.
815 */
816 if (login_sm_pdu_list_to_nvlist(ict) != IDM_STATUS_SUCCESS) {
817 goto request_fail;
818 }
819
820 if (login_sm_process_nvlist(ict) != IDM_STATUS_SUCCESS) {
821 goto request_fail;
822 }
823
824 if (login_sm_check_security(ict) != IDM_STATUS_SUCCESS) {
825 goto request_fail;
826 }
827
828 /*
829 * This would be a very good time to make sure we have
830 * negotiated the required values for the login phase. For
831 * example we definitely should have defined InitiatorName,
832 * and Target name regardless of our current login phase. These
833 * values should all be on our "negotiated values" list.
834 */
835 if (!ict->ict_op.op_initial_params_set) {
836 if (login_sm_validate_initial_parameters(ict) !=
837 IDM_STATUS_SUCCESS) {
838 goto request_fail;
839 }
840
841 /*
842 * Now setup our session association. This includes
843 * create a new session or looking up an existing session,
844 * and if this is not a discovery session then we will
845 * also register this session with STMF.
846 */
847 if (login_sm_session_bind(ict) != IDM_STATUS_SUCCESS) {
848 goto request_fail;
849 }
850
851 ict->ict_op.op_initial_params_set = B_TRUE;
852 }
853
854 request_fail:
855 if (login_sm_build_login_response(ict) == IDM_STATUS_SUCCESS) {
856 iscsit_login_sm_event(ict, ILE_LOGIN_RESP_READY, NULL);
857 } else {
858 /* Generated "login error" event. State machine will cleanup */
859 /* XXX */
860 cmn_err(CE_NOTE, "login_sm_process_request: %s\n",
861 "failed building login response");
862 ASSERT(0);
863 }
864
865 /* clean up request_nvlist and response_nvlist */
866 if (lsm->icl_request_nvlist != NULL) {
867 nvlist_free(lsm->icl_request_nvlist);
868 lsm->icl_request_nvlist = NULL;
869 }
870 if (lsm->icl_response_nvlist != NULL) {
871 nvlist_free(lsm->icl_response_nvlist);
872 lsm->icl_response_nvlist = NULL;
873 }
874 }
875
876
877 static void
878 login_sm_ffp_actions(iscsit_conn_t *ict)
879 {
880 iscsit_sess_t *ist = ict->ict_sess;
881
882 iscsit_process_negotiated_values(ict);
883 }
884
885 static idm_status_t
886 login_sm_validate_initial_parameters(iscsit_conn_t *ict)
887 {
888 int nvrc;
889 char *string_val;
890 uint8_t error_class = ISCSI_STATUS_CLASS_INITIATOR_ERR;
891 uint8_t error_detail = ISCSI_LOGIN_STATUS_MISSING_FIELDS;
892 idm_status_t status = IDM_STATUS_FAIL;
893 iscsit_conn_login_t *lsm = &ict->ict_login_sm;
894
895 /*
896 * Make sure we received the required information from the initial
897 * login
898 */
899
900 /*
901 * Initiator name and target name
902 */
903 nvrc = nvlist_lookup_string(lsm->icl_negotiated_values,
904 "InitiatorName", &string_val);
905 if (nvrc != 0) {
906 goto initial_params_done;
907 }
908 ASSERT(nvrc == 0); /* Should have caught this earlier */
909
910 lsm->icl_initiator_name = string_val;
911 if ((nvrc = nvlist_lookup_string(lsm->icl_negotiated_values,
912 "SessionType", &string_val)) == ENOENT) {
913 ict->ict_op.op_discovery_session = B_FALSE;
914 } else {
915 ict->ict_op.op_discovery_session =
916 strcmp(string_val, "Discovery") == 0 ? B_TRUE : B_FALSE;
917 }
918
919 /*
920 * Must have either TargetName or SessionType==Discovery
921 */
922 lsm->icl_target_name = NULL;
923 if ((nvrc = nvlist_lookup_string(lsm->icl_negotiated_values,
924 "TargetName", &string_val)) != ENOENT) {
925 lsm->icl_target_name = string_val;
926 } else if (ict->ict_op.op_discovery_session == B_FALSE) {
927 /* Missing target name */
928 goto initial_params_done;
929 }
930
931 /* Sucess */
932 status = IDM_STATUS_SUCCESS;
933 error_class = ISCSI_STATUS_CLASS_SUCCESS;
934 error_detail = ISCSI_LOGIN_STATUS_ACCEPT;
935
936 initial_params_done:
937 SET_LOGIN_ERROR(ict, error_class, error_detail);
938 return (status);
939 }
940
941
942 /*
943 * login_sm_session_bind
944 *
945 * This function looks at the data from the initial login request
946 * of a new connection and either looks up and existing session,
947 * creates a new session, or returns an error. RFC3720 section 5.3.1
948 * defines these rules:
949 *
950 * +------------------------------------------------------------------+
951 * |ISID | TSIH | CID | Target action |
952 * +------------------------------------------------------------------+
953 * |new | non-zero | any | fail the login |
954 * | | | | ("session does not exist") |
955 * +------------------------------------------------------------------+
956 * |new | zero | any | instantiate a new session |
957 * +------------------------------------------------------------------+
958 * |existing | zero | any | do session reinstatement |
959 * | | | | (see section 5.3.5) |
960 * +------------------------------------------------------------------+
961 * |existing | non-zero | new | add a new connection to |
962 * | | existing | | the session |
963 * +------------------------------------------------------------------+
964 * |existing | non-zero |existing| do connection reinstatement|
965 * | | existing | | (see section 5.3.4) |
966 * +------------------------------------------------------------------+
967 * |existing | non-zero | any | fail the login |
968 * | | new | | ("session does not exist") |
969 * +------------------------------------------------------------------+
970 *
971 */
972
973 static idm_status_t
974 login_sm_session_bind(iscsit_conn_t *ict)
975 {
976 iscsit_conn_login_t *lsm = &ict->ict_login_sm;
977 iscsit_tgt_t *tgt = NULL;
978 iscsit_sess_t *sess = NULL;
979 iscsit_sess_t *new_sess = NULL;
980 iscsit_conn_t *existing_ict = NULL;
981 uint8_t error_class;
982 uint8_t error_detail;
983
984 /*
985 * Look up target. If target name is set then we should have
986 * a corresponding target context configured.
987 */
988 if (lsm->icl_target_name != NULL) {
989 tgt = iscsit_tgt_lookup(lsm->icl_target_name);
990 if (tgt == NULL) {
991 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_INITIATOR_ERR,
992 ISCSI_LOGIN_STATUS_TGT_NOT_FOUND);
993 goto session_bind_error;
994 }
995 }
996
997 ASSERT((tgt != NULL) || (ict->ict_op.op_discovery_session == B_TRUE));
998
999 /*
1000 * Check if there is an existing session matching this ISID. If
1001 * tgt == NULL then we'll look for the session on the global list
1002 * of discovery session. If we find a session then the ISID
1003 * exists.
1004 *
1005 * It shouldn't be necessary but as an extra precaution we'll match
1006 * TSIH as well (treating TSIH of 0 as a wildcard). We should not
1007 * have more than one session for the same ISID on a target so any
1008 * session we find should match the TSIH we provide.
1009 */
1010 sess = iscsit_tgt_lookup_sess(tgt, lsm->icl_initiator_name,
1011 lsm->icl_isid, lsm->icl_tsih);
1012 if (sess != NULL) {
1013 existing_ict = iscsit_sess_lookup_conn(sess,
1014 ict->ict_cid);
1015 }
1016
1017 /*
1018 * If this is a discovery session, make sure it has appropriate
1019 * parameters.
1020 */
1021 if ((ict->ict_op.op_discovery_session == B_TRUE) &&
1022 ((lsm->icl_tsih != ISCSI_UNSPEC_TSIH) || (sess != NULL))) {
1023 /* XXX Do we need to check for existing ISID (sess != NULL)? */
1024 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_INITIATOR_ERR,
1025 ISCSI_LOGIN_STATUS_INVALID_REQUEST);
1026 goto session_bind_error;
1027 }
1028
1029 /*
1030 * Check the two error conditions from the table.
1031 *
1032 * ISID=new, TSIH=non-zero
1033 */
1034 if ((sess == NULL) && (lsm->icl_tsih != ISCSI_UNSPEC_TSIH)) {
1035 /* fail the login */
1036 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_INITIATOR_ERR,
1037 ISCSI_LOGIN_STATUS_NO_SESSION);
1038 goto session_bind_error;
1039 }
1040
1041 /* ISID=existing, TSIH=non-zero new */
1042 if ((sess != NULL) && (lsm->icl_tsih != 0) &&
1043 (sess->ist_tsih != lsm->icl_tsih)) {
1044 /* fail the login */
1045 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_INITIATOR_ERR,
1046 ISCSI_LOGIN_STATUS_NO_SESSION);
1047 goto session_bind_error;
1048 }
1049
1050 /*
1051 * Handle the remaining table cases in order
1052 */
1053 if (sess == NULL) {
1054 /* Should have caught this above */
1055 ASSERT(lsm->icl_tsih == ISCSI_UNSPEC_TSIH);
1056 /*
1057 * ISID=new, TSIH=zero --> instantiate a new session
1058 */
1059 new_sess = iscsit_sess_create(tgt, ict, lsm->icl_cmdsn,
1060 lsm->icl_isid, lsm->icl_initiator_name,
1061 lsm->icl_target_name, &error_class, &error_detail);
1062 ASSERT(new_sess != NULL);
1063
1064 /* Session create may have failed even if it returned a value */
1065 if (error_class != ISCSI_STATUS_CLASS_SUCCESS) {
1066 SET_LOGIN_ERROR(ict, error_class, error_detail);
1067 goto session_bind_error;
1068 }
1069
1070 /*
1071 * If we don't already have an STMF session and this is not
1072 * a discovery session then we need to allocate and register
1073 * one.
1074 */
1075 if (!ict->ict_op.op_discovery_session) {
1076 if (login_sm_session_register(ict) !=
1077 IDM_STATUS_SUCCESS) {
1078 /* login_sm_session_register sets error codes */
1079 goto session_bind_error;
1080 }
1081 }
1082
1083 } else {
1084 if (lsm->icl_tsih == ISCSI_UNSPEC_TSIH) {
1085 /*
1086 * ISID=existing, TSIH=zero --> Session reinstatement
1087 */
1088 new_sess = iscsit_sess_reinstate(sess, ict,
1089 &error_class, &error_detail);
1090 ASSERT(new_sess != NULL);
1091
1092 if (error_class != ISCSI_STATUS_CLASS_SUCCESS) {
1093 SET_LOGIN_ERROR(ict, error_class, error_detail);
1094 goto session_bind_error;
1095 }
1096
1097 /*
1098 * If we don't already have an STMF session and this is
1099 * not a discovery session then we need to allocate and
1100 * register one.
1101 */
1102 if (!ict->ict_op.op_discovery_session) {
1103 if (login_sm_session_register(ict) !=
1104 IDM_STATUS_SUCCESS) {
1105 /*
1106 * login_sm_session_register sets
1107 * error codes
1108 */
1109 goto session_bind_error;
1110 }
1111 }
1112 } else {
1113 /*
1114 * The following code covers these two cases:
1115 * ISID=existing, TSIH=non-zero existing, CID=new
1116 * --> add new connection to MC/S session
1117 * ISID=existing, TSIH=non-zero existing, CID=existing
1118 * --> do connection reinstatement
1119 *
1120 * Session continuation uses this path as well
1121 */
1122 cmn_err(CE_NOTE, "login_sm_session_bind: add new "
1123 "conn/sess continue");
1124 if (existing_ict != NULL) {
1125 /*
1126 * ISID=existing, TSIH=non-zero existing,
1127 * CID=existing --> do connection reinstatement
1128 */
1129 if (iscsit_conn_reinstate(existing_ict, ict) !=
1130 IDM_STATUS_SUCCESS) {
1131 /*
1132 * Most likely this means the connection
1133 * the initiator is trying to reinstate
1134 * is not in an acceptable state.
1135 */
1136 SET_LOGIN_ERROR(ict,
1137 ISCSI_STATUS_CLASS_INITIATOR_ERR,
1138 ISCSI_LOGIN_STATUS_INIT_ERR);
1139 goto session_bind_error;
1140 }
1141 }
1142
1143 iscsit_sess_sm_event(sess, SE_CONN_IN_LOGIN, ict);
1144 }
1145 }
1146
1147 return (IDM_STATUS_SUCCESS);
1148
1149 session_bind_error:
1150 /*
1151 * If session bind fails we will fail the login but don't destroy
1152 * the session until later.
1153 */
1154 return (IDM_STATUS_FAIL);
1155 }
1156
1157
1158 static idm_status_t
1159 login_sm_session_register(iscsit_conn_t *ict)
1160 {
1161 iscsit_sess_t *ist = ict->ict_sess;
1162 stmf_scsi_session_t *ss;
1163
1164 ss = stmf_alloc(STMF_STRUCT_SCSI_SESSION, 0,
1165 0);
1166 if (ss == NULL) {
1167 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_TARGET_ERR,
1168 ISCSI_LOGIN_STATUS_NO_RESOURCES);
1169 return (IDM_STATUS_FAIL);
1170 }
1171
1172 ss->ss_rport_id = kmem_zalloc(sizeof (scsi_devid_desc_t) +
1173 strlen(ist->ist_initiator_name) + 1, KM_SLEEP);
1174 strcpy((char *)ss->ss_rport_id->ident, ist->ist_initiator_name);
1175 ss->ss_rport_id->ident_length = strlen(ist->ist_initiator_name);
1176 ss->ss_rport_id->protocol_id = PROTOCOL_iSCSI;
1177 ss->ss_rport_id->piv = 1;
1178 ss->ss_rport_id->code_set = CODE_SET_ASCII;
1179 ss->ss_rport_id->association = ID_IS_TARGET_PORT;
1180
1181 ss->ss_lport = ist->ist_lport;
1182
1183 if (stmf_register_scsi_session(ict->ict_sess->ist_lport, ss) !=
1184 STMF_SUCCESS) {
1185 kmem_free(ss->ss_rport_id,
1186 sizeof (scsi_devid_desc_t) +
1187 strlen(ist->ist_initiator_name) + 1);
1188 stmf_free(ss);
1189 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_TARGET_ERR,
1190 ISCSI_LOGIN_STATUS_TARGET_ERROR);
1191 return (IDM_STATUS_FAIL);
1192 }
1193
1194 ss->ss_port_private = ict->ict_sess;
1195 ict->ict_sess->ist_stmf_sess = ss;
1196
1197 return (IDM_STATUS_SUCCESS);
1198 }
1199
1200
1201 static idm_status_t
1202 login_sm_req_pdu_check(iscsit_conn_t *ict, idm_pdu_t *pdu)
1203 {
1204 uint8_t error_class;
1205 uint8_t error_detail;
1206 uint8_t csg_req;
1207 iscsit_conn_login_t *lsm = &ict->ict_login_sm;
1208 iscsi_login_hdr_t *lh = (iscsi_login_hdr_t *)pdu->isp_hdr;
1209 iscsi_login_rsp_hdr_t *lh_resp =
1210 (iscsi_login_rsp_hdr_t *)lsm->icl_login_rej_resp->isp_hdr;
1211
1212 /*
1213 * Check CSG
1214 */
1215 csg_req = ISCSI_LOGIN_CURRENT_STAGE(lh->flags);
1216 switch (csg_req) {
1217 case ISCSI_SECURITY_NEGOTIATION_STAGE:
1218 case ISCSI_OP_PARMS_NEGOTIATION_STAGE:
1219 if ((csg_req != lsm->icl_login_csg) &&
1220 (lsm->icl_login_state != ILS_LOGIN_INIT)) {
1221 /*
1222 * Inappropriate CSG change. Initiator can only
1223 * change CSG after we've responded with the
1224 * transit bit set. If we had responded with
1225 * a CSG change previous we would have updated
1226 * our copy of CSG.
1227 *
1228 * The exception is when we are in ILS_LOGIN_INIT
1229 * state since we haven't determined our initial
1230 * CSG value yet.
1231 */
1232 error_class = ISCSI_STATUS_CLASS_INITIATOR_ERR;
1233 error_detail = ISCSI_LOGIN_STATUS_INVALID_REQUEST;
1234 goto pdu_check_fail;
1235 }
1236 break;
1237 case ISCSI_FULL_FEATURE_PHASE:
1238 default:
1239 error_class = ISCSI_STATUS_CLASS_INITIATOR_ERR;
1240 error_detail = ISCSI_LOGIN_STATUS_INVALID_REQUEST;
1241 goto pdu_check_fail;
1242 }
1243
1244 /*
1245 * If this is the first login PDU for a new connection then
1246 * the session will be NULL.
1247 */
1248 if (ict->ict_sess != NULL) {
1249 /*
1250 * We've already created a session on a previous PDU. Make
1251 * sure this PDU is consistent with what we've already seen
1252 */
1253 if ((ict->ict_cid != ntohs(lh->cid)) ||
1254 (bcmp(ict->ict_sess->ist_isid, lh->isid,
1255 ISCSI_ISID_LEN) != 0)) {
1256 error_class = ISCSI_STATUS_CLASS_INITIATOR_ERR;
1257 error_detail = ISCSI_LOGIN_STATUS_INIT_ERR;
1258 goto pdu_check_fail;
1259 }
1260 }
1261
1262 /*
1263 * Make sure we are compatible with the version range
1264 */
1265 if ((lh->min_version > ISCSIT_MAX_VERSION) ||
1266 (lh->max_version < ISCSIT_MIN_VERSION)) {
1267 error_class = ISCSI_STATUS_CLASS_INITIATOR_ERR;
1268 error_detail = ISCSI_LOGIN_STATUS_NO_VERSION;
1269 goto pdu_check_fail;
1270 }
1271
1272 /*
1273 * Just in case the initiator changes things up on us along the way
1274 * check against our active_version -- we can't change the active
1275 * version and the initiator is not *supposed* to change its
1276 * min_version and max_version values so this should never happen.
1277 * Of course we only do this if the response header template has
1278 * been built.
1279 */
1280 if ((lh_resp->opcode == ISCSI_OP_LOGIN_RSP) && /* header valid */
1281 ((lh->min_version > lh_resp->active_version) ||
1282 (lh->max_version < lh_resp->active_version))) {
1283 error_class = ISCSI_STATUS_CLASS_INITIATOR_ERR;
1284 error_detail = ISCSI_LOGIN_STATUS_INIT_ERR;
1285 goto pdu_check_fail;
1286 }
1287
1288 return (IDM_STATUS_SUCCESS);
1289
1290 pdu_check_fail:
1291 /* Error status contains login response code */
1292 ASSERT(0); /* build and send login response XXX */
1293 return (IDM_STATUS_FAIL);
1294 }
1295
1296 static idm_status_t
1297 login_sm_pdu_list_to_nvlist(iscsit_conn_t *ict)
1298 {
1299 iscsit_conn_login_t *lsm = &ict->ict_login_sm;
1300 idm_pdu_t *pdu, *next_pdu;
1301 boolean_t split_kv = B_FALSE;
1302 char *textbuf, *leftover_textbuf;
1303 int textbuflen, leftover_textbuflen;
1304 char *split_kvbuf;
1305 int split_kvbuflen, cont_fraglen;
1306 iscsi_login_hdr_t *lh;
1307 boolean_t first_pdu = B_TRUE; /* XXX */
1308 uint8_t error_class = 0;
1309 uint8_t error_detail = 0;
1310 int rc;
1311
1312 /* Allocate a new nvlist for request key/value pairs */
1313 ASSERT(lsm->icl_request_nvlist == NULL);
1314 rc = nvlist_alloc(&lsm->icl_request_nvlist, NV_UNIQUE_NAME,
1315 KM_NOSLEEP);
1316 if (rc != 0) {
1317 error_class = ISCSI_STATUS_CLASS_TARGET_ERR;
1318 error_detail = ISCSI_LOGIN_STATUS_NO_RESOURCES;
1319 goto kvpair_xlate_fail;
1320 }
1321
1322 /*
1323 * A login request can be split across multiple PDU's. The state
1324 * machine has collected all the PDU's that make up this login request
1325 * and assembled them on the "icl_pdu_list" queue. Process each PDU
1326 * and convert the text keywords to nvlist form.
1327 */
1328 pdu = list_head(&lsm->icl_pdu_list);
1329 while (pdu != NULL) {
1330 next_pdu = list_next(&lsm->icl_pdu_list, pdu);
1331
1332 list_remove(&lsm->icl_pdu_list, pdu);
1333
1334 lh = (iscsi_login_hdr_t *)pdu->isp_hdr;
1335
1336 /*
1337 * Set the CSG, NSG and Transit bits based on the first PDU
1338 * in the login sequence. We'll clear the transit bit if
1339 * we encounter any login parameters in the request that
1340 * required an additional login transfer (i.e. no acceptable
1341 * choices in range or we needed to change a boolean
1342 * value from "Yes" to "No").
1343 */
1344 if (first_pdu) {
1345 lsm->icl_login_csg =
1346 ISCSI_LOGIN_CURRENT_STAGE(lh->flags);
1347 lsm->icl_login_nsg =
1348 ISCSI_LOGIN_NEXT_STAGE(lh->flags);
1349 lsm->icl_login_transit =
1350 lh->flags & ISCSI_FLAG_LOGIN_TRANSIT;
1351 first_pdu = B_FALSE;
1352 }
1353
1354 textbuf = (char *)pdu->isp_data;
1355 textbuflen = pdu->isp_datalen;
1356 if (textbuflen == 0) {
1357 /* This shouldn't really happen but it could.. */
1358 pdu = next_pdu;
1359 continue;
1360 }
1361
1362 /*
1363 * If we encountered a split key-value pair on the last
1364 * PDU then handle it now by grabbing the remainder of the
1365 * key-value pair from the next PDU and splicing them
1366 * together. Obviously on the first PDU this will never
1367 * happen.
1368 */
1369 if (split_kv) {
1370 cont_fraglen = iscsi_textbuf_to_firstfraglen(textbuf,
1371 textbuflen);
1372 if (cont_fraglen == pdu->isp_datalen) {
1373 /*
1374 * This key-value pair spans more than two
1375 * PDU's. We don't handle this.
1376 *
1377 * XXX Actually we probably *do* need to handle
1378 * this. And it shouldn't be that difficult
1379 * since we have all the PDU's up front.
1380 * The standard talks about 64k key-value pairs
1381 * but the login PDU's are required to use
1382 * the default "max recv segment size" which is
1383 * 8k. A 64k key-value with thus be spread
1384 * across at least 8 PDU's. We'll do it later..
1385 */
1386 ASSERT(0); /* XXX */
1387
1388 /* XXX Not an error, remove it later */
1389 error_class = ISCSI_STATUS_CLASS_TARGET_ERR;
1390 error_detail = ISCSI_LOGIN_STATUS_TARGET_ERROR;
1391 goto kvpair_xlate_fail;
1392 }
1393
1394 split_kvbuflen = leftover_textbuflen + cont_fraglen;
1395 split_kvbuf = kmem_alloc(split_kvbuflen, KM_NOSLEEP);
1396 if (split_kvbuf == NULL) {
1397 error_class = ISCSI_STATUS_CLASS_TARGET_ERR;
1398 error_detail = ISCSI_LOGIN_STATUS_NO_RESOURCES;
1399 goto kvpair_xlate_fail;
1400 }
1401
1402 bcopy(leftover_textbuf, split_kvbuf,
1403 leftover_textbuflen);
1404 bcopy(textbuf,
1405 (uint8_t *)split_kvbuf + leftover_textbuflen,
1406 cont_fraglen);
1407
1408
1409 if (iscsi_textbuf_to_nvlist(lsm->icl_request_nvlist,
1410 &split_kvbuf, &split_kvbuflen) != 0) {
1411 /*
1412 * Need to handle E2BIG case, indicating that
1413 * a key-value pair is split across multiple
1414 * PDU's.
1415 */
1416 ASSERT(0); /* XXX */
1417
1418 error_class = ISCSI_STATUS_CLASS_TARGET_ERR;
1419 error_detail = ISCSI_LOGIN_STATUS_TARGET_ERROR;
1420 goto kvpair_xlate_fail;
1421 }
1422
1423 ASSERT(split_kvbuflen != NULL);
1424 kmem_free(split_kvbuf, split_kvbuflen);
1425
1426 /* Now handle the remainder of the PDU as normal */
1427 textbuf += (cont_fraglen + 1);
1428 textbuflen -= (cont_fraglen + 1);
1429 }
1430
1431 /*
1432 * Convert each key-value pair in the text buffer to nvlist
1433 * format. If the list has already been created the nvpair
1434 * elements will be added on to the existing list. Otherwise
1435 * a new nvlist will be created.
1436 */
1437 if (iscsi_textbuf_to_nvlist(lsm->icl_request_nvlist,
1438 &textbuf, &textbuflen) != 0) {
1439 ASSERT(0); /* XXX */
1440
1441 error_class = ISCSI_STATUS_CLASS_TARGET_ERR;
1442 error_detail = ISCSI_LOGIN_STATUS_TARGET_ERROR;
1443 goto kvpair_xlate_fail;
1444 }
1445
1446 ASSERT(
1447 ((lh->flags & ISCSI_FLAG_LOGIN_CONTINUE) &
1448 (next_pdu != NULL)) |
1449 (!(lh->flags & ISCSI_FLAG_LOGIN_CONTINUE) &
1450 (next_pdu == NULL)));
1451
1452 if ((lh->flags & ISCSI_FLAG_LOGIN_CONTINUE) &
1453 (textbuflen != 0)) {
1454 /*
1455 * Key-value pair is split over two PDU's. We
1456 * assume it willl never be split over more than
1457 * two PDU's.
1458 */
1459 split_kv = B_TRUE;
1460 leftover_textbuf = textbuf;
1461 leftover_textbuflen = textbuflen;
1462 } else {
1463 split_kv = B_FALSE;
1464 if (textbuflen != 0) {
1465 /*
1466 * Incomplete keyword but no additional
1467 * PDU's. This is a malformed login
1468 * request.
1469 */
1470 ASSERT(0); /* XXX */
1471
1472 error_class = ISCSI_STATUS_CLASS_INITIATOR_ERR;
1473 error_detail =
1474 ISCSI_LOGIN_STATUS_INVALID_REQUEST;
1475 goto kvpair_xlate_fail;
1476 }
1477 }
1478
1479 pdu = next_pdu;
1480 }
1481
1482 /*
1483 * At this point we should have a complete nvlist representing
1484 * all the iSCSI key-value pairs in the login request PDU's
1485 * that make up this request.
1486 */
1487
1488 return (IDM_STATUS_SUCCESS);
1489
1490 kvpair_xlate_fail:
1491 if (error_class != 0) {
1492 SET_LOGIN_ERROR(ict, error_class, error_detail);
1493 }
1494 return (IDM_STATUS_FAIL);
1495 }
1496
1497
1498 static idm_status_t
1499 login_sm_process_nvlist(iscsit_conn_t *ict)
1500 {
1501 iscsit_conn_login_t *lsm = &ict->ict_login_sm;
1502 char *nvp_name;
1503 data_type_t nvp_type;
1504 nvpair_t *nvp;
1505 nvpair_t *next_nvp;
1506 nvpair_t *negotiated_nvp;
1507 int nvrc, rc;
1508 kv_status_t kvrc;
1509 uint8_t error_class;
1510 uint8_t error_detail;
1511 idm_status_t idm_status;
1512
1513 error_class = ISCSI_STATUS_CLASS_SUCCESS;
1514 error_detail = ISCSI_LOGIN_STATUS_ACCEPT;
1515
1516 /* Allocate a new nvlist for response key/value pairs */
1517 ASSERT(lsm->icl_response_nvlist == NULL);
1518 rc = nvlist_alloc(&lsm->icl_response_nvlist, NV_UNIQUE_NAME,
1519 KM_NOSLEEP);
1520 if (rc != 0) {
1521 error_class = ISCSI_STATUS_CLASS_TARGET_ERR;
1522 error_detail = ISCSI_LOGIN_STATUS_NO_RESOURCES;
1523 goto process_nvlist_done;
1524 }
1525
1526 nvp = nvlist_next_nvpair(lsm->icl_request_nvlist, NULL);
1527 while (nvp != NULL) {
1528 next_nvp = nvlist_next_nvpair(lsm->icl_request_nvlist, nvp);
1529 nvp_name = nvpair_name(nvp);
1530 nvp_type = nvpair_type(nvp);
1531 /*
1532 * If we've already agreed upon a value then make sure this
1533 * is not attempting to change that value. From RFC3270
1534 * section 5.3:
1535 *
1536 * "Neither the initiator nor the target should attempt to
1537 * declare or negotiate a parameter more than once during
1538 * login except for responses to specific keys that
1539 * explicitly allow repeated key declarations (e.g.,
1540 * TargetAddress). An attempt to renegotiate/redeclare
1541 * parameters not specifically allowed MUST be detected
1542 * by the initiator and target. If such an attempt is
1543 * detected by the target, the target MUST respond
1544 * with Login reject (initiator error); ..."
1545 */
1546 if (nvlist_lookup_nvpair(lsm->icl_negotiated_values,
1547 nvp_name, &negotiated_nvp) == 0) {
1548 /*
1549 * OK, we've already negotiated a value for this.
1550 * If the new value is the same value then everything's
1551 * OK. If the new value is different then we have
1552 * to reject the login (section 5.3 of rfc3270, last
1553 * paragraph)
1554 */
1555 if (iscsi_nvpair_cmp(nvp, negotiated_nvp) != 0) {
1556 kvrc = KV_VALUE_ERROR; /* initiator error */
1557 } else {
1558 kvrc = KV_HANDLED; /* silently ignore it */
1559 }
1560 } else {
1561 kvrc = iscsit_handle_key(ict, nvp, nvp_name);
1562 }
1563
1564 iscsi_kvstat_to_error(kvrc, &error_class, &error_detail);
1565 if (error_class != ISCSI_STATUS_CLASS_SUCCESS) {
1566 break;
1567 }
1568
1569 nvp = next_nvp;
1570 }
1571
1572 process_nvlist_done:
1573 if (error_class == ISCSI_STATUS_CLASS_SUCCESS) {
1574 idm_status = IDM_STATUS_SUCCESS;
1575 } else {
1576 /* supply login class/detail for login errors */
1577 SET_LOGIN_ERROR(ict, error_class, error_detail);
1578 idm_status = IDM_STATUS_FAIL;
1579 }
1580
1581 return (idm_status);
1582 }
1583
1584 static idm_status_t
1585 login_sm_check_security(iscsit_conn_t *ict)
1586 {
1587 iscsit_conn_login_t *lsm = &ict->ict_login_sm;
1588 kv_status_t kvrc;
1589 uint8_t error_class;
1590 uint8_t error_detail;
1591 idm_status_t idm_status;
1592
1593 error_class = ISCSI_STATUS_CLASS_SUCCESS;
1594 error_detail = ISCSI_LOGIN_STATUS_ACCEPT;
1595
1596 /* Check authentication status. */
1597 if (lsm->icl_login_csg == ISCSI_SECURITY_NEGOTIATION_STAGE) {
1598 /*
1599 * We should have some authentication key/value pair(s)
1600 * received from initiator and the authentication phase
1601 * has been shifted when the key/value pair(s) are being
1602 * handled in the previous call iscsit_handle_security_key.
1603 * Now it turns to target to check the authentication phase
1604 * and shift it after taking some authentication action.
1605 */
1606 kvrc = iscsit_reply_security_key(ict);
1607 iscsi_kvstat_to_error(kvrc, &error_class, &error_detail);
1608 } else if (!ict->ict_login_sm.icl_auth_pass) {
1609 /*
1610 * XXX check access.
1611 * This is just a temporary workaround -- obviously
1612 * in the long run we can't take this approach since the target
1613 * may be configurerd to require authentication.
1614 */
1615 ict->ict_login_sm.icl_auth_pass = 1;
1616 }
1617
1618 if (error_class == ISCSI_STATUS_CLASS_SUCCESS) {
1619 idm_status = IDM_STATUS_SUCCESS;
1620 } else {
1621 /* supply login class/detail for login errors */
1622 SET_LOGIN_ERROR(ict, error_class, error_detail);
1623 idm_status = IDM_STATUS_FAIL;
1624 }
1625
1626 return (idm_status);
1627 }
1628
1629 static idm_status_t
1630 login_sm_build_login_response(iscsit_conn_t *ict)
1631 {
1632 iscsit_conn_login_t *lsm = &ict->ict_login_sm;
1633 iscsi_login_rsp_hdr_t *lh;
1634 int rc;
1635
1636 char *nvp_name;
1637 data_type_t nvp_type;
1638 nvpair_t *nvp;
1639 nvpair_t *next_nvp;
1640 int nvrc;
1641
1642 idm_status_t idm_status = IDM_STATUS_SUCCESS;
1643
1644 /*
1645 * XXX In the future we need to implement the following process
1646 * for the response:
1647 *
1648 * 1. Calculate the required text buffer space to hold the
1649 * response key-value pairs.
1650 * 2. Allocate a text buffer for those responses.
1651 * 3. Convert the nvlist values into key-value pairs
1652 * 4. Build a PDU to transmit the first login response PDU
1653 * 5. If there is more data, wait for an ack then goto step 4.
1654 *
1655 */
1656 if (lsm->icl_login_resp == NULL) {
1657 lsm->icl_login_resp = idm_pdu_alloc(sizeof (iscsi_hdr_t), 0);
1658 idm_pdu_init(lsm->icl_login_resp, ict->ict_ic, ict,
1659 login_resp_complete_cb);
1660
1661 /*
1662 * Use the BHS header values from the response template
1663 */
1664 bcopy(lsm->icl_login_rej_resp->isp_hdr,
1665 lsm->icl_login_resp->isp_hdr, sizeof (iscsi_hdr_t));
1666 }
1667
1668 lh = (iscsi_login_rsp_hdr_t *)lsm->icl_login_resp->isp_hdr;
1669
1670 /* Set error class/detail */
1671 lh->status_class = lsm->icl_login_resp_err_class;
1672 lh->status_detail = lsm->icl_login_resp_err_detail;
1673
1674 /* Set CSG, NSG and Transit */
1675 lh->flags = 0;
1676 lh->flags |= lsm->icl_login_csg << 2;
1677 if (lh->status_class == ISCSI_STATUS_CLASS_SUCCESS) {
1678 if (lsm->icl_login_transit &&
1679 lsm->icl_auth_pass != 0) {
1680 lh->flags |= lsm->icl_login_nsg;
1681 lh->flags |= ISCSI_FLAG_LOGIN_TRANSIT;
1682 lsm->icl_login_csg = lsm->icl_login_nsg;
1683 /* If we are transitioning to FFP then set TSIH */
1684 if (lsm->icl_login_csg == ISCSI_FULL_FEATURE_PHASE) {
1685 lh->tsid = htons(ict->ict_sess->ist_tsih);
1686 }
1687 }
1688
1689 rc = iscsi_nvlist_to_textbuf(lsm->icl_response_nvlist,
1690 &lsm->icl_login_resp_buf,
1691 &lsm->icl_login_resp_len,
1692 &lsm->icl_login_resp_valid_len);
1693 if (rc != 0) {
1694 idm_status = IDM_STATUS_FAIL;
1695 } else {
1696 lsm->icl_login_resp->isp_data =
1697 (uint8_t *)lsm->icl_login_resp_buf;
1698 lsm->icl_login_resp->isp_datalen =
1699 lsm->icl_login_resp_valid_len;
1700 }
1701 } else {
1702 lsm->icl_login_resp->isp_data = 0;
1703 lsm->icl_login_resp->isp_datalen = 0;
1704 }
1705
1706 return (idm_status);
1707 }
1708
1709 static kv_status_t
1710 iscsit_handle_key(iscsit_conn_t *ict, nvpair_t *nvp, char *nvp_name)
1711 {
1712 iscsit_conn_login_t *lsm = &ict->ict_login_sm;
1713 kv_status_t kvrc;
1714 const iscsi_kv_xlate_t *ikvx;
1715
1716 ikvx = iscsi_lookup_kv_xlate(nvp_name, strlen(nvp_name));
1717 if (ikvx->ik_key_id == KI_MAX_KEY) {
1718 /*
1719 * Any key not understood by the acceptor may be igonred
1720 * by the acceptor without affecting the basic function.
1721 * However, the answer for a key not understood MUST be
1722 * key=NotUnderstood.
1723 */
1724 kvrc = iscsit_reply_constant(ict, nvp_name,
1725 ISCSI_TEXT_NOTUNDERSTOOD);
1726 } else {
1727 kvrc = iscsit_handle_common_key(ict, nvp, ikvx);
1728 if (kvrc == KV_UNHANDLED) {
1729 switch (lsm->icl_login_csg) {
1730 case ISCSI_SECURITY_NEGOTIATION_STAGE:
1731 kvrc = iscsit_handle_security_key(
1732 ict, nvp, ikvx);
1733 break;
1734 case ISCSI_OP_PARMS_NEGOTIATION_STAGE:
1735 kvrc = iscsit_handle_operational_key(
1736 ict, nvp, ikvx);
1737 break;
1738 case ISCSI_FULL_FEATURE_PHASE:
1739 default:
1740 /* What are we doing here? */
1741 ASSERT(0);
1742 kvrc = KV_UNHANDLED;
1743 }
1744 }
1745 }
1746
1747 return (kvrc);
1748 }
1749
1750 static kv_status_t
1751 iscsit_handle_common_key(iscsit_conn_t *ict, nvpair_t *nvp,
1752 const iscsi_kv_xlate_t *ikvx)
1753 {
1754 iscsit_conn_login_t *lsm = &ict->ict_login_sm;
1755 kv_status_t kvrc;
1756 char *string_val;
1757 uint8_t *binary_val;
1758 int binary_val_len;
1759 int nvrc;
1760
1761 switch (ikvx->ik_key_id) {
1762 case KI_INITIATOR_NAME:
1763 case KI_INITIATOR_ALIAS:
1764 nvrc = nvlist_add_nvpair(lsm->icl_negotiated_values, nvp);
1765 kvrc = iscsi_nvstat_to_kvstat(nvrc);
1766 break;
1767 case KI_TARGET_NAME:
1768 /* We'll validate the target during login_sm_session_bind() */
1769 nvrc = nvpair_value_string(nvp, &string_val);
1770 ASSERT(nvrc == 0); /* We built this nvlist */
1771
1772 nvrc = nvlist_add_nvpair(lsm->icl_negotiated_values, nvp);
1773 kvrc = iscsi_nvstat_to_kvstat(nvrc);
1774 break;
1775 case KI_TARGET_ALIAS:
1776 case KI_TARGET_ADDRESS:
1777 case KI_TARGET_PORTAL_GROUP_TAG:
1778 kvrc = KV_TARGET_ONLY; /* Only the target can declare this */
1779 break;
1780 case KI_SESSION_TYPE:
1781 /*
1782 * If we don't receive this key on the initial login
1783 * we assume this is a normal session.
1784 */
1785 nvrc = nvlist_add_nvpair(lsm->icl_negotiated_values, nvp);
1786 kvrc = iscsi_nvstat_to_kvstat(nvrc);
1787 nvrc = nvpair_value_string(nvp, &string_val);
1788 ASSERT(nvrc == 0); /* We built this nvlist */
1789 ict->ict_op.op_discovery_session =
1790 strcmp(string_val, "Discovery") == 0 ? B_TRUE : B_FALSE;
1791 break;
1792 default:
1793 /*
1794 * This is not really an error but we should
1795 * leave this nvpair on the list since we
1796 * didn't do anything with it. Either
1797 * the security or operational phase
1798 * handling functions should process it.
1799 */
1800 kvrc = KV_UNHANDLED;
1801 break;
1802 }
1803
1804 return (kvrc);
1805 }
1806
1807 static kv_status_t
1808 iscsit_handle_security_key(iscsit_conn_t *ict, nvpair_t *nvp,
1809 const iscsi_kv_xlate_t *ikvx)
1810 {
1811 iscsit_conn_login_t *lsm = &ict->ict_login_sm;
1812 iscsit_auth_client_t *client = &lsm->icl_auth_client;
1813 iscsikey_id_t kv_id;
1814 kv_status_t kvrc;
1815 iscsit_auth_handler_t handler;
1816
1817 /*
1818 * After all of security keys are handled, this function will
1819 * be called again to verify current authentication status
1820 * and perform some actual authentication work. At this time,
1821 * the nvp and ikvx will be passed in as NULLs.
1822 */
1823 if (ikvx != NULL) {
1824 kv_id = ikvx->ik_key_id;
1825 } else {
1826 kv_id = 0;
1827 }
1828
1829 handler = iscsit_auth_get_handler(client, kv_id);
1830 if (handler) {
1831 kvrc = handler(ict, nvp, ikvx);
1832 } else {
1833 kvrc = KV_UNHANDLED; /* invalid request */
1834 }
1835
1836 return (kvrc);
1837 }
1838
1839 static kv_status_t
1840 iscsit_reply_security_key(iscsit_conn_t *ict)
1841 {
1842 return (iscsit_handle_security_key(ict, NULL, NULL));
1843 }
1844
1845 static kv_status_t
1846 iscsit_handle_operational_key(iscsit_conn_t *ict, nvpair_t *nvp,
1847 const iscsi_kv_xlate_t *ikvx)
1848 {
1849 iscsit_conn_login_t *lsm = &ict->ict_login_sm;
1850 kv_status_t kvrc = KV_UNHANDLED;
1851 nvpair_t *lov_nvpair;
1852 char *string_val;
1853 boolean_t bool_val;
1854 uint64_t num_val;
1855 int nvrc;
1856
1857 /*
1858 * Retrieve values. All value lookups are expected to succeed
1859 * since we build the nvlist while decoding the text buffer. This
1860 * step is intended to eliminate some duplication of code (for example
1861 * we only need to code the numerical value lookup once). We will
1862 * handle the values (if necessary) below.
1863 */
1864 switch (ikvx->ik_key_id) {
1865 /* Lists */
1866 case KI_HEADER_DIGEST:
1867 case KI_DATA_DIGEST:
1868 break;
1869 /* Booleans */
1870 case KI_INITIAL_R2T:
1871 case KI_IMMEDIATE_DATA:
1872 case KI_DATA_PDU_IN_ORDER:
1873 case KI_DATA_SEQUENCE_IN_ORDER:
1874 case KI_IFMARKER:
1875 case KI_OFMARKER:
1876 nvrc = nvpair_value_boolean_value(nvp, &bool_val);
1877 ASSERT(nvrc == 0); /* We built this nvlist */
1878 break;
1879 /* Numericals */
1880 case KI_MAX_CONNECTIONS:
1881 case KI_MAX_RECV_DATA_SEGMENT_LENGTH:
1882 case KI_MAX_BURST_LENGTH:
1883 case KI_FIRST_BURST_LENGTH:
1884 case KI_DEFAULT_TIME_2_WAIT:
1885 case KI_DEFAULT_TIME_2_RETAIN:
1886 case KI_MAX_OUTSTANDING_R2T:
1887 case KI_ERROR_RECOVERY_LEVEL:
1888 nvrc = nvpair_value_uint64(nvp, &num_val);
1889 ASSERT(nvrc == 0);
1890 break;
1891 /* Ranges */
1892 case KI_OFMARKERINT:
1893 case KI_IFMARKERINT:
1894 break;
1895 default:
1896 break;
1897 }
1898
1899 /*
1900 * Now handle the values according to the key name. Sometimes we
1901 * don't care what the value is -- in that case we just add the nvpair
1902 * to the negotiated values list.
1903 */
1904 switch (ikvx->ik_key_id) {
1905 case KI_HEADER_DIGEST:
1906 kvrc = iscsit_handle_digest(ict, nvp, ikvx);
1907 break;
1908 case KI_DATA_DIGEST:
1909 kvrc = iscsit_handle_digest(ict, nvp, ikvx);
1910 break;
1911 case KI_INITIAL_R2T:
1912 /* We *require* INITIAL_R2T=yes */
1913 kvrc = iscsit_handle_boolean(ict, nvp, bool_val, ikvx,
1914 B_TRUE);
1915 break;
1916 case KI_IMMEDIATE_DATA:
1917 #ifdef LATER
1918 /* We allow any value for IMMEDIATE_DATA */
1919 kvrc = iscsit_handle_boolean(ict, nvp, bool_val, ikvx,
1920 bool_val);
1921 #else
1922 /*
1923 * For now we *require* IMMEDIATE_DATA=no. Need to figure
1924 * out how this works in STMF-land.
1925 */
1926 kvrc = iscsit_handle_boolean(ict, nvp, bool_val, ikvx,
1927 B_FALSE);
1928 #endif
1929 break;
1930 case KI_DATA_PDU_IN_ORDER:
1931 kvrc = iscsit_handle_boolean(ict, nvp, bool_val, ikvx,
1932 B_TRUE);
1933 break;
1934 case KI_DATA_SEQUENCE_IN_ORDER:
1935 /* We allow any value for DATA_SEQUENCE_IN_ORDER */
1936 kvrc = iscsit_handle_boolean(ict, nvp, bool_val, ikvx,
1937 bool_val);
1938 break;
1939 case KI_OFMARKER:
1940 case KI_IFMARKER:
1941 /* We don't support markers */
1942 kvrc = iscsit_handle_boolean(ict, nvp, bool_val, ikvx,
1943 B_FALSE);
1944 break;
1945 case KI_MAX_CONNECTIONS:
1946 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx,
1947 ISCSI_MIN_CONNECTIONS,
1948 ISCSI_MAX_CONNECTIONS,
1949 ISCSIT_MAX_CONNECTIONS);
1950 break;
1951 case KI_MAX_RECV_DATA_SEGMENT_LENGTH:
1952 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx,
1953 ISCSI_MIN_RECV_DATA_SEGMENT_LENGTH,
1954 ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH,
1955 ISCSIT_MAX_RECV_DATA_SEGMENT_LENGTH);
1956 break;
1957 case KI_MAX_BURST_LENGTH:
1958 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx,
1959 ISCSI_MIN_MAX_BURST_LENGTH,
1960 ISCSI_MAX_BURST_LENGTH,
1961 ISCSIT_MAX_BURST_LENGTH);
1962 break;
1963 case KI_FIRST_BURST_LENGTH:
1964 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx,
1965 ISCSI_MIN_FIRST_BURST_LENGTH,
1966 ISCSI_MAX_FIRST_BURST_LENGTH,
1967 ISCSIT_MAX_FIRST_BURST_LENGTH);
1968 break;
1969 case KI_DEFAULT_TIME_2_WAIT:
1970 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx,
1971 ISCSI_MIN_TIME2WAIT,
1972 ISCSI_MAX_TIME2WAIT,
1973 ISCSIT_MAX_TIME2WAIT);
1974 break;
1975 case KI_DEFAULT_TIME_2_RETAIN:
1976 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx,
1977 ISCSI_MIN_TIME2RETAIN,
1978 ISCSI_MAX_TIME2RETAIN,
1979 ISCSIT_MAX_TIME2RETAIN);
1980 break;
1981 case KI_MAX_OUTSTANDING_R2T:
1982 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx,
1983 ISCSI_MIN_MAX_OUTSTANDING_R2T,
1984 ISCSI_MAX_OUTSTANDING_R2T,
1985 ISCSIT_MAX_OUTSTANDING_R2T);
1986 break;
1987 case KI_ERROR_RECOVERY_LEVEL:
1988 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx,
1989 ISCSI_MIN_ERROR_RECOVERY_LEVEL,
1990 ISCSI_MAX_ERROR_RECOVERY_LEVEL,
1991 ISCSIT_MAX_ERROR_RECOVERY_LEVEL);
1992 break;
1993 case KI_OFMARKERINT:
1994 case KI_IFMARKERINT:
1995 kvrc = iscsit_reply_constant(ict, ikvx->ik_key_name,
1996 ISCSI_TEXT_IRRELEVANT);
1997 break;
1998 default:
1999 kvrc = KV_UNHANDLED; /* invalid request */
2000 break;
2001 }
2002
2003 return (kvrc);
2004 }
2005
2006 static kv_status_t
2007 iscsit_reply_constant(iscsit_conn_t *ict,
2008 const char *nvp_name, const char *text)
2009 {
2010 iscsit_conn_login_t *lsm = &ict->ict_login_sm;
2011 kv_status_t kvrc;
2012 int nvrc;
2013
2014 nvrc = nvlist_add_string(lsm->icl_response_nvlist,
2015 nvp_name, text);
2016 kvrc = iscsi_nvstat_to_kvstat(nvrc);
2017
2018 return (kvrc);
2019 }
2020
2021 /* XXX Ugh. This needs to be revisited */
2022 static kv_status_t
2023 iscsit_handle_digest(iscsit_conn_t *ict, nvpair_t *choices,
2024 const iscsi_kv_xlate_t *ikvx)
2025 {
2026 iscsit_conn_login_t *lsm = &ict->ict_login_sm;
2027 kv_status_t kvrc = KV_VALUE_ERROR;
2028 int nvrc;
2029 nvpair_t *digest_choice;
2030 nvpair_t *digest_response;
2031 char *digest_type_string;
2032 char *digest_choice_string;
2033
2034 /*
2035 * XXX Need to add persistent config here if we want users to allow
2036 * disabling of digests on the target side. You could argue that
2037 * this makes things too complicated... just let the initiator state
2038 * what it wants and we'll take it. For now that's exactly what
2039 * we'll do.
2040 */
2041 digest_choice = iscsi_get_next_listvalue(choices, NULL);
2042
2043 /*
2044 * Loop through all choices. As soon as we find a choice
2045 * that we support add the value to our negotiated values list
2046 * and respond with that value in the login response.
2047 */
2048 while (digest_choice != NULL) {
2049 nvrc = nvpair_value_string(digest_choice,
2050 &digest_choice_string);
2051 ASSERT(nvrc == 0);
2052
2053 /*
2054 * XXX no crc32c for now. Digest calculation is done in
2055 * IDM and we don't have the interface in place to tell
2056 * IDM to calculate digests.
2057 */
2058 #ifdef LATER
2059 if ((strcasecmp(digest_choice, "crc32c") == 0) ||
2060 (strcasecmp(digest_choice_string, "none") == 0)) {
2061 } /* removeme, don't break bracket-matching */
2062 #else
2063 if (strcasecmp(digest_choice_string, "none") == 0) {
2064 #endif
2065 /* Add to negotiated values list */
2066 nvrc = nvlist_add_string(lsm->icl_negotiated_values,
2067 ikvx->ik_key_name, digest_choice_string);
2068 kvrc = iscsi_nvstat_to_kvstat(nvrc);
2069 if (nvrc == 0) {
2070 /* Add to login response list */
2071 nvrc = nvlist_add_string(
2072 lsm->icl_response_nvlist,
2073 ikvx->ik_key_name, digest_choice_string);
2074 kvrc = iscsi_nvstat_to_kvstat(nvrc);
2075 }
2076 break;
2077 }
2078 digest_choice = iscsi_get_next_listvalue(choices,
2079 digest_choice);
2080 }
2081
2082 /*
2083 * XXX
2084 * Would the initiator ever specify only crc32c? We can avoid issues
2085 * as long as we support both (which we will but not in the prototype.)
2086 */
2087
2088 return (kvrc);
2089 }
2090
2091
2092 static kv_status_t
2093 iscsit_handle_boolean(iscsit_conn_t *ict, nvpair_t *nvp, boolean_t value,
2094 const iscsi_kv_xlate_t *ikvx, boolean_t iscsit_value)
2095 {
2096 iscsit_conn_login_t *lsm = &ict->ict_login_sm;
2097 kv_status_t kvrc;
2098 int nvrc;
2099
2100 if (value != iscsit_value) {
2101 /* Respond back to initiator with our value */
2102 value = iscsit_value;
2103 lsm->icl_login_transit = B_FALSE;
2104 nvrc = 0;
2105 } else {
2106 /* Add this to our negotiated values */
2107 nvrc = nvlist_add_nvpair(lsm->icl_negotiated_values,
2108 nvp);
2109 }
2110
2111 /* Response of Simple-value Negotiation */
2112 if (nvrc == 0 && !ikvx->ik_declarative) {
2113 nvrc = nvlist_add_boolean_value(
2114 lsm->icl_response_nvlist, ikvx->ik_key_name, value);
2115 }
2116 kvrc = iscsi_nvstat_to_kvstat(nvrc);
2117
2118 return (kvrc);
2119 }
2120
2121 static kv_status_t
2122 iscsit_handle_numerical(iscsit_conn_t *ict, nvpair_t *nvp, uint64_t value,
2123 const iscsi_kv_xlate_t *ikvx,
2124 uint64_t iscsi_min_value, uint64_t iscsi_max_value,
2125 uint64_t iscsit_max_value)
2126 {
2127 iscsit_conn_login_t *lsm = &ict->ict_login_sm;
2128 kv_status_t kvrc;
2129 int nvrc;
2130
2131 /* Validate against standard */
2132 if ((value < iscsi_min_value) || (value > iscsi_max_value)) {
2133 kvrc = KV_VALUE_ERROR;
2134 } else {
2135 if (value > iscsit_max_value) {
2136 /* Respond back to initiator with our value */
2137 value = iscsit_max_value;
2138 lsm->icl_login_transit = B_FALSE;
2139 nvrc = 0;
2140 } else {
2141 /* Add this to our negotiated values */
2142 nvrc = nvlist_add_nvpair(lsm->icl_negotiated_values,
2143 nvp);
2144 }
2145
2146 /* Response of Simple-value Negotiation */
2147 if (nvrc == 0 && !ikvx->ik_declarative) {
2148 nvrc = nvlist_add_uint64(lsm->icl_response_nvlist,
2149 ikvx->ik_key_name, value);
2150 }
2151 kvrc = iscsi_nvstat_to_kvstat(nvrc);
2152 }
2153
2154 return (kvrc);
2155 }
2156
2157
2158 static void
2159 iscsit_process_negotiated_values(iscsit_conn_t *ict)
2160 {
2161 iscsit_conn_login_t *lsm = &ict->ict_login_sm;
2162 char *string_val;
2163 boolean_t boolean_val;
2164 uint64_t uint64_val;
2165 int nvrc;
2166 kv_status_t kvrc;
2167
2168 /*
2169 * Initiator alias and target alias
2170 */
2171 if ((nvrc = nvlist_lookup_string(lsm->icl_negotiated_values,
2172 "InitiatorAlias", &string_val)) != ENOENT) {
2173 ASSERT(nvrc == 0);
2174 ict->ict_sess->ist_initiator_alias =
2175 kmem_alloc(strlen(string_val) + 1, KM_SLEEP);
2176 strcpy(ict->ict_sess->ist_initiator_alias, string_val);
2177 }
2178
2179 if ((nvrc = nvlist_lookup_string(lsm->icl_negotiated_values,
2180 "TargetAlias", &string_val)) != ENOENT) {
2181 ASSERT(nvrc == 0);
2182 ict->ict_sess->ist_target_alias =
2183 kmem_alloc(strlen(string_val) + 1, KM_SLEEP);
2184 strcpy(ict->ict_sess->ist_target_alias, string_val);
2185 }
2186
2187 /*
2188 * Operational parameters. We process SessionType when it is
2189 * initially received since it is required on the initial login.
2190 */
2191 if ((nvrc = nvlist_lookup_boolean_value(lsm->icl_negotiated_values,
2192 "InitialR2T", &boolean_val)) != ENOENT) {
2193 ASSERT(nvrc == 0);
2194 ict->ict_op.op_initial_r2t = boolean_val;
2195 }
2196
2197 if ((nvrc = nvlist_lookup_boolean_value(lsm->icl_negotiated_values,
2198 "ImmediateData", &boolean_val)) != ENOENT) {
2199 ASSERT(nvrc == 0);
2200 ict->ict_op.op_immed_data = boolean_val;
2201 }
2202
2203 if ((nvrc = nvlist_lookup_boolean_value(lsm->icl_negotiated_values,
2204 "DataPDUInOrder", &boolean_val)) != ENOENT) {
2205 ASSERT(nvrc == 0);
2206 ict->ict_op.op_data_pdu_in_order = boolean_val;
2207 }
2208
2209 if ((nvrc = nvlist_lookup_boolean_value(lsm->icl_negotiated_values,
2210 "DataSequenceInOrder", &boolean_val)) != ENOENT) {
2211 ASSERT(nvrc == 0);
2212 ict->ict_op.op_data_sequence_in_order = boolean_val;
2213 }
2214
2215 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values,
2216 "MaxConnections", &uint64_val)) != ENOENT) {
2217 ASSERT(nvrc == 0);
2218 ict->ict_op.op_max_connections = uint64_val;
2219 }
2220
2221 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values,
2222 "MaxRecvDataSegmentLength", &uint64_val)) != ENOENT) {
2223 ASSERT(nvrc == 0);
2224 ict->ict_op.op_max_recv_data_segment_length = uint64_val;
2225 }
2226
2227 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values,
2228 "MaxBurstLength", &uint64_val)) != ENOENT) {
2229 ASSERT(nvrc == 0);
2230 ict->ict_op.op_max_burst_length = uint64_val;
2231 }
2232
2233 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values,
2234 "FirstBurstLength", &uint64_val)) != ENOENT) {
2235 ASSERT(nvrc == 0);
2236 ict->ict_op.op_first_burst_length = uint64_val;
2237 }
2238
2239 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values,
2240 "DefaultTime2Wait", &uint64_val)) != ENOENT) {
2241 ASSERT(nvrc == 0);
2242 ict->ict_op.op_default_time_2_wait = uint64_val;
2243 }
2244
2245 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values,
2246 "DefaultTime2Retain", &uint64_val)) != ENOENT) {
2247 ASSERT(nvrc == 0);
2248 ict->ict_op.op_default_time_2_retain = uint64_val;
2249 }
2250
2251 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values,
2252 "MaxOutstandingR2T", &uint64_val)) != ENOENT) {
2253 ASSERT(nvrc == 0);
2254 ict->ict_op.op_max_outstanding_r2t = uint64_val;
2255 }
2256
2257 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values,
2258 "ErrorRecoveryLevel", &uint64_val)) != ENOENT) {
2259 ASSERT(nvrc == 0);
2260 ict->ict_op.op_error_recovery_level = uint64_val;
2261 }
2262 }