@@ -423,6 +423,79 @@ const char *target_parse_pr_out_transport_id(struct se_portal_group *tpg,
return buf + offset;
}
+/**
+ * target_parse_emulated_name - parse TransportID and acl name from user buffer
+ * @proto_id: SCSI protocol identifier
+ * @user_buf: buffer with emualted name to extract acl and TransportID from
+ * @acl_name: buffer to store se_node_acl name in
+ * @max_name_len: len of acl_name buffer
+ * @tpt_id_name: Pointer to the TransportID name will be stored here.
+ */
+int target_parse_emulated_name(u8 proto_id, const char *user_buf,
+ unsigned char *acl_name, int max_name_len,
+ unsigned char **tpt_id_name)
+{
+ int user_len = strlen(user_buf);
+ char *proto_prefix, *name_start;
+
+ if (user_len >= max_name_len) {
+ pr_err("Emulated name: %s, exceeds max: %d\n", user_buf,
+ max_name_len);
+ return -EINVAL;
+ }
+
+ switch (proto_id) {
+ case SCSI_PROTOCOL_SAS:
+ proto_prefix = "naa.";
+ break;
+ case SCSI_PROTOCOL_FCP:
+ proto_prefix = "fc.";
+ break;
+ case SCSI_PROTOCOL_ISCSI:
+ proto_prefix = "iqn.";
+ break;
+ default:
+ pr_err("Unsupported proto_id: 0x%02x\n", proto_id);
+ return -EINVAL;
+ }
+
+ name_start = strstr(user_buf, proto_prefix);
+ if (!name_start) {
+ pr_err("Invalid emulated name %s. Must start with %s\n",
+ user_buf, proto_prefix);
+ return -EINVAL;
+ }
+
+ switch (proto_id) {
+ case SCSI_PROTOCOL_SAS:
+ sprintf(acl_name, name_start);
+ break;
+ case SCSI_PROTOCOL_FCP:
+ sprintf(acl_name, &name_start[3]); /* Skip over "fc." */
+ break;
+ case SCSI_PROTOCOL_ISCSI:
+ sprintf(acl_name, name_start);
+ break;
+ }
+
+ if (acl_name[user_len - 1] == '\n')
+ acl_name[user_len - 1] = '\0';
+
+ if (proto_id == SCSI_PROTOCOL_SAS) {
+ /*
+ * target_setup_session will want the naa. prefix to match
+ * the ACL name, but the t10 transport id only wants the
+ * address.
+ */
+ *tpt_id_name = acl_name + 4;
+ } else {
+ *tpt_id_name = acl_name;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(target_parse_emulated_name);
+
struct t10_transport_id *target_create_transport_id(u8 proto, const char *name,
const char *session_id)
{
@@ -125,6 +125,8 @@ struct target_core_fabric_ops {
int target_depend_item(struct config_item *item);
void target_undepend_item(struct config_item *item);
+int target_parse_emulated_name(u8, const char *, unsigned char *, int,
+ unsigned char **);
struct t10_transport_id *target_create_transport_id(u8, const char *,
const char *);
void target_free_transport_id(struct t10_transport_id *);