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 }