From 07b0d4fa30d021322efa8a423295a0677325ec8d Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Mon, 20 Jul 2015 12:15:21 +0100 Subject: [PATCH] [xferbuf] Add xfer_buffer() to provide direct access to underlying buffer Allow data transfer buffer users to provide direct access to their underlying data transfer buffer. Signed-off-by: Michael Brown --- src/core/xferbuf.c | 39 ++++++++++++++++++++++++++++++++++++++ src/include/ipxe/xferbuf.h | 5 +++++ 2 files changed, 44 insertions(+) diff --git a/src/core/xferbuf.c b/src/core/xferbuf.c index 7f9780b3a..afc72ae76 100644 --- a/src/core/xferbuf.c +++ b/src/core/xferbuf.c @@ -283,3 +283,42 @@ struct xfer_buffer_operations xferbuf_umalloc_operations = { .write = xferbuf_umalloc_write, .read = xferbuf_umalloc_read, }; + +/** + * Get underlying data transfer buffer + * + * @v interface Data transfer interface + * @ret xferbuf Data transfer buffer, or NULL on error + * + * This call will check that the xfer_buffer() handler belongs to the + * destination interface which also provides xfer_deliver() for this + * interface. + * + * This is done to prevent accidental accesses to a data transfer + * buffer which may be located behind a non-transparent datapath via a + * series of pass-through interfaces. + */ +struct xfer_buffer * xfer_buffer ( struct interface *intf ) { + struct interface *dest; + xfer_buffer_TYPE ( void * ) *op = + intf_get_dest_op ( intf, xfer_buffer, &dest ); + void *object = intf_object ( dest ); + struct interface *xfer_deliver_dest; + struct xfer_buffer *xferbuf; + + /* Check that this operation is provided by the same interface + * which handles xfer_deliver(). + */ + intf_get_dest_op ( intf, xfer_deliver, &xfer_deliver_dest ); + + if ( op && ( dest == xfer_deliver_dest ) ) { + xferbuf = op ( object ); + } else { + /* Default is to not have a data transfer buffer */ + xferbuf = NULL; + } + + intf_put ( xfer_deliver_dest ); + intf_put ( dest ); + return xferbuf; +} diff --git a/src/include/ipxe/xferbuf.h b/src/include/ipxe/xferbuf.h index f2f336252..cb0b1a0e8 100644 --- a/src/include/ipxe/xferbuf.h +++ b/src/include/ipxe/xferbuf.h @@ -12,6 +12,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include #include #include +#include #include /** A data transfer buffer */ @@ -97,4 +98,8 @@ extern int xferbuf_deliver ( struct xfer_buffer *xferbuf, struct io_buffer *iobuf, struct xfer_metadata *meta ); +extern struct xfer_buffer * xfer_buffer ( struct interface *intf ); +#define xfer_buffer_TYPE( object_type ) \ + typeof ( struct xfer_buffer * ( object_type ) ) + #endif /* _IPXE_XFERBUF_H */