Commit 420b2353 authored by Shuhei Matsumoto's avatar Shuhei Matsumoto Committed by Tomasz Zawadzki
Browse files

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: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Change-Id: I4573a69c0a32eafcfe48080a033c135e127da321
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/3221


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent 2c8309e0
Loading
Loading
Loading
Loading
+14 −5
Original line number Diff line number Diff line
@@ -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;
+25 −0
Original line number Diff line number Diff line
@@ -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)
{
+3 −0
Original line number Diff line number Diff line
@@ -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,
+5 −0
Original line number Diff line number Diff line
@@ -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),