iscsit_login.c (9586:bd5e99a50121) | iscsit_login.c (9601:e0ed15140e6d) |
---|---|
1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 91 unchanged lines hidden (view full) --- 100 101static void 102login_sm_send_ack(iscsit_conn_t *ict, idm_pdu_t *pdu); 103 104static idm_status_t 105login_sm_validate_ack(iscsit_conn_t *ict, idm_pdu_t *pdu); 106 107static boolean_t | 1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 91 unchanged lines hidden (view full) --- 100 101static void 102login_sm_send_ack(iscsit_conn_t *ict, idm_pdu_t *pdu); 103 104static idm_status_t 105login_sm_validate_ack(iscsit_conn_t *ict, idm_pdu_t *pdu); 106 107static boolean_t |
108login_sm_is_last_response(iscsit_conn_t *ict); | 108login_sm_is_last_response(idm_pdu_t *pdu); |
109 110static void 111login_sm_handle_initial_login(iscsit_conn_t *ict, idm_pdu_t *pdu); 112 113static void | 109 110static void 111login_sm_handle_initial_login(iscsit_conn_t *ict, idm_pdu_t *pdu); 112 113static void |
114login_sm_send_next_response(iscsit_conn_t *ict); | 114login_sm_send_next_response(iscsit_conn_t *ict, idm_pdu_t *pdu); |
115 116static void 117login_sm_process_request(iscsit_conn_t *ict); 118 119static idm_status_t 120login_sm_req_pdu_check(iscsit_conn_t *ict, idm_pdu_t *pdu); 121 122static idm_status_t 123login_sm_process_nvlist(iscsit_conn_t *ict); 124 125static idm_status_t 126login_sm_check_security(iscsit_conn_t *ict); 127 | 115 116static void 117login_sm_process_request(iscsit_conn_t *ict); 118 119static idm_status_t 120login_sm_req_pdu_check(iscsit_conn_t *ict, idm_pdu_t *pdu); 121 122static idm_status_t 123login_sm_process_nvlist(iscsit_conn_t *ict); 124 125static idm_status_t 126login_sm_check_security(iscsit_conn_t *ict); 127 |
128static void | 128static idm_pdu_t * |
129login_sm_build_login_response(iscsit_conn_t *ict); 130 131static void 132login_sm_ffp_actions(iscsit_conn_t *ict); 133 134static idm_status_t 135login_sm_validate_initial_parameters(iscsit_conn_t *ict); 136 --- 54 unchanged lines hidden (view full) --- 191 192idm_status_t 193iscsit_login_sm_init(iscsit_conn_t *ict) 194{ 195 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 196 197 bzero(lsm, sizeof (iscsit_conn_login_t)); 198 | 129login_sm_build_login_response(iscsit_conn_t *ict); 130 131static void 132login_sm_ffp_actions(iscsit_conn_t *ict); 133 134static idm_status_t 135login_sm_validate_initial_parameters(iscsit_conn_t *ict); 136 --- 54 unchanged lines hidden (view full) --- 191 192idm_status_t 193iscsit_login_sm_init(iscsit_conn_t *ict) 194{ 195 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 196 197 bzero(lsm, sizeof (iscsit_conn_login_t)); 198 |
199 /* initialize the response pdu */ 200 ict->ict_login_sm.icl_login_resp = 201 idm_pdu_alloc(sizeof (iscsi_hdr_t), 0); 202 if (ict->ict_login_sm.icl_login_resp == NULL) { 203 return (IDM_STATUS_FAIL); 204 } 205 idm_pdu_init(ict->ict_login_sm.icl_login_resp, 206 ict->ict_ic, ict, login_resp_complete_cb); 207 lsm->icl_login_resp->isp_flags |= IDM_PDU_LOGIN_TX; 208 | |
209 (void) nvlist_alloc(&lsm->icl_negotiated_values, NV_UNIQUE_NAME, 210 KM_SLEEP); 211 212 /* 213 * Hold connection until the login state machine completes 214 */ 215 iscsit_conn_hold(ict); 216 --- 40 unchanged lines hidden (view full) --- 257 return (IDM_STATUS_SUCCESS); 258} 259 260static void 261login_resp_complete_cb(idm_pdu_t *pdu, idm_status_t status) 262{ 263 iscsit_conn_t *ict = pdu->isp_private; 264 | 199 (void) nvlist_alloc(&lsm->icl_negotiated_values, NV_UNIQUE_NAME, 200 KM_SLEEP); 201 202 /* 203 * Hold connection until the login state machine completes 204 */ 205 iscsit_conn_hold(ict); 206 --- 40 unchanged lines hidden (view full) --- 247 return (IDM_STATUS_SUCCESS); 248} 249 250static void 251login_resp_complete_cb(idm_pdu_t *pdu, idm_status_t status) 252{ 253 iscsit_conn_t *ict = pdu->isp_private; 254 |
265 ASSERT(ict->ict_login_sm.icl_login_resp == pdu); | |
266 /* | 255 /* |
267 * The icl_login_resp response buffer should only ever be used 268 * during the LOGIN phase. | 256 * Check that this is a login pdu |
269 */ 270 ASSERT((pdu->isp_flags & IDM_PDU_LOGIN_TX) != 0); | 257 */ 258 ASSERT((pdu->isp_flags & IDM_PDU_LOGIN_TX) != 0); |
259 idm_pdu_free(pdu); |
|
271 272 if ((status != IDM_STATUS_SUCCESS) || 273 (ict->ict_login_sm.icl_login_resp_err_class != 0)) { | 260 261 if ((status != IDM_STATUS_SUCCESS) || 262 (ict->ict_login_sm.icl_login_resp_err_class != 0)) { |
263 /* 264 * Transport or login error occurred. 265 */ |
|
274 iscsit_login_sm_event(ict, ILE_LOGIN_ERROR, NULL); | 266 iscsit_login_sm_event(ict, ILE_LOGIN_ERROR, NULL); |
275 } else if (login_sm_is_last_response(ict) == B_TRUE) { 276 iscsit_login_sm_event(ict, ILE_LOGIN_RESP_COMPLETE, NULL); | |
277 } | 267 } |
268 iscsit_conn_rele(ict); |
|
278} 279 280void 281iscsit_login_sm_fini(iscsit_conn_t *ict) 282{ 283 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 284 285 mutex_enter(&lsm->icl_mutex); 286 list_destroy(&lsm->icl_pdu_list); 287 list_destroy(&lsm->icl_login_events); | 269} 270 271void 272iscsit_login_sm_fini(iscsit_conn_t *ict) 273{ 274 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 275 276 mutex_enter(&lsm->icl_mutex); 277 list_destroy(&lsm->icl_pdu_list); 278 list_destroy(&lsm->icl_login_events); |
288 mutex_exit(&lsm->icl_mutex); 289 mutex_destroy(&lsm->icl_mutex); | |
290 291 kmem_free(lsm->icl_login_resp_tmpl, sizeof (iscsi_login_rsp_hdr_t)); | 279 280 kmem_free(lsm->icl_login_resp_tmpl, sizeof (iscsi_login_rsp_hdr_t)); |
292 idm_pdu_free(lsm->icl_login_resp); | |
293 294 /* clean up the login response idm text buffer */ 295 if (lsm->icl_login_resp_itb != NULL) { 296 idm_itextbuf_free(lsm->icl_login_resp_itb); 297 lsm->icl_login_resp_itb = NULL; 298 } 299 300 nvlist_free(lsm->icl_negotiated_values); | 281 282 /* clean up the login response idm text buffer */ 283 if (lsm->icl_login_resp_itb != NULL) { 284 idm_itextbuf_free(lsm->icl_login_resp_itb); 285 lsm->icl_login_resp_itb = NULL; 286 } 287 288 nvlist_free(lsm->icl_negotiated_values); |
301 iscsit_conn_rele(ict); | 289 mutex_destroy(&lsm->icl_mutex); |
302} 303 304void 305iscsit_login_sm_event(iscsit_conn_t *ict, iscsit_login_event_t event, 306 idm_pdu_t *pdu) 307{ 308 /* 309 * This is a bit ugly but if we're already in ILS_LOGIN_ERROR --- 11 unchanged lines hidden (view full) --- 321} 322void 323iscsit_login_sm_event_locked(iscsit_conn_t *ict, iscsit_login_event_t event, 324 idm_pdu_t *pdu) 325{ 326 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 327 login_event_ctx_t *ctx; 328 | 290} 291 292void 293iscsit_login_sm_event(iscsit_conn_t *ict, iscsit_login_event_t event, 294 idm_pdu_t *pdu) 295{ 296 /* 297 * This is a bit ugly but if we're already in ILS_LOGIN_ERROR --- 11 unchanged lines hidden (view full) --- 309} 310void 311iscsit_login_sm_event_locked(iscsit_conn_t *ict, iscsit_login_event_t event, 312 idm_pdu_t *pdu) 313{ 314 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 315 login_event_ctx_t *ctx; 316 |
317 ASSERT(mutex_owned(&lsm->icl_mutex)); |
|
329 ctx = kmem_zalloc(sizeof (*ctx), KM_SLEEP); 330 331 ctx->le_ctx_event = event; 332 ctx->le_pdu = pdu; 333 334 list_insert_tail(&lsm->icl_login_events, ctx); 335 336 /* --- 47 unchanged lines hidden (view full) --- 384} 385 386static void 387login_sm_complete(void *ict_void) 388{ 389 iscsit_conn_t *ict = ict_void; 390 391 /* | 318 ctx = kmem_zalloc(sizeof (*ctx), KM_SLEEP); 319 320 ctx->le_ctx_event = event; 321 ctx->le_pdu = pdu; 322 323 list_insert_tail(&lsm->icl_login_events, ctx); 324 325 /* --- 47 unchanged lines hidden (view full) --- 373} 374 375static void 376login_sm_complete(void *ict_void) 377{ 378 iscsit_conn_t *ict = ict_void; 379 380 /* |
392 * State machine has run to completion, release state machine resources | 381 * State machine has run to completion, resources 382 * will be cleaned up when connection is destroyed. |
393 */ | 383 */ |
394 iscsit_login_sm_fini(ict); | 384 iscsit_conn_rele(ict); |
395} 396 397static void 398login_sm_event_dispatch(iscsit_conn_login_t *lsm, iscsit_conn_t *ict, 399 login_event_ctx_t *ctx) 400{ 401 idm_pdu_t *pdu = ctx->le_pdu; /* Only valid for some events */ 402 --- 4 unchanged lines hidden (view full) --- 407 (void *)ict, 408 iscsit_ile_name[ctx->le_ctx_event], ctx->le_ctx_event); 409 410 /* State independent actions */ 411 switch (ctx->le_ctx_event) { 412 case ILE_LOGIN_RCV: 413 /* Perform basic sanity checks on the header */ 414 if (login_sm_req_pdu_check(ict, pdu) != IDM_STATUS_SUCCESS) { | 385} 386 387static void 388login_sm_event_dispatch(iscsit_conn_login_t *lsm, iscsit_conn_t *ict, 389 login_event_ctx_t *ctx) 390{ 391 idm_pdu_t *pdu = ctx->le_pdu; /* Only valid for some events */ 392 --- 4 unchanged lines hidden (view full) --- 397 (void *)ict, 398 iscsit_ile_name[ctx->le_ctx_event], ctx->le_ctx_event); 399 400 /* State independent actions */ 401 switch (ctx->le_ctx_event) { 402 case ILE_LOGIN_RCV: 403 /* Perform basic sanity checks on the header */ 404 if (login_sm_req_pdu_check(ict, pdu) != IDM_STATUS_SUCCESS) { |
405 idm_pdu_t *rpdu; 406 |
|
415 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_INITIATOR_ERR, 416 ISCSI_LOGIN_STATUS_INVALID_REQUEST); 417 /* 418 * If we haven't processed any PDU's yet then use 419 * this one as a template for the response 420 */ 421 if (ict->ict_login_sm.icl_login_resp_tmpl->opcode == 0) 422 login_sm_handle_initial_login(ict, pdu); | 407 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_INITIATOR_ERR, 408 ISCSI_LOGIN_STATUS_INVALID_REQUEST); 409 /* 410 * If we haven't processed any PDU's yet then use 411 * this one as a template for the response 412 */ 413 if (ict->ict_login_sm.icl_login_resp_tmpl->opcode == 0) 414 login_sm_handle_initial_login(ict, pdu); |
423 login_sm_build_login_response(ict); 424 login_sm_send_next_response(ict); | 415 rpdu = login_sm_build_login_response(ict); 416 login_sm_send_next_response(ict, rpdu); |
425 idm_pdu_complete(pdu, IDM_STATUS_SUCCESS); 426 kmem_free(ctx, sizeof (*ctx)); 427 return; 428 } 429 break; 430 default: 431 break; 432 } --- 112 unchanged lines hidden (view full) --- 545 default: 546 ASSERT(0); 547 } 548} 549 550static void 551login_sm_responding(iscsit_conn_t *ict, login_event_ctx_t *ctx) 552{ | 417 idm_pdu_complete(pdu, IDM_STATUS_SUCCESS); 418 kmem_free(ctx, sizeof (*ctx)); 419 return; 420 } 421 break; 422 default: 423 break; 424 } --- 112 unchanged lines hidden (view full) --- 537 default: 538 ASSERT(0); 539 } 540} 541 542static void 543login_sm_responding(iscsit_conn_t *ict, login_event_ctx_t *ctx) 544{ |
553 idm_pdu_t *pdu; | 545 idm_pdu_t *pdu, *rpdu; |
554 555 switch (ctx->le_ctx_event) { 556 case ILE_LOGIN_RCV: 557 pdu = ctx->le_pdu; 558 /* 559 * We should only be in "responding" state if we have not 560 * sent the last PDU of a multi-PDU login response sequence. 561 * In that case we expect this received PDU to be an 562 * acknowledgement from the initiator (login PDU with C 563 * bit cleared and no data). If it's the acknowledgement 564 * we are expecting then we send the next PDU in the login 565 * response sequence. Otherwise it's a protocol error and 566 * the login fails. 567 */ 568 if (login_sm_validate_ack(ict, pdu) == IDM_STATUS_SUCCESS) { | 546 547 switch (ctx->le_ctx_event) { 548 case ILE_LOGIN_RCV: 549 pdu = ctx->le_pdu; 550 /* 551 * We should only be in "responding" state if we have not 552 * sent the last PDU of a multi-PDU login response sequence. 553 * In that case we expect this received PDU to be an 554 * acknowledgement from the initiator (login PDU with C 555 * bit cleared and no data). If it's the acknowledgement 556 * we are expecting then we send the next PDU in the login 557 * response sequence. Otherwise it's a protocol error and 558 * the login fails. 559 */ 560 if (login_sm_validate_ack(ict, pdu) == IDM_STATUS_SUCCESS) { |
569 login_sm_build_login_response(ict); 570 login_sm_send_next_response(ict); | 561 rpdu = login_sm_build_login_response(ict); 562 login_sm_send_next_response(ict, rpdu); |
571 } else { 572 login_sm_new_state(ict, ctx, ILS_LOGIN_ERROR); 573 } 574 idm_pdu_complete(pdu, IDM_STATUS_SUCCESS); 575 break; 576 case ILE_LOGIN_FFP: 577 login_sm_new_state(ict, ctx, ILS_LOGIN_FFP); 578 break; --- 111 unchanged lines hidden (view full) --- 690 } 691} 692 693static void 694login_sm_new_state(iscsit_conn_t *ict, login_event_ctx_t *ctx, 695 iscsit_login_state_t new_state) 696{ 697 iscsit_conn_login_t *lsm = &ict->ict_login_sm; | 563 } else { 564 login_sm_new_state(ict, ctx, ILS_LOGIN_ERROR); 565 } 566 idm_pdu_complete(pdu, IDM_STATUS_SUCCESS); 567 break; 568 case ILE_LOGIN_FFP: 569 login_sm_new_state(ict, ctx, ILS_LOGIN_FFP); 570 break; --- 111 unchanged lines hidden (view full) --- 682 } 683} 684 685static void 686login_sm_new_state(iscsit_conn_t *ict, login_event_ctx_t *ctx, 687 iscsit_login_state_t new_state) 688{ 689 iscsit_conn_login_t *lsm = &ict->ict_login_sm; |
690 idm_pdu_t *rpdu; |
|
698 699 /* 700 * Validate new state 701 */ 702 ASSERT(new_state != ILS_UNDEFINED); 703 ASSERT3U(new_state, <, ILS_MAX_STATE); 704 705 new_state = (new_state < ILS_MAX_STATE) ? --- 19 unchanged lines hidden (view full) --- 725 case ILS_LOGIN_WAITING: 726 /* Do nothing, waiting for more login PDU's */ 727 break; 728 case ILS_LOGIN_PROCESSING: 729 /* All login PDU's received, process login request */ 730 login_sm_process_request(ict); 731 break; 732 case ILS_LOGIN_RESPONDING: | 691 692 /* 693 * Validate new state 694 */ 695 ASSERT(new_state != ILS_UNDEFINED); 696 ASSERT3U(new_state, <, ILS_MAX_STATE); 697 698 new_state = (new_state < ILS_MAX_STATE) ? --- 19 unchanged lines hidden (view full) --- 718 case ILS_LOGIN_WAITING: 719 /* Do nothing, waiting for more login PDU's */ 720 break; 721 case ILS_LOGIN_PROCESSING: 722 /* All login PDU's received, process login request */ 723 login_sm_process_request(ict); 724 break; 725 case ILS_LOGIN_RESPONDING: |
733 login_sm_send_next_response(ict); | 726 rpdu = login_sm_build_login_response(ict); 727 login_sm_send_next_response(ict, rpdu); |
734 break; 735 case ILS_LOGIN_RESPONDED: 736 /* clean up the login response idm text buffer */ 737 if (lsm->icl_login_resp_itb != NULL) { 738 idm_itextbuf_free(lsm->icl_login_resp_itb); 739 lsm->icl_login_resp_itb = NULL; 740 } 741 break; 742 case ILS_LOGIN_FFP: 743 login_sm_ffp_actions(ict); 744 break; 745 case ILS_LOGIN_DONE: 746 case ILS_LOGIN_ERROR: | 728 break; 729 case ILS_LOGIN_RESPONDED: 730 /* clean up the login response idm text buffer */ 731 if (lsm->icl_login_resp_itb != NULL) { 732 idm_itextbuf_free(lsm->icl_login_resp_itb); 733 lsm->icl_login_resp_itb = NULL; 734 } 735 break; 736 case ILS_LOGIN_FFP: 737 login_sm_ffp_actions(ict); 738 break; 739 case ILS_LOGIN_DONE: 740 case ILS_LOGIN_ERROR: |
747 /* Free login SM resources */ | 741 /* 742 * Flag the terminal state for the dispatcher 743 */ |
748 lsm->icl_login_complete = B_TRUE; 749 break; 750 case ILS_LOGIN_INIT: /* Initial state, can't return */ 751 default: 752 ASSERT(0); 753 /*NOTREACHED*/ 754 } 755} 756 757/*ARGSUSED*/ 758static void 759login_sm_send_ack(iscsit_conn_t *ict, idm_pdu_t *pdu) 760{ 761 iscsit_conn_login_t *lsm = &ict->ict_login_sm; | 744 lsm->icl_login_complete = B_TRUE; 745 break; 746 case ILS_LOGIN_INIT: /* Initial state, can't return */ 747 default: 748 ASSERT(0); 749 /*NOTREACHED*/ 750 } 751} 752 753/*ARGSUSED*/ 754static void 755login_sm_send_ack(iscsit_conn_t *ict, idm_pdu_t *pdu) 756{ 757 iscsit_conn_login_t *lsm = &ict->ict_login_sm; |
758 idm_pdu_t *lack; |
|
762 | 759 |
763 ASSERT((lsm->icl_login_resp->isp_flags & IDM_PDU_LOGIN_TX) != 0); 764 bcopy(lsm->icl_login_resp_tmpl, 765 lsm->icl_login_resp->isp_hdr, sizeof (iscsi_hdr_t)); 766 idm_pdu_tx(lsm->icl_login_resp); | 760 /* 761 * allocate the response pdu 762 */ 763 lack = idm_pdu_alloc(sizeof (iscsi_hdr_t), 0); 764 idm_pdu_init(lack, ict->ict_ic, ict, login_resp_complete_cb); 765 lack->isp_flags |= IDM_PDU_LOGIN_TX; 766 767 /* 768 * copy the response template into the response pdu 769 */ 770 bcopy(lsm->icl_login_resp_tmpl, lack->isp_hdr, sizeof (iscsi_hdr_t)); 771 772 iscsit_conn_hold(ict); 773 idm_pdu_tx(lack); |
767} 768 769/*ARGSUSED*/ 770static idm_status_t 771login_sm_validate_ack(iscsit_conn_t *ict, idm_pdu_t *pdu) 772{ 773 iscsi_hdr_t *ihp = pdu->isp_hdr; 774 if (ihp->flags & ISCSI_FLAG_TEXT_CONTINUE) { 775 return (IDM_STATUS_FAIL); 776 } 777 if (ntoh24(ihp->dlength) != 0) { 778 return (IDM_STATUS_FAIL); 779 } 780 return (IDM_STATUS_SUCCESS); 781} 782 783static boolean_t | 774} 775 776/*ARGSUSED*/ 777static idm_status_t 778login_sm_validate_ack(iscsit_conn_t *ict, idm_pdu_t *pdu) 779{ 780 iscsi_hdr_t *ihp = pdu->isp_hdr; 781 if (ihp->flags & ISCSI_FLAG_TEXT_CONTINUE) { 782 return (IDM_STATUS_FAIL); 783 } 784 if (ntoh24(ihp->dlength) != 0) { 785 return (IDM_STATUS_FAIL); 786 } 787 return (IDM_STATUS_SUCCESS); 788} 789 790static boolean_t |
784login_sm_is_last_response(iscsit_conn_t *ict) | 791login_sm_is_last_response(idm_pdu_t *pdu) |
785{ | 792{ |
786 iscsit_conn_login_t *lsm = &ict->ict_login_sm; | |
787 | 793 |
788 if (lsm->icl_login_resp->isp_hdr->flags & ISCSI_FLAG_LOGIN_CONTINUE) { | 794 if (pdu->isp_hdr->flags & ISCSI_FLAG_LOGIN_CONTINUE) { |
789 return (B_FALSE); 790 } 791 return (B_TRUE); 792} 793 794 795static void 796login_sm_handle_initial_login(iscsit_conn_t *ict, idm_pdu_t *pdu) --- 64 unchanged lines hidden (view full) --- 861 862 /* 863 * StatSn, ExpCmdSn and MaxCmdSn will be set immediately before 864 * transmission 865 */ 866} 867 868static void | 795 return (B_FALSE); 796 } 797 return (B_TRUE); 798} 799 800 801static void 802login_sm_handle_initial_login(iscsit_conn_t *ict, idm_pdu_t *pdu) --- 64 unchanged lines hidden (view full) --- 867 868 /* 869 * StatSn, ExpCmdSn and MaxCmdSn will be set immediately before 870 * transmission 871 */ 872} 873 874static void |
869login_sm_send_next_response(iscsit_conn_t *ict) | 875login_sm_send_next_response(iscsit_conn_t *ict, idm_pdu_t *pdu) |
870{ | 876{ |
871 idm_pdu_t *pdu = ict->ict_login_sm.icl_login_resp; | |
872 iscsi_login_rsp_hdr_t *lh_resp = (iscsi_login_rsp_hdr_t *)pdu->isp_hdr; 873 | 877 iscsi_login_rsp_hdr_t *lh_resp = (iscsi_login_rsp_hdr_t *)pdu->isp_hdr; 878 |
874 /* Tell the IDM layer this PDU is part of the login phase */ | 879 /* Make sure this PDU is part of the login phase */ |
875 ASSERT((pdu->isp_flags & IDM_PDU_LOGIN_TX) != 0); 876 877 /* 878 * Fill in header values 879 */ 880 hton24(lh_resp->dlength, pdu->isp_datalen); 881 882 /* 883 * If this is going to be the last PDU of a login response 884 * that moves us to FFP then generate the ILE_LOGIN_FFP event. 885 */ 886 if (lh_resp->status_class == ISCSI_STATUS_CLASS_SUCCESS) { 887 ASSERT(ict->ict_sess != NULL); 888 889 if ((lh_resp->flags & ISCSI_FLAG_LOGIN_TRANSIT) && 890 (ISCSI_LOGIN_NEXT_STAGE(lh_resp->flags) == 891 ISCSI_FULL_FEATURE_PHASE) && 892 !(lh_resp->flags & ISCSI_FLAG_LOGIN_CONTINUE)) { | 880 ASSERT((pdu->isp_flags & IDM_PDU_LOGIN_TX) != 0); 881 882 /* 883 * Fill in header values 884 */ 885 hton24(lh_resp->dlength, pdu->isp_datalen); 886 887 /* 888 * If this is going to be the last PDU of a login response 889 * that moves us to FFP then generate the ILE_LOGIN_FFP event. 890 */ 891 if (lh_resp->status_class == ISCSI_STATUS_CLASS_SUCCESS) { 892 ASSERT(ict->ict_sess != NULL); 893 894 if ((lh_resp->flags & ISCSI_FLAG_LOGIN_TRANSIT) && 895 (ISCSI_LOGIN_NEXT_STAGE(lh_resp->flags) == 896 ISCSI_FULL_FEATURE_PHASE) && 897 !(lh_resp->flags & ISCSI_FLAG_LOGIN_CONTINUE)) { |
893 iscsit_login_sm_event_locked(ict, ILE_LOGIN_FFP, NULL); | 898 iscsit_login_sm_event(ict, ILE_LOGIN_FFP, NULL); |
894 } | 899 } |
900 if (login_sm_is_last_response(pdu) == B_TRUE) { 901 /* 902 * The last of a potentially mult-PDU response finished. 903 */ 904 iscsit_login_sm_event(ict, ILE_LOGIN_RESP_COMPLETE, 905 NULL); 906 } |
|
895 | 907 |
908 iscsit_conn_hold(ict); |
|
896 iscsit_pdu_tx(pdu); 897 } else { 898 /* 899 * If status_class != ISCSI_STATUS_CLASS_SUCCESS then 900 * StatSN is not valid and we can call idm_pdu_tx instead 901 * of iscsit_pdu_tx. This is very good thing since in 902 * some cases of login failure we may not have a session. 903 * Since iscsit_calc_rspsn grabs the session mutex while 904 * it is retrieving values for expcmdsn and maxcmdsn this 905 * would cause a panic. 906 * 907 * Since we still want a value for expcmdsn, fill in an 908 * appropriate value based on the login request before 909 * sending the response. Cmdsn/expcmdsn do not advance during 910 * login phase. 911 */ 912 lh_resp->expcmdsn = htonl(ict->ict_login_sm.icl_cmdsn); 913 lh_resp->maxcmdsn = htonl(ict->ict_login_sm.icl_cmdsn + 1); 914 | 909 iscsit_pdu_tx(pdu); 910 } else { 911 /* 912 * If status_class != ISCSI_STATUS_CLASS_SUCCESS then 913 * StatSN is not valid and we can call idm_pdu_tx instead 914 * of iscsit_pdu_tx. This is very good thing since in 915 * some cases of login failure we may not have a session. 916 * Since iscsit_calc_rspsn grabs the session mutex while 917 * it is retrieving values for expcmdsn and maxcmdsn this 918 * would cause a panic. 919 * 920 * Since we still want a value for expcmdsn, fill in an 921 * appropriate value based on the login request before 922 * sending the response. Cmdsn/expcmdsn do not advance during 923 * login phase. 924 */ 925 lh_resp->expcmdsn = htonl(ict->ict_login_sm.icl_cmdsn); 926 lh_resp->maxcmdsn = htonl(ict->ict_login_sm.icl_cmdsn + 1); 927 |
915 idm_pdu_tx(ict->ict_login_sm.icl_login_resp); | 928 iscsit_conn_hold(ict); 929 idm_pdu_tx(pdu); |
916 } 917 918} 919 920static void 921login_sm_process_request(iscsit_conn_t *ict) 922{ 923 iscsit_conn_login_t *lsm = &ict->ict_login_sm; --- 70 unchanged lines hidden (view full) --- 994 if (login_sm_process_nvlist(ict) != IDM_STATUS_SUCCESS) { 995 goto request_fail; 996 } 997 998 if (login_sm_check_security(ict) != IDM_STATUS_SUCCESS) { 999 goto request_fail; 1000 } 1001 | 930 } 931 932} 933 934static void 935login_sm_process_request(iscsit_conn_t *ict) 936{ 937 iscsit_conn_login_t *lsm = &ict->ict_login_sm; --- 70 unchanged lines hidden (view full) --- 1008 if (login_sm_process_nvlist(ict) != IDM_STATUS_SUCCESS) { 1009 goto request_fail; 1010 } 1011 1012 if (login_sm_check_security(ict) != IDM_STATUS_SUCCESS) { 1013 goto request_fail; 1014 } 1015 |
1002request_fail: 1003 login_sm_build_login_response(ict); | 1016 /* clean up request_nvlist */ 1017 if (lsm->icl_request_nvlist != NULL) { 1018 nvlist_free(lsm->icl_request_nvlist); 1019 lsm->icl_request_nvlist = NULL; 1020 } 1021 1022 /* convert any responses to textbuf form */ 1023 ASSERT(lsm->icl_login_resp_itb == NULL); 1024 if (lsm->icl_response_nvlist) { 1025 lsm->icl_login_resp_itb = idm_nvlist_to_itextbuf( 1026 lsm->icl_response_nvlist); 1027 if (lsm->icl_login_resp_itb == NULL) { 1028 /* Still need to send the resp so continue */ 1029 SET_LOGIN_ERROR(ict, 1030 ISCSI_STATUS_CLASS_TARGET_ERR, 1031 ISCSI_LOGIN_STATUS_NO_RESOURCES); 1032 } 1033 /* clean up response_nvlist */ 1034 nvlist_free(lsm->icl_response_nvlist); 1035 lsm->icl_response_nvlist = NULL; 1036 } 1037 1038 /* tell the state machine to send the textbuf */ |
1004 iscsit_login_sm_event(ict, ILE_LOGIN_RESP_READY, NULL); | 1039 iscsit_login_sm_event(ict, ILE_LOGIN_RESP_READY, NULL); |
1040 return; |
|
1005 | 1041 |
1042request_fail: 1043 |
|
1006 /* clean up request_nvlist and response_nvlist */ 1007 if (lsm->icl_request_nvlist != NULL) { 1008 nvlist_free(lsm->icl_request_nvlist); 1009 lsm->icl_request_nvlist = NULL; 1010 } 1011 if (lsm->icl_response_nvlist != NULL) { 1012 nvlist_free(lsm->icl_response_nvlist); 1013 lsm->icl_response_nvlist = NULL; --- 888 unchanged lines hidden (view full) --- 1902 /* supply login class/detail for login errors */ 1903 SET_LOGIN_ERROR(ict, error_class, error_detail); 1904 idm_status = IDM_STATUS_FAIL; 1905 } 1906 1907 return (idm_status); 1908} 1909 | 1044 /* clean up request_nvlist and response_nvlist */ 1045 if (lsm->icl_request_nvlist != NULL) { 1046 nvlist_free(lsm->icl_request_nvlist); 1047 lsm->icl_request_nvlist = NULL; 1048 } 1049 if (lsm->icl_response_nvlist != NULL) { 1050 nvlist_free(lsm->icl_response_nvlist); 1051 lsm->icl_response_nvlist = NULL; --- 888 unchanged lines hidden (view full) --- 1940 /* supply login class/detail for login errors */ 1941 SET_LOGIN_ERROR(ict, error_class, error_detail); 1942 idm_status = IDM_STATUS_FAIL; 1943 } 1944 1945 return (idm_status); 1946} 1947 |
1910static void | 1948static idm_pdu_t * |
1911login_sm_build_login_response(iscsit_conn_t *ict) 1912{ 1913 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 1914 iscsi_login_rsp_hdr_t *lh; 1915 int transit, text_transit = 1; | 1949login_sm_build_login_response(iscsit_conn_t *ict) 1950{ 1951 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 1952 iscsi_login_rsp_hdr_t *lh; 1953 int transit, text_transit = 1; |
1954 idm_pdu_t *login_resp; |
|
1916 1917 /* | 1955 1956 /* |
1918 * 1. Convert response nvlist to an idm text buffer that holds 1919 * response key-value pairs. 1920 * 2. Build a PDU to transmit the first login response PDU 1921 * 3. If there is more data, wait for an ack then goto step 2. | 1957 * Create a response PDU and fill it with as much of 1958 * the response text that will fit. |
1922 */ | 1959 */ |
1923 ASSERT(lsm->icl_login_resp != NULL); | |
1924 | 1960 |
1925 if (lsm->icl_response_nvlist) { 1926 if (lsm->icl_login_resp_itb == NULL) { 1927 /* initialze the idm text buf to send pdus */ 1928 lsm->icl_login_resp_itb = idm_nvlist_to_itextbuf( 1929 lsm->icl_response_nvlist); 1930 if (lsm->icl_login_resp_itb == NULL) { 1931 SET_LOGIN_ERROR(ict, 1932 ISCSI_STATUS_CLASS_TARGET_ERR, 1933 ISCSI_LOGIN_STATUS_NO_RESOURCES); 1934 /* Still need to send the resp so continue */ 1935 } else { 1936 lsm->icl_login_resp_buf = 1937 idm_pdu_init_text_data(lsm->icl_login_resp, 1938 lsm->icl_login_resp_itb, 1939 ISCSI_DEFAULT_MAX_RECV_SEG_LEN, 1940 lsm->icl_login_resp_buf, &text_transit); 1941 } 1942 } else { 1943 lsm->icl_login_resp_buf = idm_pdu_init_text_data( 1944 lsm->icl_login_resp, lsm->icl_login_resp_itb, 1945 ISCSI_DEFAULT_MAX_RECV_SEG_LEN, 1946 lsm->icl_login_resp_buf, &text_transit); | 1961 if (lsm->icl_login_resp_itb) { 1962 /* allocate a pdu with space for text */ 1963 login_resp = idm_pdu_alloc(sizeof (iscsi_hdr_t), 1964 ISCSI_DEFAULT_MAX_RECV_SEG_LEN); 1965 /* copy a chunk of text into the pdu */ 1966 lsm->icl_login_resp_buf = idm_pdu_init_text_data( 1967 login_resp, lsm->icl_login_resp_itb, 1968 ISCSI_DEFAULT_MAX_RECV_SEG_LEN, 1969 lsm->icl_login_resp_buf, &text_transit); 1970 if (text_transit) { 1971 /* text buf has been consumed */ 1972 idm_itextbuf_free(lsm->icl_login_resp_itb); 1973 lsm->icl_login_resp_itb = NULL; 1974 lsm->icl_login_resp_buf = NULL; |
1947 } 1948 } else { | 1975 } 1976 } else { |
1949 lsm->icl_login_resp->isp_data = NULL; 1950 lsm->icl_login_resp->isp_datalen = 0; | 1977 /* allocate a pdu for just a header */ 1978 login_resp = idm_pdu_alloc(sizeof (iscsi_hdr_t), 0); |
1951 } | 1979 } |
1980 /* finish initializing the pdu */ 1981 idm_pdu_init(login_resp, 1982 ict->ict_ic, ict, login_resp_complete_cb); 1983 login_resp->isp_flags |= IDM_PDU_LOGIN_TX; |
|
1952 1953 /* 1954 * Use the BHS header values from the response template 1955 */ 1956 bcopy(lsm->icl_login_resp_tmpl, | 1984 1985 /* 1986 * Use the BHS header values from the response template 1987 */ 1988 bcopy(lsm->icl_login_resp_tmpl, |
1957 lsm->icl_login_resp->isp_hdr, sizeof (iscsi_login_rsp_hdr_t)); | 1989 login_resp->isp_hdr, sizeof (iscsi_login_rsp_hdr_t)); |
1958 | 1990 |
1959 lh = (iscsi_login_rsp_hdr_t *)lsm->icl_login_resp->isp_hdr; | 1991 lh = (iscsi_login_rsp_hdr_t *)login_resp->isp_hdr; |
1960 1961 /* Set error class/detail */ 1962 lh->status_class = lsm->icl_login_resp_err_class; 1963 lh->status_detail = lsm->icl_login_resp_err_detail; 1964 /* Set CSG, NSG and Transit */ 1965 lh->flags = 0; 1966 lh->flags |= lsm->icl_login_csg << 2; 1967 --- 17 unchanged lines hidden (view full) --- 1985 } 1986 1987 /* If we are transitioning to FFP then set TSIH */ 1988 if (transit && (lh->flags & ISCSI_FLAG_LOGIN_TRANSIT) && 1989 lsm->icl_login_csg == ISCSI_FULL_FEATURE_PHASE) { 1990 lh->tsid = htons(ict->ict_sess->ist_tsih); 1991 } 1992 } else { | 1992 1993 /* Set error class/detail */ 1994 lh->status_class = lsm->icl_login_resp_err_class; 1995 lh->status_detail = lsm->icl_login_resp_err_detail; 1996 /* Set CSG, NSG and Transit */ 1997 lh->flags = 0; 1998 lh->flags |= lsm->icl_login_csg << 2; 1999 --- 17 unchanged lines hidden (view full) --- 2017 } 2018 2019 /* If we are transitioning to FFP then set TSIH */ 2020 if (transit && (lh->flags & ISCSI_FLAG_LOGIN_TRANSIT) && 2021 lsm->icl_login_csg == ISCSI_FULL_FEATURE_PHASE) { 2022 lh->tsid = htons(ict->ict_sess->ist_tsih); 2023 } 2024 } else { |
1993 lsm->icl_login_resp->isp_data = 0; 1994 lsm->icl_login_resp->isp_datalen = 0; | 2025 login_resp->isp_data = 0; 2026 login_resp->isp_datalen = 0; |
1995 } | 2027 } |
2028 return (login_resp); |
|
1996} 1997 1998static kv_status_t 1999iscsit_handle_key(iscsit_conn_t *ict, nvpair_t *nvp, char *nvp_name) 2000{ 2001 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 2002 kv_status_t kvrc; 2003 const idm_kv_xlate_t *ikvx; --- 537 unchanged lines hidden --- | 2029} 2030 2031static kv_status_t 2032iscsit_handle_key(iscsit_conn_t *ict, nvpair_t *nvp, char *nvp_name) 2033{ 2034 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 2035 kv_status_t kvrc; 2036 const idm_kv_xlate_t *ikvx; --- 537 unchanged lines hidden --- |