lib/iscsi: Inform initiator that target has temporary moved to a different address

If the portal group map of the target has a redirect portal,
iscsi_tgt_node_is_moved() fills the buffer by the redirected address
and returns true.

iscsi_op_login_check_target() calls iscsi_tgt_node_is_redirected() before
calling iscsi_tgt_node_access() because login redirection can be
checked before any or after all security check.

If iscsi_tgt_node_is_redirected() returns true, notify login redirection
to the corresponding initiator.

Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Change-Id: I4573a69c0a32eafcfe48080a033c135e127da321
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/3221
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Shuhei Matsumoto 2020-08-10 00:41:40 +09:00 committed by Tomasz Zawadzki
parent 2c8309e00e
commit 420b2353ea
4 changed files with 47 additions and 5 deletions

View File

@ -1427,8 +1427,8 @@ iscsi_op_login_check_target(struct spdk_iscsi_conn *conn,
const char *target_name,
struct spdk_iscsi_tgt_node **target)
{
bool result;
struct iscsi_bhs_login_rsp *rsph;
char buf[MAX_TMPBUF] = {};
rsph = (struct iscsi_bhs_login_rsp *)&rsp_pdu->bhs;
*target = iscsi_find_tgt_node(target_name);
@ -1445,10 +1445,19 @@ iscsi_op_login_check_target(struct spdk_iscsi_conn *conn,
rsph->status_detail = ISCSI_LOGIN_TARGET_REMOVED;
return SPDK_ISCSI_LOGIN_ERROR_RESPONSE;
}
result = iscsi_tgt_node_access(conn, *target,
conn->initiator_name,
conn->initiator_addr);
if (!result) {
if (iscsi_tgt_node_is_redirected(conn, *target, buf, MAX_TMPBUF)) {
SPDK_INFOLOG(SPDK_LOG_ISCSI, "target %s is redirectd\n", target_name);
rsp_pdu->data_segment_len = iscsi_append_text("TargetAddress",
buf,
rsp_pdu->data,
rsp_pdu->data_buf_len,
rsp_pdu->data_segment_len);
rsph->status_class = ISCSI_CLASS_REDIRECT;
rsph->status_detail = ISCSI_LOGIN_TARGET_TEMPORARILY_MOVED;
return SPDK_ISCSI_LOGIN_ERROR_RESPONSE;
}
if (!iscsi_tgt_node_access(conn, *target, conn->initiator_name,
conn->initiator_addr)) {
SPDK_ERRLOG("access denied\n");
rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR;
rsph->status_detail = ISCSI_LOGIN_AUTHORIZATION_FAIL;

View File

@ -914,6 +914,31 @@ iscsi_tgt_node_redirect(struct spdk_iscsi_tgt_node *target, int pg_tag,
return 0;
}
bool
iscsi_tgt_node_is_redirected(struct spdk_iscsi_conn *conn,
struct spdk_iscsi_tgt_node *target,
char *buf, int buf_len)
{
struct spdk_iscsi_pg_map *pg_map;
if (conn == NULL || target == NULL || buf == NULL || buf_len == 0) {
return false;
}
pg_map = iscsi_tgt_node_find_pg_map(target, conn->portal->group);
if (pg_map == NULL) {
return false;
}
if (pg_map->redirect_host[0] == '\0' || pg_map->redirect_port[0] == '\0') {
return false;
}
snprintf(buf, buf_len, "%s:%s", pg_map->redirect_host, pg_map->redirect_port);
return true;
}
static int
check_iscsi_name(const char *name)
{

View File

@ -130,6 +130,9 @@ int iscsi_target_node_remove_pg_ig_maps(struct spdk_iscsi_tgt_node *target,
uint16_t num_maps);
int iscsi_tgt_node_redirect(struct spdk_iscsi_tgt_node *target, int pg_tag,
const char *host, const char *port);
bool iscsi_tgt_node_is_redirected(struct spdk_iscsi_conn *conn,
struct spdk_iscsi_tgt_node *target,
char *buf, int buf_len);
bool iscsi_tgt_node_access(struct spdk_iscsi_conn *conn,
struct spdk_iscsi_tgt_node *target, const char *iqn,

View File

@ -79,6 +79,11 @@ iscsi_tgt_node_access(struct spdk_iscsi_conn *conn,
}
}
DEFINE_STUB(iscsi_tgt_node_is_redirected, bool,
(struct spdk_iscsi_conn *conn, struct spdk_iscsi_tgt_node *target,
char *buf, int buf_len),
false);
DEFINE_STUB(iscsi_send_tgts, int,
(struct spdk_iscsi_conn *conn, const char *iiqn,
const char *tiqn, uint8_t *data, int alloc_len, int data_len),