Exemple #1
0
int digest_rx_data(struct iscsi_cmnd *cmnd)
{
	struct tio *tio;
	struct iscsi_cmnd *scsi_cmnd;
	struct iscsi_data_out_hdr *req;
	u32 offset, crc;

	switch (cmnd_opcode(cmnd)) {
	case ISCSI_OP_SCSI_REJECT:
	case ISCSI_OP_PDU_REJECT:
	case ISCSI_OP_DATA_REJECT:
		return 0;
	case ISCSI_OP_SCSI_DATA_OUT:
		scsi_cmnd = cmnd->req;
		req = (struct iscsi_data_out_hdr *) &cmnd->pdu.bhs;
		tio = scsi_cmnd->tio;
		offset = be32_to_cpu(req->buffer_offset);
		break;
	default:
		tio = cmnd->tio;
		offset = 0;
	}

	digest_data(&cmnd->conn->rx_hash, cmnd, tio, offset, (u8 *) &crc);

	if (!cmnd->conn->read_overflow &&
	    (cmnd_opcode(cmnd) != ISCSI_OP_PDU_REJECT)) {
		if (crc != cmnd->ddigest)
			return -EIO;
	}

	return 0;
}
Exemple #2
0
/**
 * debug handling of header digest errors:
 * simulates a digest error after n PDUs / every n-th PDU of type
 * HDIGEST_ERR_CORRUPT_PDU_TYPE.
 */
static inline void __dbg_simulate_header_digest_error(struct iscsi_cmnd *cmnd)
{
#define HDIGEST_ERR_AFTER_N_CMNDS 1000
#define HDIGEST_ERR_ONLY_ONCE     1
#define HDIGEST_ERR_CORRUPT_PDU_TYPE ISCSI_OP_SCSI_CMD
#define HDIGEST_ERR_CORRUPT_PDU_WITH_DATA_ONLY 0

	static int num_cmnds = 0;
	static int num_errs = 0;

	if (cmnd_opcode(cmnd) == HDIGEST_ERR_CORRUPT_PDU_TYPE) {
		if (HDIGEST_ERR_CORRUPT_PDU_WITH_DATA_ONLY) {
			if (cmnd->pdu.datasize)
				num_cmnds++;
		} else
			num_cmnds++;
	}

	if ((num_cmnds == HDIGEST_ERR_AFTER_N_CMNDS)
	    && (!(HDIGEST_ERR_ONLY_ONCE && num_errs))) {
		printk("*** Faking header digest error ***\n");
		printk("\tcmnd: 0x%x, itt 0x%x, sn 0x%x\n",
		       cmnd_opcode(cmnd),
		       be32_to_cpu(cmnd->pdu.bhs.itt),
		       be32_to_cpu(cmnd->pdu.bhs.sn));
		cmnd->hdigest = ~cmnd->hdigest;
		/* make things even worse by manipulating header fields */
		cmnd->pdu.datasize += 8;
		num_errs++;
		num_cmnds = 0;
	}
	return;
}
static void isert_update_len_sn(struct iscsi_cmnd *cmnd)
{
	TRACE_ENTRY();

	iscsi_cmnd_set_length(&cmnd->pdu);
	switch (cmnd_opcode(cmnd)) {
	case ISCSI_OP_NOP_IN:
		if (cmnd->pdu.bhs.itt == ISCSI_RESERVED_TAG)
			cmnd->pdu.bhs.sn = (__force u32)cmnd_set_sn(cmnd, 0);
		else
			cmnd_set_sn(cmnd, 1);
		break;
	case ISCSI_OP_SCSI_RSP:
		cmnd_set_sn(cmnd, 1);
		break;
	case ISCSI_OP_SCSI_TASK_MGT_RSP:
		cmnd_set_sn(cmnd, 1);
		break;
	case ISCSI_OP_TEXT_RSP:
		cmnd_set_sn(cmnd, 1);
		break;
	case ISCSI_OP_SCSI_DATA_IN:
	{
		struct iscsi_data_in_hdr *rsp =
			(struct iscsi_data_in_hdr *)&cmnd->pdu.bhs;

		cmnd_set_sn(cmnd, (rsp->flags & ISCSI_FLG_FINAL) ? 1 : 0);
		break;
	}
	case ISCSI_OP_LOGOUT_RSP:
		cmnd_set_sn(cmnd, 1);
		break;
	case ISCSI_OP_R2T:
		cmnd->pdu.bhs.sn = (__force u32)cmnd_set_sn(cmnd, 0);
		break;
	case ISCSI_OP_ASYNC_MSG:
		cmnd_set_sn(cmnd, 1);
		break;
	case ISCSI_OP_REJECT:
		cmnd_set_sn(cmnd, 1);
		break;
	default:
		PRINT_ERROR("Unexpected cmnd op %x", cmnd_opcode(cmnd));
		break;
	}

	TRACE_EXIT();
}
Exemple #4
0
/**
 * debug handling of data digest errors:
 * simulates a digest error after n PDUs / every n-th PDU of type
 * DDIGEST_ERR_CORRUPT_PDU_TYPE.
 */
static inline void __dbg_simulate_data_digest_error(struct iscsi_cmnd *cmnd)
{
#define DDIGEST_ERR_AFTER_N_CMNDS 50
#define DDIGEST_ERR_ONLY_ONCE     1
#define DDIGEST_ERR_CORRUPT_PDU_TYPE   ISCSI_OP_SCSI_DATA_OUT
#define DDIGEST_ERR_CORRUPT_UNSOL_DATA_ONLY 0

	static int num_cmnds = 0;
	static int num_errs = 0;

	if ((cmnd->pdu.datasize)
	    && (cmnd_opcode(cmnd) == DDIGEST_ERR_CORRUPT_PDU_TYPE)) {
		switch (cmnd_opcode(cmnd)) {
		case ISCSI_OP_SCSI_DATA_OUT:
			if ((DDIGEST_ERR_CORRUPT_UNSOL_DATA_ONLY)
			    && (cmnd->pdu.bhs.ttt != ISCSI_RESERVED_TAG))
				break;
		default:
			num_cmnds++;
		}
	}

	if ((num_cmnds == DDIGEST_ERR_AFTER_N_CMNDS)
	    && (!(DDIGEST_ERR_ONLY_ONCE && num_errs))
	    && (cmnd->pdu.datasize)
	    && (!cmnd->conn->read_overflow)) {
		printk("*** Faking data digest error: ***");
		printk("\tcmnd 0x%x, itt 0x%x, sn 0x%x\n",
		       cmnd_opcode(cmnd),
		       be32_to_cpu(cmnd->pdu.bhs.itt),
		       be32_to_cpu(cmnd->pdu.bhs.sn));
		cmnd->ddigest = ~cmnd->ddigest;
		num_errs++;
		num_cmnds = 0;
	}
}