From 4327d5d39f101f1df0ace6c03f3b3ada5f6a6213 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Wed, 16 Jun 2010 01:31:29 +0100 Subject: [PATCH] [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 --- src/arch/i386/interface/pxe/pxe_tftp.c | 92 +++--- src/arch/i386/interface/pxe/pxe_udp.c | 35 ++- src/core/downloader.c | 48 ++-- src/core/filter.c | 74 ----- src/core/hw.c | 29 +- src/core/open.c | 69 ++--- src/core/posix_io.c | 47 +--- src/core/resolv.c | 43 ++- src/core/xfer.c | 371 +++++++++---------------- src/drivers/block/srp.c | 46 +-- src/include/ipxe/filter.h | 75 ----- src/include/ipxe/http.h | 6 +- src/include/ipxe/ib_cmrc.h | 2 +- src/include/ipxe/iscsi.h | 2 +- src/include/ipxe/open.h | 28 +- src/include/ipxe/srp.h | 2 +- src/include/ipxe/tls.h | 10 +- src/include/ipxe/udp.h | 7 +- src/include/ipxe/xfer.h | 245 +++------------- src/net/infiniband/ib_cmrc.c | 58 ++-- src/net/tcp.c | 52 ++-- src/net/tcp/ftp.c | 144 ++++------ src/net/tcp/http.c | 95 ++----- src/net/tcp/https.c | 2 +- src/net/tcp/iscsi.c | 75 ++--- src/net/tls.c | 164 +++++------ src/net/udp.c | 68 ++--- src/net/udp/dhcp.c | 37 ++- src/net/udp/dns.c | 81 +++--- src/net/udp/slam.c | 134 +++------ src/net/udp/tftp.c | 134 +++------ 31 files changed, 764 insertions(+), 1511 deletions(-) delete mode 100644 src/core/filter.c delete mode 100644 src/include/ipxe/filter.h diff --git a/src/arch/i386/interface/pxe/pxe_tftp.c b/src/arch/i386/interface/pxe/pxe_tftp.c index 84f6527ad..7eaa63e54 100644 --- a/src/arch/i386/interface/pxe/pxe_tftp.c +++ b/src/arch/i386/interface/pxe/pxe_tftp.c @@ -31,6 +31,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include +#include #include #include #include @@ -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 */ @@ -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 ), }; /** @@ -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 */ @@ -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, @@ -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; } @@ -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 ); @@ -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 ); diff --git a/src/arch/i386/interface/pxe/pxe_udp.c b/src/arch/i386/interface/pxe/pxe_udp.c index cdc9d0aee..fc0e79b36 100644 --- a/src/arch/i386/interface/pxe/pxe_udp.c +++ b/src/arch/i386/interface/pxe/pxe_udp.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -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 */ @@ -45,7 +46,7 @@ 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 @@ -53,11 +54,9 @@ struct pxe_udp_connection { * 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; @@ -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, }, @@ -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; @@ -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; @@ -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; } diff --git a/src/core/downloader.c b/src/core/downloader.c index de5ea458c..488c86d9c 100644 --- a/src/core/downloader.c +++ b/src/core/downloader.c @@ -21,6 +21,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include +#include #include #include #include @@ -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; @@ -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 ); } @@ -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; @@ -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 @@ -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; diff --git a/src/core/filter.c b/src/core/filter.c deleted file mode 100644 index 94a521459..000000000 --- a/src/core/filter.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown . - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -FILE_LICENCE ( GPL2_OR_LATER ); - -#include -#include - -/** @file - * - * Data transfer filters - * - */ - -/* - * Pass-through methods to be used by filters which don't want to - * intercept all events. - * - */ - -void filter_close ( struct xfer_interface *xfer, int rc ) { - struct xfer_interface *other = filter_other_half ( xfer ); - - xfer_close ( other, rc ); -} - -int filter_vredirect ( struct xfer_interface *xfer, int type, - va_list args ) { - struct xfer_interface *other = filter_other_half ( xfer ); - - return xfer_vredirect ( other, type, args ); -} - -size_t filter_window ( struct xfer_interface *xfer ) { - struct xfer_interface *other = filter_other_half ( xfer ); - - return xfer_window ( other ); -} - -struct io_buffer * filter_alloc_iob ( struct xfer_interface *xfer, - size_t len ) { - struct xfer_interface *other = filter_other_half ( xfer ); - - return xfer_alloc_iob ( other, len ); -} - -int filter_deliver_iob ( struct xfer_interface *xfer, struct io_buffer *iobuf, - struct xfer_metadata *meta ) { - struct xfer_interface *other = filter_other_half ( xfer ); - - return xfer_deliver_iob_meta ( other, iobuf, meta ); -} - -int filter_deliver_raw ( struct xfer_interface *xfer, const void *data, - size_t len ) { - struct xfer_interface *other = filter_other_half ( xfer ); - - return xfer_deliver_raw ( other, data, len ); -} diff --git a/src/core/hw.c b/src/core/hw.c index b4a190271..aca558099 100644 --- a/src/core/hw.c +++ b/src/core/hw.c @@ -15,33 +15,24 @@ struct hw { struct refcnt refcnt; - struct xfer_interface xfer; + struct interface xfer; struct process process; }; static const char hw_msg[] = "Hello world!\n"; static void hw_finished ( struct hw *hw, int rc ) { - xfer_nullify ( &hw->xfer ); - xfer_close ( &hw->xfer, rc ); + intf_shutdown ( &hw->xfer, rc ); process_del ( &hw->process ); } -static void hw_xfer_close ( struct xfer_interface *xfer, int rc ) { - struct hw *hw = container_of ( xfer, struct hw, xfer ); - - hw_finished ( hw, rc ); -} - -static struct xfer_interface_operations hw_xfer_operations = { - .close = hw_xfer_close, - .vredirect = ignore_xfer_vredirect, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = xfer_deliver_as_raw, - .deliver_raw = ignore_xfer_deliver_raw, +static struct interface_operation hw_xfer_operations[] = { + INTF_OP ( intf_close, struct hw *, hw_finished ), }; +static struct interface_descriptor hw_xfer_desc = + INTF_DESC ( struct hw, xfer, hw_xfer_operations ); + static void hw_step ( struct process *process ) { struct hw *hw = container_of ( process, struct hw, process ); int rc; @@ -52,7 +43,7 @@ static void hw_step ( struct process *process ) { } } -static int hw_open ( struct xfer_interface *xfer, struct uri *uri __unused ) { +static int hw_open ( struct interface *xfer, struct uri *uri __unused ) { struct hw *hw; /* Allocate and initialise structure */ @@ -60,11 +51,11 @@ static int hw_open ( struct xfer_interface *xfer, struct uri *uri __unused ) { if ( ! hw ) return -ENOMEM; ref_init ( &hw->refcnt, NULL ); - xfer_init ( &hw->xfer, &hw_xfer_operations, &hw->refcnt ); + intf_init ( &hw->xfer, &hw_xfer_desc, &hw->refcnt ); process_init ( &hw->process, hw_step, &hw->refcnt ); /* Attach parent interface, mortalise self, and return */ - xfer_plug_plug ( &hw->xfer, xfer ); + intf_plug_plug ( &hw->xfer, xfer ); ref_put ( &hw->refcnt ); return 0; } diff --git a/src/core/open.c b/src/core/open.c index 58edef561..f8ee9f3a8 100644 --- a/src/core/open.c +++ b/src/core/open.c @@ -35,14 +35,14 @@ FILE_LICENCE ( GPL2_OR_LATER ); /** * Open URI * - * @v xfer Data transfer interface + * @v intf Data transfer interface * @v uri URI * @ret rc Return status code * * The URI will be regarded as being relative to the current working * URI (see churi()). */ -int xfer_open_uri ( struct xfer_interface *xfer, struct uri *uri ) { +int xfer_open_uri ( struct interface *intf, struct uri *uri ) { struct uri_opener *opener; struct uri *resolved_uri; int rc = -ENOTSUP; @@ -55,14 +55,16 @@ int xfer_open_uri ( struct xfer_interface *xfer, struct uri *uri ) { /* Find opener which supports this URI scheme */ for_each_table_entry ( opener, URI_OPENERS ) { if ( strcmp ( resolved_uri->scheme, opener->scheme ) == 0 ) { - DBGC ( xfer, "XFER %p opening %s URI\n", - xfer, opener->scheme ); - rc = opener->open ( xfer, resolved_uri ); + DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT + " opening %s URI\n", INTF_DBG ( intf ), + resolved_uri->scheme ); + rc = opener->open ( intf, resolved_uri ); goto done; } } - DBGC ( xfer, "XFER %p attempted to open unsupported URI scheme " - "\"%s\"\n", xfer, resolved_uri->scheme ); + DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to open " + "unsupported URI scheme \"%s\"\n", + INTF_DBG ( intf ), resolved_uri->scheme ); done: uri_put ( resolved_uri ); @@ -72,25 +74,26 @@ int xfer_open_uri ( struct xfer_interface *xfer, struct uri *uri ) { /** * Open URI string * - * @v xfer Data transfer interface + * @v intf Data transfer interface * @v uri_string URI string (e.g. "http://ipxe.org/kernel") * @ret rc Return status code * * The URI will be regarded as being relative to the current working * URI (see churi()). */ -int xfer_open_uri_string ( struct xfer_interface *xfer, +int xfer_open_uri_string ( struct interface *intf, const char *uri_string ) { struct uri *uri; int rc; - DBGC ( xfer, "XFER %p opening URI %s\n", xfer, uri_string ); + DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " opening URI %s\n", + INTF_DBG ( intf ), uri_string ); uri = parse_uri ( uri_string ); if ( ! uri ) return -ENOMEM; - rc = xfer_open_uri ( xfer, uri ); + rc = xfer_open_uri ( intf, uri ); uri_put ( uri ); return rc; @@ -99,29 +102,30 @@ int xfer_open_uri_string ( struct xfer_interface *xfer, /** * Open socket * - * @v xfer Data transfer interface + * @v intf Data transfer interface * @v semantics Communication semantics (e.g. SOCK_STREAM) * @v peer Peer socket address * @v local Local socket address, or NULL * @ret rc Return status code */ -int xfer_open_socket ( struct xfer_interface *xfer, int semantics, +int xfer_open_socket ( struct interface *intf, int semantics, struct sockaddr *peer, struct sockaddr *local ) { struct socket_opener *opener; - DBGC ( xfer, "XFER %p opening (%s,%s) socket\n", xfer, - socket_semantics_name ( semantics ), + DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " opening (%s,%s) socket\n", + INTF_DBG ( intf ), socket_semantics_name ( semantics ), socket_family_name ( peer->sa_family ) ); for_each_table_entry ( opener, SOCKET_OPENERS ) { if ( ( opener->semantics == semantics ) && ( opener->family == peer->sa_family ) ) { - return opener->open ( xfer, peer, local ); + return opener->open ( intf, peer, local ); } } - DBGC ( xfer, "XFER %p attempted to open unsupported socket type " - "(%s,%s)\n", xfer, socket_semantics_name ( semantics ), + DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to open " + "unsupported socket type (%s,%s)\n", + INTF_DBG ( intf ), socket_semantics_name ( semantics ), socket_family_name ( peer->sa_family ) ); return -ENOTSUP; } @@ -129,30 +133,31 @@ int xfer_open_socket ( struct xfer_interface *xfer, int semantics, /** * Open location * - * @v xfer Data transfer interface + * @v intf Data transfer interface * @v type Location type * @v args Remaining arguments depend upon location type * @ret rc Return status code */ -int xfer_vopen ( struct xfer_interface *xfer, int type, va_list args ) { +int xfer_vopen ( struct interface *intf, int type, va_list args ) { switch ( type ) { case LOCATION_URI_STRING: { const char *uri_string = va_arg ( args, const char * ); - return xfer_open_uri_string ( xfer, uri_string ); } + return xfer_open_uri_string ( intf, uri_string ); } case LOCATION_URI: { struct uri *uri = va_arg ( args, struct uri * ); - return xfer_open_uri ( xfer, uri ); } + return xfer_open_uri ( intf, uri ); } case LOCATION_SOCKET: { int semantics = va_arg ( args, int ); struct sockaddr *peer = va_arg ( args, struct sockaddr * ); struct sockaddr *local = va_arg ( args, struct sockaddr * ); - return xfer_open_socket ( xfer, semantics, peer, local ); } + return xfer_open_socket ( intf, semantics, peer, local ); } default: - DBGC ( xfer, "XFER %p attempted to open unsupported location " - "type %d\n", xfer, type ); + DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to " + "open unsupported location type %d\n", + INTF_DBG ( intf ), type ); return -ENOTSUP; } } @@ -160,17 +165,17 @@ int xfer_vopen ( struct xfer_interface *xfer, int type, va_list args ) { /** * Open location * - * @v xfer Data transfer interface + * @v intf Data transfer interface * @v type Location type * @v ... Remaining arguments depend upon location type * @ret rc Return status code */ -int xfer_open ( struct xfer_interface *xfer, int type, ... ) { +int xfer_open ( struct interface *intf, int type, ... ) { va_list args; int rc; va_start ( args, type ); - rc = xfer_vopen ( xfer, type, args ); + rc = xfer_vopen ( intf, type, args ); va_end ( args ); return rc; } @@ -178,7 +183,7 @@ int xfer_open ( struct xfer_interface *xfer, int type, ... ) { /** * Reopen location * - * @v xfer Data transfer interface + * @v intf Data transfer interface * @v type Location type * @v args Remaining arguments depend upon location type * @ret rc Return status code @@ -187,11 +192,11 @@ int xfer_open ( struct xfer_interface *xfer, int type, ... ) { * using xfer_vopen(). It is intended to be used as a .vredirect * method handler. */ -int xfer_vreopen ( struct xfer_interface *xfer, int type, va_list args ) { +int xfer_vreopen ( struct interface *intf, int type, va_list args ) { /* Close existing connection */ - xfer_close ( xfer, 0 ); + intf_restart ( intf, 0 ); /* Open new location */ - return xfer_vopen ( xfer, type, args ); + return xfer_vopen ( intf, type, args ); } diff --git a/src/core/posix_io.c b/src/core/posix_io.c index 2ecb15410..f7ca3f0db 100644 --- a/src/core/posix_io.c +++ b/src/core/posix_io.c @@ -22,6 +22,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include +#include #include #include #include @@ -50,7 +51,7 @@ struct posix_file { */ int rc; /** Data transfer interface */ - struct xfer_interface xfer; + struct interface xfer; /** Current seek position */ size_t pos; /** File size */ @@ -87,38 +88,21 @@ static void posix_file_free ( struct refcnt *refcnt ) { * @v rc Reason for termination */ static void posix_file_finished ( struct posix_file *file, int rc ) { - xfer_nullify ( &file->xfer ); - xfer_close ( &file->xfer, rc ); + intf_shutdown ( &file->xfer, rc ); file->rc = rc; } -/** - * Handle close() event - * - * @v xfer POSIX file data transfer interface - * @v rc Reason for close - */ -static void posix_file_xfer_close ( struct xfer_interface *xfer, int rc ) { - struct posix_file *file = - container_of ( xfer, struct posix_file, xfer ); - - posix_file_finished ( file, rc ); -} - /** * Handle deliver_iob() event * - * @v xfer POSIX file data transfer interface + * @v file POSIX file * @v iobuf I/O buffer * @v meta Data transfer metadata * @ret rc Return status code */ -static int -posix_file_xfer_deliver_iob ( struct xfer_interface *xfer, - struct io_buffer *iobuf, - struct xfer_metadata *meta ) { - struct posix_file *file = - container_of ( xfer, struct posix_file, xfer ); +static int posix_file_xfer_deliver ( struct posix_file *file, + struct io_buffer *iobuf, + struct xfer_metadata *meta ) { /* Keep track of file position solely for the filesize */ if ( meta->whence != SEEK_CUR ) @@ -137,15 +121,15 @@ posix_file_xfer_deliver_iob ( struct xfer_interface *xfer, } /** POSIX file data transfer interface operations */ -static struct xfer_interface_operations posix_file_xfer_operations = { - .close = posix_file_xfer_close, - .vredirect = xfer_vreopen, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = posix_file_xfer_deliver_iob, - .deliver_raw = xfer_deliver_as_iob, +static struct interface_operation posix_file_xfer_operations[] = { + INTF_OP ( xfer_deliver, struct posix_file *, posix_file_xfer_deliver ), + INTF_OP ( intf_close, struct posix_file *, posix_file_finished ), }; +/** POSIX file data transfer interface descriptor */ +static struct interface_descriptor posix_file_xfer_desc = + INTF_DESC ( struct posix_file, xfer, posix_file_xfer_operations ); + /** * Identify file by file descriptor * @@ -201,8 +185,7 @@ int open ( const char *uri_string ) { ref_init ( &file->refcnt, posix_file_free ); file->fd = fd; file->rc = -EINPROGRESS; - xfer_init ( &file->xfer, &posix_file_xfer_operations, - &file->refcnt ); + intf_init ( &file->xfer, &posix_file_xfer_desc, &file->refcnt ); INIT_LIST_HEAD ( &file->data ); /* Open URI on data transfer interface */ diff --git a/src/core/resolv.c b/src/core/resolv.c index 4256de471..91f0c15ce 100644 --- a/src/core/resolv.c +++ b/src/core/resolv.c @@ -299,7 +299,7 @@ struct named_socket { /** Reference counter */ struct refcnt refcnt; /** Data transfer interface */ - struct xfer_interface xfer; + struct interface xfer; /** Name resolution interface */ struct interface resolv; /** Communication semantics (e.g. SOCK_STREAM) */ @@ -319,33 +319,30 @@ struct named_socket { static void named_close ( struct named_socket *named, int rc ) { /* Shut down interfaces */ intf_shutdown ( &named->resolv, rc ); - xfer_nullify ( &named->xfer ); - xfer_close ( &named->xfer, rc ); + intf_shutdown ( &named->xfer, rc ); } /** - * Handle close() event + * Check flow control window * - * @v xfer Data transfer interface - * @v rc Reason for close + * @v named Named socket + * @ret len Length of window */ -static void named_xfer_close ( struct xfer_interface *xfer, int rc ) { - struct named_socket *named = - container_of ( xfer, struct named_socket, xfer ); - - named_close ( named, rc ); +static size_t named_window ( struct named_socket *named __unused ) { + /* Not ready for data until we have redirected away */ + return 0; } /** Named socket opener data transfer interface operations */ -static struct xfer_interface_operations named_xfer_ops = { - .close = named_xfer_close, - .vredirect = ignore_xfer_vredirect, - .window = no_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = xfer_deliver_as_raw, - .deliver_raw = ignore_xfer_deliver_raw, +static struct interface_operation named_xfer_ops[] = { + INTF_OP ( xfer_window, struct named_socket *, named_window ), + INTF_OP ( intf_close, struct named_socket *, named_close ), }; +/** Named socket opener data transfer interface descriptor */ +static struct interface_descriptor named_xfer_desc = + INTF_DESC ( struct named_socket, xfer, named_xfer_ops ); + /** * Name resolved * @@ -357,7 +354,7 @@ static void named_resolv_done ( struct named_socket *named, int rc; /* Nullify data transfer interface */ - xfer_nullify ( &named->xfer ); + intf_nullify ( &named->xfer ); /* Redirect data-xfer interface */ if ( ( rc = xfer_redirect ( &named->xfer, LOCATION_SOCKET, @@ -370,7 +367,7 @@ static void named_resolv_done ( struct named_socket *named, } else { /* Redirection succeeded - unplug data-xfer interface */ DBGC ( named, "NAMED %p redirected successfully\n", named ); - xfer_unplug ( &named->xfer ); + intf_unplug ( &named->xfer ); } /* Terminate named socket opener */ @@ -396,7 +393,7 @@ static struct interface_descriptor named_resolv_desc = * @v local Local socket address, or NULL * @ret rc Return status code */ -int xfer_open_named_socket ( struct xfer_interface *xfer, int semantics, +int xfer_open_named_socket ( struct interface *xfer, int semantics, struct sockaddr *peer, const char *name, struct sockaddr *local ) { struct named_socket *named; @@ -407,7 +404,7 @@ int xfer_open_named_socket ( struct xfer_interface *xfer, int semantics, if ( ! named ) return -ENOMEM; ref_init ( &named->refcnt, NULL ); - xfer_init ( &named->xfer, &named_xfer_ops, &named->refcnt ); + intf_init ( &named->xfer, &named_xfer_desc, &named->refcnt ); intf_init ( &named->resolv, &named_resolv_desc, &named->refcnt ); named->semantics = semantics; if ( local ) { @@ -423,7 +420,7 @@ int xfer_open_named_socket ( struct xfer_interface *xfer, int semantics, goto err; /* Attach parent interface, mortalise self, and return */ - xfer_plug_plug ( &named->xfer, xfer ); + intf_plug_plug ( &named->xfer, xfer ); ref_put ( &named->refcnt ); return 0; diff --git a/src/core/xfer.c b/src/core/xfer.c index 8dbfef6c8..057ab8b3f 100644 --- a/src/core/xfer.c +++ b/src/core/xfer.c @@ -21,7 +21,9 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include +#include #include +#include /** @file * @@ -37,178 +39,206 @@ FILE_LICENCE ( GPL2_OR_LATER ); */ static struct xfer_metadata dummy_metadata; -/** - * Close data transfer interface +/***************************************************************************** + * + * Data transfer interface operations * - * @v xfer Data transfer interface - * @v rc Reason for close */ -void xfer_close ( struct xfer_interface *xfer, int rc ) { - struct xfer_interface *dest = xfer_get_dest ( xfer ); - struct xfer_interface_operations *op = xfer->op; - - DBGC ( xfer, "XFER %p->%p close\n", xfer, dest ); - - xfer_unplug ( xfer ); - xfer_nullify ( xfer ); - dest->op->close ( dest, rc ); - xfer->op = op; - xfer_put ( dest ); -} /** * Send redirection event * - * @v xfer Data transfer interface + * @v intf Data transfer interface * @v type New location type * @v args Remaining arguments depend upon location type * @ret rc Return status code */ -int xfer_vredirect ( struct xfer_interface *xfer, int type, va_list args ) { - struct xfer_interface *dest = xfer_get_dest ( xfer ); +int xfer_vredirect ( struct interface *intf, int type, va_list args ) { + struct interface *dest; + xfer_vredirect_TYPE ( void * ) *op = + intf_get_dest_op ( intf, xfer_vredirect, &dest ); + void *object = intf_object ( dest ); int rc; - DBGC ( xfer, "XFER %p->%p redirect\n", xfer, dest ); + DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " redirect\n", + INTF_INTF_DBG ( intf, dest ) ); - rc = dest->op->vredirect ( dest, type, args ); + if ( op ) { + rc = op ( object, type, args ); + } else { + /* Default is to reopen the interface as instructed */ + rc = xfer_vreopen ( dest, type, args ); + } if ( rc != 0 ) { - DBGC ( xfer, "XFER %p<-%p redirect: %s\n", xfer, dest, + DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " redirect " + "failed: %s\n", INTF_INTF_DBG ( intf, dest ), strerror ( rc ) ); } - xfer_put ( dest ); - return rc; -} -/** - * Send redirection event - * - * @v xfer Data transfer interface - * @v type New location type - * @v ... Remaining arguments depend upon location type - * @ret rc Return status code - */ -int xfer_redirect ( struct xfer_interface *xfer, int type, ... ) { - va_list args; - int rc; - - va_start ( args, type ); - rc = xfer_vredirect ( xfer, type, args ); - va_end ( args ); + intf_put ( dest ); return rc; } /** * Check flow control window * - * @v xfer Data transfer interface + * @v intf Data transfer interface * @ret len Length of window */ -size_t xfer_window ( struct xfer_interface *xfer ) { - struct xfer_interface *dest = xfer_get_dest ( xfer ); +size_t xfer_window ( struct interface *intf ) { + struct interface *dest; + xfer_window_TYPE ( void * ) *op = + intf_get_dest_op ( intf, xfer_window, &dest ); + void *object = intf_object ( dest ); size_t len; - len = dest->op->window ( dest ); + if ( op ) { + len = op ( object ); + } else { + /* Default is to provide an unlimited window */ + len = ~( ( size_t ) 0 ); + } - xfer_put ( dest ); + intf_put ( dest ); return len; } /** * Allocate I/O buffer * - * @v xfer Data transfer interface + * @v intf Data transfer interface * @v len I/O buffer payload length * @ret iobuf I/O buffer */ -struct io_buffer * xfer_alloc_iob ( struct xfer_interface *xfer, size_t len ) { - struct xfer_interface *dest = xfer_get_dest ( xfer ); +struct io_buffer * xfer_alloc_iob ( struct interface *intf, size_t len ) { + struct interface *dest; + xfer_alloc_iob_TYPE ( void * ) *op = + intf_get_dest_op ( intf, xfer_alloc_iob, &dest ); + void *object = intf_object ( dest ); struct io_buffer *iobuf; - DBGC ( xfer, "XFER %p->%p alloc_iob %zd\n", xfer, dest, len ); + DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " alloc_iob %zd\n", + INTF_INTF_DBG ( intf, dest ), len ); - iobuf = dest->op->alloc_iob ( dest, len ); + if ( op ) { + iobuf = op ( object, len ); + } else { + /* Default is to allocate an I/O buffer with no + * reserved space. + */ + iobuf = alloc_iob ( len ); + } if ( ! iobuf ) { - DBGC ( xfer, "XFER %p<-%p alloc_iob failed\n", xfer, dest ); + DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " alloc_iob " + "failed\n", INTF_INTF_DBG ( intf, dest ) ); } - xfer_put ( dest ); + + intf_put ( dest ); return iobuf; } /** - * Deliver datagram as I/O buffer with metadata + * Deliver datagram * - * @v xfer Data transfer interface + * @v intf Data transfer interface * @v iobuf Datagram I/O buffer * @v meta Data transfer metadata * @ret rc Return status code */ -int xfer_deliver_iob_meta ( struct xfer_interface *xfer, - struct io_buffer *iobuf, - struct xfer_metadata *meta ) { - struct xfer_interface *dest = xfer_get_dest ( xfer ); +int xfer_deliver ( struct interface *intf, + struct io_buffer *iobuf, + struct xfer_metadata *meta ) { + struct interface *dest; + xfer_deliver_TYPE ( void * ) *op = + intf_get_dest_op ( intf, xfer_deliver, &dest ); + void *object = intf_object ( dest ); int rc; - DBGC ( xfer, "XFER %p->%p deliver_iob %zd\n", xfer, dest, - iob_len ( iobuf ) ); + DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " deliver %zd\n", + INTF_INTF_DBG ( intf, dest ), iob_len ( iobuf ) ); - rc = dest->op->deliver_iob ( dest, iobuf, meta ); + if ( op ) { + rc = op ( object, iobuf, meta ); + } else { + /* Default is to discard the I/O buffer */ + free_iob ( iobuf ); + rc = -EPIPE; + } if ( rc != 0 ) { - DBGC ( xfer, "XFER %p<-%p deliver_iob: %s\n", xfer, dest, - strerror ( rc ) ); + DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT + " deliver failed: %s\n", + INTF_INTF_DBG ( intf, dest ), strerror ( rc ) ); } - xfer_put ( dest ); + + intf_put ( dest ); + return rc; +} + +/***************************************************************************** + * + * Data transfer interface helper functions + * + */ + +/** + * Send redirection event + * + * @v intf Data transfer interface + * @v type New location type + * @v ... Remaining arguments depend upon location type + * @ret rc Return status code + */ +int xfer_redirect ( struct interface *intf, int type, ... ) { + va_list args; + int rc; + + va_start ( args, type ); + rc = xfer_vredirect ( intf, type, args ); + va_end ( args ); return rc; } /** - * Deliver datagram as I/O buffer with metadata + * Deliver datagram as I/O buffer without metadata * - * @v xfer Data transfer interface + * @v intf Data transfer interface * @v iobuf Datagram I/O buffer * @ret rc Return status code */ -int xfer_deliver_iob ( struct xfer_interface *xfer, - struct io_buffer *iobuf ) { - return xfer_deliver_iob_meta ( xfer, iobuf, &dummy_metadata ); +int xfer_deliver_iob ( struct interface *intf, struct io_buffer *iobuf ) { + return xfer_deliver ( intf, iobuf, &dummy_metadata ); } /** * Deliver datagram as raw data * - * @v xfer Data transfer interface + * @v intf Data transfer interface * @v iobuf Datagram I/O buffer * @ret rc Return status code */ -int xfer_deliver_raw ( struct xfer_interface *xfer, - const void *data, size_t len ) { - struct xfer_interface *dest = xfer_get_dest ( xfer ); - int rc; +int xfer_deliver_raw ( struct interface *intf, const void *data, size_t len ) { + struct io_buffer *iobuf; - DBGC ( xfer, "XFER %p->%p deliver_raw %p+%zd\n", xfer, dest, - data, len ); + iobuf = xfer_alloc_iob ( intf, len ); + if ( ! iobuf ) + return -ENOMEM; - rc = dest->op->deliver_raw ( dest, data, len ); - - if ( rc != 0 ) { - DBGC ( xfer, "XFER %p<-%p deliver_raw: %s\n", xfer, dest, - strerror ( rc ) ); - } - xfer_put ( dest ); - return rc; + memcpy ( iob_put ( iobuf, len ), data, len ); + return xfer_deliver_iob ( intf, iobuf ); } /** * Deliver formatted string * - * @v xfer Data transfer interface + * @v intf Data transfer interface * @v format Format string * @v args Arguments corresponding to the format string * @ret rc Return status code */ -int xfer_vprintf ( struct xfer_interface *xfer, const char *format, +int xfer_vprintf ( struct interface *intf, const char *format, va_list args ) { size_t len; va_list args_tmp; @@ -219,24 +249,24 @@ int xfer_vprintf ( struct xfer_interface *xfer, const char *format, char buf[len + 1]; vsnprintf ( buf, sizeof ( buf ), format, args_tmp ); va_end ( args_tmp ); - return xfer_deliver_raw ( xfer, buf, len ); + return xfer_deliver_raw ( intf, buf, len ); } } /** * Deliver formatted string * - * @v xfer Data transfer interface + * @v intf Data transfer interface * @v format Format string * @v ... Arguments corresponding to the format string * @ret rc Return status code */ -int xfer_printf ( struct xfer_interface *xfer, const char *format, ... ) { +int xfer_printf ( struct interface *intf, const char *format, ... ) { va_list args; int rc; va_start ( args, format ); - rc = xfer_vprintf ( xfer, format, args ); + rc = xfer_vprintf ( intf, format, args ); va_end ( args ); return rc; } @@ -244,174 +274,25 @@ int xfer_printf ( struct xfer_interface *xfer, const char *format, ... ) { /** * Seek to position * - * @v xfer Data transfer interface + * @v intf Data transfer interface * @v offset Offset to new position * @v whence Basis for new position * @ret rc Return status code */ -int xfer_seek ( struct xfer_interface *xfer, off_t offset, int whence ) { +int xfer_seek ( struct interface *intf, off_t offset, int whence ) { struct io_buffer *iobuf; struct xfer_metadata meta = { .offset = offset, .whence = whence, }; - DBGC ( xfer, "XFER %p seek %s+%ld\n", xfer, - whence_text ( whence ), offset ); + DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " seek %s+%ld\n", + INTF_DBG ( intf ), whence_text ( whence ), offset ); /* Allocate and send a zero-length data buffer */ - iobuf = xfer_alloc_iob ( xfer, 0 ); - if ( ! iobuf ) - return -ENOMEM; - return xfer_deliver_iob_meta ( xfer, iobuf, &meta ); -} - -/**************************************************************************** - * - * Helper methods - * - * These functions are designed to be used as methods in the - * xfer_interface_operations table. - * - */ - -/** - * Ignore close() event - * - * @v xfer Data transfer interface - * @v rc Reason for close - */ -void ignore_xfer_close ( struct xfer_interface *xfer __unused, - int rc __unused ) { - /* Nothing to do */ -} - -/** - * Ignore vredirect() event - * - * @v xfer Data transfer interface - * @v type New location type - * @v args Remaining arguments depend upon location type - * @ret rc Return status code - */ -int ignore_xfer_vredirect ( struct xfer_interface *xfer __unused, - int type __unused, va_list args __unused ) { - return 0; -} - -/** - * Unlimited flow control window - * - * @v xfer Data transfer interface - * @ret len Length of window - * - * This handler indicates that the interface is always ready to accept - * data. - */ -size_t unlimited_xfer_window ( struct xfer_interface *xfer __unused ) { - return ~( ( size_t ) 0 ); -} - -/** - * No flow control window - * - * @v xfer Data transfer interface - * @ret len Length of window - * - * This handler indicates that the interface is never ready to accept - * data. - */ -size_t no_xfer_window ( struct xfer_interface *xfer __unused ) { - return 0; -} - -/** - * Allocate I/O buffer - * - * @v xfer Data transfer interface - * @v len I/O buffer payload length - * @ret iobuf I/O buffer - */ -struct io_buffer * -default_xfer_alloc_iob ( struct xfer_interface *xfer __unused, size_t len ) { - return alloc_iob ( len ); -} - -/** - * Deliver datagram as raw data - * - * @v xfer Data transfer interface - * @v iobuf Datagram I/O buffer - * @v meta Data transfer metadata - * @ret rc Return status code - * - * This function is intended to be used as the deliver() method for - * data transfer interfaces that prefer to handle raw data. - */ -int xfer_deliver_as_raw ( struct xfer_interface *xfer, - struct io_buffer *iobuf, - struct xfer_metadata *meta __unused ) { - int rc; - - rc = xfer->op->deliver_raw ( xfer, iobuf->data, iob_len ( iobuf ) ); - free_iob ( iobuf ); - return rc; -} - -/** - * Deliver datagram as I/O buffer - * - * @v xfer Data transfer interface - * @v data Data buffer - * @v len Length of data buffer - * @ret rc Return status code - * - * This function is intended to be used as the deliver_raw() method - * for data transfer interfaces that prefer to handle I/O buffers. - */ -int xfer_deliver_as_iob ( struct xfer_interface *xfer, - const void *data, size_t len ) { - struct io_buffer *iobuf; - - iobuf = xfer->op->alloc_iob ( xfer, len ); + iobuf = xfer_alloc_iob ( intf, 0 ); if ( ! iobuf ) return -ENOMEM; - memcpy ( iob_put ( iobuf, len ), data, len ); - return xfer->op->deliver_iob ( xfer, iobuf, &dummy_metadata ); + return xfer_deliver ( intf, iobuf, &meta ); } - -/** - * Ignore datagram as raw data event - * - * @v xfer Data transfer interface - * @v data Data buffer - * @v len Length of data buffer - * @ret rc Return status code - */ -int ignore_xfer_deliver_raw ( struct xfer_interface *xfer, - const void *data __unused, size_t len ) { - DBGC ( xfer, "XFER %p %zd bytes delivered %s\n", xfer, len, - ( ( xfer == &null_xfer ) ? - "before connection" : "after termination" ) ); - return 0; -} - -/** Null data transfer interface operations */ -struct xfer_interface_operations null_xfer_ops = { - .close = ignore_xfer_close, - .vredirect = ignore_xfer_vredirect, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = xfer_deliver_as_raw, - .deliver_raw = ignore_xfer_deliver_raw, -}; - -/** - * Null data transfer interface - * - * This is the interface to which data transfer interfaces are - * connected when unplugged. It will never generate messages, and - * will silently absorb all received messages. - */ -struct xfer_interface null_xfer = XFER_INIT ( &null_xfer_ops ); diff --git a/src/drivers/block/srp.c b/src/drivers/block/srp.c index 49fb214ea..a8deab15d 100644 --- a/src/drivers/block/srp.c +++ b/src/drivers/block/srp.c @@ -75,7 +75,7 @@ static void srp_scsi_done ( struct srp_device *srp, int rc ) { static void srp_fail ( struct srp_device *srp, int rc ) { /* Close underlying socket */ - xfer_close ( &srp->socket, rc ); + intf_restart ( &srp->socket, rc ); /* Clear session state */ srp->state = 0; @@ -364,16 +364,14 @@ static int srp_unrecognised ( struct srp_device *srp, /** * Receive data from underlying socket * - * @v xfer Data transfer interface + * @v srp SRP device * @v iobuf Datagram I/O buffer * @v meta Data transfer metadata * @ret rc Return status code */ -static int srp_xfer_deliver_iob ( struct xfer_interface *xfer, - struct io_buffer *iobuf, - struct xfer_metadata *meta __unused ) { - struct srp_device *srp = - container_of ( xfer, struct srp_device, socket ); +static int srp_xfer_deliver ( struct srp_device *srp, + struct io_buffer *iobuf, + struct xfer_metadata *meta __unused ) { struct srp_common *common = iobuf->data; int ( * type ) ( struct srp_device *srp, struct io_buffer *iobuf ); int rc; @@ -405,31 +403,16 @@ static int srp_xfer_deliver_iob ( struct xfer_interface *xfer, return rc; } -/** - * Underlying socket closed - * - * @v xfer Data transfer interface - * @v rc Reason for close - */ -static void srp_xfer_close ( struct xfer_interface *xfer, int rc ) { - struct srp_device *srp = - container_of ( xfer, struct srp_device, socket ); - - DBGC ( srp, "SRP %p socket closed: %s\n", srp, strerror ( rc ) ); - - srp_fail ( srp, rc ); -} - /** SRP data transfer interface operations */ -static struct xfer_interface_operations srp_xfer_operations = { - .close = srp_xfer_close, - .vredirect = ignore_xfer_vredirect, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = srp_xfer_deliver_iob, - .deliver_raw = xfer_deliver_as_iob, +static struct interface_operation srp_xfer_operations[] = { + INTF_OP ( xfer_deliver, struct srp_device *, srp_xfer_deliver ), + INTF_OP ( intf_close, struct srp_device *, srp_fail ), }; +/** SRP data transfer interface descriptor */ +static struct interface_descriptor srp_xfer_desc = + INTF_DESC ( struct srp_device, socket, srp_xfer_operations ); + /** * Issue SCSI command via SRP * @@ -483,7 +466,7 @@ int srp_attach ( struct scsi_device *scsi, const char *root_path ) { goto err_alloc; } ref_init ( &srp->refcnt, NULL ); - xfer_init ( &srp->socket, &srp_xfer_operations, &srp->refcnt ); + intf_init ( &srp->socket, &srp_xfer_desc, &srp->refcnt ); srp->transport = transport; DBGC ( srp, "SRP %p using %s\n", srp, root_path ); @@ -516,8 +499,7 @@ void srp_detach ( struct scsi_device *scsi ) { container_of ( scsi->backend, struct srp_device, refcnt ); /* Close socket */ - xfer_nullify ( &srp->socket ); - xfer_close ( &srp->socket, 0 ); + intf_shutdown ( &srp->socket, 0 ); scsi->command = scsi_detached_command; ref_put ( scsi->backend ); scsi->backend = NULL; diff --git a/src/include/ipxe/filter.h b/src/include/ipxe/filter.h deleted file mode 100644 index b23a98d91..000000000 --- a/src/include/ipxe/filter.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef _IPXE_FILTER_H -#define _IPXE_FILTER_H - -/** @file - * - * Data transfer filters - * - */ - -FILE_LICENCE ( GPL2_OR_LATER ); - -#include -#include - -/** - * Half of a data transfer filter - * - * Embed two of these structures within a structure implementing a - * data transfer filter, and intialise with filter_init(). You can - * then use the filter_xxx() methods as the data transfer interface - * methods as required. - */ -struct xfer_filter_half { - /** Data transfer interface */ - struct xfer_interface xfer; - /** Other half of the data transfer filter */ - struct xfer_filter_half *other; -}; - -/** - * Get data transfer interface for the other half of a data transfer filter - * - * @v xfer Data transfer interface - * @ret other Other half's data transfer interface - */ -static inline __attribute__ (( always_inline )) struct xfer_interface * -filter_other_half ( struct xfer_interface *xfer ) { - struct xfer_filter_half *half = - container_of ( xfer, struct xfer_filter_half, xfer ); - return &half->other->xfer; -} - -extern void filter_close ( struct xfer_interface *xfer, int rc ); -extern int filter_vredirect ( struct xfer_interface *xfer, int type, - va_list args ); -extern size_t filter_window ( struct xfer_interface *xfer ); -extern struct io_buffer * filter_alloc_iob ( struct xfer_interface *xfer, - size_t len ); -extern int filter_deliver_iob ( struct xfer_interface *xfer, - struct io_buffer *iobuf, - struct xfer_metadata *meta ); -extern int filter_deliver_raw ( struct xfer_interface *xfer, const void *data, - size_t len ); - -/** - * Initialise a data transfer filter - * - * @v left "Left" half of the filter - * @v left_op Data transfer interface operations for "left" half - * @v right "Right" half of the filter - * @v right_op Data transfer interface operations for "right" half - * @v refcnt Containing object reference counter, or NULL - */ -static inline void filter_init ( struct xfer_filter_half *left, - struct xfer_interface_operations *left_op, - struct xfer_filter_half *right, - struct xfer_interface_operations *right_op, - struct refcnt *refcnt ) { - xfer_init ( &left->xfer, left_op, refcnt ); - xfer_init ( &right->xfer, right_op, refcnt ); - left->other = right; - right->other = left; -} - -#endif /* _IPXE_FILTER_H */ diff --git a/src/include/ipxe/http.h b/src/include/ipxe/http.h index 97014d1f4..d8f4ca5ac 100644 --- a/src/include/ipxe/http.h +++ b/src/include/ipxe/http.h @@ -15,9 +15,9 @@ FILE_LICENCE ( GPL2_OR_LATER ); /** HTTPS default port */ #define HTTPS_PORT 443 -extern int http_open_filter ( struct xfer_interface *xfer, struct uri *uri, +extern int http_open_filter ( struct interface *xfer, struct uri *uri, unsigned int default_port, - int ( * filter ) ( struct xfer_interface *, - struct xfer_interface ** ) ); + int ( * filter ) ( struct interface *, + struct interface ** ) ); #endif /* _IPXE_HTTP_H */ diff --git a/src/include/ipxe/ib_cmrc.h b/src/include/ipxe/ib_cmrc.h index c02b15dcb..4f2eae69e 100644 --- a/src/include/ipxe/ib_cmrc.h +++ b/src/include/ipxe/ib_cmrc.h @@ -12,7 +12,7 @@ FILE_LICENCE ( BSD2 ); #include #include -extern int ib_cmrc_open ( struct xfer_interface *xfer, +extern int ib_cmrc_open ( struct interface *xfer, struct ib_device *ibdev, struct ib_gid *dgid, struct ib_gid_half *service_id ); diff --git a/src/include/ipxe/iscsi.h b/src/include/ipxe/iscsi.h index c5e725154..a604e1e4f 100644 --- a/src/include/ipxe/iscsi.h +++ b/src/include/ipxe/iscsi.h @@ -498,7 +498,7 @@ struct iscsi_session { struct refcnt refcnt; /** Transport-layer socket */ - struct xfer_interface socket; + struct interface socket; /** Target address */ char *target_address; diff --git a/src/include/ipxe/open.h b/src/include/ipxe/open.h index 04e37e0e6..c000990c0 100644 --- a/src/include/ipxe/open.h +++ b/src/include/ipxe/open.h @@ -13,8 +13,8 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include -struct xfer_interface; struct uri; +struct interface; /** Location types */ enum { @@ -53,11 +53,11 @@ struct uri_opener { const char *scheme; /** Open URI * - * @v xfer Data transfer interface + * @v intf Object interface * @v uri URI * @ret rc Return status code */ - int ( * open ) ( struct xfer_interface *xfer, struct uri *uri ); + int ( * open ) ( struct interface *intf, struct uri *uri ); }; /** URI opener table */ @@ -74,12 +74,12 @@ struct socket_opener { int family; /** Open socket * - * @v xfer Data transfer interface + * @v intf Object interface * @v peer Peer socket address * @v local Local socket address, or NULL * @ret rc Return status code */ - int ( * open ) ( struct xfer_interface *xfer, struct sockaddr *peer, + int ( * open ) ( struct interface *intf, struct sockaddr *peer, struct sockaddr *local ); }; @@ -89,17 +89,17 @@ struct socket_opener { /** Register a socket opener */ #define __socket_opener __table_entry ( SOCKET_OPENERS, 01 ) -extern int xfer_open_uri ( struct xfer_interface *xfer, struct uri *uri ); -extern int xfer_open_uri_string ( struct xfer_interface *xfer, +extern int xfer_open_uri ( struct interface *intf, struct uri *uri ); +extern int xfer_open_uri_string ( struct interface *intf, const char *uri_string ); -extern int xfer_open_named_socket ( struct xfer_interface *xfer, - int semantics, struct sockaddr *peer, - const char *name, struct sockaddr *local ); -extern int xfer_open_socket ( struct xfer_interface *xfer, int semantics, +extern int xfer_open_named_socket ( struct interface *intf, int semantics, + struct sockaddr *peer, const char *name, + struct sockaddr *local ); +extern int xfer_open_socket ( struct interface *intf, int semantics, struct sockaddr *peer, struct sockaddr *local ); -extern int xfer_vopen ( struct xfer_interface *xfer, int type, va_list args ); -extern int xfer_open ( struct xfer_interface *xfer, int type, ... ); -extern int xfer_vreopen ( struct xfer_interface *xfer, int type, +extern int xfer_vopen ( struct interface *intf, int type, va_list args ); +extern int xfer_open ( struct interface *intf, int type, ... ); +extern int xfer_vreopen ( struct interface *intf, int type, va_list args ); #endif /* _IPXE_OPEN_H */ diff --git a/src/include/ipxe/srp.h b/src/include/ipxe/srp.h index 7c0ff4c93..e519838a4 100644 --- a/src/include/ipxe/srp.h +++ b/src/include/ipxe/srp.h @@ -832,7 +832,7 @@ struct srp_device { struct scsi_command *command; /** Underlying data transfer interface */ - struct xfer_interface socket; + struct interface socket; /** Transport type */ struct srp_transport_type *transport; diff --git a/src/include/ipxe/tls.h b/src/include/ipxe/tls.h index 2cc36dd7c..94cd322c8 100644 --- a/src/include/ipxe/tls.h +++ b/src/include/ipxe/tls.h @@ -11,7 +11,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include -#include +#include #include #include #include @@ -134,9 +134,9 @@ struct tls_session { struct refcnt refcnt; /** Plaintext stream */ - struct xfer_filter_half plainstream; + struct interface plainstream; /** Ciphertext stream */ - struct xfer_filter_half cipherstream; + struct interface cipherstream; /** Current TX cipher specification */ struct tls_cipherspec tx_cipherspec; @@ -181,7 +181,7 @@ struct tls_session { void *rx_data; }; -extern int add_tls ( struct xfer_interface *xfer, - struct xfer_interface **next ); +extern int add_tls ( struct interface *xfer, + struct interface **next ); #endif /* _IPXE_TLS_H */ diff --git a/src/include/ipxe/udp.h b/src/include/ipxe/udp.h index 5e55c5e8c..c18a29723 100644 --- a/src/include/ipxe/udp.h +++ b/src/include/ipxe/udp.h @@ -16,7 +16,8 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include -struct xfer_interface; +struct interface; +struct sockaddr; /** * UDP constants @@ -40,8 +41,8 @@ struct udp_header { uint16_t chksum; }; -extern int udp_open_promisc ( struct xfer_interface *xfer ); -extern int udp_open ( struct xfer_interface *xfer, struct sockaddr *peer, +extern int udp_open_promisc ( struct interface *xfer ); +extern int udp_open ( struct interface *xfer, struct sockaddr *peer, struct sockaddr *local ); #endif /* _IPXE_UDP_H */ diff --git a/src/include/ipxe/xfer.h b/src/include/ipxe/xfer.h index 8a3f9bb1c..67da15f16 100644 --- a/src/include/ipxe/xfer.h +++ b/src/include/ipxe/xfer.h @@ -12,88 +12,11 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include -#include -struct xfer_interface; struct xfer_metadata; - -/** Data transfer interface operations */ -struct xfer_interface_operations { - /** Close interface - * - * @v xfer Data transfer interface - * @v rc Reason for close - */ - void ( * close ) ( struct xfer_interface *xfer, int rc ); - /** Redirect to new location - * - * @v xfer Data transfer interface - * @v type New location type - * @v args Remaining arguments depend upon location type - * @ret rc Return status code - */ - int ( * vredirect ) ( struct xfer_interface *xfer, int type, - va_list args ); - /** Check flow control window - * - * @v xfer Data transfer interface - * @ret len Length of window - * - * Flow control is regarded as advisory but not mandatory. - * Users who have control over their own rate of data - * generation should perform a flow control check before - * generating new data. Users who have no control (such as - * NIC drivers or filter layers) are not obliged to check. - * - * Data transfer interfaces must be prepared to accept - * datagrams even if they are advertising a window of zero - * bytes. - */ - size_t ( * window ) ( struct xfer_interface *xfer ); - /** Allocate I/O buffer - * - * @v xfer Data transfer interface - * @v len I/O buffer payload length - * @ret iobuf I/O buffer - */ - struct io_buffer * ( * alloc_iob ) ( struct xfer_interface *xfer, - size_t len ); - /** Deliver datagram as I/O buffer with metadata - * - * @v xfer Data transfer interface - * @v iobuf Datagram I/O buffer - * @v meta Data transfer metadata - * @ret rc Return status code - * - * A data transfer interface that wishes to support only raw - * data delivery should set this method to - * xfer_deliver_as_raw(). - */ - int ( * deliver_iob ) ( struct xfer_interface *xfer, - struct io_buffer *iobuf, - struct xfer_metadata *meta ); - /** Deliver datagram as raw data - * - * @v xfer Data transfer interface - * @v data Data buffer - * @v len Length of data buffer - * @ret rc Return status code - * - * A data transfer interface that wishes to support only I/O - * buffer delivery should set this method to - * xfer_deliver_as_iob(). - */ - int ( * deliver_raw ) ( struct xfer_interface *xfer, - const void *data, size_t len ); -}; - -/** A data transfer interface */ -struct xfer_interface { - /** Generic object communication interface */ - struct interface intf; - /** Operations for received messages */ - struct xfer_interface_operations *op; -}; +struct io_buffer; +struct sockaddr; +struct net_device; /** Basis positions for seek() events */ enum seek_whence { @@ -132,146 +55,40 @@ whence_text ( int whence ) { } } -extern struct xfer_interface null_xfer; -extern struct xfer_interface_operations null_xfer_ops; +/* Data transfer interface operations */ -extern void xfer_close ( struct xfer_interface *xfer, int rc ); -extern int xfer_vredirect ( struct xfer_interface *xfer, int type, +extern int xfer_vredirect ( struct interface *intf, int type, va_list args ); -extern int xfer_redirect ( struct xfer_interface *xfer, int type, ... ); -extern size_t xfer_window ( struct xfer_interface *xfer ); -extern struct io_buffer * xfer_alloc_iob ( struct xfer_interface *xfer, +#define xfer_vredirect_TYPE( object_type ) \ + typeof ( int ( object_type, int type, va_list args ) ) + +extern size_t xfer_window ( struct interface *intf ); +#define xfer_window_TYPE( object_type ) \ + typeof ( size_t ( object_type ) ) + +extern struct io_buffer * xfer_alloc_iob ( struct interface *intf, size_t len ); -extern int xfer_deliver_iob ( struct xfer_interface *xfer, +#define xfer_alloc_iob_TYPE( object_type ) \ + typeof ( struct io_buffer * ( object_type, size_t len ) ) + +extern int xfer_deliver ( struct interface *intf, + struct io_buffer *iobuf, + struct xfer_metadata *meta ); +#define xfer_deliver_TYPE( object_type ) \ + typeof ( int ( object_type, struct io_buffer *iobuf, \ + struct xfer_metadata *meta ) ) + +/* Data transfer interface helper functions */ + +extern int xfer_redirect ( struct interface *xfer, int type, ... ); +extern int xfer_deliver_iob ( struct interface *intf, struct io_buffer *iobuf ); -extern int xfer_deliver_iob_meta ( struct xfer_interface *xfer, - struct io_buffer *iobuf, - struct xfer_metadata *meta ); -extern int xfer_deliver_raw ( struct xfer_interface *xfer, +extern int xfer_deliver_raw ( struct interface *intf, const void *data, size_t len ); -extern int xfer_vprintf ( struct xfer_interface *xfer, +extern int xfer_vprintf ( struct interface *intf, const char *format, va_list args ); extern int __attribute__ (( format ( printf, 2, 3 ) )) -xfer_printf ( struct xfer_interface *xfer, const char *format, ... ); -extern int xfer_seek ( struct xfer_interface *xfer, off_t offset, int whence ); - -extern void ignore_xfer_close ( struct xfer_interface *xfer, int rc ); -extern int ignore_xfer_vredirect ( struct xfer_interface *xfer, - int type, va_list args ); -extern size_t unlimited_xfer_window ( struct xfer_interface *xfer ); -extern size_t no_xfer_window ( struct xfer_interface *xfer ); -extern struct io_buffer * default_xfer_alloc_iob ( struct xfer_interface *xfer, - size_t len ); -extern int xfer_deliver_as_raw ( struct xfer_interface *xfer, - struct io_buffer *iobuf, - struct xfer_metadata *meta ); -extern int xfer_deliver_as_iob ( struct xfer_interface *xfer, - const void *data, size_t len ); -extern int ignore_xfer_deliver_raw ( struct xfer_interface *xfer, - const void *data __unused, size_t len ); - -/** - * Initialise a data transfer interface - * - * @v xfer Data transfer interface - * @v op Data transfer interface operations - * @v refcnt Containing object reference counter, or NULL - */ -static inline void xfer_init ( struct xfer_interface *xfer, - struct xfer_interface_operations *op, - struct refcnt *refcnt ) { - xfer->intf.dest = &null_xfer.intf; - xfer->intf.refcnt = refcnt; - xfer->op = op; -} - -/** - * Initialise a static data transfer interface - * - * @v operations Data transfer interface operations - */ -#define XFER_INIT( operations ) { \ - .intf = { \ - .dest = &null_xfer.intf, \ - .refcnt = NULL, \ - }, \ - .op = operations, \ - } - -/** - * Get data transfer interface from generic object communication interface - * - * @v intf Generic object communication interface - * @ret xfer Data transfer interface - */ -static inline __attribute__ (( always_inline )) struct xfer_interface * -intf_to_xfer ( struct interface *intf ) { - return container_of ( intf, struct xfer_interface, intf ); -} - -/** - * Get reference to destination data transfer interface - * - * @v xfer Data transfer interface - * @ret dest Destination interface - */ -static inline __attribute__ (( always_inline )) struct xfer_interface * -xfer_get_dest ( struct xfer_interface *xfer ) { - return intf_to_xfer ( intf_get ( xfer->intf.dest ) ); -} - -/** - * Drop reference to data transfer interface - * - * @v xfer Data transfer interface - */ -static inline __attribute__ (( always_inline )) void -xfer_put ( struct xfer_interface *xfer ) { - intf_put ( &xfer->intf ); -} - -/** - * Plug a data transfer interface into a new destination interface - * - * @v xfer Data transfer interface - * @v dest New destination interface - */ -static inline __attribute__ (( always_inline )) void -xfer_plug ( struct xfer_interface *xfer, struct xfer_interface *dest ) { - intf_plug ( &xfer->intf, &dest->intf ); -} - -/** - * Plug two data transfer interfaces together - * - * @v a Data transfer interface A - * @v b Data transfer interface B - */ -static inline __attribute__ (( always_inline )) void -xfer_plug_plug ( struct xfer_interface *a, struct xfer_interface *b ) { - intf_plug_plug ( &a->intf, &b->intf ); -} - -/** - * Unplug a data transfer interface - * - * @v xfer Data transfer interface - */ -static inline __attribute__ (( always_inline )) void -xfer_unplug ( struct xfer_interface *xfer ) { - intf_plug ( &xfer->intf, &null_xfer.intf ); -} - -/** - * Stop using a data transfer interface - * - * @v xfer Data transfer interface - * - * After calling this method, no further messages will be received via - * the interface. - */ -static inline void xfer_nullify ( struct xfer_interface *xfer ) { - xfer->op = &null_xfer_ops; -}; +xfer_printf ( struct interface *intf, const char *format, ... ); +extern int xfer_seek ( struct interface *intf, off_t offset, int whence ); #endif /* _IPXE_XFER_H */ diff --git a/src/net/infiniband/ib_cmrc.c b/src/net/infiniband/ib_cmrc.c index b7b9cd819..f596c36dc 100644 --- a/src/net/infiniband/ib_cmrc.c +++ b/src/net/infiniband/ib_cmrc.c @@ -70,7 +70,7 @@ struct ib_cmrc_connection { /** Reference count */ struct refcnt refcnt; /** Data transfer interface */ - struct xfer_interface xfer; + struct interface xfer; /** Infiniband device */ struct ib_device *ibdev; /** Completion queue */ @@ -135,8 +135,7 @@ static void ib_cmrc_shutdown ( struct process *process ) { static void ib_cmrc_close ( struct ib_cmrc_connection *cmrc, int rc ) { /* Close data transfer interface */ - xfer_nullify ( &cmrc->xfer ); - xfer_close ( &cmrc->xfer, rc ); + intf_shutdown ( &cmrc->xfer, rc ); /* Schedule shutdown process */ process_add ( &cmrc->shutdown ); @@ -263,16 +262,14 @@ static struct ib_completion_queue_operations ib_cmrc_completion_ops = { /** * Send data via CMRC * - * @v xfer Data transfer interface + * @v cmrc CMRC connection * @v iobuf Datagram I/O buffer * @v meta Data transfer metadata * @ret rc Return status code */ -static int ib_cmrc_xfer_deliver_iob ( struct xfer_interface *xfer, - struct io_buffer *iobuf, - struct xfer_metadata *meta __unused ) { - struct ib_cmrc_connection *cmrc = - container_of ( xfer, struct ib_cmrc_connection, xfer ); +static int ib_cmrc_xfer_deliver ( struct ib_cmrc_connection *cmrc, + struct io_buffer *iobuf, + struct xfer_metadata *meta __unused ) { int rc; /* If no connection has yet been attempted, send this datagram @@ -326,12 +323,10 @@ static int ib_cmrc_xfer_deliver_iob ( struct xfer_interface *xfer, /** * Check CMRC flow control window * - * @v xfer Data transfer interface + * @v cmrc CMRC connection * @ret len Length of window */ -static size_t ib_cmrc_xfer_window ( struct xfer_interface *xfer ) { - struct ib_cmrc_connection *cmrc = - container_of ( xfer, struct ib_cmrc_connection, xfer ); +static size_t ib_cmrc_xfer_window ( struct ib_cmrc_connection *cmrc ) { /* We indicate a window only when we are successfully * connected. @@ -339,30 +334,19 @@ static size_t ib_cmrc_xfer_window ( struct xfer_interface *xfer ) { return ( cmrc->connected ? IB_MAX_PAYLOAD_SIZE : 0 ); } -/** - * Close CMRC data-transfer interface - * - * @v xfer Data transfer interface - * @v rc Reason for close - */ -static void ib_cmrc_xfer_close ( struct xfer_interface *xfer, int rc ) { - struct ib_cmrc_connection *cmrc = - container_of ( xfer, struct ib_cmrc_connection, xfer ); - - DBGC ( cmrc, "CMRC %p closed: %s\n", cmrc, strerror ( rc ) ); - ib_cmrc_close ( cmrc, rc ); -} - /** CMRC data transfer interface operations */ -static struct xfer_interface_operations ib_cmrc_xfer_operations = { - .close = ib_cmrc_xfer_close, - .vredirect = ignore_xfer_vredirect, - .window = ib_cmrc_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = ib_cmrc_xfer_deliver_iob, - .deliver_raw = xfer_deliver_as_iob, +static struct interface_operation ib_cmrc_xfer_operations[] = { + INTF_OP ( xfer_deliver, struct ib_cmrc_connection *, + ib_cmrc_xfer_deliver ), + INTF_OP ( xfer_window, struct ib_cmrc_connection *, + ib_cmrc_xfer_window ), + INTF_OP ( intf_close, struct ib_cmrc_connection *, ib_cmrc_close ), }; +/** CMRC data transfer interface descriptor */ +static struct interface_descriptor ib_cmrc_xfer_desc = + INTF_DESC ( struct ib_cmrc_connection, xfer, ib_cmrc_xfer_operations ); + /** * Open CMRC connection * @@ -372,7 +356,7 @@ static struct xfer_interface_operations ib_cmrc_xfer_operations = { * @v service_id Service ID * @ret rc Returns status code */ -int ib_cmrc_open ( struct xfer_interface *xfer, struct ib_device *ibdev, +int ib_cmrc_open ( struct interface *xfer, struct ib_device *ibdev, struct ib_gid *dgid, struct ib_gid_half *service_id ) { struct ib_cmrc_connection *cmrc; int rc; @@ -384,7 +368,7 @@ int ib_cmrc_open ( struct xfer_interface *xfer, struct ib_device *ibdev, goto err_alloc; } ref_init ( &cmrc->refcnt, NULL ); - xfer_init ( &cmrc->xfer, &ib_cmrc_xfer_operations, &cmrc->refcnt ); + intf_init ( &cmrc->xfer, &ib_cmrc_xfer_desc, &cmrc->refcnt ); cmrc->ibdev = ibdev; memcpy ( &cmrc->dgid, dgid, sizeof ( cmrc->dgid ) ); memcpy ( &cmrc->service_id, service_id, sizeof ( cmrc->service_id ) ); @@ -422,7 +406,7 @@ int ib_cmrc_open ( struct xfer_interface *xfer, struct ib_device *ibdev, /* Attach to parent interface, transfer reference (implicitly) * to our shutdown process, and return. */ - xfer_plug_plug ( &cmrc->xfer, xfer ); + intf_plug_plug ( &cmrc->xfer, xfer ); return 0; ib_destroy_qp ( ibdev, cmrc->qp ); diff --git a/src/net/tcp.c b/src/net/tcp.c index b5b9ff608..d64153f3e 100644 --- a/src/net/tcp.c +++ b/src/net/tcp.c @@ -31,7 +31,7 @@ struct tcp_connection { struct list_head list; /** Data transfer interface */ - struct xfer_interface xfer; + struct interface xfer; /** Data transfer interface closed flag */ int xfer_closed; @@ -92,7 +92,7 @@ struct tcp_connection { static LIST_HEAD ( tcp_conns ); /* Forward declarations */ -static struct xfer_interface_operations tcp_xfer_operations; +static struct interface_descriptor tcp_xfer_desc; static void tcp_expired ( struct retry_timer *timer, int over ); static int tcp_rx_ack ( struct tcp_connection *tcp, uint32_t ack, uint32_t win ); @@ -211,7 +211,7 @@ static int tcp_bind ( struct tcp_connection *tcp, unsigned int port ) { * @v local Local socket address, or NULL * @ret rc Return status code */ -static int tcp_open ( struct xfer_interface *xfer, struct sockaddr *peer, +static int tcp_open ( struct interface *xfer, struct sockaddr *peer, struct sockaddr *local ) { struct sockaddr_tcpip *st_peer = ( struct sockaddr_tcpip * ) peer; struct sockaddr_tcpip *st_local = ( struct sockaddr_tcpip * ) local; @@ -225,7 +225,7 @@ static int tcp_open ( struct xfer_interface *xfer, struct sockaddr *peer, return -ENOMEM; DBGC ( tcp, "TCP %p allocated\n", tcp ); ref_init ( &tcp->refcnt, NULL ); - xfer_init ( &tcp->xfer, &tcp_xfer_operations, &tcp->refcnt ); + intf_init ( &tcp->xfer, &tcp_xfer_desc, &tcp->refcnt ); timer_init ( &tcp->timer, tcp_expired ); tcp->prev_tcp_state = TCP_CLOSED; tcp->tcp_state = TCP_STATE_SENT ( TCP_SYN ); @@ -245,7 +245,7 @@ static int tcp_open ( struct xfer_interface *xfer, struct sockaddr *peer, /* Attach parent interface, transfer reference to connection * list and return */ - xfer_plug_plug ( &tcp->xfer, xfer ); + intf_plug_plug ( &tcp->xfer, xfer ); list_add ( &tcp->list, &tcp_conns ); return 0; @@ -268,8 +268,7 @@ static void tcp_close ( struct tcp_connection *tcp, int rc ) { struct io_buffer *tmp; /* Close data transfer interface */ - xfer_nullify ( &tcp->xfer ); - xfer_close ( &tcp->xfer, rc ); + intf_shutdown ( &tcp->xfer, rc ); tcp->xfer_closed = 1; /* If we are in CLOSED, or have otherwise not yet received a @@ -1044,12 +1043,10 @@ struct tcpip_protocol tcp_protocol __tcpip_protocol = { /** * Close interface * - * @v xfer Data transfer interface + * @v tcp TCP connection * @v rc Reason for close */ -static void tcp_xfer_close ( struct xfer_interface *xfer, int rc ) { - struct tcp_connection *tcp = - container_of ( xfer, struct tcp_connection, xfer ); +static void tcp_xfer_close ( struct tcp_connection *tcp, int rc ) { /* Close data transfer interface */ tcp_close ( tcp, rc ); @@ -1061,12 +1058,10 @@ static void tcp_xfer_close ( struct xfer_interface *xfer, int rc ) { /** * Check flow control window * - * @v xfer Data transfer interface + * @v tcp TCP connection * @ret len Length of window */ -static size_t tcp_xfer_window ( struct xfer_interface *xfer ) { - struct tcp_connection *tcp = - container_of ( xfer, struct tcp_connection, xfer ); +static size_t tcp_xfer_window ( struct tcp_connection *tcp ) { /* Not ready if data queue is non-empty. This imposes a limit * of only one unACKed packet in the TX queue at any time; we @@ -1082,16 +1077,14 @@ static size_t tcp_xfer_window ( struct xfer_interface *xfer ) { /** * Deliver datagram as I/O buffer * - * @v xfer Data transfer interface + * @v tcp TCP connection * @v iobuf Datagram I/O buffer * @v meta Data transfer metadata * @ret rc Return status code */ -static int tcp_xfer_deliver_iob ( struct xfer_interface *xfer, - struct io_buffer *iobuf, - struct xfer_metadata *meta __unused ) { - struct tcp_connection *tcp = - container_of ( xfer, struct tcp_connection, xfer ); +static int tcp_xfer_deliver ( struct tcp_connection *tcp, + struct io_buffer *iobuf, + struct xfer_metadata *meta __unused ) { /* Enqueue packet */ list_add_tail ( &iobuf->list, &tcp->queue ); @@ -1103,15 +1096,16 @@ static int tcp_xfer_deliver_iob ( struct xfer_interface *xfer, } /** TCP data transfer interface operations */ -static struct xfer_interface_operations tcp_xfer_operations = { - .close = tcp_xfer_close, - .vredirect = ignore_xfer_vredirect, - .window = tcp_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = tcp_xfer_deliver_iob, - .deliver_raw = xfer_deliver_as_iob, +static struct interface_operation tcp_xfer_operations[] = { + INTF_OP ( xfer_deliver, struct tcp_connection *, tcp_xfer_deliver ), + INTF_OP ( xfer_window, struct tcp_connection *, tcp_xfer_window ), + INTF_OP ( intf_close, struct tcp_connection *, tcp_xfer_close ), }; +/** TCP data transfer interface descriptor */ +static struct interface_descriptor tcp_xfer_desc = + INTF_DESC ( struct tcp_connection, xfer, tcp_xfer_operations ); + /*************************************************************************** * * Openers @@ -1136,7 +1130,7 @@ int tcp_sock_stream = TCP_SOCK_STREAM; * @v uri URI * @ret rc Return status code */ -static int tcp_open_uri ( struct xfer_interface *xfer, struct uri *uri ) { +static int tcp_open_uri ( struct interface *xfer, struct uri *uri ) { struct sockaddr_tcpip peer; /* Sanity check */ diff --git a/src/net/tcp/ftp.c b/src/net/tcp/ftp.c index 58794c8b2..957f05cc8 100644 --- a/src/net/tcp/ftp.c +++ b/src/net/tcp/ftp.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -48,14 +49,14 @@ struct ftp_request { /** Reference counter */ struct refcnt refcnt; /** Data transfer interface */ - struct xfer_interface xfer; + struct interface xfer; /** URI being fetched */ struct uri *uri; /** FTP control channel interface */ - struct xfer_interface control; + struct interface control; /** FTP data channel interface */ - struct xfer_interface data; + struct interface data; /** Current state */ enum ftp_state state; @@ -95,12 +96,9 @@ static void ftp_done ( struct ftp_request *ftp, int rc ) { DBGC ( ftp, "FTP %p completed (%s)\n", ftp, strerror ( rc ) ); /* Close all data transfer interfaces */ - xfer_nullify ( &ftp->xfer ); - xfer_close ( &ftp->xfer, rc ); - xfer_nullify ( &ftp->control ); - xfer_close ( &ftp->control, rc ); - xfer_nullify ( &ftp->data ); - xfer_close ( &ftp->data, rc ); + intf_shutdown ( &ftp->data, rc ); + intf_shutdown ( &ftp->control, rc ); + intf_shutdown ( &ftp->xfer, rc ); } /***************************************************************************** @@ -166,26 +164,6 @@ static struct ftp_control_string ftp_strings[] = { [FTP_DONE] = { NULL, NULL }, }; -/** - * Handle control channel being closed - * - * @v control FTP control channel interface - * @v rc Reason for close - * - * When the control channel is closed, the data channel must also be - * closed, if it is currently open. - */ -static void ftp_control_close ( struct xfer_interface *control, int rc ) { - struct ftp_request *ftp = - container_of ( control, struct ftp_request, control ); - - DBGC ( ftp, "FTP %p control connection closed: %s\n", - ftp, strerror ( rc ) ); - - /* Complete FTP operation */ - ftp_done ( ftp, rc ); -} - /** * Parse FTP byte sequence value * @@ -298,23 +276,25 @@ static void ftp_reply ( struct ftp_request *ftp ) { /** * Handle new data arriving on FTP control channel * - * @v control FTP control channel interface - * @v data New data - * @v len Length of new data + * @v ftp FTP request + * @v iob I/O buffer + * @v meta Data transfer metadata + * @ret rc Return status code * * Data is collected until a complete line is received, at which point * its information is passed to ftp_reply(). */ -static int ftp_control_deliver_raw ( struct xfer_interface *control, - const void *data, size_t len ) { - struct ftp_request *ftp = - container_of ( control, struct ftp_request, control ); +static int ftp_control_deliver ( struct ftp_request *ftp, + struct io_buffer *iobuf, + struct xfer_metadata *meta __unused ) { + char *data = iobuf->data; + size_t len = iob_len ( iobuf ); char *recvbuf = ftp->recvbuf; size_t recvsize = ftp->recvsize; char c; while ( len-- ) { - c = * ( ( char * ) data++ ); + c = *(data++); switch ( c ) { case '\r' : case '\n' : @@ -351,19 +331,22 @@ static int ftp_control_deliver_raw ( struct xfer_interface *control, ftp->recvbuf = recvbuf; ftp->recvsize = recvsize; + /* Free I/O buffer */ + free_iob ( iobuf ); + return 0; } -/** FTP control channel operations */ -static struct xfer_interface_operations ftp_control_operations = { - .close = ftp_control_close, - .vredirect = xfer_vreopen, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = xfer_deliver_as_raw, - .deliver_raw = ftp_control_deliver_raw, +/** FTP control channel interface operations */ +static struct interface_operation ftp_control_operations[] = { + INTF_OP ( xfer_deliver, struct ftp_request *, ftp_control_deliver ), + INTF_OP ( intf_close, struct ftp_request *, ftp_done ), }; +/** FTP control channel interface descriptor */ +static struct interface_descriptor ftp_control_desc = + INTF_DESC ( struct ftp_request, control, ftp_control_operations ); + /***************************************************************************** * * FTP data channel @@ -373,7 +356,7 @@ static struct xfer_interface_operations ftp_control_operations = { /** * Handle FTP data channel being closed * - * @v data FTP data channel interface + * @v ftp FTP request * @v rc Reason for closure * * When the data channel is closed, the control channel should be left @@ -382,9 +365,7 @@ static struct xfer_interface_operations ftp_control_operations = { * * If the data channel is closed due to an error, we abort the request. */ -static void ftp_data_closed ( struct xfer_interface *data, int rc ) { - struct ftp_request *ftp = - container_of ( data, struct ftp_request, data ); +static void ftp_data_closed ( struct ftp_request *ftp, int rc ) { DBGC ( ftp, "FTP %p data connection closed: %s\n", ftp, strerror ( rc ) ); @@ -400,16 +381,14 @@ static void ftp_data_closed ( struct xfer_interface *data, int rc ) { /** * Handle data delivery via FTP data channel * - * @v xfer FTP data channel interface + * @v ftp FTP request * @v iobuf I/O buffer * @v meta Data transfer metadata * @ret rc Return status code */ -static int ftp_data_deliver_iob ( struct xfer_interface *data, - struct io_buffer *iobuf, - struct xfer_metadata *meta __unused ) { - struct ftp_request *ftp = - container_of ( data, struct ftp_request, data ); +static int ftp_data_deliver ( struct ftp_request *ftp, + struct io_buffer *iobuf, + struct xfer_metadata *meta __unused ) { int rc; if ( ( rc = xfer_deliver_iob ( &ftp->xfer, iobuf ) ) != 0 ) { @@ -421,48 +400,31 @@ static int ftp_data_deliver_iob ( struct xfer_interface *data, return 0; } -/** FTP data channel operations */ -static struct xfer_interface_operations ftp_data_operations = { - .close = ftp_data_closed, - .vredirect = xfer_vreopen, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = ftp_data_deliver_iob, - .deliver_raw = xfer_deliver_as_iob, +/** FTP data channel interface operations */ +static struct interface_operation ftp_data_operations[] = { + INTF_OP ( xfer_deliver, struct ftp_request *, ftp_data_deliver ), + INTF_OP ( intf_close, struct ftp_request *, ftp_data_closed ), }; +/** FTP data channel interface descriptor */ +static struct interface_descriptor ftp_data_desc = + INTF_DESC ( struct ftp_request, data, ftp_data_operations ); + /***************************************************************************** * * Data transfer interface * */ -/** - * Close FTP data transfer interface - * - * @v xfer FTP data transfer interface - * @v rc Reason for close - */ -static void ftp_xfer_closed ( struct xfer_interface *xfer, int rc ) { - struct ftp_request *ftp = - container_of ( xfer, struct ftp_request, xfer ); - - DBGC ( ftp, "FTP %p data transfer interface closed: %s\n", - ftp, strerror ( rc ) ); - - ftp_done ( ftp, rc ); -} - /** FTP data transfer interface operations */ -static struct xfer_interface_operations ftp_xfer_operations = { - .close = ftp_xfer_closed, - .vredirect = ignore_xfer_vredirect, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = xfer_deliver_as_raw, - .deliver_raw = ignore_xfer_deliver_raw, +static struct interface_operation ftp_xfer_operations[] = { + INTF_OP ( intf_close, struct ftp_request *, ftp_done ), }; +/** FTP data transfer interface descriptor */ +static struct interface_descriptor ftp_xfer_desc = + INTF_DESC ( struct ftp_request, xfer, ftp_xfer_operations ); + /***************************************************************************** * * URI opener @@ -476,7 +438,7 @@ static struct xfer_interface_operations ftp_xfer_operations = { * @v uri Uniform Resource Identifier * @ret rc Return status code */ -static int ftp_open ( struct xfer_interface *xfer, struct uri *uri ) { +static int ftp_open ( struct interface *xfer, struct uri *uri ) { struct ftp_request *ftp; struct sockaddr_tcpip server; int rc; @@ -492,10 +454,10 @@ static int ftp_open ( struct xfer_interface *xfer, struct uri *uri ) { if ( ! ftp ) return -ENOMEM; ref_init ( &ftp->refcnt, ftp_free ); - xfer_init ( &ftp->xfer, &ftp_xfer_operations, &ftp->refcnt ); + intf_init ( &ftp->xfer, &ftp_xfer_desc, &ftp->refcnt ); + intf_init ( &ftp->control, &ftp_control_desc, &ftp->refcnt ); + intf_init ( &ftp->data, &ftp_data_desc, &ftp->refcnt ); ftp->uri = uri_get ( uri ); - xfer_init ( &ftp->control, &ftp_control_operations, &ftp->refcnt ); - xfer_init ( &ftp->data, &ftp_data_operations, &ftp->refcnt ); ftp->recvbuf = ftp->status_text; ftp->recvsize = sizeof ( ftp->status_text ) - 1; @@ -510,7 +472,7 @@ static int ftp_open ( struct xfer_interface *xfer, struct uri *uri ) { goto err; /* Attach to parent interface, mortalise self, and return */ - xfer_plug_plug ( &ftp->xfer, xfer ); + intf_plug_plug ( &ftp->xfer, xfer ); ref_put ( &ftp->refcnt ); return 0; diff --git a/src/net/tcp/http.c b/src/net/tcp/http.c index d6a9fad7e..13c500d50 100644 --- a/src/net/tcp/http.c +++ b/src/net/tcp/http.c @@ -64,12 +64,12 @@ struct http_request { /** Reference count */ struct refcnt refcnt; /** Data transfer interface */ - struct xfer_interface xfer; + struct interface xfer; /** URI being fetched */ struct uri *uri; /** Transport layer interface */ - struct xfer_interface socket; + struct interface socket; /** TX process */ struct process process; @@ -125,10 +125,8 @@ static void http_done ( struct http_request *http, int rc ) { process_del ( &http->process ); /* Close all data transfer interfaces */ - xfer_nullify ( &http->socket ); - xfer_close ( &http->socket, rc ); - xfer_nullify ( &http->xfer ); - xfer_close ( &http->xfer, rc ); + intf_shutdown ( &http->socket, rc ); + intf_shutdown ( &http->xfer, rc ); } /** @@ -349,16 +347,14 @@ static int http_rx_data ( struct http_request *http, /** * Handle new data arriving via HTTP connection * - * @v socket Transport layer interface + * @v http HTTP request * @v iobuf I/O buffer * @v meta Data transfer metadata * @ret rc Return status code */ -static int http_socket_deliver_iob ( struct xfer_interface *socket, - struct io_buffer *iobuf, - struct xfer_metadata *meta __unused ) { - struct http_request *http = - container_of ( socket, struct http_request, socket ); +static int http_socket_deliver ( struct http_request *http, + struct io_buffer *iobuf, + struct xfer_metadata *meta __unused ) { struct http_line_handler *lh; char *line; ssize_t len; @@ -469,58 +465,25 @@ static void http_step ( struct process *process ) { } } -/** - * HTTP connection closed by network stack - * - * @v socket Transport layer interface - * @v rc Reason for close - */ -static void http_socket_close ( struct xfer_interface *socket, int rc ) { - struct http_request *http = - container_of ( socket, struct http_request, socket ); - - DBGC ( http, "HTTP %p socket closed: %s\n", - http, strerror ( rc ) ); - - http_done ( http, rc ); -} - -/** HTTP socket operations */ -static struct xfer_interface_operations http_socket_operations = { - .close = http_socket_close, - .vredirect = xfer_vreopen, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = http_socket_deliver_iob, - .deliver_raw = xfer_deliver_as_iob, +/** HTTP socket interface operations */ +static struct interface_operation http_socket_operations[] = { + INTF_OP ( xfer_deliver, struct http_request *, http_socket_deliver ), + INTF_OP ( intf_close, struct http_request *, http_done ), }; -/** - * Close HTTP data transfer interface - * - * @v xfer Data transfer interface - * @v rc Reason for close - */ -static void http_xfer_close ( struct xfer_interface *xfer, int rc ) { - struct http_request *http = - container_of ( xfer, struct http_request, xfer ); - - DBGC ( http, "HTTP %p interface closed: %s\n", - http, strerror ( rc ) ); - - http_done ( http, rc ); -} +/** HTTP socket interface descriptor */ +static struct interface_descriptor http_socket_desc = + INTF_DESC ( struct http_request, socket, http_socket_operations ); /** HTTP data transfer interface operations */ -static struct xfer_interface_operations http_xfer_operations = { - .close = http_xfer_close, - .vredirect = ignore_xfer_vredirect, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = xfer_deliver_as_raw, - .deliver_raw = ignore_xfer_deliver_raw, +static struct interface_operation http_xfer_operations[] = { + INTF_OP ( intf_close, struct http_request *, http_done ), }; +/** HTTP data transfer interface descriptor */ +static struct interface_descriptor http_xfer_desc = + INTF_DESC ( struct http_request, xfer, http_xfer_operations ); + /** * Initiate an HTTP connection, with optional filter * @@ -530,13 +493,13 @@ static struct xfer_interface_operations http_xfer_operations = { * @v filter Filter to apply to socket, or NULL * @ret rc Return status code */ -int http_open_filter ( struct xfer_interface *xfer, struct uri *uri, +int http_open_filter ( struct interface *xfer, struct uri *uri, unsigned int default_port, - int ( * filter ) ( struct xfer_interface *xfer, - struct xfer_interface **next ) ) { + int ( * filter ) ( struct interface *xfer, + struct interface **next ) ) { struct http_request *http; struct sockaddr_tcpip server; - struct xfer_interface *socket; + struct interface *socket; int rc; /* Sanity checks */ @@ -548,9 +511,9 @@ int http_open_filter ( struct xfer_interface *xfer, struct uri *uri, if ( ! http ) return -ENOMEM; ref_init ( &http->refcnt, http_free ); - xfer_init ( &http->xfer, &http_xfer_operations, &http->refcnt ); + intf_init ( &http->xfer, &http_xfer_desc, &http->refcnt ); http->uri = uri_get ( uri ); - xfer_init ( &http->socket, &http_socket_operations, &http->refcnt ); + intf_init ( &http->socket, &http_socket_desc, &http->refcnt ); process_init ( &http->process, http_step, &http->refcnt ); /* Open socket */ @@ -567,7 +530,7 @@ int http_open_filter ( struct xfer_interface *xfer, struct uri *uri, goto err; /* Attach to parent interface, mortalise self, and return */ - xfer_plug_plug ( &http->xfer, xfer ); + intf_plug_plug ( &http->xfer, xfer ); ref_put ( &http->refcnt ); return 0; @@ -586,7 +549,7 @@ int http_open_filter ( struct xfer_interface *xfer, struct uri *uri, * @v uri Uniform Resource Identifier * @ret rc Return status code */ -static int http_open ( struct xfer_interface *xfer, struct uri *uri ) { +static int http_open ( struct interface *xfer, struct uri *uri ) { return http_open_filter ( xfer, uri, HTTP_PORT, NULL ); } diff --git a/src/net/tcp/https.c b/src/net/tcp/https.c index b738f4167..805d108bb 100644 --- a/src/net/tcp/https.c +++ b/src/net/tcp/https.c @@ -40,7 +40,7 @@ FEATURE ( FEATURE_PROTOCOL, "HTTPS", DHCP_EB_FEATURE_HTTPS, 1 ); * @v uri Uniform Resource Identifier * @ret rc Return status code */ -static int https_open ( struct xfer_interface *xfer, struct uri *uri ) { +static int https_open ( struct interface *xfer, struct uri *uri ) { return http_open_filter ( xfer, uri, HTTPS_PORT, add_tls ); } diff --git a/src/net/tcp/iscsi.c b/src/net/tcp/iscsi.c index 24cbda2c5..80c63a6b1 100644 --- a/src/net/tcp/iscsi.c +++ b/src/net/tcp/iscsi.c @@ -27,6 +27,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include +#include #include #include #include @@ -199,7 +200,7 @@ static int iscsi_open_connection ( struct iscsi_session *iscsi ) { static void iscsi_close_connection ( struct iscsi_session *iscsi, int rc ) { /* Close all data transfer interfaces */ - xfer_close ( &iscsi->socket, rc ); + intf_restart ( &iscsi->socket, rc ); /* Clear connection status */ iscsi->status = 0; @@ -1435,9 +1436,9 @@ static int iscsi_rx_data ( struct iscsi_session *iscsi, const void *data, /** * Receive new data * - * @v socket Transport layer interface - * @v data Received data - * @v len Length of received data + * @v iscsi iSCSI session + * @v iobuf I/O buffer + * @v meta Data transfer metadata * @ret rc Return status code * * This handles received PDUs. The receive strategy is to fill in @@ -1447,10 +1448,9 @@ static int iscsi_rx_data ( struct iscsi_session *iscsi, const void *data, * always has a full copy of the BHS available, even for portions of * the data in different packets to the BHS. */ -static int iscsi_socket_deliver_raw ( struct xfer_interface *socket, - const void *data, size_t len ) { - struct iscsi_session *iscsi = - container_of ( socket, struct iscsi_session, socket ); +static int iscsi_socket_deliver ( struct iscsi_session *iscsi, + struct io_buffer *iobuf, + struct xfer_metadata *meta __unused ) { struct iscsi_bhs_common *common = &iscsi->rx_bhs.common; int ( * rx ) ( struct iscsi_session *iscsi, const void *data, size_t len, size_t remaining ); @@ -1483,48 +1483,52 @@ static int iscsi_socket_deliver_raw ( struct xfer_interface *socket, break; default: assert ( 0 ); - return -EINVAL; + rc = -EINVAL; + goto done; } frag_len = iscsi->rx_len - iscsi->rx_offset; - if ( frag_len > len ) - frag_len = len; + if ( frag_len > iob_len ( iobuf ) ) + frag_len = iob_len ( iobuf ); remaining = iscsi->rx_len - iscsi->rx_offset - frag_len; - if ( ( rc = rx ( iscsi, data, frag_len, remaining ) ) != 0 ) { + if ( ( rc = rx ( iscsi, iobuf->data, frag_len, + remaining ) ) != 0 ) { DBGC ( iscsi, "iSCSI %p could not process received " "data: %s\n", iscsi, strerror ( rc ) ); iscsi_close_connection ( iscsi, rc ); iscsi_scsi_done ( iscsi, rc ); - return rc; + goto done; } iscsi->rx_offset += frag_len; - data += frag_len; - len -= frag_len; + iob_pull ( iobuf, frag_len ); /* If all the data for this state has not yet been * received, stay in this state for now. */ - if ( iscsi->rx_offset != iscsi->rx_len ) - return 0; + if ( iscsi->rx_offset != iscsi->rx_len ) { + rc = 0; + goto done; + } iscsi->rx_state = next_state; iscsi->rx_offset = 0; } - return 0; + done: + /* Free I/O buffer */ + free_iob ( iobuf ); + return rc; } /** * Handle stream connection closure * - * @v socket Transport layer interface + * @v iscsi iSCSI session * @v rc Reason for close * */ -static void iscsi_socket_close ( struct xfer_interface *socket, int rc ) { - struct iscsi_session *iscsi = - container_of ( socket, struct iscsi_session, socket ); +static void iscsi_socket_close ( struct iscsi_session *iscsi, int rc ) { /* Even a graceful close counts as an error for iSCSI */ if ( ! rc ) @@ -1552,15 +1556,13 @@ static void iscsi_socket_close ( struct xfer_interface *socket, int rc ) { /** * Handle redirection event * - * @v socket Transport layer interface + * @v iscsi iSCSI session * @v type Location type * @v args Remaining arguments depend upon location type * @ret rc Return status code */ -static int iscsi_vredirect ( struct xfer_interface *socket, int type, +static int iscsi_vredirect ( struct iscsi_session *iscsi, int type, va_list args ) { - struct iscsi_session *iscsi = - container_of ( socket, struct iscsi_session, socket ); va_list tmp; struct sockaddr *peer; @@ -1578,20 +1580,20 @@ static int iscsi_vredirect ( struct xfer_interface *socket, int type, va_end ( tmp ); } - return xfer_vreopen ( socket, type, args ); + return xfer_vreopen ( &iscsi->socket, type, args ); } -/** iSCSI socket operations */ -static struct xfer_interface_operations iscsi_socket_operations = { - .close = iscsi_socket_close, - .vredirect = iscsi_vredirect, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = xfer_deliver_as_raw, - .deliver_raw = iscsi_socket_deliver_raw, +/** iSCSI socket interface operations */ +static struct interface_operation iscsi_socket_operations[] = { + INTF_OP ( xfer_deliver, struct iscsi_session *, iscsi_socket_deliver ), + INTF_OP ( xfer_vredirect, struct iscsi_session *, iscsi_vredirect ), + INTF_OP ( intf_close, struct iscsi_session *, iscsi_socket_close ), }; +/** iSCSI socket interface descriptor */ +static struct interface_descriptor iscsi_socket_desc = + INTF_DESC ( struct iscsi_session, socket, iscsi_socket_operations ); /**************************************************************************** * @@ -1641,7 +1643,6 @@ void iscsi_detach ( struct scsi_device *scsi ) { struct iscsi_session *iscsi = container_of ( scsi->backend, struct iscsi_session, refcnt ); - xfer_nullify ( &iscsi->socket ); iscsi_close_connection ( iscsi, 0 ); process_del ( &iscsi->process ); scsi->command = scsi_detached_command; @@ -1793,7 +1794,7 @@ int iscsi_attach ( struct scsi_device *scsi, const char *root_path ) { if ( ! iscsi ) return -ENOMEM; ref_init ( &iscsi->refcnt, iscsi_free ); - xfer_init ( &iscsi->socket, &iscsi_socket_operations, &iscsi->refcnt ); + intf_init ( &iscsi->socket, &iscsi_socket_desc, &iscsi->refcnt ); process_init ( &iscsi->process, iscsi_tx_step, &iscsi->refcnt ); /* Parse root path */ diff --git a/src/net/tls.c b/src/net/tls.c index 8825c5c13..a9d627588 100644 --- a/src/net/tls.c +++ b/src/net/tls.c @@ -35,9 +35,9 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include +#include #include #include -#include #include #include #include @@ -107,10 +107,8 @@ static void tls_close ( struct tls_session *tls, int rc ) { process_del ( &tls->process ); /* Close ciphertext and plaintext streams */ - xfer_nullify ( &tls->cipherstream.xfer ); - xfer_close ( &tls->cipherstream.xfer, rc ); - xfer_nullify ( &tls->plainstream.xfer ); - xfer_close ( &tls->plainstream.xfer, rc ); + intf_shutdown ( &tls->cipherstream, rc ); + intf_shutdown ( &tls->plainstream, rc ); } /****************************************************************************** @@ -1030,7 +1028,7 @@ static int tls_new_record ( struct tls_session *tls, case TLS_TYPE_HANDSHAKE: return tls_new_handshake ( tls, data, len ); case TLS_TYPE_DATA: - return xfer_deliver_raw ( &tls->plainstream.xfer, data, len ); + return xfer_deliver_raw ( &tls->plainstream, data, len ); default: /* RFC4346 says that we should just ignore unknown * record types. @@ -1209,8 +1207,7 @@ static int tls_send_plaintext ( struct tls_session *tls, unsigned int type, /* Allocate ciphertext */ ciphertext_len = ( sizeof ( *tlshdr ) + plaintext_len ); - ciphertext = xfer_alloc_iob ( &tls->cipherstream.xfer, - ciphertext_len ); + ciphertext = xfer_alloc_iob ( &tls->cipherstream, ciphertext_len ); if ( ! ciphertext ) { DBGC ( tls, "TLS %p could not allocate %zd bytes for " "ciphertext\n", tls, ciphertext_len ); @@ -1234,9 +1231,8 @@ static int tls_send_plaintext ( struct tls_session *tls, unsigned int type, plaintext = NULL; /* Send ciphertext */ - rc = xfer_deliver_iob ( &tls->cipherstream.xfer, ciphertext ); - ciphertext = NULL; - if ( rc != 0 ) { + if ( ( rc = xfer_deliver_iob ( &tls->cipherstream, + iob_disown ( ciphertext ) ) ) != 0 ) { DBGC ( tls, "TLS %p could not deliver ciphertext: %s\n", tls, strerror ( rc ) ); goto done; @@ -1435,66 +1431,61 @@ static int tls_new_ciphertext ( struct tls_session *tls, ****************************************************************************** */ -/** - * Close interface - * - * @v xfer Plainstream data transfer interface - * @v rc Reason for close - */ -static void tls_plainstream_close ( struct xfer_interface *xfer, int rc ) { - struct tls_session *tls = - container_of ( xfer, struct tls_session, plainstream.xfer ); - - tls_close ( tls, rc ); -} - /** * Check flow control window * - * @v xfer Plainstream data transfer interface + * @v tls TLS session * @ret len Length of window */ -static size_t tls_plainstream_window ( struct xfer_interface *xfer ) { - struct tls_session *tls = - container_of ( xfer, struct tls_session, plainstream.xfer ); +static size_t tls_plainstream_window ( struct tls_session *tls ) { /* Block window unless we are ready to accept data */ if ( tls->tx_state != TLS_TX_DATA ) return 0; - return filter_window ( xfer ); + return xfer_window ( &tls->cipherstream ); } /** * Deliver datagram as raw data * - * @v xfer Plainstream data transfer interface - * @v data Data buffer - * @v len Length of data buffer + * @v tls TLS session + * @v iobuf I/O buffer + * @v meta Data transfer metadata * @ret rc Return status code */ -static int tls_plainstream_deliver_raw ( struct xfer_interface *xfer, - const void *data, size_t len ) { - struct tls_session *tls = - container_of ( xfer, struct tls_session, plainstream.xfer ); +static int tls_plainstream_deliver ( struct tls_session *tls, + struct io_buffer *iobuf, + struct xfer_metadata *meta __unused ) { + int rc; /* Refuse unless we are ready to accept data */ - if ( tls->tx_state != TLS_TX_DATA ) - return -ENOTCONN; + if ( tls->tx_state != TLS_TX_DATA ) { + rc = -ENOTCONN; + goto done; + } - return tls_send_plaintext ( tls, TLS_TYPE_DATA, data, len ); + if ( ( rc = tls_send_plaintext ( tls, TLS_TYPE_DATA, iobuf->data, + iob_len ( iobuf ) ) ) != 0 ) + goto done; + + done: + free_iob ( iobuf ); + return rc; } -/** TLS plaintext stream operations */ -static struct xfer_interface_operations tls_plainstream_operations = { - .close = tls_plainstream_close, - .vredirect = ignore_xfer_vredirect, - .window = tls_plainstream_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = xfer_deliver_as_raw, - .deliver_raw = tls_plainstream_deliver_raw, +/** TLS plaintext stream interface operations */ +static struct interface_operation tls_plainstream_ops[] = { + INTF_OP ( xfer_deliver, struct tls_session *, tls_plainstream_deliver ), + INTF_OP ( xfer_window, struct tls_session *, tls_plainstream_window ), + INTF_OP ( intf_close, struct tls_session *, tls_close ), }; +/** TLS plaintext stream interface descriptor */ +static struct interface_descriptor tls_plainstream_desc = + INTF_DESC_PASSTHRU ( struct tls_session, plainstream, + tls_plainstream_ops, cipherstream ); + /****************************************************************************** * * Ciphertext stream operations @@ -1502,19 +1493,6 @@ static struct xfer_interface_operations tls_plainstream_operations = { ****************************************************************************** */ -/** - * Close interface - * - * @v xfer Plainstream data transfer interface - * @v rc Reason for close - */ -static void tls_cipherstream_close ( struct xfer_interface *xfer, int rc ) { - struct tls_session *tls = - container_of ( xfer, struct tls_session, cipherstream.xfer ); - - tls_close ( tls, rc ); -} - /** * Handle received TLS header * @@ -1569,22 +1547,21 @@ static int tls_newdata_process_data ( struct tls_session *tls ) { /** * Receive new ciphertext * - * @v app Stream application - * @v data Data received - * @v len Length of received data + * @v tls TLS session + * @v iobuf I/O buffer + * @v meta Data transfer metadat * @ret rc Return status code */ -static int tls_cipherstream_deliver_raw ( struct xfer_interface *xfer, - const void *data, size_t len ) { - struct tls_session *tls = - container_of ( xfer, struct tls_session, cipherstream.xfer ); +static int tls_cipherstream_deliver ( struct tls_session *tls, + struct io_buffer *iobuf, + struct xfer_metadata *xfer __unused ) { size_t frag_len; void *buf; size_t buf_len; int ( * process ) ( struct tls_session *tls ); int rc; - while ( len ) { + while ( iob_len ( iobuf ) ) { /* Select buffer according to current state */ switch ( tls->rx_state ) { case TLS_RX_HEADER: @@ -1599,41 +1576,46 @@ static int tls_cipherstream_deliver_raw ( struct xfer_interface *xfer, break; default: assert ( 0 ); - return -EINVAL; + rc = -EINVAL; + goto done; } /* Copy data portion to buffer */ frag_len = ( buf_len - tls->rx_rcvd ); - if ( frag_len > len ) - frag_len = len; - memcpy ( ( buf + tls->rx_rcvd ), data, frag_len ); + if ( frag_len > iob_len ( iobuf ) ) + frag_len = iob_len ( iobuf ); + memcpy ( ( buf + tls->rx_rcvd ), iobuf->data, frag_len ); tls->rx_rcvd += frag_len; - data += frag_len; - len -= frag_len; + iob_pull ( iobuf, frag_len ); /* Process data if buffer is now full */ if ( tls->rx_rcvd == buf_len ) { if ( ( rc = process ( tls ) ) != 0 ) { tls_close ( tls, rc ); - return rc; + goto done; } tls->rx_rcvd = 0; } } + rc = 0; - return 0; + done: + free_iob ( iobuf ); + return rc; } -/** TLS ciphertext stream operations */ -static struct xfer_interface_operations tls_cipherstream_operations = { - .close = tls_cipherstream_close, - .vredirect = xfer_vreopen, - .window = filter_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = xfer_deliver_as_raw, - .deliver_raw = tls_cipherstream_deliver_raw, +/** TLS ciphertext stream interface operations */ +static struct interface_operation tls_cipherstream_ops[] = { + INTF_OP ( xfer_deliver, struct tls_session *, + tls_cipherstream_deliver ), + INTF_OP ( intf_close, struct tls_session *, tls_close ), }; +/** TLS ciphertext stream interface descriptor */ +static struct interface_descriptor tls_cipherstream_desc = + INTF_DESC_PASSTHRU ( struct tls_session, cipherstream, + tls_cipherstream_ops, plainstream ); + /****************************************************************************** * * Controlling process @@ -1652,7 +1634,7 @@ static void tls_step ( struct process *process ) { int rc; /* Wait for cipherstream to become ready */ - if ( ! xfer_window ( &tls->cipherstream.xfer ) ) + if ( ! xfer_window ( &tls->cipherstream ) ) return; switch ( tls->tx_state ) { @@ -1723,7 +1705,7 @@ static void tls_step ( struct process *process ) { ****************************************************************************** */ -int add_tls ( struct xfer_interface *xfer, struct xfer_interface **next ) { +int add_tls ( struct interface *xfer, struct interface **next ) { struct tls_session *tls; /* Allocate and initialise TLS structure */ @@ -1732,9 +1714,8 @@ int add_tls ( struct xfer_interface *xfer, struct xfer_interface **next ) { return -ENOMEM; memset ( tls, 0, sizeof ( *tls ) ); ref_init ( &tls->refcnt, free_tls ); - filter_init ( &tls->plainstream, &tls_plainstream_operations, - &tls->cipherstream, &tls_cipherstream_operations, - &tls->refcnt ); + intf_init ( &tls->plainstream, &tls_plainstream_desc, &tls->refcnt ); + intf_init ( &tls->cipherstream, &tls_cipherstream_desc, &tls->refcnt ); tls_clear_cipher ( tls, &tls->tx_cipherspec ); tls_clear_cipher ( tls, &tls->tx_cipherspec_pending ); tls_clear_cipher ( tls, &tls->rx_cipherspec ); @@ -1751,9 +1732,8 @@ int add_tls ( struct xfer_interface *xfer, struct xfer_interface **next ) { process_init ( &tls->process, tls_step, &tls->refcnt ); /* Attach to parent interface, mortalise self, and return */ - xfer_plug_plug ( &tls->plainstream.xfer, xfer ); - *next = &tls->cipherstream.xfer; + intf_plug_plug ( &tls->plainstream, xfer ); + *next = &tls->cipherstream; ref_put ( &tls->refcnt ); return 0; } - diff --git a/src/net/udp.c b/src/net/udp.c index dcc69c36c..0ed1503a2 100644 --- a/src/net/udp.c +++ b/src/net/udp.c @@ -29,7 +29,7 @@ struct udp_connection { struct list_head list; /** Data transfer interface */ - struct xfer_interface xfer; + struct interface xfer; /** Local socket address */ struct sockaddr_tcpip local; @@ -43,7 +43,7 @@ struct udp_connection { static LIST_HEAD ( udp_conns ); /* Forward declatations */ -static struct xfer_interface_operations udp_xfer_operations; +static struct interface_descriptor udp_xfer_desc; struct tcpip_protocol udp_protocol; /** @@ -97,7 +97,7 @@ static int udp_bind ( struct udp_connection *udp ) { * @v promisc Socket is promiscuous * @ret rc Return status code */ -static int udp_open_common ( struct xfer_interface *xfer, +static int udp_open_common ( struct interface *xfer, struct sockaddr *peer, struct sockaddr *local, int promisc ) { struct sockaddr_tcpip *st_peer = ( struct sockaddr_tcpip * ) peer; @@ -111,7 +111,7 @@ static int udp_open_common ( struct xfer_interface *xfer, return -ENOMEM; DBGC ( udp, "UDP %p allocated\n", udp ); ref_init ( &udp->refcnt, NULL ); - xfer_init ( &udp->xfer, &udp_xfer_operations, &udp->refcnt ); + intf_init ( &udp->xfer, &udp_xfer_desc, &udp->refcnt ); if ( st_peer ) memcpy ( &udp->peer, st_peer, sizeof ( udp->peer ) ); if ( st_local ) @@ -126,7 +126,7 @@ static int udp_open_common ( struct xfer_interface *xfer, /* Attach parent interface, transfer reference to connection * list and return */ - xfer_plug_plug ( &udp->xfer, xfer ); + intf_plug_plug ( &udp->xfer, xfer ); list_add ( &udp->list, &udp_conns ); return 0; @@ -143,7 +143,7 @@ static int udp_open_common ( struct xfer_interface *xfer, * @v local Local socket address, or NULL * @ret rc Return status code */ -int udp_open ( struct xfer_interface *xfer, struct sockaddr *peer, +int udp_open ( struct interface *xfer, struct sockaddr *peer, struct sockaddr *local ) { return udp_open_common ( xfer, peer, local, 0 ); } @@ -157,7 +157,7 @@ int udp_open ( struct xfer_interface *xfer, struct sockaddr *peer, * Promiscuous UDP connections are required in order to support the * PXE API. */ -int udp_open_promisc ( struct xfer_interface *xfer ) { +int udp_open_promisc ( struct interface *xfer ) { return udp_open_common ( xfer, NULL, NULL, 1 ); } @@ -170,8 +170,7 @@ int udp_open_promisc ( struct xfer_interface *xfer ) { static void udp_close ( struct udp_connection *udp, int rc ) { /* Close data transfer interface */ - xfer_nullify ( &udp->xfer ); - xfer_close ( &udp->xfer, rc ); + intf_shutdown ( &udp->xfer, rc ); /* Remove from list of connections and drop list's reference */ list_del ( &udp->list ); @@ -331,7 +330,7 @@ static int udp_rx ( struct io_buffer *iobuf, struct sockaddr_tcpip *st_src, memset ( &meta, 0, sizeof ( meta ) ); meta.src = ( struct sockaddr * ) st_src; meta.dest = ( struct sockaddr * ) st_dest; - rc = xfer_deliver_iob_meta ( &udp->xfer, iob_disown ( iobuf ), &meta ); + rc = xfer_deliver ( &udp->xfer, iob_disown ( iobuf ), &meta ); done: free_iob ( iobuf ); @@ -351,31 +350,15 @@ struct tcpip_protocol udp_protocol __tcpip_protocol = { *************************************************************************** */ -/** - * Close interface - * - * @v xfer Data transfer interface - * @v rc Reason for close - */ -static void udp_xfer_close ( struct xfer_interface *xfer, int rc ) { - struct udp_connection *udp = - container_of ( xfer, struct udp_connection, xfer ); - - /* Close connection */ - udp_close ( udp, rc ); -} - /** * Allocate I/O buffer for UDP * - * @v xfer Data transfer interface + * @v udp UDP connection * @v len Payload size * @ret iobuf I/O buffer, or NULL */ -static struct io_buffer * udp_alloc_iob ( struct xfer_interface *xfer, - size_t len ) { - struct udp_connection *udp = - container_of ( xfer, struct udp_connection, xfer ); +static struct io_buffer * udp_xfer_alloc_iob ( struct udp_connection *udp, + size_t len ) { struct io_buffer *iobuf; iobuf = alloc_iob ( UDP_MAX_HLEN + len ); @@ -391,16 +374,14 @@ static struct io_buffer * udp_alloc_iob ( struct xfer_interface *xfer, /** * Deliver datagram as I/O buffer * - * @v xfer Data transfer interface + * @v udp UDP connection * @v iobuf Datagram I/O buffer * @v meta Data transfer metadata * @ret rc Return status code */ -static int udp_xfer_deliver_iob ( struct xfer_interface *xfer, - struct io_buffer *iobuf, - struct xfer_metadata *meta ) { - struct udp_connection *udp = - container_of ( xfer, struct udp_connection, xfer ); +static int udp_xfer_deliver ( struct udp_connection *udp, + struct io_buffer *iobuf, + struct xfer_metadata *meta ) { /* Transmit data, if possible */ udp_tx ( udp, iobuf, ( ( struct sockaddr_tcpip * ) meta->src ), @@ -410,15 +391,16 @@ static int udp_xfer_deliver_iob ( struct xfer_interface *xfer, } /** UDP data transfer interface operations */ -static struct xfer_interface_operations udp_xfer_operations = { - .close = udp_xfer_close, - .vredirect = ignore_xfer_vredirect, - .window = unlimited_xfer_window, - .alloc_iob = udp_alloc_iob, - .deliver_iob = udp_xfer_deliver_iob, - .deliver_raw = xfer_deliver_as_iob, +static struct interface_operation udp_xfer_operations[] = { + INTF_OP ( xfer_deliver, struct udp_connection *, udp_xfer_deliver ), + INTF_OP ( xfer_alloc_iob, struct udp_connection *, udp_xfer_alloc_iob ), + INTF_OP ( intf_close, struct udp_connection *, udp_close ), }; +/** UDP data transfer interface descriptor */ +static struct interface_descriptor udp_xfer_desc = + INTF_DESC ( struct udp_connection, xfer, udp_xfer_operations ); + /*************************************************************************** * * Openers @@ -443,7 +425,7 @@ int udp_sock_dgram = UDP_SOCK_DGRAM; * @v uri URI * @ret rc Return status code */ -static int udp_open_uri ( struct xfer_interface *xfer, struct uri *uri ) { +static int udp_open_uri ( struct interface *xfer, struct uri *uri ) { struct sockaddr_tcpip peer; /* Sanity check */ diff --git a/src/net/udp/dhcp.c b/src/net/udp/dhcp.c index 991983197..fb62bef53 100644 --- a/src/net/udp/dhcp.c +++ b/src/net/udp/dhcp.c @@ -26,6 +26,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include +#include #include #include #include @@ -240,7 +241,7 @@ struct dhcp_session { /** Job control interface */ struct interface job; /** Data transfer interface */ - struct xfer_interface xfer; + struct interface xfer; /** Network device being configured */ struct net_device *netdev; @@ -298,8 +299,7 @@ static void dhcp_finished ( struct dhcp_session *dhcp, int rc ) { stop_timer ( &dhcp->timer ); /* Shut down interfaces */ - xfer_nullify ( &dhcp->xfer ); - xfer_close ( &dhcp->xfer, rc ); + intf_shutdown ( &dhcp->xfer, rc ); intf_shutdown ( &dhcp->job, rc ); } @@ -1241,8 +1241,8 @@ static int dhcp_tx ( struct dhcp_session *dhcp ) { /* Transmit the packet */ iob_put ( iobuf, dhcppkt.len ); - if ( ( rc = xfer_deliver_iob_meta ( &dhcp->xfer, iob_disown ( iobuf ), - &meta ) ) != 0 ) { + if ( ( rc = xfer_deliver ( &dhcp->xfer, iob_disown ( iobuf ), + &meta ) ) != 0 ) { DBGC ( dhcp, "DHCP %p could not transmit UDP packet: %s\n", dhcp, strerror ( rc ) ); goto done; @@ -1256,16 +1256,14 @@ static int dhcp_tx ( struct dhcp_session *dhcp ) { /** * Receive new data * - * @v xfer Data transfer interface + * @v dhcp DHCP session * @v iobuf I/O buffer * @v meta Transfer metadata * @ret rc Return status code */ -static int dhcp_deliver_iob ( struct xfer_interface *xfer, - struct io_buffer *iobuf, - struct xfer_metadata *meta ) { - struct dhcp_session *dhcp = - container_of ( xfer, struct dhcp_session, xfer ); +static int dhcp_deliver ( struct dhcp_session *dhcp, + struct io_buffer *iobuf, + struct xfer_metadata *meta ) { struct sockaddr_in *peer; size_t data_len; struct dhcp_packet *dhcppkt; @@ -1328,15 +1326,14 @@ static int dhcp_deliver_iob ( struct xfer_interface *xfer, } /** DHCP data transfer interface operations */ -static struct xfer_interface_operations dhcp_xfer_operations = { - .close = ignore_xfer_close, - .vredirect = xfer_vreopen, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = dhcp_deliver_iob, - .deliver_raw = xfer_deliver_as_iob, +static struct interface_operation dhcp_xfer_operations[] = { + INTF_OP ( xfer_deliver, struct dhcp_session *, dhcp_deliver ), }; +/** DHCP data transfer interface descriptor */ +static struct interface_descriptor dhcp_xfer_desc = + INTF_DESC ( struct dhcp_session, xfer, dhcp_xfer_operations ); + /** * Handle DHCP retry timer expiry * @@ -1427,7 +1424,7 @@ int start_dhcp ( struct interface *job, struct net_device *netdev ) { return -ENOMEM; ref_init ( &dhcp->refcnt, dhcp_free ); intf_init ( &dhcp->job, &dhcp_job_desc, &dhcp->refcnt ); - xfer_init ( &dhcp->xfer, &dhcp_xfer_operations, &dhcp->refcnt ); + intf_init ( &dhcp->xfer, &dhcp_xfer_desc, &dhcp->refcnt ); timer_init ( &dhcp->timer, dhcp_timer_expired ); dhcp->netdev = netdev_get ( netdev ); dhcp->local.sin_family = AF_INET; @@ -1530,7 +1527,7 @@ int start_pxebs ( struct interface *job, struct net_device *netdev, return -ENOMEM; ref_init ( &dhcp->refcnt, dhcp_free ); intf_init ( &dhcp->job, &dhcp_job_desc, &dhcp->refcnt ); - xfer_init ( &dhcp->xfer, &dhcp_xfer_operations, &dhcp->refcnt ); + intf_init ( &dhcp->xfer, &dhcp_xfer_desc, &dhcp->refcnt ); timer_init ( &dhcp->timer, dhcp_timer_expired ); dhcp->netdev = netdev_get ( netdev ); dhcp->local.sin_family = AF_INET; diff --git a/src/net/udp/dns.c b/src/net/udp/dns.c index fd1ea0a28..8283e6fba 100644 --- a/src/net/udp/dns.c +++ b/src/net/udp/dns.c @@ -28,6 +28,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include +#include #include #include #include @@ -60,7 +61,7 @@ struct dns_request { /** Name resolution interface */ struct interface resolv; /** Data transfer interface */ - struct xfer_interface socket; + struct interface socket; /** Retry timer */ struct retry_timer timer; @@ -89,11 +90,8 @@ static void dns_done ( struct dns_request *dns, int rc ) { /* Stop the retry timer */ stop_timer ( &dns->timer ); - /* Close data transfer interface */ - xfer_nullify ( &dns->socket ); - xfer_close ( &dns->socket, rc ); - /* Shut down interfaces */ + intf_shutdown ( &dns->socket, rc ); intf_shutdown ( &dns->resolv, rc ); } @@ -322,25 +320,26 @@ static void dns_timer_expired ( struct retry_timer *timer, int fail ) { /** * Receive new data * - * @v socket UDP socket - * @v data DNS reply - * @v len Length of DNS reply + * @v dns DNS request + * @v iobuf I/O buffer + * @v meta Data transfer metadata * @ret rc Return status code */ -static int dns_xfer_deliver_raw ( struct xfer_interface *socket, - const void *data, size_t len ) { - struct dns_request *dns = - container_of ( socket, struct dns_request, socket ); - const struct dns_header *reply = data; +static int dns_xfer_deliver ( struct dns_request *dns, + struct io_buffer *iobuf, + struct xfer_metadata *meta __unused ) { + const struct dns_header *reply = iobuf->data; union dns_rr_info *rr_info; struct sockaddr_in *sin; unsigned int qtype = dns->qinfo->qtype; + int rc; /* Sanity check */ - if ( len < sizeof ( *reply ) ) { + if ( iob_len ( iobuf ) < sizeof ( *reply ) ) { DBGC ( dns, "DNS %p received underlength packet length %zd\n", - dns, len ); - return -EINVAL; + dns, iob_len ( iobuf ) ); + rc = -EINVAL; + goto done; } /* Check reply ID matches query ID */ @@ -348,7 +347,8 @@ static int dns_xfer_deliver_raw ( struct xfer_interface *socket, DBGC ( dns, "DNS %p received unexpected reply ID %d " "(wanted %d)\n", dns, ntohs ( reply->id ), ntohs ( dns->query.dns.id ) ); - return -EINVAL; + rc = -EINVAL; + goto done; } DBGC ( dns, "DNS %p received reply ID %d\n", dns, ntohs ( reply->id )); @@ -382,7 +382,8 @@ static int dns_xfer_deliver_raw ( struct xfer_interface *socket, /* Mark operation as complete */ dns_done ( dns, 0 ); - return 0; + rc = 0; + goto done; case htons ( DNS_TYPE_CNAME ): @@ -399,7 +400,8 @@ static int dns_xfer_deliver_raw ( struct xfer_interface *socket, DBGC ( dns, "DNS %p recursion exceeded\n", dns ); dns_done ( dns, -ELOOP ); - return 0; + rc = 0; + goto done; } break; @@ -422,7 +424,8 @@ static int dns_xfer_deliver_raw ( struct xfer_interface *socket, DBGC ( dns, "DNS %p found no A record; trying CNAME\n", dns ); dns->qinfo->qtype = htons ( DNS_TYPE_CNAME ); dns_send_packet ( dns ); - return 0; + rc = 0; + goto done; case htons ( DNS_TYPE_CNAME ): /* We asked for a CNAME record. If we got a response @@ -431,29 +434,35 @@ static int dns_xfer_deliver_raw ( struct xfer_interface *socket, */ if ( dns->qinfo->qtype == htons ( DNS_TYPE_A ) ) { dns_send_packet ( dns ); - return 0; + rc = 0; + goto done; } else { DBGC ( dns, "DNS %p found no CNAME record\n", dns ); dns_done ( dns, -ENXIO ); - return 0; + rc = 0; + goto done; } default: assert ( 0 ); dns_done ( dns, -EINVAL ); - return 0; + rc = -EINVAL; + goto done; } + + done: + /* Free I/O buffer */ + free_iob ( iobuf ); + return rc; } /** * Receive new data * - * @v socket UDP socket + * @v dns DNS request * @v rc Reason for close */ -static void dns_xfer_close ( struct xfer_interface *socket, int rc ) { - struct dns_request *dns = - container_of ( socket, struct dns_request, socket ); +static void dns_xfer_close ( struct dns_request *dns, int rc ) { if ( ! rc ) rc = -ECONNABORTED; @@ -461,16 +470,16 @@ static void dns_xfer_close ( struct xfer_interface *socket, int rc ) { dns_done ( dns, rc ); } -/** DNS socket operations */ -static struct xfer_interface_operations dns_socket_operations = { - .close = dns_xfer_close, - .vredirect = xfer_vreopen, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = xfer_deliver_as_raw, - .deliver_raw = dns_xfer_deliver_raw, +/** DNS socket interface operations */ +static struct interface_operation dns_socket_operations[] = { + INTF_OP ( xfer_deliver, struct dns_request *, dns_xfer_deliver ), + INTF_OP ( intf_close, struct dns_request *, dns_xfer_close ), }; +/** DNS socket interface descriptor */ +static struct interface_descriptor dns_socket_desc = + INTF_DESC ( struct dns_request, socket, dns_socket_operations ); + /** DNS resolver interface operations */ static struct interface_operation dns_resolv_op[] = { INTF_OP ( intf_close, struct dns_request *, dns_done ), @@ -517,7 +526,7 @@ static int dns_resolv ( struct interface *resolv, } ref_init ( &dns->refcnt, NULL ); intf_init ( &dns->resolv, &dns_resolv_desc, &dns->refcnt ); - xfer_init ( &dns->socket, &dns_socket_operations, &dns->refcnt ); + intf_init ( &dns->socket, &dns_socket_desc, &dns->refcnt ); timer_init ( &dns->timer, dns_timer_expired ); memcpy ( &dns->sa, sa, sizeof ( dns->sa ) ); diff --git a/src/net/udp/slam.c b/src/net/udp/slam.c index a5a2421fa..84bb9cba3 100644 --- a/src/net/udp/slam.c +++ b/src/net/udp/slam.c @@ -119,11 +119,11 @@ struct slam_request { struct refcnt refcnt; /** Data transfer interface */ - struct xfer_interface xfer; + struct interface xfer; /** Unicast socket */ - struct xfer_interface socket; + struct interface socket; /** Multicast socket */ - struct xfer_interface mc_socket; + struct interface mc_socket; /** Master client retry timer */ struct retry_timer master_timer; @@ -184,12 +184,9 @@ static void slam_finished ( struct slam_request *slam, int rc ) { stop_timer ( &slam->slave_timer ); /* Close all data transfer interfaces */ - xfer_nullify ( &slam->socket ); - xfer_close ( &slam->socket, rc ); - xfer_nullify ( &slam->mc_socket ); - xfer_close ( &slam->mc_socket, rc ); - xfer_nullify ( &slam->xfer ); - xfer_close ( &slam->xfer, rc ); + intf_shutdown ( &slam->socket, rc ); + intf_shutdown ( &slam->mc_socket, rc ); + intf_shutdown ( &slam->xfer, rc ); } /**************************************************************************** @@ -473,15 +470,13 @@ static int slam_pull_header ( struct slam_request *slam, /** * Receive SLAM data packet * - * @v mc_socket SLAM multicast socket + * @v slam SLAM request * @v iobuf I/O buffer * @ret rc Return status code */ -static int slam_mc_socket_deliver ( struct xfer_interface *mc_socket, +static int slam_mc_socket_deliver ( struct slam_request *slam, struct io_buffer *iobuf, struct xfer_metadata *rx_meta __unused ) { - struct slam_request *slam = - container_of ( mc_socket, struct slam_request, mc_socket ); struct xfer_metadata meta; unsigned long packet; size_t len; @@ -533,8 +528,7 @@ static int slam_mc_socket_deliver ( struct xfer_interface *mc_socket, memset ( &meta, 0, sizeof ( meta ) ); meta.whence = SEEK_SET; meta.offset = ( packet * slam->block_size ); - if ( ( rc = xfer_deliver_iob_meta ( &slam->xfer, iobuf, - &meta ) ) != 0 ) + if ( ( rc = xfer_deliver ( &slam->xfer, iobuf, &meta ) ) != 0 ) goto err; /* Mark block as received */ @@ -556,15 +550,13 @@ static int slam_mc_socket_deliver ( struct xfer_interface *mc_socket, /** * Receive SLAM non-data packet * - * @v socket SLAM unicast socket + * @v slam SLAM request * @v iobuf I/O buffer * @ret rc Return status code */ -static int slam_socket_deliver ( struct xfer_interface *socket, +static int slam_socket_deliver ( struct slam_request *slam, struct io_buffer *iobuf, struct xfer_metadata *rx_meta __unused ) { - struct slam_request *slam = - container_of ( socket, struct slam_request, socket ); int rc; /* Restart the master client timer */ @@ -597,90 +589,41 @@ static int slam_socket_deliver ( struct xfer_interface *socket, } -/** - * Close SLAM unicast socket - * - * @v socket SLAM unicast socket - * @v rc Reason for close - */ -static void slam_socket_close ( struct xfer_interface *socket, int rc ) { - struct slam_request *slam = - container_of ( socket, struct slam_request, socket ); - - DBGC ( slam, "SLAM %p unicast socket closed: %s\n", - slam, strerror ( rc ) ); - - slam_finished ( slam, rc ); -} - -/** SLAM unicast socket data transfer operations */ -static struct xfer_interface_operations slam_socket_operations = { - .close = slam_socket_close, - .vredirect = xfer_vreopen, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = slam_socket_deliver, - .deliver_raw = xfer_deliver_as_iob, +/** SLAM unicast socket interface operations */ +static struct interface_operation slam_socket_operations[] = { + INTF_OP ( xfer_deliver, struct slam_request *, slam_socket_deliver ), + INTF_OP ( intf_close, struct slam_request *, slam_finished ), }; -/** - * Close SLAM multicast socket - * - * @v mc_socket SLAM multicast socket - * @v rc Reason for close - */ -static void slam_mc_socket_close ( struct xfer_interface *mc_socket, int rc ){ - struct slam_request *slam = - container_of ( mc_socket, struct slam_request, mc_socket ); +/** SLAM unicast socket interface descriptor */ +static struct interface_descriptor slam_socket_desc = + INTF_DESC ( struct slam_request, socket, slam_socket_operations ); - DBGC ( slam, "SLAM %p multicast socket closed: %s\n", - slam, strerror ( rc ) ); - - slam_finished ( slam, rc ); -} - -/** SLAM multicast socket data transfer operations */ -static struct xfer_interface_operations slam_mc_socket_operations = { - .close = slam_mc_socket_close, - .vredirect = xfer_vreopen, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = slam_mc_socket_deliver, - .deliver_raw = xfer_deliver_as_iob, +/** SLAM multicast socket interface operations */ +static struct interface_operation slam_mc_socket_operations[] = { + INTF_OP ( xfer_deliver, struct slam_request *, slam_mc_socket_deliver ), + INTF_OP ( intf_close, struct slam_request *, slam_finished ), }; +/** SLAM multicast socket interface descriptor */ +static struct interface_descriptor slam_mc_socket_desc = + INTF_DESC ( struct slam_request, mc_socket, slam_mc_socket_operations ); + /**************************************************************************** * * Data transfer interface * */ -/** - * Close SLAM data transfer interface - * - * @v xfer SLAM data transfer interface - * @v rc Reason for close - */ -static void slam_xfer_close ( struct xfer_interface *xfer, int rc ) { - struct slam_request *slam = - container_of ( xfer, struct slam_request, xfer ); - - DBGC ( slam, "SLAM %p data transfer interface closed: %s\n", - slam, strerror ( rc ) ); - - slam_finished ( slam, rc ); -} - -/** SLAM data transfer operations */ -static struct xfer_interface_operations slam_xfer_operations = { - .close = slam_xfer_close, - .vredirect = ignore_xfer_vredirect, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = xfer_deliver_as_raw, - .deliver_raw = ignore_xfer_deliver_raw, +/** SLAM data transfer interface operations */ +static struct interface_operation slam_xfer_operations[] = { + INTF_OP ( intf_close, struct slam_request *, slam_finished ), }; +/** SLAM data transfer interface descriptor */ +static struct interface_descriptor slam_xfer_desc = + INTF_DESC ( struct slam_request, xfer, slam_xfer_operations ); + /** * Parse SLAM URI multicast address * @@ -729,7 +672,7 @@ static int slam_parse_multicast_address ( struct slam_request *slam, * @v uri Uniform Resource Identifier * @ret rc Return status code */ -static int slam_open ( struct xfer_interface *xfer, struct uri *uri ) { +static int slam_open ( struct interface *xfer, struct uri *uri ) { static const struct sockaddr_in default_multicast = { .sin_family = AF_INET, .sin_port = htons ( SLAM_DEFAULT_MULTICAST_PORT ), @@ -749,10 +692,9 @@ static int slam_open ( struct xfer_interface *xfer, struct uri *uri ) { if ( ! slam ) return -ENOMEM; ref_init ( &slam->refcnt, slam_free ); - xfer_init ( &slam->xfer, &slam_xfer_operations, &slam->refcnt ); - xfer_init ( &slam->socket, &slam_socket_operations, &slam->refcnt ); - xfer_init ( &slam->mc_socket, &slam_mc_socket_operations, - &slam->refcnt ); + intf_init ( &slam->xfer, &slam_xfer_desc, &slam->refcnt ); + intf_init ( &slam->socket, &slam_socket_desc, &slam->refcnt ); + intf_init ( &slam->mc_socket, &slam_mc_socket_desc, &slam->refcnt ); timer_init ( &slam->master_timer, slam_master_timer_expired ); timer_init ( &slam->slave_timer, slam_slave_timer_expired ); /* Fake an invalid cached header of { 0x00, ... } */ @@ -795,7 +737,7 @@ static int slam_open ( struct xfer_interface *xfer, struct uri *uri ) { start_timer_fixed ( &slam->slave_timer, SLAM_SLAVE_TIMEOUT ); /* Attach to parent interface, mortalise self, and return */ - xfer_plug_plug ( &slam->xfer, xfer ); + intf_plug_plug ( &slam->xfer, xfer ); ref_put ( &slam->refcnt ); return 0; diff --git a/src/net/udp/tftp.c b/src/net/udp/tftp.c index 5e98f58cd..3bcd0a258 100644 --- a/src/net/udp/tftp.c +++ b/src/net/udp/tftp.c @@ -27,6 +27,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include +#include #include #include #include @@ -79,14 +80,14 @@ struct tftp_request { /** Reference count */ struct refcnt refcnt; /** Data transfer interface */ - struct xfer_interface xfer; + struct interface xfer; /** URI being fetched */ struct uri *uri; /** Transport layer interface */ - struct xfer_interface socket; + struct interface socket; /** Multicast transport layer interface */ - struct xfer_interface mc_socket; + struct interface mc_socket; /** Data block size * @@ -183,12 +184,9 @@ static void tftp_done ( struct tftp_request *tftp, int rc ) { stop_timer ( &tftp->timer ); /* Close all data transfer interfaces */ - xfer_nullify ( &tftp->socket ); - xfer_close ( &tftp->socket, rc ); - xfer_nullify ( &tftp->mc_socket ); - xfer_close ( &tftp->mc_socket, rc ); - xfer_nullify ( &tftp->xfer ); - xfer_close ( &tftp->xfer, rc ); + intf_shutdown ( &tftp->socket, rc ); + intf_shutdown ( &tftp->mc_socket, rc ); + intf_shutdown ( &tftp->xfer, rc ); } /** @@ -202,7 +200,7 @@ static int tftp_reopen ( struct tftp_request *tftp ) { int rc; /* Close socket */ - xfer_close ( &tftp->socket, 0 ); + intf_restart ( &tftp->socket, 0 ); /* Disable ACK sending. */ tftp->flags &= ~TFTP_FL_SEND_ACK; @@ -236,7 +234,7 @@ static int tftp_reopen_mc ( struct tftp_request *tftp, int rc; /* Close multicast socket */ - xfer_close ( &tftp->mc_socket, 0 ); + intf_restart ( &tftp->mc_socket, 0 ); /* Open multicast socket. We never send via this socket, so * use the local address as the peer address (since the peer @@ -423,7 +421,7 @@ static int tftp_send_ack ( struct tftp_request *tftp ) { ack->block = htons ( block ); /* ACK always goes to the peer recorded from the RRQ response */ - return xfer_deliver_iob_meta ( &tftp->socket, iobuf, &meta ); + return xfer_deliver ( &tftp->socket, iobuf, &meta ); } /** @@ -459,7 +457,7 @@ static int tftp_send_error ( struct tftp_request *tftp, int errcode, strcpy ( err->errmsg, errmsg ); /* ERR always goes to the peer recorded from the RRQ response */ - return xfer_deliver_iob_meta ( &tftp->socket, iobuf, &meta ); + return xfer_deliver ( &tftp->socket, iobuf, &meta ); } /** @@ -525,7 +523,7 @@ static void tftp_timer_expired ( struct retry_timer *timer, int fail ) { tftp->flags = TFTP_FL_RRQ_SIZES; /* Close multicast socket */ - xfer_close ( &tftp->mc_socket, 0 ); + intf_restart ( &tftp->mc_socket, 0 ); /* Reset retry timer */ start_timer_nodelay ( &tftp->timer ); @@ -858,8 +856,8 @@ static int tftp_rx_data ( struct tftp_request *tftp, memset ( &meta, 0, sizeof ( meta ) ); meta.whence = SEEK_SET; meta.offset = offset; - if ( ( rc = xfer_deliver_iob_meta ( &tftp->xfer, iob_disown ( iobuf ), - &meta ) ) != 0 ) { + if ( ( rc = xfer_deliver ( &tftp->xfer, iob_disown ( iobuf ), + &meta ) ) != 0 ) { DBGC ( tftp, "TFTP %p could not deliver data: %s\n", tftp, strerror ( rc ) ); goto done; @@ -998,16 +996,14 @@ static int tftp_rx ( struct tftp_request *tftp, /** * Receive new data via socket * - * @v socket Transport layer interface + * @v tftp TFTP connection * @v iobuf I/O buffer * @v meta Transfer metadata * @ret rc Return status code */ -static int tftp_socket_deliver_iob ( struct xfer_interface *socket, - struct io_buffer *iobuf, - struct xfer_metadata *meta ) { - struct tftp_request *tftp = - container_of ( socket, struct tftp_request, socket ); +static int tftp_socket_deliver ( struct tftp_request *tftp, + struct io_buffer *iobuf, + struct xfer_metadata *meta ) { /* Enable sending ACKs when we receive a unicast packet. This * covers three cases: @@ -1030,67 +1026,30 @@ static int tftp_socket_deliver_iob ( struct xfer_interface *socket, } /** TFTP socket operations */ -static struct xfer_interface_operations tftp_socket_operations = { - .close = ignore_xfer_close, - .vredirect = xfer_vreopen, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = tftp_socket_deliver_iob, - .deliver_raw = xfer_deliver_as_iob, +static struct interface_operation tftp_socket_operations[] = { + INTF_OP ( xfer_deliver, struct tftp_request *, tftp_socket_deliver ), }; -/** - * Receive new data via multicast socket - * - * @v mc_socket Multicast transport layer interface - * @v iobuf I/O buffer - * @v meta Transfer metadata - * @ret rc Return status code - */ -static int tftp_mc_socket_deliver_iob ( struct xfer_interface *mc_socket, - struct io_buffer *iobuf, - struct xfer_metadata *meta ) { - struct tftp_request *tftp = - container_of ( mc_socket, struct tftp_request, mc_socket ); - - return tftp_rx ( tftp, iobuf, meta ); -} +/** TFTP socket interface descriptor */ +static struct interface_descriptor tftp_socket_desc = + INTF_DESC ( struct tftp_request, socket, tftp_socket_operations ); /** TFTP multicast socket operations */ -static struct xfer_interface_operations tftp_mc_socket_operations = { - .close = ignore_xfer_close, - .vredirect = xfer_vreopen, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = tftp_mc_socket_deliver_iob, - .deliver_raw = xfer_deliver_as_iob, +static struct interface_operation tftp_mc_socket_operations[] = { + INTF_OP ( xfer_deliver, struct tftp_request *, tftp_rx ), }; -/** - * Close TFTP data transfer interface - * - * @v xfer Data transfer interface - * @v rc Reason for close - */ -static void tftp_xfer_close ( struct xfer_interface *xfer, int rc ) { - struct tftp_request *tftp = - container_of ( xfer, struct tftp_request, xfer ); - - DBGC ( tftp, "TFTP %p interface closed: %s\n", - tftp, strerror ( rc ) ); - - tftp_done ( tftp, rc ); -} +/** TFTP multicast socket interface descriptor */ +static struct interface_descriptor tftp_mc_socket_desc = + INTF_DESC ( struct tftp_request, mc_socket, tftp_mc_socket_operations ); /** * Check flow control window * - * @v xfer Data transfer interface + * @v tftp TFTP connection * @ret len Length of window */ -static size_t tftp_xfer_window ( struct xfer_interface *xfer ) { - struct tftp_request *tftp = - container_of ( xfer, struct tftp_request, xfer ); +static size_t tftp_xfer_window ( struct tftp_request *tftp ) { /* We abuse this data-xfer method to convey the blocksize to * the caller. This really should be done using some kind of @@ -1101,15 +1060,15 @@ static size_t tftp_xfer_window ( struct xfer_interface *xfer ) { } /** TFTP data transfer interface operations */ -static struct xfer_interface_operations tftp_xfer_operations = { - .close = tftp_xfer_close, - .vredirect = ignore_xfer_vredirect, - .window = tftp_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = xfer_deliver_as_raw, - .deliver_raw = ignore_xfer_deliver_raw, +static struct interface_operation tftp_xfer_operations[] = { + INTF_OP ( xfer_window, struct tftp_request *, tftp_xfer_window ), + INTF_OP ( intf_close, struct tftp_request *, tftp_done ), }; +/** TFTP data transfer interface descriptor */ +static struct interface_descriptor tftp_xfer_desc = + INTF_DESC ( struct tftp_request, xfer, tftp_xfer_operations ); + /** * Initiate TFTP/TFTM/MTFTP download * @@ -1117,7 +1076,7 @@ static struct xfer_interface_operations tftp_xfer_operations = { * @v uri Uniform Resource Identifier * @ret rc Return status code */ -static int tftp_core_open ( struct xfer_interface *xfer, struct uri *uri, +static int tftp_core_open ( struct interface *xfer, struct uri *uri, unsigned int default_port, struct sockaddr *multicast, unsigned int flags ) { @@ -1135,10 +1094,9 @@ static int tftp_core_open ( struct xfer_interface *xfer, struct uri *uri, if ( ! tftp ) return -ENOMEM; ref_init ( &tftp->refcnt, tftp_free ); - xfer_init ( &tftp->xfer, &tftp_xfer_operations, &tftp->refcnt ); - xfer_init ( &tftp->socket, &tftp_socket_operations, &tftp->refcnt ); - xfer_init ( &tftp->mc_socket, &tftp_mc_socket_operations, - &tftp->refcnt ); + intf_init ( &tftp->xfer, &tftp_xfer_desc, &tftp->refcnt ); + intf_init ( &tftp->socket, &tftp_socket_desc, &tftp->refcnt ); + intf_init ( &tftp->mc_socket, &tftp_mc_socket_desc, &tftp->refcnt ); timer_init ( &tftp->timer, tftp_timer_expired ); tftp->uri = uri_get ( uri ); tftp->blksize = TFTP_DEFAULT_BLKSIZE; @@ -1159,7 +1117,7 @@ static int tftp_core_open ( struct xfer_interface *xfer, struct uri *uri, start_timer_nodelay ( &tftp->timer ); /* Attach to parent interface, mortalise self, and return */ - xfer_plug_plug ( &tftp->xfer, xfer ); + intf_plug_plug ( &tftp->xfer, xfer ); ref_put ( &tftp->refcnt ); return 0; @@ -1178,7 +1136,7 @@ static int tftp_core_open ( struct xfer_interface *xfer, struct uri *uri, * @v uri Uniform Resource Identifier * @ret rc Return status code */ -static int tftp_open ( struct xfer_interface *xfer, struct uri *uri ) { +static int tftp_open ( struct interface *xfer, struct uri *uri ) { return tftp_core_open ( xfer, uri, TFTP_PORT, NULL, TFTP_FL_RRQ_SIZES ); @@ -1197,7 +1155,7 @@ struct uri_opener tftp_uri_opener __uri_opener = { * @v uri Uniform Resource Identifier * @ret rc Return status code */ -static int tftpsize_open ( struct xfer_interface *xfer, struct uri *uri ) { +static int tftpsize_open ( struct interface *xfer, struct uri *uri ) { return tftp_core_open ( xfer, uri, TFTP_PORT, NULL, ( TFTP_FL_RRQ_SIZES | TFTP_FL_SIZEONLY ) ); @@ -1217,7 +1175,7 @@ struct uri_opener tftpsize_uri_opener __uri_opener = { * @v uri Uniform Resource Identifier * @ret rc Return status code */ -static int tftm_open ( struct xfer_interface *xfer, struct uri *uri ) { +static int tftm_open ( struct interface *xfer, struct uri *uri ) { return tftp_core_open ( xfer, uri, TFTP_PORT, NULL, ( TFTP_FL_RRQ_SIZES | TFTP_FL_RRQ_MULTICAST ) ); @@ -1237,7 +1195,7 @@ struct uri_opener tftm_uri_opener __uri_opener = { * @v uri Uniform Resource Identifier * @ret rc Return status code */ -static int mtftp_open ( struct xfer_interface *xfer, struct uri *uri ) { +static int mtftp_open ( struct interface *xfer, struct uri *uri ) { return tftp_core_open ( xfer, uri, MTFTP_PORT, ( struct sockaddr * ) &tftp_mtftp_socket, TFTP_FL_MTFTP_RECOVERY );