iscsi-target: Add login_keys_workaround attribute for non RFC initiators
commit 138d351eefb727ab9e41a3dc5f112ceb4f6e59f2 upstream. This patch re-introduces part of a long standing login workaround that was recently dropped by: commit 1c99de981f30b3e7868b8d20ce5479fa1c0fea46 Author: Nicholas Bellinger <nab@linux-iscsi.org> Date: Sun Apr 2 13:36:44 2017 -0700 iscsi-target: Drop work-around for legacy GlobalSAN initiator Namely, the workaround for FirstBurstLength ended up being required by Mellanox Flexboot PXE boot ROMs as reported by Robert. So this patch re-adds the work-around for FirstBurstLength within iscsi_check_proposer_for_optional_reply(), and makes the key optional to respond when the initiator does not propose, nor respond to it. Also as requested by Arun, this patch introduces a new TPG attribute named 'login_keys_workaround' that controls the use of both the FirstBurstLength workaround, as well as the two other existing workarounds for gPXE iSCSI boot client. By default, the workaround is enabled with login_keys_workaround=1, since Mellanox FlexBoot requires it, and Arun has verified the Qlogic MSFT initiator already proposes FirstBurstLength, so it's uneffected by this re-adding this part of the original work-around. Reported-by: Robert LeBlanc <robert@leblancnet.us> Cc: Robert LeBlanc <robert@leblancnet.us> Reviewed-by: Arun Easi <arun.easi@cavium.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
8045fe0a20
commit
c50e87ecca
7 changed files with 64 additions and 16 deletions
|
@ -868,6 +868,7 @@ DEF_TPG_ATTRIB(default_erl);
|
||||||
DEF_TPG_ATTRIB(t10_pi);
|
DEF_TPG_ATTRIB(t10_pi);
|
||||||
DEF_TPG_ATTRIB(fabric_prot_type);
|
DEF_TPG_ATTRIB(fabric_prot_type);
|
||||||
DEF_TPG_ATTRIB(tpg_enabled_sendtargets);
|
DEF_TPG_ATTRIB(tpg_enabled_sendtargets);
|
||||||
|
DEF_TPG_ATTRIB(login_keys_workaround);
|
||||||
|
|
||||||
static struct configfs_attribute *lio_target_tpg_attrib_attrs[] = {
|
static struct configfs_attribute *lio_target_tpg_attrib_attrs[] = {
|
||||||
&iscsi_tpg_attrib_attr_authentication,
|
&iscsi_tpg_attrib_attr_authentication,
|
||||||
|
@ -883,6 +884,7 @@ static struct configfs_attribute *lio_target_tpg_attrib_attrs[] = {
|
||||||
&iscsi_tpg_attrib_attr_t10_pi,
|
&iscsi_tpg_attrib_attr_t10_pi,
|
||||||
&iscsi_tpg_attrib_attr_fabric_prot_type,
|
&iscsi_tpg_attrib_attr_fabric_prot_type,
|
||||||
&iscsi_tpg_attrib_attr_tpg_enabled_sendtargets,
|
&iscsi_tpg_attrib_attr_tpg_enabled_sendtargets,
|
||||||
|
&iscsi_tpg_attrib_attr_login_keys_workaround,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -818,7 +818,8 @@ static int iscsi_target_handle_csg_zero(
|
||||||
SENDER_TARGET,
|
SENDER_TARGET,
|
||||||
login->rsp_buf,
|
login->rsp_buf,
|
||||||
&login->rsp_length,
|
&login->rsp_length,
|
||||||
conn->param_list);
|
conn->param_list,
|
||||||
|
conn->tpg->tpg_attrib.login_keys_workaround);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -888,7 +889,8 @@ static int iscsi_target_handle_csg_one(struct iscsi_conn *conn, struct iscsi_log
|
||||||
SENDER_TARGET,
|
SENDER_TARGET,
|
||||||
login->rsp_buf,
|
login->rsp_buf,
|
||||||
&login->rsp_length,
|
&login->rsp_length,
|
||||||
conn->param_list);
|
conn->param_list,
|
||||||
|
conn->tpg->tpg_attrib.login_keys_workaround);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
|
iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
|
||||||
ISCSI_LOGIN_STATUS_INIT_ERR);
|
ISCSI_LOGIN_STATUS_INIT_ERR);
|
||||||
|
|
|
@ -764,7 +764,8 @@ static int iscsi_check_for_auth_key(char *key)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void iscsi_check_proposer_for_optional_reply(struct iscsi_param *param)
|
static void iscsi_check_proposer_for_optional_reply(struct iscsi_param *param,
|
||||||
|
bool keys_workaround)
|
||||||
{
|
{
|
||||||
if (IS_TYPE_BOOL_AND(param)) {
|
if (IS_TYPE_BOOL_AND(param)) {
|
||||||
if (!strcmp(param->value, NO))
|
if (!strcmp(param->value, NO))
|
||||||
|
@ -772,19 +773,31 @@ static void iscsi_check_proposer_for_optional_reply(struct iscsi_param *param)
|
||||||
} else if (IS_TYPE_BOOL_OR(param)) {
|
} else if (IS_TYPE_BOOL_OR(param)) {
|
||||||
if (!strcmp(param->value, YES))
|
if (!strcmp(param->value, YES))
|
||||||
SET_PSTATE_REPLY_OPTIONAL(param);
|
SET_PSTATE_REPLY_OPTIONAL(param);
|
||||||
/*
|
|
||||||
* Required for gPXE iSCSI boot client
|
if (keys_workaround) {
|
||||||
*/
|
/*
|
||||||
if (!strcmp(param->name, IMMEDIATEDATA))
|
* Required for gPXE iSCSI boot client
|
||||||
SET_PSTATE_REPLY_OPTIONAL(param);
|
*/
|
||||||
|
if (!strcmp(param->name, IMMEDIATEDATA))
|
||||||
|
SET_PSTATE_REPLY_OPTIONAL(param);
|
||||||
|
}
|
||||||
} else if (IS_TYPE_NUMBER(param)) {
|
} else if (IS_TYPE_NUMBER(param)) {
|
||||||
if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH))
|
if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH))
|
||||||
SET_PSTATE_REPLY_OPTIONAL(param);
|
SET_PSTATE_REPLY_OPTIONAL(param);
|
||||||
/*
|
|
||||||
* Required for gPXE iSCSI boot client
|
if (keys_workaround) {
|
||||||
*/
|
/*
|
||||||
if (!strcmp(param->name, MAXCONNECTIONS))
|
* Required for Mellanox Flexboot PXE boot ROM
|
||||||
SET_PSTATE_REPLY_OPTIONAL(param);
|
*/
|
||||||
|
if (!strcmp(param->name, FIRSTBURSTLENGTH))
|
||||||
|
SET_PSTATE_REPLY_OPTIONAL(param);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Required for gPXE iSCSI boot client
|
||||||
|
*/
|
||||||
|
if (!strcmp(param->name, MAXCONNECTIONS))
|
||||||
|
SET_PSTATE_REPLY_OPTIONAL(param);
|
||||||
|
}
|
||||||
} else if (IS_PHASE_DECLARATIVE(param))
|
} else if (IS_PHASE_DECLARATIVE(param))
|
||||||
SET_PSTATE_REPLY_OPTIONAL(param);
|
SET_PSTATE_REPLY_OPTIONAL(param);
|
||||||
}
|
}
|
||||||
|
@ -1421,7 +1434,8 @@ int iscsi_encode_text_output(
|
||||||
u8 sender,
|
u8 sender,
|
||||||
char *textbuf,
|
char *textbuf,
|
||||||
u32 *length,
|
u32 *length,
|
||||||
struct iscsi_param_list *param_list)
|
struct iscsi_param_list *param_list,
|
||||||
|
bool keys_workaround)
|
||||||
{
|
{
|
||||||
char *output_buf = NULL;
|
char *output_buf = NULL;
|
||||||
struct iscsi_extra_response *er;
|
struct iscsi_extra_response *er;
|
||||||
|
@ -1457,7 +1471,8 @@ int iscsi_encode_text_output(
|
||||||
*length += 1;
|
*length += 1;
|
||||||
output_buf = textbuf + *length;
|
output_buf = textbuf + *length;
|
||||||
SET_PSTATE_PROPOSER(param);
|
SET_PSTATE_PROPOSER(param);
|
||||||
iscsi_check_proposer_for_optional_reply(param);
|
iscsi_check_proposer_for_optional_reply(param,
|
||||||
|
keys_workaround);
|
||||||
pr_debug("Sending key: %s=%s\n",
|
pr_debug("Sending key: %s=%s\n",
|
||||||
param->name, param->value);
|
param->name, param->value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ extern int iscsi_extract_key_value(char *, char **, char **);
|
||||||
extern int iscsi_update_param_value(struct iscsi_param *, char *);
|
extern int iscsi_update_param_value(struct iscsi_param *, char *);
|
||||||
extern int iscsi_decode_text_input(u8, u8, char *, u32, struct iscsi_conn *);
|
extern int iscsi_decode_text_input(u8, u8, char *, u32, struct iscsi_conn *);
|
||||||
extern int iscsi_encode_text_output(u8, u8, char *, u32 *,
|
extern int iscsi_encode_text_output(u8, u8, char *, u32 *,
|
||||||
struct iscsi_param_list *);
|
struct iscsi_param_list *, bool);
|
||||||
extern int iscsi_check_negotiated_keys(struct iscsi_param_list *);
|
extern int iscsi_check_negotiated_keys(struct iscsi_param_list *);
|
||||||
extern void iscsi_set_connection_parameters(struct iscsi_conn_ops *,
|
extern void iscsi_set_connection_parameters(struct iscsi_conn_ops *,
|
||||||
struct iscsi_param_list *);
|
struct iscsi_param_list *);
|
||||||
|
|
|
@ -227,6 +227,7 @@ static void iscsit_set_default_tpg_attribs(struct iscsi_portal_group *tpg)
|
||||||
a->t10_pi = TA_DEFAULT_T10_PI;
|
a->t10_pi = TA_DEFAULT_T10_PI;
|
||||||
a->fabric_prot_type = TA_DEFAULT_FABRIC_PROT_TYPE;
|
a->fabric_prot_type = TA_DEFAULT_FABRIC_PROT_TYPE;
|
||||||
a->tpg_enabled_sendtargets = TA_DEFAULT_TPG_ENABLED_SENDTARGETS;
|
a->tpg_enabled_sendtargets = TA_DEFAULT_TPG_ENABLED_SENDTARGETS;
|
||||||
|
a->login_keys_workaround = TA_DEFAULT_LOGIN_KEYS_WORKAROUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
int iscsit_tpg_add_portal_group(struct iscsi_tiqn *tiqn, struct iscsi_portal_group *tpg)
|
int iscsit_tpg_add_portal_group(struct iscsi_tiqn *tiqn, struct iscsi_portal_group *tpg)
|
||||||
|
@ -899,3 +900,21 @@ int iscsit_ta_tpg_enabled_sendtargets(
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int iscsit_ta_login_keys_workaround(
|
||||||
|
struct iscsi_portal_group *tpg,
|
||||||
|
u32 flag)
|
||||||
|
{
|
||||||
|
struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
|
||||||
|
|
||||||
|
if ((flag != 0) && (flag != 1)) {
|
||||||
|
pr_err("Illegal value %d\n", flag);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
a->login_keys_workaround = flag;
|
||||||
|
pr_debug("iSCSI_TPG[%hu] - TPG enabled bit for login keys workaround: %s ",
|
||||||
|
tpg->tpgt, (a->login_keys_workaround) ? "ON" : "OFF");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -39,5 +39,6 @@ extern int iscsit_ta_default_erl(struct iscsi_portal_group *, u32);
|
||||||
extern int iscsit_ta_t10_pi(struct iscsi_portal_group *, u32);
|
extern int iscsit_ta_t10_pi(struct iscsi_portal_group *, u32);
|
||||||
extern int iscsit_ta_fabric_prot_type(struct iscsi_portal_group *, u32);
|
extern int iscsit_ta_fabric_prot_type(struct iscsi_portal_group *, u32);
|
||||||
extern int iscsit_ta_tpg_enabled_sendtargets(struct iscsi_portal_group *, u32);
|
extern int iscsit_ta_tpg_enabled_sendtargets(struct iscsi_portal_group *, u32);
|
||||||
|
extern int iscsit_ta_login_keys_workaround(struct iscsi_portal_group *, u32);
|
||||||
|
|
||||||
#endif /* ISCSI_TARGET_TPG_H */
|
#endif /* ISCSI_TARGET_TPG_H */
|
||||||
|
|
|
@ -64,6 +64,14 @@
|
||||||
#define TA_DEFAULT_FABRIC_PROT_TYPE 0
|
#define TA_DEFAULT_FABRIC_PROT_TYPE 0
|
||||||
/* TPG status needs to be enabled to return sendtargets discovery endpoint info */
|
/* TPG status needs to be enabled to return sendtargets discovery endpoint info */
|
||||||
#define TA_DEFAULT_TPG_ENABLED_SENDTARGETS 1
|
#define TA_DEFAULT_TPG_ENABLED_SENDTARGETS 1
|
||||||
|
/*
|
||||||
|
* Used to control the sending of keys with optional to respond state bit,
|
||||||
|
* as a workaround for non RFC compliant initiators,that do not propose,
|
||||||
|
* nor respond to specific keys required for login to complete.
|
||||||
|
*
|
||||||
|
* See iscsi_check_proposer_for_optional_reply() for more details.
|
||||||
|
*/
|
||||||
|
#define TA_DEFAULT_LOGIN_KEYS_WORKAROUND 1
|
||||||
|
|
||||||
#define ISCSI_IOV_DATA_BUFFER 5
|
#define ISCSI_IOV_DATA_BUFFER 5
|
||||||
|
|
||||||
|
@ -765,6 +773,7 @@ struct iscsi_tpg_attrib {
|
||||||
u8 t10_pi;
|
u8 t10_pi;
|
||||||
u32 fabric_prot_type;
|
u32 fabric_prot_type;
|
||||||
u32 tpg_enabled_sendtargets;
|
u32 tpg_enabled_sendtargets;
|
||||||
|
u32 login_keys_workaround;
|
||||||
struct iscsi_portal_group *tpg;
|
struct iscsi_portal_group *tpg;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue