Пример #1
0
/**
 * Transmit SRP SCSI command
 *
 * @v srp		SRP device
 */
static void srp_cmd ( struct srp_device *srp ) {
	struct io_buffer *iobuf;
	struct srp_cmd *cmd;
	struct srp_memory_descriptor *data_out;
	struct srp_memory_descriptor *data_in;
	int rc;

	assert ( srp->state & SRP_STATE_LOGGED_IN );

	/* Allocate I/O buffer */
	iobuf = xfer_alloc_iob ( &srp->socket, SRP_MAX_I_T_IU_LEN );
	if ( ! iobuf ) {
		rc = -ENOMEM;
		goto err;
	}

	/* Construct base portion */
	cmd = iob_put ( iobuf, sizeof ( *cmd ) );
	memset ( cmd, 0, sizeof ( *cmd ) );
	cmd->type = SRP_CMD;
	cmd->tag.dwords[1] = htonl ( ++srp_tag );
	cmd->lun = srp->lun;
	memcpy ( &cmd->cdb, &srp->command->cdb, sizeof ( cmd->cdb ) );

	/* Construct data-out descriptor, if present */
	if ( srp->command->data_out ) {
		cmd->data_buffer_formats |= SRP_CMD_DO_FMT_DIRECT;
		data_out = iob_put ( iobuf, sizeof ( *data_out ) );
		data_out->address =
		    cpu_to_be64 ( user_to_phys ( srp->command->data_out, 0 ) );
		data_out->handle = ntohl ( srp->memory_handle );
		data_out->len = ntohl ( srp->command->data_out_len );
	}

	/* Construct data-in descriptor, if present */
	if ( srp->command->data_in ) {
		cmd->data_buffer_formats |= SRP_CMD_DI_FMT_DIRECT;
		data_in = iob_put ( iobuf, sizeof ( *data_in ) );
		data_in->address =
		     cpu_to_be64 ( user_to_phys ( srp->command->data_in, 0 ) );
		data_in->handle = ntohl ( srp->memory_handle );
		data_in->len = ntohl ( srp->command->data_in_len );
	}

	DBGC2 ( srp, "SRP %p TX SCSI command tag %08x%08x\n", srp,
		ntohl ( cmd->tag.dwords[0] ), ntohl ( cmd->tag.dwords[1] ) );
	DBGC2_HDA ( srp, 0, iobuf->data, iob_len ( iobuf ) );

	/* Send IU */
	if ( ( rc = xfer_deliver_iob ( &srp->socket, iobuf ) ) != 0 ) {
		DBGC ( srp, "SRP %p could not send command: %s\n",
		       srp, strerror ( rc ) );
		goto err;
	}

	return;

 err:
	srp_fail ( srp, rc );
}
Пример #2
0
/**
 * Dump LACP packet
 *
 * @v iobuf		I/O buffer
 * @v netdev		Network device
 * @v label		"RX" or "TX"
 */
static void eth_slow_lacp_dump ( struct io_buffer *iobuf,
				 struct net_device *netdev,
				 const char *label ) {
	union eth_slow_packet *eth_slow = iobuf->data;
	struct eth_slow_lacp *lacp = &eth_slow->lacp;

	DBGC ( netdev,
	       "SLOW %s %s LACP actor (%04x,%s,%04x,%02x,%04x) [%s]\n",
	       netdev->name, label, ntohs ( lacp->actor.system_priority ),
	       eth_ntoa ( lacp->actor.system ),
	       ntohs ( lacp->actor.key ),
	       ntohs ( lacp->actor.port_priority ),
	       ntohs ( lacp->actor.port ),
	       eth_slow_lacp_state_name ( lacp->actor.state ) );
	DBGC ( netdev,
	       "SLOW %s %s LACP partner (%04x,%s,%04x,%02x,%04x) [%s]\n",
	       netdev->name, label, ntohs ( lacp->partner.system_priority ),
	       eth_ntoa ( lacp->partner.system ),
	       ntohs ( lacp->partner.key ),
	       ntohs ( lacp->partner.port_priority ),
	       ntohs ( lacp->partner.port ),
	       eth_slow_lacp_state_name ( lacp->partner.state ) );
	DBGC ( netdev, "SLOW %s %s LACP collector %04x (%d us)\n",
	       netdev->name, label, ntohs ( lacp->collector.max_delay ),
	       ( ntohs ( lacp->collector.max_delay ) * 10 ) );
	DBGC2_HDA ( netdev, 0, iobuf->data, iob_len ( iobuf ) );
}
Пример #3
0
/**
 * Build OCSP request
 *
 * @v ocsp		OCSP check
 * @ret rc		Return status code
 */
static int ocsp_request ( struct ocsp_check *ocsp ) {
	struct digest_algorithm *digest = &ocsp_digest_algorithm;
	struct asn1_builder *builder = &ocsp->request.builder;
	struct asn1_cursor *cert_id_tail = &ocsp->request.cert_id_tail;
	uint8_t digest_ctx[digest->ctxsize];
	uint8_t name_digest[digest->digestsize];
	uint8_t pubkey_digest[digest->digestsize];
	int rc;

	/* Generate digests */
	digest_init ( digest, digest_ctx );
	digest_update ( digest, digest_ctx, ocsp->cert->issuer.raw.data,
			ocsp->cert->issuer.raw.len );
	digest_final ( digest, digest_ctx, name_digest );
	digest_init ( digest, digest_ctx );
	digest_update ( digest, digest_ctx,
			ocsp->issuer->subject.public_key.raw_bits.data,
			ocsp->issuer->subject.public_key.raw_bits.len );
	digest_final ( digest, digest_ctx, pubkey_digest );

	/* Construct request */
	if ( ( rc = ( asn1_prepend_raw ( builder, ocsp->cert->serial.raw.data,
					 ocsp->cert->serial.raw.len ),
		      asn1_prepend ( builder, ASN1_OCTET_STRING,
				     pubkey_digest, sizeof ( pubkey_digest ) ),
		      asn1_prepend ( builder, ASN1_OCTET_STRING,
				     name_digest, sizeof ( name_digest ) ),
		      asn1_prepend ( builder, ASN1_SEQUENCE,
				     ocsp_algorithm_id,
				     sizeof ( ocsp_algorithm_id ) ),
		      asn1_wrap ( builder, ASN1_SEQUENCE ),
		      asn1_wrap ( builder, ASN1_SEQUENCE ),
		      asn1_wrap ( builder, ASN1_SEQUENCE ),
		      asn1_wrap ( builder, ASN1_SEQUENCE ),
		      asn1_wrap ( builder, ASN1_SEQUENCE ) ) ) != 0 ) {
		DBGC ( ocsp, "OCSP %p \"%s\" could not build request: %s\n",
		       ocsp, x509_name ( ocsp->cert ), strerror ( rc ) );
		return rc;
	}
	DBGC2 ( ocsp, "OCSP %p \"%s\" request is:\n",
		ocsp, x509_name ( ocsp->cert ) );
	DBGC2_HDA ( ocsp, 0, builder->data, builder->len );

	/* Parse certificate ID for comparison with response */
	cert_id_tail->data = builder->data;
	cert_id_tail->len = builder->len;
	if ( ( rc = ( asn1_enter ( cert_id_tail, ASN1_SEQUENCE ),
		      asn1_enter ( cert_id_tail, ASN1_SEQUENCE ),
		      asn1_enter ( cert_id_tail, ASN1_SEQUENCE ),
		      asn1_enter ( cert_id_tail, ASN1_SEQUENCE ),
		      asn1_enter ( cert_id_tail, ASN1_SEQUENCE ),
		      asn1_skip ( cert_id_tail, ASN1_SEQUENCE ) ) ) != 0 ) {
		DBGC ( ocsp, "OCSP %p \"%s\" could not locate certID: %s\n",
		       ocsp, x509_name ( ocsp->cert ), strerror ( rc ) );
		return rc;
	}

	return 0;
}
Пример #4
0
/**
 * Dump marker packet
 *
 * @v iobuf		I/O buffer
 * @v netdev		Network device
 * @v label		"RX" or "TX"
 */
static void eth_slow_marker_dump ( struct io_buffer *iobuf,
				   struct net_device *netdev,
				   const char *label ) {
	union eth_slow_packet *eth_slow = iobuf->data;
	struct eth_slow_marker *marker = &eth_slow->marker;

	DBGC ( netdev, "SLOW %s %s marker %s port %04x system %s xact %08x\n",
	       netdev->name, label,
	       eth_slow_marker_tlv_name ( marker->marker.tlv.type ),
	       ntohs ( marker->marker.port ),
	       eth_ntoa ( marker->marker.system ),
	       ntohl ( marker->marker.xact ) );
	DBGC2_HDA ( netdev, 0, iobuf->data, iob_len ( iobuf ) );
}
Пример #5
0
/**
 * Initiate SRP login
 *
 * @v srp		SRP device
 */
static void srp_login ( struct srp_device *srp ) {
	struct io_buffer *iobuf;
	struct srp_login_req *login_req;
	int rc;

	assert ( ! ( srp->state & SRP_STATE_SOCKET_OPEN ) );

	/* Open underlying socket */
	if ( ( rc = srp->transport->connect ( srp ) ) != 0 ) {
		DBGC ( srp, "SRP %p could not open socket: %s\n",
		       srp, strerror ( rc ) );
		goto err;
	}
	srp->state |= SRP_STATE_SOCKET_OPEN;

	/* Allocate I/O buffer */
	iobuf = xfer_alloc_iob ( &srp->socket, sizeof ( *login_req ) );
	if ( ! iobuf ) {
		rc = -ENOMEM;
		goto err;
	}

	/* Construct login request IU */
	login_req = iob_put ( iobuf, sizeof ( *login_req ) );
	memset ( login_req, 0, sizeof ( *login_req ) );
	login_req->type = SRP_LOGIN_REQ;
	login_req->tag.dwords[1] = htonl ( ++srp_tag );
	login_req->max_i_t_iu_len = htonl ( SRP_MAX_I_T_IU_LEN );
	login_req->required_buffer_formats = SRP_LOGIN_REQ_FMT_DDBD;
	memcpy ( &login_req->port_ids, &srp->port_ids,
		 sizeof ( login_req->port_ids ) );

	DBGC2 ( srp, "SRP %p TX login request tag %08x%08x\n",
		srp, ntohl ( login_req->tag.dwords[0] ),
		ntohl ( login_req->tag.dwords[1] ) );
	DBGC2_HDA ( srp, 0, iobuf->data, iob_len ( iobuf ) );

	/* Send login request IU */
	if ( ( rc = xfer_deliver_iob ( &srp->socket, iobuf ) ) != 0 ) {
		DBGC ( srp, "SRP %p could not send login request: %s\n",
		       srp, strerror ( rc ) );
		goto err;
	}

	return;

 err:
	srp_fail ( srp, rc );
}
Пример #6
0
/**
 * Manage receive filters
 *
 * @v snp		SNP interface
 * @v enable		Receive filters to enable
 * @v disable		Receive filters to disable
 * @v mcast_reset	Reset multicast filters
 * @v mcast_count	Number of multicast filters
 * @v mcast		Multicast filters
 * @ret efirc		EFI status code
 */
static EFI_STATUS EFIAPI
efi_snp_receive_filters ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, UINT32 enable,
			  UINT32 disable, BOOLEAN mcast_reset,
			  UINTN mcast_count, EFI_MAC_ADDRESS *mcast ) {
	struct efi_snp_device *snpdev =
		container_of ( snp, struct efi_snp_device, snp );
	unsigned int i;

	DBGC2 ( snpdev, "SNPDEV %p RECEIVE_FILTERS %08x&~%08x%s %ld mcast\n",
		snpdev, enable, disable, ( mcast_reset ? " reset" : "" ),
		( ( unsigned long ) mcast_count ) );
	for ( i = 0 ; i < mcast_count ; i++ ) {
		DBGC2_HDA ( snpdev, i, &mcast[i],
			    snpdev->netdev->ll_protocol->ll_addr_len );
	}

	/* Lie through our teeth, otherwise MNP refuses to accept us */
	return 0;
}
Пример #7
0
/**
 * Transmit Fibre Channel ELS frame
 *
 * @v els		Fibre Channel ELS transaction
 * @v data		Data to transmit
 * @v len		Length of data
 * @ret rc		Return status code
 */
int fc_els_tx ( struct fc_els *els, const void *data, size_t len ) {
    struct xfer_metadata meta;
    struct sockaddr_fc dest;
    int rc;

    DBGC2 ( els, FCELS_FMT " transmitting:\n", FCELS_ARGS ( els ) );
    DBGC2_HDA ( els, 0, data, len );

    /* Construct metadata */
    memset ( &meta, 0, sizeof ( meta ) );
    meta.flags = ( fc_els_is_request ( els ) ?
                   XFER_FL_OVER : ( XFER_FL_RESPONSE | XFER_FL_OUT ) );
    meta.dest = fc_fill_sockaddr ( &dest, &els->peer_port_id );

    /* Transmit frame */
    if ( ( rc = xfer_deliver_raw_meta ( &els->xchg, data, len,
                                        &meta ) ) != 0 ) {
        DBGC ( els, FCELS_FMT " could not deliver frame: %s\n",
               FCELS_ARGS ( els ), strerror ( rc ) );
        return rc;
    }

    return 0;
}
Пример #8
0
/**
 * Receive Fibre Channel ELS frame
 *
 * @v els		Fibre Channel ELS transaction
 * @v iobuf		I/O buffer
 * @v meta		Data transfer metadata
 * @ret rc		Return status code
 */
static int fc_els_rx ( struct fc_els *els,
                       struct io_buffer *iobuf,
                       struct xfer_metadata *meta ) {
    struct fc_els_frame_common *frame = iobuf->data;
    struct sockaddr_fc *src = ( ( struct sockaddr_fc * ) meta->src );
    struct sockaddr_fc *dest = ( ( struct sockaddr_fc * ) meta->dest );
    size_t len = iob_len ( iobuf );
    int rc;

    /* Sanity check */
    if ( len < sizeof ( *frame ) ) {
        DBGC ( els, FCELS_FMT " received underlength frame:\n",
               FCELS_ARGS ( els ) );
        DBGC_HDA ( els, 0, frame, len );
        rc = -EINVAL;
        goto done;
    }
    if ( ! src ) {
        DBGC ( els, FCELS_FMT " received frame missing source "
               "address:\n", FCELS_ARGS ( els ) );
        rc = -EINVAL;
        goto done;
    }
    if ( ! dest ) {
        DBGC ( els, FCELS_FMT " received frame missing destination "
               "address:\n", FCELS_ARGS ( els ) );
        rc = -EINVAL;
        goto done;
    }

    /* Check for rejection responses */
    if ( fc_els_is_request ( els ) &&
            ( frame->command != FC_ELS_LS_ACC ) ) {
        DBGC ( els, FCELS_FMT " rejected:\n", FCELS_ARGS ( els ) );
        DBGC_HDA ( els, 0, frame, len );
        rc = -EACCES;
        goto done;
    }

    /* Update port IDs */
    memcpy ( &els->port_id, &dest->sfc_port_id, sizeof ( els->port_id ) );
    memcpy ( &els->peer_port_id, &src->sfc_port_id,
             sizeof ( els->peer_port_id ) );

    /* Determine handler, if necessary */
    if ( ! els->handler )
        els->handler = fc_els_detect ( els, frame, len );
    if ( ! els->handler )
        els->handler = &fc_els_unknown_handler;

    DBGC2 ( els, FCELS_FMT " received:\n", FCELS_ARGS ( els ) );
    DBGC2_HDA ( els, 0, frame, len );

    /* Handle received frame */
    if ( ( rc = els->handler->rx ( els, frame, len ) ) != 0 ) {
        DBGC ( els, FCELS_FMT " could not handle received frame: "
               "%s\n", FCELS_ARGS ( els ), strerror ( rc ) );
        DBGC_HDA ( els, 0, frame, len );
        goto done;
    }

done:
    /* Free I/O buffer */
    free_iob ( iobuf );

    /* Close transaction */
    fc_els_close ( els, rc );

    return rc;
}