Now only iSCSI TransportID is parsed. From other protocols the binary representation is passed to tcm core. That is wrong as that TID is compared against nacl->initiatorname which is in human readable format. This patch adds a parsing of TID for other protocols. Signed-off-by: Dmitry Bogdanov <d.bogdanov@xxxxxxxxx> --- drivers/target/target_core_fabric_lib.c | 119 ++++++++++++++++-------- drivers/target/target_core_internal.h | 4 +- drivers/target/target_core_pr.c | 14 ++- 3 files changed, 89 insertions(+), 48 deletions(-) diff --git a/drivers/target/target_core_fabric_lib.c b/drivers/target/target_core_fabric_lib.c index 32c2afbb3033..34fdab558e24 100644 --- a/drivers/target/target_core_fabric_lib.c +++ b/drivers/target/target_core_fabric_lib.c @@ -214,15 +214,67 @@ static int iscsi_get_pr_transport_id( return len; } -static char *iscsi_parse_pr_out_transport_id( - struct se_portal_group *se_tpg, - char *buf, - u32 *out_tid_len, +static u32 sas_parse_pr_out_transport_id( + const char *buf, + char *initiatorname, + char **port_nexus_ptr) +{ + char port_name[17]; + + bin2hex(port_name, buf + 4, 8); + snprintf(initiatorname, 36, "naa.%s", port_name); + + return 24; +} + + +static u32 sbp_parse_pr_out_transport_id( + const char *buf, + char *initiatorname, + char **port_nexus_ptr) +{ + bin2hex(initiatorname, buf + 8, 8); + + return 24; +} + +static u32 srp_parse_pr_out_transport_id( + const char *buf, + char *initiatorname, + char **port_nexus_ptr) +{ + char port_name[33]; + + bin2hex(port_name, buf + 8, 16); + snprintf(initiatorname, 36, "0x%s", port_name); + + return 24; +} + +static u32 fc_parse_pr_out_transport_id( + const char *buf, + char *initiatorname, + char **port_nexus_ptr) +{ + /* + * Format the FCP Initiator port_name into colon separated values to + * match the format by tcm_qla2xxx explicit ConfigFS NodeACLs. + */ + snprintf(initiatorname, 36, "%8phC", buf + 8); + + return 24; +} + +u32 iscsi_parse_pr_out_transport_id( + const char *buf, + char *initiatorname, char **port_nexus_ptr) { char *p; int i; u8 format_code = (buf[0] & 0xc0); + u32 out_tid_len; + /* * Check for FORMAT CODE 00b or 01b from spc4r17, section 7.5.4.6: * @@ -239,18 +291,10 @@ static char *iscsi_parse_pr_out_transport_id( if ((format_code != 0x00) && (format_code != 0x40)) { pr_err("Illegal format code: 0x%02x for iSCSI" " Initiator Transport ID\n", format_code); - return NULL; - } - /* - * If the caller wants the TransportID Length, we set that value for the - * entire iSCSI Tarnsport ID now. - */ - if (out_tid_len) { - /* The shift works thanks to integer promotion rules */ - *out_tid_len = get_unaligned_be16(&buf[2]); - /* Add four bytes for iSCSI Transport ID header */ - *out_tid_len += 4; + return 0; } + /* The shift works thanks to integer promotion rules */ + out_tid_len = get_unaligned_be16(&buf[2]); /* * Check for ',i,0x' separator between iSCSI Name and iSCSI Initiator @@ -263,9 +307,10 @@ static char *iscsi_parse_pr_out_transport_id( pr_err("Unable to locate \",i,0x\" separator" " for Initiator port identifier: %s\n", &buf[4]); - return NULL; + return 0; } - *p = '\0'; /* Terminate iSCSI Name */ + memcpy(initiatorname, &buf[4], p - buf - 4); + initiatorname[p - buf - 4] = '\0'; /* Terminate iSCSI Name */ p += 5; /* Skip over ",i,0x" separator */ *port_nexus_ptr = p; @@ -293,10 +338,16 @@ static char *iscsi_parse_pr_out_transport_id( *p = tolower(*p); p++; } - } else + } else { + strscpy(initiatorname, &buf[4], out_tid_len); + initiatorname[p - buf] = '\0'; /* Terminate iSCSI Name */ *port_nexus_ptr = NULL; + } + + /* Add four bytes for iSCSI Transport ID header */ + out_tid_len += 4; - return &buf[4]; + return out_tid_len; } int target_get_pr_transport_id_len(struct t10_pr_registration *pr_reg) @@ -351,33 +402,25 @@ int target_gen_pr_transport_id( } } -const char *target_parse_pr_out_transport_id(struct se_portal_group *tpg, - char *buf, u32 *out_tid_len, char **port_nexus_ptr) +u32 target_parse_pr_out_transport_id( + const char *buf, char *initiatorname, char **port_nexus_ptr) { - u32 offset; - - switch (tpg->proto_id) { + switch (buf[0] & 0xF) { case SCSI_PROTOCOL_SAS: - /* - * Assume the FORMAT CODE 00b from spc4r17, 7.5.4.7 TransportID - * for initiator ports using SCSI over SAS Serial SCSI Protocol. - */ - offset = 4; - break; + return sas_parse_pr_out_transport_id(buf, initiatorname, port_nexus_ptr); case SCSI_PROTOCOL_SBP: + return sbp_parse_pr_out_transport_id(buf, initiatorname, port_nexus_ptr); case SCSI_PROTOCOL_SRP: + return srp_parse_pr_out_transport_id(buf, initiatorname, port_nexus_ptr); case SCSI_PROTOCOL_FCP: - offset = 8; - break; + return fc_parse_pr_out_transport_id(buf, initiatorname, port_nexus_ptr); case SCSI_PROTOCOL_ISCSI: - return iscsi_parse_pr_out_transport_id(tpg, buf, out_tid_len, - port_nexus_ptr); + return iscsi_parse_pr_out_transport_id(buf, initiatorname, port_nexus_ptr); default: - pr_err("Unknown proto_id: 0x%02x\n", tpg->proto_id); - return NULL; + pr_err("Unknown proto_id: 0x%02x\n", buf[0] & 0xF); + return 0; } *port_nexus_ptr = NULL; - *out_tid_len = 24; - return buf + offset; + return 24; } diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h index 51c0151c05c2..bbdddcd83fa4 100644 --- a/drivers/target/target_core_internal.h +++ b/drivers/target/target_core_internal.h @@ -105,8 +105,8 @@ int target_gen_pr_transport_id(struct t10_pr_registration *pr_reg, int proto_id, const char *initiatorname, unsigned char *isid); -const char *target_parse_pr_out_transport_id(struct se_portal_group *tpg, - char *buf, u32 *out_tid_len, char **port_nexus_ptr); +u32 target_parse_pr_out_transport_id( + const char *buf, char *initiatorname, char **port_nexus_ptr); /* target_core_hba.c */ struct se_hba *core_alloc_hba(const char *, u32, u32); diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index c4ee6999cf96..f5796d60ed76 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -1419,7 +1419,7 @@ core_scsi3_decode_spec_i_port( LIST_HEAD(tid_dest_list); struct pr_transport_id_holder *tidh_new, *tidh, *tidh_tmp; unsigned char *buf, *ptr, proto_ident; - const unsigned char *i_str = NULL; + unsigned char i_str[TRANSPORT_IQN_LEN] = {0}; char *iport_ptr = NULL, i_buf[PR_REG_ISID_ID_LEN]; sense_reason_t ret; u32 tpdl, tid_len = 0; @@ -1512,9 +1512,8 @@ core_scsi3_decode_spec_i_port( dest_rtpi = tmp_lun->lun_tpg->tpg_rtpi; iport_ptr = NULL; - i_str = target_parse_pr_out_transport_id(tmp_tpg, - ptr, &tid_len, &iport_ptr); - if (!i_str) + tid_len = target_parse_pr_out_transport_id(ptr, i_str, &iport_ptr); + if (!tid_len) continue; /* * Determine if this SCSI device server requires that @@ -3087,7 +3086,7 @@ core_scsi3_emulate_pro_register_and_move(struct se_cmd *cmd, u64 res_key, struct t10_pr_registration *pr_reg, *pr_res_holder, *dest_pr_reg; struct t10_reservation *pr_tmpl = &dev->t10_pr; unsigned char *buf; - const unsigned char *initiator_str; + unsigned char initiator_str[TRANSPORT_IQN_LEN] = { }; char *iport_ptr = NULL, i_buf[PR_REG_ISID_ID_LEN] = { }; u32 tid_len, tmp_tid_len; int new_reg = 0, type, scope, matching_iname; @@ -3212,9 +3211,8 @@ core_scsi3_emulate_pro_register_and_move(struct se_cmd *cmd, u64 res_key, ret = TCM_INVALID_PARAMETER_LIST; goto out; } - initiator_str = target_parse_pr_out_transport_id(dest_se_tpg, - &buf[24], &tmp_tid_len, &iport_ptr); - if (!initiator_str) { + tmp_tid_len = target_parse_pr_out_transport_id(&buf[24], initiator_str, &iport_ptr); + if (!tmp_tid_len) { pr_err("SPC-3 PR REGISTER_AND_MOVE: Unable to locate" " initiator_str from Transport ID\n"); ret = TCM_INVALID_PARAMETER_LIST; -- 2.25.1