[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 <vfazio@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
pull/989/head
Michael Brown 2023-07-04 16:50:03 +01:00
parent 8244410690
commit b5b60ea33d
3 changed files with 59 additions and 17 deletions

View File

@ -285,6 +285,7 @@ void intf_shutdown ( struct interface *intf, int rc ) {
intf_nullify ( intf ); intf_nullify ( intf );
/* Transfer destination to temporary interface */ /* Transfer destination to temporary interface */
intf_temp_init ( &tmp, intf );
tmp.dest = intf->dest; tmp.dest = intf->dest;
intf->dest = &null_intf; intf->dest = &null_intf;

View File

@ -60,7 +60,7 @@ static struct xfer_metadata dummy_metadata;
* @ret rc Return status code * @ret rc Return status code
*/ */
int xfer_vredirect ( struct interface *intf, int type, va_list args ) { 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; struct interface *dest;
xfer_vredirect_TYPE ( void * ) *op = xfer_vredirect_TYPE ( void * ) *op =
intf_get_dest_op_no_passthru ( intf, xfer_vredirect, &dest ); 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 * If redirection fails, then send intf_close() to the
* parent interface. * parent interface.
*/ */
intf_temp_init ( &tmp, intf );
intf_plug ( &tmp, dest ); intf_plug ( &tmp, dest );
rc = xfer_vreopen ( dest, type, args ); rc = xfer_vreopen ( dest, type, args );
if ( rc == 0 ) { if ( rc == 0 ) {

View File

@ -133,17 +133,30 @@ struct interface {
struct interface *dest; struct interface *dest;
/** Reference counter /** Reference counter
* *
* If this interface is not part of a reference-counted * If this interface is not part of a reference-counted object
* object, this field may be NULL. * then this field is NULL.
*/ */
struct refcnt *refcnt; struct refcnt *refcnt;
/** Interface descriptor */ /** Interface descriptor
struct interface_descriptor *desc;
/** Original 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 ); 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->dest = &null_intf;
intf->refcnt = refcnt; intf->refcnt = refcnt;
intf->desc = desc; 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 * @v descriptor Object interface descriptor
*/ */
#define INTF_INIT( descriptor ) { \ #define INTF_INIT( descriptor ) { \
.dest = &null_intf, \ .dest = &null_intf, \
.refcnt = NULL, \ .refcnt = NULL, \
.desc = &(descriptor), \ .desc = &(descriptor), \
.original = &(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) * 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. * 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() */ /** printf() format string for INTF_DBG() */
#define INTF_FMT "%p+%zx" #define INTF_FMT "%p+%zx"
@ -251,7 +289,9 @@ static inline void intf_init ( struct interface *intf,
* @v intf Object interface * @v intf Object interface
* @ret args printf() argument list corresponding to INTF_FMT * @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() */ /** printf() format string for INTF_INTF_DBG() */
#define INTF_INTF_FMT INTF_FMT "->" INTF_FMT #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 ) { static inline void intf_reinit ( struct interface *intf ) {
/* Restore original interface descriptor */ /* Restore original interface descriptor */
intf->desc = intf->original; intf->desc = intf->original.desc;
} }
#endif /* _IPXE_INTERFACE_H */ #endif /* _IPXE_INTERFACE_H */