| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /******************************************************************************* |
|---|
| 2 | 3 | * This file contains main functions related to iSCSI Parameter negotiation. |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 5 | 6 | * |
|---|
| 6 | 7 | * Author: Nicholas A. Bellinger <nab@linux-iscsi.org> |
|---|
| 7 | 8 | * |
|---|
| 8 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 9 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 10 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 11 | | - * (at your option) any later version. |
|---|
| 12 | | - * |
|---|
| 13 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 14 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 15 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 16 | | - * GNU General Public License for more details. |
|---|
| 17 | 9 | ******************************************************************************/ |
|---|
| 18 | 10 | |
|---|
| 19 | 11 | #include <linux/ctype.h> |
|---|
| .. | .. |
|---|
| 160 | 152 | |
|---|
| 161 | 153 | if (strstr("None", authtype)) |
|---|
| 162 | 154 | return 1; |
|---|
| 163 | | -#ifdef CANSRP |
|---|
| 164 | | - else if (strstr("SRP", authtype)) |
|---|
| 165 | | - return srp_main_loop(conn, auth, in_buf, out_buf, |
|---|
| 166 | | - &in_length, out_length); |
|---|
| 167 | | -#endif |
|---|
| 168 | 155 | else if (strstr("CHAP", authtype)) |
|---|
| 169 | 156 | return chap_main_loop(conn, auth, in_buf, out_buf, |
|---|
| 170 | 157 | &in_length, out_length); |
|---|
| 171 | | - else if (strstr("SPKM1", authtype)) |
|---|
| 172 | | - return 2; |
|---|
| 173 | | - else if (strstr("SPKM2", authtype)) |
|---|
| 174 | | - return 2; |
|---|
| 175 | | - else if (strstr("KRB5", authtype)) |
|---|
| 176 | | - return 2; |
|---|
| 177 | | - else |
|---|
| 178 | | - return 2; |
|---|
| 158 | + /* SRP, SPKM1, SPKM2 and KRB5 are unsupported */ |
|---|
| 159 | + return 2; |
|---|
| 179 | 160 | } |
|---|
| 180 | 161 | |
|---|
| 181 | 162 | static void iscsi_remove_failed_auth_entry(struct iscsi_conn *conn) |
|---|
| .. | .. |
|---|
| 500 | 481 | { |
|---|
| 501 | 482 | if (sk->sk_state == TCP_CLOSE_WAIT || sk->sk_state == TCP_CLOSE) { |
|---|
| 502 | 483 | pr_debug("__iscsi_target_sk_check_close: TCP_CLOSE_WAIT|TCP_CLOSE," |
|---|
| 503 | | - "returning FALSE\n"); |
|---|
| 484 | + "returning TRUE\n"); |
|---|
| 504 | 485 | return true; |
|---|
| 505 | 486 | } |
|---|
| 506 | 487 | return false; |
|---|
| .. | .. |
|---|
| 643 | 624 | pr_debug("iscsi_target_do_login_rx after rx_login_io, %p, %s:%d\n", |
|---|
| 644 | 625 | conn, current->comm, current->pid); |
|---|
| 645 | 626 | |
|---|
| 627 | + /* |
|---|
| 628 | + * LOGIN_FLAGS_READ_ACTIVE is cleared so that sk_data_ready |
|---|
| 629 | + * could be triggered again after this. |
|---|
| 630 | + * |
|---|
| 631 | + * LOGIN_FLAGS_WRITE_ACTIVE is cleared after we successfully |
|---|
| 632 | + * process a login PDU, so that sk_state_chage can do login |
|---|
| 633 | + * cleanup as needed if the socket is closed. If a delayed work is |
|---|
| 634 | + * ongoing (LOGIN_FLAGS_WRITE_ACTIVE or LOGIN_FLAGS_READ_ACTIVE), |
|---|
| 635 | + * sk_state_change will leave the cleanup to the delayed work or |
|---|
| 636 | + * it will schedule a delayed work to do cleanup. |
|---|
| 637 | + */ |
|---|
| 638 | + if (conn->sock) { |
|---|
| 639 | + struct sock *sk = conn->sock->sk; |
|---|
| 640 | + |
|---|
| 641 | + write_lock_bh(&sk->sk_callback_lock); |
|---|
| 642 | + if (!test_bit(LOGIN_FLAGS_INITIAL_PDU, &conn->login_flags)) { |
|---|
| 643 | + clear_bit(LOGIN_FLAGS_READ_ACTIVE, &conn->login_flags); |
|---|
| 644 | + set_bit(LOGIN_FLAGS_WRITE_ACTIVE, &conn->login_flags); |
|---|
| 645 | + } |
|---|
| 646 | + write_unlock_bh(&sk->sk_callback_lock); |
|---|
| 647 | + } |
|---|
| 648 | + |
|---|
| 646 | 649 | rc = iscsi_target_do_login(conn, login); |
|---|
| 647 | 650 | if (rc < 0) { |
|---|
| 648 | 651 | goto err; |
|---|
| 649 | 652 | } else if (!rc) { |
|---|
| 650 | | - if (iscsi_target_sk_check_and_clear(conn, LOGIN_FLAGS_READ_ACTIVE)) |
|---|
| 653 | + if (iscsi_target_sk_check_and_clear(conn, |
|---|
| 654 | + LOGIN_FLAGS_WRITE_ACTIVE)) |
|---|
| 651 | 655 | goto err; |
|---|
| 652 | 656 | } else if (rc == 1) { |
|---|
| 657 | + cancel_delayed_work(&conn->login_work); |
|---|
| 653 | 658 | iscsi_target_nego_release(conn); |
|---|
| 654 | 659 | iscsi_post_login_handler(np, conn, zero_tsih); |
|---|
| 655 | 660 | iscsit_deaccess_np(np, tpg, tpg_np); |
|---|
| .. | .. |
|---|
| 658 | 663 | |
|---|
| 659 | 664 | err: |
|---|
| 660 | 665 | iscsi_target_restore_sock_callbacks(conn); |
|---|
| 666 | + cancel_delayed_work(&conn->login_work); |
|---|
| 661 | 667 | iscsi_target_login_drop(conn, login); |
|---|
| 662 | 668 | iscsit_deaccess_np(np, tpg, tpg_np); |
|---|
| 663 | 669 | } |
|---|
| .. | .. |
|---|
| 688 | 694 | state = __iscsi_target_sk_check_close(sk); |
|---|
| 689 | 695 | pr_debug("__iscsi_target_sk_close_change: state: %d\n", state); |
|---|
| 690 | 696 | |
|---|
| 691 | | - if (test_bit(LOGIN_FLAGS_READ_ACTIVE, &conn->login_flags)) { |
|---|
| 692 | | - pr_debug("Got LOGIN_FLAGS_READ_ACTIVE=1 sk_state_change" |
|---|
| 693 | | - " conn: %p\n", conn); |
|---|
| 697 | + if (test_bit(LOGIN_FLAGS_READ_ACTIVE, &conn->login_flags) || |
|---|
| 698 | + test_bit(LOGIN_FLAGS_WRITE_ACTIVE, &conn->login_flags)) { |
|---|
| 699 | + pr_debug("Got LOGIN_FLAGS_{READ|WRITE}_ACTIVE=1" |
|---|
| 700 | + " sk_state_change conn: %p\n", conn); |
|---|
| 694 | 701 | if (state) |
|---|
| 695 | 702 | set_bit(LOGIN_FLAGS_CLOSED, &conn->login_flags); |
|---|
| 696 | 703 | write_unlock_bh(&sk->sk_callback_lock); |
|---|
| .. | .. |
|---|
| 1072 | 1079 | iscsi_target_set_sock_callbacks(conn); |
|---|
| 1073 | 1080 | |
|---|
| 1074 | 1081 | login->np = np; |
|---|
| 1082 | + conn->tpg = NULL; |
|---|
| 1075 | 1083 | |
|---|
| 1076 | 1084 | login_req = (struct iscsi_login_req *) login->req; |
|---|
| 1077 | 1085 | payload_length = ntoh24(login_req->dlength); |
|---|
| .. | .. |
|---|
| 1141 | 1149 | */ |
|---|
| 1142 | 1150 | sessiontype = strncmp(s_buf, DISCOVERY, 9); |
|---|
| 1143 | 1151 | if (!sessiontype) { |
|---|
| 1144 | | - conn->tpg = iscsit_global->discovery_tpg; |
|---|
| 1145 | 1152 | if (!login->leading_connection) |
|---|
| 1146 | 1153 | goto get_target; |
|---|
| 1147 | 1154 | |
|---|
| .. | .. |
|---|
| 1158 | 1165 | * Serialize access across the discovery struct iscsi_portal_group to |
|---|
| 1159 | 1166 | * process login attempt. |
|---|
| 1160 | 1167 | */ |
|---|
| 1168 | + conn->tpg = iscsit_global->discovery_tpg; |
|---|
| 1161 | 1169 | if (iscsit_access_np(np, conn->tpg) < 0) { |
|---|
| 1162 | 1170 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, |
|---|
| 1163 | 1171 | ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE); |
|---|
| 1172 | + conn->tpg = NULL; |
|---|
| 1164 | 1173 | ret = -1; |
|---|
| 1165 | 1174 | goto out; |
|---|
| 1166 | 1175 | } |
|---|