From b5b60ea33dc48a297515f95ac19cca20bb39edd1 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Tue, 4 Jul 2023 16:50:03 +0100 Subject: [interface] Fix debug message values for temporary interfaces The interface debug message values constructed by INTF_DBG() et al rely on the interface being embedded within a containing object. This assumption is not valid for the temporary outbound-only interfaces constructed on the stack by intf_shutdown() and xfer_vredirect(). Formalise the notion of a temporary outbound-only interface as having a NULL interface descriptor, and overload the "original interface descriptor" field to contain a pointer to the original interface that the temporary interface is shadowing. Originally-fixed-by: Vincent Fazio Signed-off-by: Michael Brown --- src/core/interface.c | 1 + src/core/xfer.c | 3 +- src/include/ipxe/interface.h | 72 ++++++++++++++++++++++++++++++++++---------- 3 files changed, 59 insertions(+), 17 deletions(-) diff --git a/src/core/interface.c b/src/core/interface.c index 34a4180a5..ea0606893 100644 --- a/src/core/interface.c +++ b/src/core/interface.c @@ -285,6 +285,7 @@ void intf_shutdown ( struct interface *intf, int rc ) { intf_nullify ( intf ); /* Transfer destination to temporary interface */ + intf_temp_init ( &tmp, intf ); tmp.dest = intf->dest; intf->dest = &null_intf; diff --git a/src/core/xfer.c b/src/core/xfer.c index 0faf3292a..269359e15 100644 --- a/src/core/xfer.c +++ b/src/core/xfer.c @@ -60,7 +60,7 @@ static struct xfer_metadata dummy_metadata; * @ret rc Return status code */ int xfer_vredirect ( struct interface *intf, int type, va_list args ) { - struct interface tmp = INTF_INIT ( null_intf_desc ); + struct interface tmp; struct interface *dest; xfer_vredirect_TYPE ( void * ) *op = intf_get_dest_op_no_passthru ( intf, xfer_vredirect, &dest ); @@ -85,6 +85,7 @@ int xfer_vredirect ( struct interface *intf, int type, va_list args ) { * If redirection fails, then send intf_close() to the * parent interface. */ + intf_temp_init ( &tmp, intf ); intf_plug ( &tmp, dest ); rc = xfer_vreopen ( dest, type, args ); if ( rc == 0 ) { diff --git a/src/include/ipxe/interface.h b/src/include/ipxe/interface.h index 19f58a4b4..d2fa8190c 100644 --- a/src/include/ipxe/interface.h +++ b/src/include/ipxe/interface.h @@ -133,17 +133,30 @@ struct interface { struct interface *dest; /** Reference counter * - * If this interface is not part of a reference-counted - * object, this field may be NULL. + * If this interface is not part of a reference-counted object + * then this field is NULL. */ struct refcnt *refcnt; - /** Interface descriptor */ - struct interface_descriptor *desc; - /** Original interface descriptor + /** Interface descriptor * - * Used by intf_reinit(). + * If this is a temporary outbound-only interface created by + * intf_temp_init() then this field is NULL. */ - struct interface_descriptor *original; + struct interface_descriptor *desc; + /** Original interface properties */ + union { + /** Original interface descriptor + * + * Used by intf_reinit(). + */ + struct interface_descriptor *desc; + /** Original interface + * + * Used for temporary outbound-only interfaces created + * by intf_temp_init(). + */ + struct interface *intf; + } original; }; extern void intf_plug ( struct interface *intf, struct interface *dest ); @@ -193,7 +206,7 @@ static inline void intf_init ( struct interface *intf, intf->dest = &null_intf; intf->refcnt = refcnt; intf->desc = desc; - intf->original = desc; + intf->original.desc = desc; } /** @@ -201,13 +214,38 @@ static inline void intf_init ( struct interface *intf, * * @v descriptor Object interface descriptor */ -#define INTF_INIT( descriptor ) { \ - .dest = &null_intf, \ - .refcnt = NULL, \ - .desc = &(descriptor), \ - .original = &(descriptor), \ +#define INTF_INIT( descriptor ) { \ + .dest = &null_intf, \ + .refcnt = NULL, \ + .desc = &(descriptor), \ + .original = { \ + .desc = &(descriptor), \ + }, \ } +/** + * Initialise a temporary outbound-only object interface + * + * @v intf Temporary outbound-only object interface + * @v original Original object interface + */ +static inline void intf_temp_init ( struct interface *intf, + struct interface *original ) { + intf->dest = &null_intf; + intf->desc = NULL; + intf->original.intf = original; +} + +/** + * Get original interface + * + * @v intf Object interface (possibly a temporary interface) + * @ret intf Original object interface + */ +static inline struct interface * intf_origin ( struct interface *intf ) { + return ( intf->desc ? intf : intf->original.intf ); +} + /** * Get object interface destination and operation method (without pass-through) * @@ -240,7 +278,7 @@ static inline void intf_init ( struct interface *intf, * * Use as the first argument to DBGC() or equivalent macro. */ -#define INTF_COL( intf ) intf_object ( intf ) +#define INTF_COL( intf ) intf_object ( intf_origin ( intf ) ) /** printf() format string for INTF_DBG() */ #define INTF_FMT "%p+%zx" @@ -251,7 +289,9 @@ static inline void intf_init ( struct interface *intf, * @v intf Object interface * @ret args printf() argument list corresponding to INTF_FMT */ -#define INTF_DBG( intf ) intf_object ( intf ), (intf)->desc->offset +#define INTF_DBG( intf ) \ + intf_object ( intf_origin ( intf ) ), \ + intf_origin ( intf )->desc->offset /** printf() format string for INTF_INTF_DBG() */ #define INTF_INTF_FMT INTF_FMT "->" INTF_FMT @@ -273,7 +313,7 @@ static inline void intf_init ( struct interface *intf, static inline void intf_reinit ( struct interface *intf ) { /* Restore original interface descriptor */ - intf->desc = intf->original; + intf->desc = intf->original.desc; } #endif /* _IPXE_INTERFACE_H */ -- cgit