mirror of https://gitee.com/openkylin/linux.git
[SCSI] libfc: recode incoming PRLI handling
Reduce indentation in fc_rport_recv_prli_req() using gotos. Also add payload length checks. Signed-off-by: Joe Eykholt <jeykholt@cisco.com> Signed-off-by: Robert Love <robert.w.love@intel.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
This commit is contained in:
parent
fc193172e6
commit
a2f6a024e1
|
@ -1442,59 +1442,39 @@ static void fc_rport_recv_prli_req(struct fc_rport_priv *rdata,
|
|||
struct fc_els_spp *spp; /* response spp */
|
||||
unsigned int len;
|
||||
unsigned int plen;
|
||||
enum fc_els_rjt_reason reason = ELS_RJT_UNAB;
|
||||
enum fc_els_rjt_explan explan = ELS_EXPL_NONE;
|
||||
enum fc_els_spp_resp resp;
|
||||
struct fc_seq_els_data rjt_data;
|
||||
u32 f_ctl;
|
||||
u32 fcp_parm;
|
||||
u32 roles = FC_RPORT_ROLE_UNKNOWN;
|
||||
rjt_data.fp = NULL;
|
||||
|
||||
rjt_data.fp = NULL;
|
||||
fh = fc_frame_header_get(rx_fp);
|
||||
|
||||
FC_RPORT_DBG(rdata, "Received PRLI request while in state %s\n",
|
||||
fc_rport_state(rdata));
|
||||
|
||||
switch (rdata->rp_state) {
|
||||
case RPORT_ST_PRLI:
|
||||
case RPORT_ST_RTV:
|
||||
case RPORT_ST_READY:
|
||||
case RPORT_ST_ADISC:
|
||||
reason = ELS_RJT_NONE;
|
||||
break;
|
||||
default:
|
||||
fc_frame_free(rx_fp);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
len = fr_len(rx_fp) - sizeof(*fh);
|
||||
pp = fc_frame_payload_get(rx_fp, sizeof(*pp));
|
||||
if (pp == NULL) {
|
||||
reason = ELS_RJT_PROT;
|
||||
explan = ELS_EXPL_INV_LEN;
|
||||
} else {
|
||||
if (!pp)
|
||||
goto reject_len;
|
||||
plen = ntohs(pp->prli.prli_len);
|
||||
if ((plen % 4) != 0 || plen > len) {
|
||||
reason = ELS_RJT_PROT;
|
||||
explan = ELS_EXPL_INV_LEN;
|
||||
} else if (plen < len) {
|
||||
if ((plen % 4) != 0 || plen > len || plen < 16)
|
||||
goto reject_len;
|
||||
if (plen < len)
|
||||
len = plen;
|
||||
}
|
||||
plen = pp->prli.prli_spp_len;
|
||||
if ((plen % 4) != 0 || plen < sizeof(*spp) ||
|
||||
plen > len || len < sizeof(*pp)) {
|
||||
reason = ELS_RJT_PROT;
|
||||
explan = ELS_EXPL_INV_LEN;
|
||||
}
|
||||
plen > len || len < sizeof(*pp) || plen < 12)
|
||||
goto reject_len;
|
||||
rspp = &pp->spp;
|
||||
|
||||
fp = fc_frame_alloc(lport, len);
|
||||
if (!fp) {
|
||||
rjt_data.reason = ELS_RJT_UNAB;
|
||||
rjt_data.explan = ELS_EXPL_INSUF_RES;
|
||||
goto reject;
|
||||
}
|
||||
if (reason != ELS_RJT_NONE ||
|
||||
(fp = fc_frame_alloc(lport, len)) == NULL) {
|
||||
rjt_data.reason = reason;
|
||||
rjt_data.explan = explan;
|
||||
lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data);
|
||||
} else {
|
||||
sp = lport->tt.seq_start_next(sp);
|
||||
WARN_ON(!sp);
|
||||
pp = fc_frame_payload_get(fp, len);
|
||||
|
@ -1519,8 +1499,7 @@ static void fc_rport_recv_prli_req(struct fc_rport_priv *rdata,
|
|||
spp->spp_type_ext = rspp->spp_type_ext;
|
||||
spp->spp_flags = rspp->spp_flags & FC_SPP_EST_IMG_PAIR;
|
||||
resp = FC_SPP_RESP_ACK;
|
||||
if (rspp->spp_flags & FC_SPP_RPA_VAL)
|
||||
resp = FC_SPP_RESP_NO_PA;
|
||||
|
||||
switch (rspp->spp_type) {
|
||||
case 0: /* common to all FC-4 types */
|
||||
break;
|
||||
|
@ -1535,8 +1514,7 @@ static void fc_rport_recv_prli_req(struct fc_rport_priv *rdata,
|
|||
roles |= FC_RPORT_ROLE_FCP_TARGET;
|
||||
rdata->ids.roles = roles;
|
||||
|
||||
spp->spp_params =
|
||||
htonl(lport->service_params);
|
||||
spp->spp_params = htonl(lport->service_params);
|
||||
break;
|
||||
default:
|
||||
resp = FC_SPP_RESP_INVL;
|
||||
|
@ -1558,20 +1536,21 @@ static void fc_rport_recv_prli_req(struct fc_rport_priv *rdata,
|
|||
FC_TYPE_ELS, f_ctl, 0);
|
||||
lport->tt.seq_send(lport, sp, fp);
|
||||
|
||||
/*
|
||||
* Get lock and re-check state.
|
||||
*/
|
||||
switch (rdata->rp_state) {
|
||||
case RPORT_ST_PRLI:
|
||||
fc_rport_enter_ready(rdata);
|
||||
break;
|
||||
case RPORT_ST_READY:
|
||||
case RPORT_ST_ADISC:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
goto drop;
|
||||
|
||||
reject_len:
|
||||
rjt_data.reason = ELS_RJT_PROT;
|
||||
rjt_data.explan = ELS_EXPL_INV_LEN;
|
||||
reject:
|
||||
lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data);
|
||||
drop:
|
||||
fc_frame_free(rx_fp);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue