Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[interface] Convert all data-xfer interfaces to generic interfaces
Remove data-xfer as an interface type, and replace data-xfer
interfaces with generic interfaces supporting the data-xfer methods.

Filter interfaces (as used by the TLS layer) are handled using the
generic pass-through interface capability.  A side-effect of this is
that deliver_raw() no longer exists as a data-xfer method.  (In
practice this doesn't lose any efficiency, since there are no
instances within the current codebase where xfer_deliver_raw() is used
to pass data to an interface supporting the deliver_raw() method.)

Signed-off-by: Michael Brown <mcb30@ipxe.org>
  • Loading branch information
mcb30 committed Jun 22, 2010
1 parent 7b4fbd9 commit 4327d5d
Show file tree
Hide file tree
Showing 31 changed files with 764 additions and 1,511 deletions.
92 changes: 42 additions & 50 deletions src/arch/i386/interface/pxe/pxe_tftp.c
Expand Up @@ -31,6 +31,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <ipxe/uaccess.h>
#include <ipxe/in.h>
#include <ipxe/tftp.h>
#include <ipxe/iobuf.h>
#include <ipxe/xfer.h>
#include <ipxe/open.h>
#include <ipxe/process.h>
Expand All @@ -39,7 +40,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
/** A PXE TFTP connection */
struct pxe_tftp_connection {
/** Data transfer interface */
struct xfer_interface xfer;
struct interface xfer;
/** Data buffer */
userptr_t buffer;
/** Size of data buffer */
Expand All @@ -58,93 +59,84 @@ struct pxe_tftp_connection {
int rc;
};

/** The PXE TFTP connection */
static struct pxe_tftp_connection pxe_tftp = {
.xfer = XFER_INIT ( &null_xfer_ops ),
};

/**
* Close PXE TFTP connection
*
* @v pxe_tftp PXE TFTP connection
* @v rc Final status code
*/
static void pxe_tftp_close ( int rc ) {
xfer_nullify ( &pxe_tftp.xfer );
xfer_close ( &pxe_tftp.xfer, rc );
pxe_tftp.rc = rc;
static void pxe_tftp_close ( struct pxe_tftp_connection *pxe_tftp, int rc ) {
intf_shutdown ( &pxe_tftp->xfer, rc );
pxe_tftp->rc = rc;
}

/**
* Receive new data
*
* @v xfer Data transfer interface
* @v pxe_tftp PXE TFTP connection
* @v iobuf I/O buffer
* @v meta Transfer metadata
* @ret rc Return status code
*/
static int pxe_tftp_xfer_deliver_iob ( struct xfer_interface *xfer __unused,
struct io_buffer *iobuf,
struct xfer_metadata *meta ) {
static int pxe_tftp_xfer_deliver ( struct pxe_tftp_connection *pxe_tftp,
struct io_buffer *iobuf,
struct xfer_metadata *meta ) {
size_t len = iob_len ( iobuf );
int rc = 0;

/* Calculate new buffer position */
if ( meta->whence != SEEK_CUR )
pxe_tftp.offset = 0;
pxe_tftp.offset += meta->offset;
pxe_tftp->offset = 0;
pxe_tftp->offset += meta->offset;

/* Copy data block to buffer */
if ( len == 0 ) {
/* No data (pure seek); treat as success */
} else if ( pxe_tftp.offset < pxe_tftp.start ) {
} else if ( pxe_tftp->offset < pxe_tftp->start ) {
DBG ( " buffer underrun at %zx (min %zx)",
pxe_tftp.offset, pxe_tftp.start );
pxe_tftp->offset, pxe_tftp->start );
rc = -ENOBUFS;
} else if ( ( pxe_tftp.offset + len ) >
( pxe_tftp.start + pxe_tftp.size ) ) {
} else if ( ( pxe_tftp->offset + len ) >
( pxe_tftp->start + pxe_tftp->size ) ) {
DBG ( " buffer overrun at %zx (max %zx)",
( pxe_tftp.offset + len ),
( pxe_tftp.start + pxe_tftp.size ) );
( pxe_tftp->offset + len ),
( pxe_tftp->start + pxe_tftp->size ) );
rc = -ENOBUFS;
} else {
copy_to_user ( pxe_tftp.buffer,
( pxe_tftp.offset - pxe_tftp.start ),
copy_to_user ( pxe_tftp->buffer,
( pxe_tftp->offset - pxe_tftp->start ),
iobuf->data, len );
}

/* Calculate new buffer position */
pxe_tftp.offset += len;
pxe_tftp->offset += len;

/* Record maximum offset as the file size */
if ( pxe_tftp.max_offset < pxe_tftp.offset )
pxe_tftp.max_offset = pxe_tftp.offset;
if ( pxe_tftp->max_offset < pxe_tftp->offset )
pxe_tftp->max_offset = pxe_tftp->offset;

/* Terminate transfer on error */
if ( rc != 0 )
pxe_tftp_close ( rc );
pxe_tftp_close ( pxe_tftp, rc );

free_iob ( iobuf );
return rc;
}

/**
* Handle close() event
*
* @v xfer Data transfer interface
* @v rc Reason for close
*/
static void pxe_tftp_xfer_close ( struct xfer_interface *xfer __unused,
int rc ) {
pxe_tftp_close ( rc );
}
/** PXE TFTP connection interface operations */
static struct interface_operation pxe_tftp_xfer_ops[] = {
INTF_OP ( xfer_deliver, struct pxe_tftp_connection *,
pxe_tftp_xfer_deliver ),
INTF_OP ( intf_close, struct pxe_tftp_connection *, pxe_tftp_close ),
};

static struct xfer_interface_operations pxe_tftp_xfer_ops = {
.close = pxe_tftp_xfer_close,
.vredirect = xfer_vreopen,
.window = unlimited_xfer_window,
.alloc_iob = default_xfer_alloc_iob,
.deliver_iob = pxe_tftp_xfer_deliver_iob,
.deliver_raw = xfer_deliver_as_iob,
/** PXE TFTP connection interface descriptor */
static struct interface_descriptor pxe_tftp_xfer_desc =
INTF_DESC ( struct pxe_tftp_connection, xfer, pxe_tftp_xfer_ops );

/** The PXE TFTP connection */
static struct pxe_tftp_connection pxe_tftp = {
.xfer = INTF_INIT ( pxe_tftp_xfer_desc ),
};

/**
Expand Down Expand Up @@ -173,7 +165,7 @@ static int pxe_tftp_open ( uint32_t ipaddress, unsigned int port,

/* Reset PXE TFTP connection structure */
memset ( &pxe_tftp, 0, sizeof ( pxe_tftp ) );
xfer_init ( &pxe_tftp.xfer, &pxe_tftp_xfer_ops, NULL );
intf_init ( &pxe_tftp.xfer, &pxe_tftp_xfer_desc, NULL );
pxe_tftp.rc = -EINPROGRESS;

/* Construct URI string */
Expand Down Expand Up @@ -247,7 +239,7 @@ PXENV_EXIT_t pxenv_tftp_open ( struct s_PXENV_TFTP_OPEN *tftp_open ) {
DBG ( "PXENV_TFTP_OPEN" );

/* Guard against callers that fail to close before re-opening */
pxe_tftp_close ( 0 );
pxe_tftp_close ( &pxe_tftp, 0 );

/* Open connection */
if ( ( rc = pxe_tftp_open ( tftp_open->ServerIPAddress,
Expand Down Expand Up @@ -296,7 +288,7 @@ PXENV_EXIT_t pxenv_tftp_open ( struct s_PXENV_TFTP_OPEN *tftp_open ) {
PXENV_EXIT_t pxenv_tftp_close ( struct s_PXENV_TFTP_CLOSE *tftp_close ) {
DBG ( "PXENV_TFTP_CLOSE" );

pxe_tftp_close ( 0 );
pxe_tftp_close ( &pxe_tftp, 0 );
tftp_close->Status = PXENV_STATUS_SUCCESS;
return PXENV_EXIT_SUCCESS;
}
Expand Down Expand Up @@ -491,7 +483,7 @@ PXENV_EXIT_t pxenv_tftp_read_file ( struct s_PXENV_TFTP_READ_FILE
tftp_read_file->BufferSize = pxe_tftp.max_offset;

/* Close TFTP file */
pxe_tftp_close ( rc );
pxe_tftp_close ( &pxe_tftp, rc );

tftp_read_file->Status = PXENV_STATUS ( rc );
return ( rc ? PXENV_EXIT_FAILURE : PXENV_EXIT_SUCCESS );
Expand Down Expand Up @@ -565,7 +557,7 @@ PXENV_EXIT_t pxenv_tftp_get_fsize ( struct s_PXENV_TFTP_GET_FSIZE
rc = 0;

/* Close TFTP file */
pxe_tftp_close ( rc );
pxe_tftp_close ( &pxe_tftp, rc );

tftp_get_fsize->Status = PXENV_STATUS ( rc );
return ( rc ? PXENV_EXIT_FAILURE : PXENV_EXIT_SUCCESS );
Expand Down
35 changes: 16 additions & 19 deletions src/arch/i386/interface/pxe/pxe_udp.c
Expand Up @@ -6,6 +6,7 @@

#include <string.h>
#include <byteswap.h>
#include <ipxe/iobuf.h>
#include <ipxe/xfer.h>
#include <ipxe/udp.h>
#include <ipxe/uaccess.h>
Expand Down Expand Up @@ -35,7 +36,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
/** A PXE UDP connection */
struct pxe_udp_connection {
/** Data transfer interface to UDP stack */
struct xfer_interface xfer;
struct interface xfer;
/** Local address */
struct sockaddr_in local;
/** Current PXENV_UDP_READ parameter block */
Expand All @@ -45,19 +46,17 @@ struct pxe_udp_connection {
/**
* Receive PXE UDP data
*
* @v xfer Data transfer interface
* @v pxe_udp PXE UDP connection
* @v iobuf I/O buffer
* @v meta Data transfer metadata
* @ret rc Return status code
*
* Receives a packet as part of the current pxenv_udp_read()
* operation.
*/
static int pxe_udp_deliver_iob ( struct xfer_interface *xfer,
struct io_buffer *iobuf,
struct xfer_metadata *meta ) {
struct pxe_udp_connection *pxe_udp =
container_of ( xfer, struct pxe_udp_connection, xfer );
static int pxe_udp_deliver ( struct pxe_udp_connection *pxe_udp,
struct io_buffer *iobuf,
struct xfer_metadata *meta ) {
struct s_PXENV_UDP_READ *pxenv_udp_read = pxe_udp->pxenv_udp_read;
struct sockaddr_in *sin_src;
struct sockaddr_in *sin_dest;
Expand Down Expand Up @@ -102,18 +101,17 @@ static int pxe_udp_deliver_iob ( struct xfer_interface *xfer,
}

/** PXE UDP data transfer interface operations */
static struct xfer_interface_operations pxe_udp_xfer_operations = {
.close = ignore_xfer_close,
.vredirect = ignore_xfer_vredirect,
.window = unlimited_xfer_window,
.alloc_iob = default_xfer_alloc_iob,
.deliver_iob = pxe_udp_deliver_iob,
.deliver_raw = xfer_deliver_as_iob,
static struct interface_operation pxe_udp_xfer_operations[] = {
INTF_OP ( xfer_deliver, struct pxe_udp_connection *, pxe_udp_deliver ),
};

/** PXE UDP data transfer interface descriptor */
static struct interface_descriptor pxe_udp_xfer_desc =
INTF_DESC ( struct pxe_udp_connection, xfer, pxe_udp_xfer_operations );

/** The PXE UDP connection */
static struct pxe_udp_connection pxe_udp = {
.xfer = XFER_INIT ( &pxe_udp_xfer_operations ),
.xfer = INTF_INIT ( pxe_udp_xfer_desc ),
.local = {
.sin_family = AF_INET,
},
Expand Down Expand Up @@ -171,7 +169,7 @@ PXENV_EXIT_t pxenv_udp_open ( struct s_PXENV_UDP_OPEN *pxenv_udp_open ) {
DBG ( " %s", inet_ntoa ( pxe_udp.local.sin_addr ) );

/* Open promiscuous UDP connection */
xfer_close ( &pxe_udp.xfer, 0 );
intf_restart ( &pxe_udp.xfer, 0 );
if ( ( rc = udp_open_promisc ( &pxe_udp.xfer ) ) != 0 ) {
pxenv_udp_open->Status = PXENV_STATUS ( rc );
return PXENV_EXIT_FAILURE;
Expand Down Expand Up @@ -206,7 +204,7 @@ PXENV_EXIT_t pxenv_udp_close ( struct s_PXENV_UDP_CLOSE *pxenv_udp_close ) {
DBG ( "PXENV_UDP_CLOSE" );

/* Close UDP connection */
xfer_close ( &pxe_udp.xfer, 0 );
intf_restart ( &pxe_udp.xfer, 0 );

pxenv_udp_close->Status = PXENV_STATUS_SUCCESS;
return PXENV_EXIT_SUCCESS;
Expand Down Expand Up @@ -304,8 +302,7 @@ PXENV_EXIT_t pxenv_udp_write ( struct s_PXENV_UDP_WRITE *pxenv_udp_write ) {
ntohs ( pxenv_udp_write->dst_port ) );

/* Transmit packet */
if ( ( rc = xfer_deliver_iob_meta ( &pxe_udp.xfer, iobuf,
&meta ) ) != 0 ) {
if ( ( rc = xfer_deliver ( &pxe_udp.xfer, iobuf, &meta ) ) != 0 ) {
pxenv_udp_write->Status = PXENV_STATUS ( rc );
return PXENV_EXIT_FAILURE;
}
Expand Down
48 changes: 16 additions & 32 deletions src/core/downloader.c
Expand Up @@ -21,6 +21,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#include <ipxe/iobuf.h>
#include <ipxe/xfer.h>
#include <ipxe/open.h>
#include <ipxe/job.h>
Expand All @@ -43,7 +44,7 @@ struct downloader {
/** Job control interface */
struct interface job;
/** Data transfer interface */
struct xfer_interface xfer;
struct interface xfer;

/** Image to contain downloaded file */
struct image *image;
Expand Down Expand Up @@ -79,8 +80,7 @@ static void downloader_finished ( struct downloader *downloader, int rc ) {
rc = downloader->register_image ( downloader->image );

/* Shut down interfaces */
xfer_nullify ( &downloader->xfer );
xfer_close ( &downloader->xfer, rc );
intf_shutdown ( &downloader->xfer, rc );
intf_shutdown ( &downloader->job, rc );
}

Expand Down Expand Up @@ -145,18 +145,16 @@ static void downloader_progress ( struct downloader *downloader,
*/

/**
* Handle deliver_raw() event received via data transfer interface
* Handle received data
*
* @v xfer Downloader data transfer interface
* @v downloader Downloader
* @v iobuf Datagram I/O buffer
* @v meta Data transfer metadata
* @ret rc Return status code
*/
static int downloader_xfer_deliver_iob ( struct xfer_interface *xfer,
struct io_buffer *iobuf,
struct xfer_metadata *meta ) {
struct downloader *downloader =
container_of ( xfer, struct downloader, xfer );
static int downloader_xfer_deliver ( struct downloader *downloader,
struct io_buffer *iobuf,
struct xfer_metadata *meta ) {
size_t len;
size_t max;
int rc;
Expand Down Expand Up @@ -184,30 +182,16 @@ static int downloader_xfer_deliver_iob ( struct xfer_interface *xfer,
return rc;
}

/**
* Handle close() event received via data transfer interface
*
* @v xfer Downloader data transfer interface
* @v rc Reason for close
*/
static void downloader_xfer_close ( struct xfer_interface *xfer, int rc ) {
struct downloader *downloader =
container_of ( xfer, struct downloader, xfer );

/* Terminate download */
downloader_finished ( downloader, rc );
}

/** Downloader data transfer interface operations */
static struct xfer_interface_operations downloader_xfer_operations = {
.close = downloader_xfer_close,
.vredirect = xfer_vreopen,
.window = unlimited_xfer_window,
.alloc_iob = default_xfer_alloc_iob,
.deliver_iob = downloader_xfer_deliver_iob,
.deliver_raw = xfer_deliver_as_iob,
static struct interface_operation downloader_xfer_operations[] = {
INTF_OP ( xfer_deliver, struct downloader *, downloader_xfer_deliver ),
INTF_OP ( intf_close, struct downloader *, downloader_finished ),
};

/** Downloader data transfer interface descriptor */
static struct interface_descriptor downloader_xfer_desc =
INTF_DESC ( struct downloader, xfer, downloader_xfer_operations );

/****************************************************************************
*
* Job control interface
Expand Down Expand Up @@ -258,7 +242,7 @@ int create_downloader ( struct interface *job, struct image *image,
ref_init ( &downloader->refcnt, downloader_free );
intf_init ( &downloader->job, &downloader_job_desc,
&downloader->refcnt );
xfer_init ( &downloader->xfer, &downloader_xfer_operations,
intf_init ( &downloader->xfer, &downloader_xfer_desc,
&downloader->refcnt );
downloader->image = image_get ( image );
downloader->register_image = register_image;
Expand Down

0 comments on commit 4327d5d

Please sign in to comment.