diff options
-rw-r--r-- | drivers/target/iscsi/iscsi_target.c | 37 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_core.h | 2 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_login.c | 31 |
3 files changed, 62 insertions, 8 deletions
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 6e070e0a8393..44262908def5 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
@@ -3164,6 +3164,30 @@ static int iscsit_send_task_mgt_rsp( | |||
3164 | return 0; | 3164 | return 0; |
3165 | } | 3165 | } |
3166 | 3166 | ||
3167 | static bool iscsit_check_inaddr_any(struct iscsi_np *np) | ||
3168 | { | ||
3169 | bool ret = false; | ||
3170 | |||
3171 | if (np->np_sockaddr.ss_family == AF_INET6) { | ||
3172 | const struct sockaddr_in6 sin6 = { | ||
3173 | .sin6_addr = IN6ADDR_ANY_INIT }; | ||
3174 | struct sockaddr_in6 *sock_in6 = | ||
3175 | (struct sockaddr_in6 *)&np->np_sockaddr; | ||
3176 | |||
3177 | if (!memcmp(sock_in6->sin6_addr.s6_addr, | ||
3178 | sin6.sin6_addr.s6_addr, 16)) | ||
3179 | ret = true; | ||
3180 | } else { | ||
3181 | struct sockaddr_in * sock_in = | ||
3182 | (struct sockaddr_in *)&np->np_sockaddr; | ||
3183 | |||
3184 | if (sock_in->sin_addr.s_addr == INADDR_ANY) | ||
3185 | ret = true; | ||
3186 | } | ||
3187 | |||
3188 | return ret; | ||
3189 | } | ||
3190 | |||
3167 | static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd) | 3191 | static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd) |
3168 | { | 3192 | { |
3169 | char *payload = NULL; | 3193 | char *payload = NULL; |
@@ -3213,12 +3237,17 @@ static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd) | |||
3213 | spin_lock(&tpg->tpg_np_lock); | 3237 | spin_lock(&tpg->tpg_np_lock); |
3214 | list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, | 3238 | list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, |
3215 | tpg_np_list) { | 3239 | tpg_np_list) { |
3240 | struct iscsi_np *np = tpg_np->tpg_np; | ||
3241 | bool inaddr_any = iscsit_check_inaddr_any(np); | ||
3242 | |||
3216 | len = sprintf(buf, "TargetAddress=" | 3243 | len = sprintf(buf, "TargetAddress=" |
3217 | "%s%s%s:%hu,%hu", | 3244 | "%s%s%s:%hu,%hu", |
3218 | (tpg_np->tpg_np->np_sockaddr.ss_family == AF_INET6) ? | 3245 | (np->np_sockaddr.ss_family == AF_INET6) ? |
3219 | "[" : "", tpg_np->tpg_np->np_ip, | 3246 | "[" : "", (inaddr_any == false) ? |
3220 | (tpg_np->tpg_np->np_sockaddr.ss_family == AF_INET6) ? | 3247 | np->np_ip : conn->local_ip, |
3221 | "]" : "", tpg_np->tpg_np->np_port, | 3248 | (np->np_sockaddr.ss_family == AF_INET6) ? |
3249 | "]" : "", (inaddr_any == false) ? | ||
3250 | np->np_port : conn->local_port, | ||
3222 | tpg->tpgt); | 3251 | tpg->tpgt); |
3223 | len += 1; | 3252 | len += 1; |
3224 | 3253 | ||
diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h index ebf81fdbb5c5..0ec3b77a0c27 100644 --- a/drivers/target/iscsi/iscsi_target_core.h +++ b/drivers/target/iscsi/iscsi_target_core.h | |||
@@ -508,6 +508,7 @@ struct iscsi_conn { | |||
508 | u16 cid; | 508 | u16 cid; |
509 | /* Remote TCP Port */ | 509 | /* Remote TCP Port */ |
510 | u16 login_port; | 510 | u16 login_port; |
511 | u16 local_port; | ||
511 | int net_size; | 512 | int net_size; |
512 | u32 auth_id; | 513 | u32 auth_id; |
513 | #define CONNFLAG_SCTP_STRUCT_FILE 0x01 | 514 | #define CONNFLAG_SCTP_STRUCT_FILE 0x01 |
@@ -527,6 +528,7 @@ struct iscsi_conn { | |||
527 | unsigned char bad_hdr[ISCSI_HDR_LEN]; | 528 | unsigned char bad_hdr[ISCSI_HDR_LEN]; |
528 | #define IPV6_ADDRESS_SPACE 48 | 529 | #define IPV6_ADDRESS_SPACE 48 |
529 | unsigned char login_ip[IPV6_ADDRESS_SPACE]; | 530 | unsigned char login_ip[IPV6_ADDRESS_SPACE]; |
531 | unsigned char local_ip[IPV6_ADDRESS_SPACE]; | ||
530 | int conn_usage_count; | 532 | int conn_usage_count; |
531 | int conn_waiting_on_uc; | 533 | int conn_waiting_on_uc; |
532 | atomic_t check_immediate_queue; | 534 | atomic_t check_immediate_queue; |
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index 373b0cc6abd8..ec47a7c5966e 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c | |||
@@ -615,8 +615,8 @@ static int iscsi_post_login_handler( | |||
615 | } | 615 | } |
616 | 616 | ||
617 | pr_debug("iSCSI Login successful on CID: %hu from %s to" | 617 | pr_debug("iSCSI Login successful on CID: %hu from %s to" |
618 | " %s:%hu,%hu\n", conn->cid, conn->login_ip, np->np_ip, | 618 | " %s:%hu,%hu\n", conn->cid, conn->login_ip, |
619 | np->np_port, tpg->tpgt); | 619 | conn->local_ip, conn->local_port, tpg->tpgt); |
620 | 620 | ||
621 | list_add_tail(&conn->conn_list, &sess->sess_conn_list); | 621 | list_add_tail(&conn->conn_list, &sess->sess_conn_list); |
622 | atomic_inc(&sess->nconn); | 622 | atomic_inc(&sess->nconn); |
@@ -658,7 +658,8 @@ static int iscsi_post_login_handler( | |||
658 | sess->session_state = TARG_SESS_STATE_LOGGED_IN; | 658 | sess->session_state = TARG_SESS_STATE_LOGGED_IN; |
659 | 659 | ||
660 | pr_debug("iSCSI Login successful on CID: %hu from %s to %s:%hu,%hu\n", | 660 | pr_debug("iSCSI Login successful on CID: %hu from %s to %s:%hu,%hu\n", |
661 | conn->cid, conn->login_ip, np->np_ip, np->np_port, tpg->tpgt); | 661 | conn->cid, conn->login_ip, conn->local_ip, conn->local_port, |
662 | tpg->tpgt); | ||
662 | 663 | ||
663 | spin_lock_bh(&sess->conn_lock); | 664 | spin_lock_bh(&sess->conn_lock); |
664 | list_add_tail(&conn->conn_list, &sess->sess_conn_list); | 665 | list_add_tail(&conn->conn_list, &sess->sess_conn_list); |
@@ -1020,6 +1021,18 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) | |||
1020 | snprintf(conn->login_ip, sizeof(conn->login_ip), "%pI6c", | 1021 | snprintf(conn->login_ip, sizeof(conn->login_ip), "%pI6c", |
1021 | &sock_in6.sin6_addr.in6_u); | 1022 | &sock_in6.sin6_addr.in6_u); |
1022 | conn->login_port = ntohs(sock_in6.sin6_port); | 1023 | conn->login_port = ntohs(sock_in6.sin6_port); |
1024 | |||
1025 | if (conn->sock->ops->getname(conn->sock, | ||
1026 | (struct sockaddr *)&sock_in6, &err, 0) < 0) { | ||
1027 | pr_err("sock_ops->getname() failed.\n"); | ||
1028 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, | ||
1029 | ISCSI_LOGIN_STATUS_TARGET_ERROR); | ||
1030 | goto new_sess_out; | ||
1031 | } | ||
1032 | snprintf(conn->local_ip, sizeof(conn->local_ip), "%pI6c", | ||
1033 | &sock_in6.sin6_addr.in6_u); | ||
1034 | conn->local_port = ntohs(sock_in6.sin6_port); | ||
1035 | |||
1023 | } else { | 1036 | } else { |
1024 | memset(&sock_in, 0, sizeof(struct sockaddr_in)); | 1037 | memset(&sock_in, 0, sizeof(struct sockaddr_in)); |
1025 | 1038 | ||
@@ -1032,6 +1045,16 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) | |||
1032 | } | 1045 | } |
1033 | sprintf(conn->login_ip, "%pI4", &sock_in.sin_addr.s_addr); | 1046 | sprintf(conn->login_ip, "%pI4", &sock_in.sin_addr.s_addr); |
1034 | conn->login_port = ntohs(sock_in.sin_port); | 1047 | conn->login_port = ntohs(sock_in.sin_port); |
1048 | |||
1049 | if (conn->sock->ops->getname(conn->sock, | ||
1050 | (struct sockaddr *)&sock_in, &err, 0) < 0) { | ||
1051 | pr_err("sock_ops->getname() failed.\n"); | ||
1052 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, | ||
1053 | ISCSI_LOGIN_STATUS_TARGET_ERROR); | ||
1054 | goto new_sess_out; | ||
1055 | } | ||
1056 | sprintf(conn->local_ip, "%pI4", &sock_in.sin_addr.s_addr); | ||
1057 | conn->local_port = ntohs(sock_in.sin_port); | ||
1035 | } | 1058 | } |
1036 | 1059 | ||
1037 | conn->network_transport = np->np_network_transport; | 1060 | conn->network_transport = np->np_network_transport; |
@@ -1039,7 +1062,7 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) | |||
1039 | pr_debug("Received iSCSI login request from %s on %s Network" | 1062 | pr_debug("Received iSCSI login request from %s on %s Network" |
1040 | " Portal %s:%hu\n", conn->login_ip, | 1063 | " Portal %s:%hu\n", conn->login_ip, |
1041 | (conn->network_transport == ISCSI_TCP) ? "TCP" : "SCTP", | 1064 | (conn->network_transport == ISCSI_TCP) ? "TCP" : "SCTP", |
1042 | np->np_ip, np->np_port); | 1065 | conn->local_ip, conn->local_port); |
1043 | 1066 | ||
1044 | pr_debug("Moving to TARG_CONN_STATE_IN_LOGIN.\n"); | 1067 | pr_debug("Moving to TARG_CONN_STATE_IN_LOGIN.\n"); |
1045 | conn->conn_state = TARG_CONN_STATE_IN_LOGIN; | 1068 | conn->conn_state = TARG_CONN_STATE_IN_LOGIN; |