Properly ignore PDUs with CmdSN outside of allowed range.
Approved by: re (glebius) Sponsored by: FreeBSD Foundation
This commit is contained in:
parent
28393634c5
commit
02a8f348b2
@ -147,7 +147,7 @@ static int cfiscsi_devid(struct ctl_scsiio *ctsio, int alloc_len);
|
||||
static void cfiscsi_datamove(union ctl_io *io);
|
||||
static void cfiscsi_done(union ctl_io *io);
|
||||
static uint32_t cfiscsi_map_lun(void *arg, uint32_t lun);
|
||||
static void cfiscsi_pdu_update_cmdsn(const struct icl_pdu *request);
|
||||
static bool cfiscsi_pdu_update_cmdsn(const struct icl_pdu *request);
|
||||
static void cfiscsi_pdu_handle_nop_out(struct icl_pdu *request);
|
||||
static void cfiscsi_pdu_handle_scsi_command(struct icl_pdu *request);
|
||||
static void cfiscsi_pdu_handle_task_request(struct icl_pdu *request);
|
||||
@ -182,7 +182,7 @@ cfiscsi_pdu_new_response(struct icl_pdu *request, int flags)
|
||||
return (icl_pdu_new_bhs(request->ip_conn, flags));
|
||||
}
|
||||
|
||||
static void
|
||||
static bool
|
||||
cfiscsi_pdu_update_cmdsn(const struct icl_pdu *request)
|
||||
{
|
||||
const struct iscsi_bhs_scsi_command *bhssc;
|
||||
@ -206,7 +206,7 @@ cfiscsi_pdu_update_cmdsn(const struct icl_pdu *request)
|
||||
*/
|
||||
if ((request->ip_bhs->bhs_opcode & ~ISCSI_BHS_OPCODE_IMMEDIATE) ==
|
||||
ISCSI_BHS_OPCODE_SCSI_DATA_OUT)
|
||||
return;
|
||||
return (false);
|
||||
|
||||
/*
|
||||
* We're only using fields common for all the request
|
||||
@ -226,38 +226,39 @@ cfiscsi_pdu_update_cmdsn(const struct icl_pdu *request)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* XXX: The target MUST silently ignore any non-immediate command
|
||||
* outside of this range or non-immediate duplicates within
|
||||
* the range.
|
||||
* The target MUST silently ignore any non-immediate command outside
|
||||
* of this range.
|
||||
*
|
||||
* XXX: ... or non-immediate duplicates within the range.
|
||||
*/
|
||||
if (cmdsn != cs->cs_cmdsn) {
|
||||
if (cmdsn < cs->cs_cmdsn || cmdsn > cs->cs_cmdsn + maxcmdsn_delta) {
|
||||
CFISCSI_SESSION_UNLOCK(cs);
|
||||
CFISCSI_SESSION_WARN(cs, "received PDU with CmdSN %d, "
|
||||
"while expected CmdSN was %d", cmdsn, cs->cs_cmdsn);
|
||||
cs->cs_cmdsn = cmdsn + 1;
|
||||
CFISCSI_SESSION_UNLOCK(cs);
|
||||
return;
|
||||
return (true);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: The CmdSN of the rejected command PDU (if it is a non-immediate
|
||||
* command) MUST NOT be considered received by the target
|
||||
* (i.e., a command sequence gap must be assumed for the CmdSN)
|
||||
*/
|
||||
|
||||
if ((request->ip_bhs->bhs_opcode & ISCSI_BHS_OPCODE_IMMEDIATE) == 0)
|
||||
cs->cs_cmdsn++;
|
||||
|
||||
CFISCSI_SESSION_UNLOCK(cs);
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
static void
|
||||
cfiscsi_pdu_handle(struct icl_pdu *request)
|
||||
{
|
||||
struct cfiscsi_session *cs;
|
||||
bool ignore;
|
||||
|
||||
cs = PDU_SESSION(request);
|
||||
|
||||
cfiscsi_pdu_update_cmdsn(request);
|
||||
ignore = cfiscsi_pdu_update_cmdsn(request);
|
||||
if (ignore) {
|
||||
icl_pdu_free(request);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle the PDU; this includes e.g. receiving the remaining
|
||||
|
Loading…
Reference in New Issue
Block a user