diff options
author | Yuri Pankov <yuri.pankov@nexenta.com> | 2016-03-07 02:14:50 +0300 |
---|---|---|
committer | Robert Mustacchi <rm@joyent.com> | 2016-03-25 20:04:13 -0700 |
commit | 1ef6182819f36233702ddc54686e703bb23a0153 (patch) | |
tree | de165fbd02b5cd13369c6417950a9928d7467a68 | |
parent | 2e27316f97ec8fac1caee78fe7fe05306261e070 (diff) | |
download | illumos-joyent-1ef6182819f36233702ddc54686e703bb23a0153.tar.gz |
2902 iscsit should fold the case of scsi names that we get from initiators
Reviewed by: Steve Peng <steve.peng@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Dan McDonald <danmcd@omniti.com>
Approved by: Robert Mustacchi <rm@joyent.com>
-rw-r--r-- | usr/src/pkg/manifests/system-header.mf | 3 | ||||
-rw-r--r-- | usr/src/uts/common/io/comstar/port/iscsit/iscsit_login.c | 79 | ||||
-rw-r--r-- | usr/src/uts/common/sys/Makefile | 4 | ||||
-rw-r--r-- | usr/src/uts/common/sys/scsi/scsi_names.h | 50 |
4 files changed, 127 insertions, 9 deletions
diff --git a/usr/src/pkg/manifests/system-header.mf b/usr/src/pkg/manifests/system-header.mf index 72efa63d8e..9cdcf6db6e 100644 --- a/usr/src/pkg/manifests/system-header.mf +++ b/usr/src/pkg/manifests/system-header.mf @@ -24,7 +24,7 @@ # Copyright (c) 2012 by Delphix. All rights reserved. # Copyright 2013 Saso Kiselkov. All rights reserved. # Copyright 2014 Garrett D'Amore <garrett@damore.org> -# Copyright 2015 Nexenta Systems, Inc. All rights reserved. +# Copyright 2016 Nexenta Systems, Inc. # set name=pkg.fmri value=pkg:/system/header@$(PKGVERS) @@ -1397,6 +1397,7 @@ file path=usr/include/sys/scsi/scsi.h file path=usr/include/sys/scsi/scsi_address.h file path=usr/include/sys/scsi/scsi_ctl.h file path=usr/include/sys/scsi/scsi_fm.h +file path=usr/include/sys/scsi/scsi_names.h file path=usr/include/sys/scsi/scsi_params.h file path=usr/include/sys/scsi/scsi_pkt.h file path=usr/include/sys/scsi/scsi_resource.h diff --git a/usr/src/uts/common/io/comstar/port/iscsit/iscsit_login.c b/usr/src/uts/common/io/comstar/port/iscsit/iscsit_login.c index f1306c438c..dc7549c9b3 100644 --- a/usr/src/uts/common/io/comstar/port/iscsit/iscsit_login.c +++ b/usr/src/uts/common/io/comstar/port/iscsit/iscsit_login.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2014 Nexenta Systems, Inc. All rights reserved. + * Copyright 2016 Nexenta Systems, Inc. */ #include <sys/cpuvar.h> @@ -32,12 +32,14 @@ #include <sys/sunddi.h> #include <sys/modctl.h> #include <sys/scsi/generic/persist.h> +#include <sys/scsi/scsi_names.h> #include <sys/socket.h> #include <sys/strsubr.h> #include <sys/sysmacros.h> #include <sys/note.h> #include <sys/sdt.h> +#include <sys/errno.h> #include <sys/stmf.h> #include <sys/stmf_ioctl.h> @@ -194,6 +196,9 @@ login_resp_complete_cb(idm_pdu_t *pdu, idm_status_t status); static idm_status_t iscsit_add_declarative_keys(iscsit_conn_t *ict); +static char * +iscsit_fold_name(char *name, size_t *buflen); + uint64_t max_dataseglen_target = ISCSIT_MAX_RECV_DATA_SEGMENT_LENGTH; /* @@ -1086,6 +1091,8 @@ login_sm_validate_initial_parameters(iscsit_conn_t *ict) { int nvrc; char *string_val; + char *u8_iscsi_name; + size_t u8_iscsi_name_len; uint8_t error_class = ISCSI_STATUS_CLASS_INITIATOR_ERR; uint8_t error_detail = ISCSI_LOGIN_STATUS_MISSING_FIELDS; idm_status_t status = IDM_STATUS_FAIL; @@ -1105,10 +1112,16 @@ login_sm_validate_initial_parameters(iscsit_conn_t *ict) "InitiatorName", &string_val)) != 0) { goto initial_params_done; } - if ((nvrc = nvlist_add_string(lsm->icl_negotiated_values, - "InitiatorName", string_val)) != 0) { + + u8_iscsi_name = iscsit_fold_name(string_val, &u8_iscsi_name_len); + if (u8_iscsi_name == NULL) goto initial_params_done; - } + nvrc = nvlist_add_string(lsm->icl_negotiated_values, "InitiatorName", + u8_iscsi_name); + kmem_free(u8_iscsi_name, u8_iscsi_name_len); + if (nvrc != 0) + goto initial_params_done; + if ((nvrc = nvlist_lookup_string(lsm->icl_negotiated_values, "InitiatorName", &string_val)) != 0) { goto initial_params_done; @@ -1155,10 +1168,15 @@ login_sm_validate_initial_parameters(iscsit_conn_t *ict) goto initial_params_done; } if (nvrc == 0) { - if ((nvrc = nvlist_add_string(lsm->icl_negotiated_values, - "TargetName", string_val)) != 0) { + u8_iscsi_name = iscsit_fold_name(string_val, + &u8_iscsi_name_len); + if (u8_iscsi_name == NULL) + goto initial_params_done; + nvrc = nvlist_add_string(lsm->icl_negotiated_values, + "TargetName", u8_iscsi_name); + kmem_free(u8_iscsi_name, u8_iscsi_name_len); + if (nvrc != 0) goto initial_params_done; - } if ((nvrc = nvlist_lookup_string(lsm->icl_negotiated_values, "TargetName", &string_val)) != 0) { goto initial_params_done; @@ -2692,3 +2710,50 @@ alloc_fail: } return (idm_status); } + +static char * +iscsit_fold_name(char *name, size_t *buflen) +{ + char *ret; + const char *sns; + int errnum; + int flag = U8_TEXTPREP_NFKC; + size_t inlen, outlen, coff; + + if (name == NULL) + return (NULL); + + /* Check for one of the supported name types */ + if (strncasecmp(name, SNS_EUI ".", strlen(SNS_EUI) + 1) == 0) { + sns = SNS_EUI; + *buflen = SNS_EUI_U8_LEN_MAX + 1; + flag |= U8_TEXTPREP_TOUPPER; + } else if (strncasecmp(name, SNS_IQN ".", strlen(SNS_IQN) + 1) == 0) { + sns = SNS_IQN; + *buflen = SNS_IQN_U8_LEN_MAX + 1; + flag |= U8_TEXTPREP_TOLOWER; + } else if (strncasecmp(name, SNS_NAA ".", strlen(SNS_NAA) + 1) == 0) { + sns = SNS_NAA; + *buflen = SNS_NAA_U8_LEN_MAX + 1; + flag |= U8_TEXTPREP_TOUPPER; + } else { + return (NULL); + } + + ret = kmem_zalloc(*buflen, KM_SLEEP); + coff = strlen(sns); + inlen = strlen(name) - coff; + outlen = *buflen - coff; + + /* Fold the case and normalize string */ + if (u8_textprep_str(name + coff, &inlen, ret + coff, &outlen, flag, + U8_UNICODE_320, &errnum) == (size_t)-1) { + kmem_free(ret, *buflen); + return (NULL); + } + + /* Copy the name type prefix */ + bcopy(sns, ret, coff); + + return (ret); +} diff --git a/usr/src/uts/common/sys/Makefile b/usr/src/uts/common/sys/Makefile index 99b877c0a3..d5dd20bff9 100644 --- a/usr/src/uts/common/sys/Makefile +++ b/usr/src/uts/common/sys/Makefile @@ -18,13 +18,14 @@ # # CDDL HEADER END # + # # Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright 2014, Joyent, Inc. All rights reserved. # Copyright 2013 Garrett D'Amore <garrett@damore.org> # Copyright 2013 Saso Kiselkov. All rights reserved. -# Copyright 2015 Nexenta Systems, Inc. All rights reserved. # Copyright 2015 Igor Kozhukhov <ikozhukhov@gmail.com> +# Copyright 2016 Nexenta Systems, Inc. # include $(SRC)/uts/Makefile.uts @@ -899,6 +900,7 @@ SCSIHDRS= \ scsi_address.h \ scsi_ctl.h \ scsi_fm.h \ + scsi_names.h \ scsi_params.h \ scsi_pkt.h \ scsi_resource.h \ diff --git a/usr/src/uts/common/sys/scsi/scsi_names.h b/usr/src/uts/common/sys/scsi/scsi_names.h new file mode 100644 index 0000000000..349020d58a --- /dev/null +++ b/usr/src/uts/common/sys/scsi/scsi_names.h @@ -0,0 +1,50 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2016 Nexenta Systems, Inc. + */ + +#ifndef _SYS_SCSI_SCSI_NAMES_H_ +#define _SYS_SCSI_SCSI_NAMES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* SCSI Name Strings */ +#define SNS_EUI "eui" +#define SNS_IQN "iqn" +#define SNS_MAC "mac" +#define SNS_NAA "naa" +#define SNS_WWN "wwn" + +/* SCSI Name String maximum length definitions */ +#define SNS_EUI_16 16 +#define SNS_IQN_223 223 +#define SNS_MAC_12 12 +#define SNS_NAA_16 16 +#define SNS_NAA_32 32 +#define SNS_WWN_16 16 + +/* + * Maximum number of bytes needed to store SCSI Name Strings in UTF-8 format, + * assuming that (per RFC3629) one UTF-8 character can take up to 4 bytes. + */ +#define SNS_EUI_U8_LEN_MAX (SNS_EUI_16 * 4) +#define SNS_IQN_U8_LEN_MAX (SNS_IQN_223 * 4) +#define SNS_NAA_U8_LEN_MAX (SNS_NAA_32 * 4) + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_SCSI_SCSI_NAMES_H_ */ |