aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2023-07-04 16:50:03 +0100
committerMichael Brown <mcb30@ipxe.org>2023-07-04 16:54:39 +0100
commitb5b60ea33dc48a297515f95ac19cca20bb39edd1 (patch)
treed8eef92727b7ec1af273ddcbe6cae2a462ea949a
parent824441069010806b63cc5d110e5acd1f1d1ee858 (diff)
downloadipxe-tmpintf.zip
ipxe-tmpintf.tar.gz
ipxe-tmpintf.tar.bz2
[interface] Fix debug message values for temporary interfacestmpintf
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>
-rw-r--r--src/core/interface.c1
-rw-r--r--src/core/xfer.c3
-rw-r--r--src/include/ipxe/interface.h72
3 files changed, 59 insertions, 17 deletions
diff --git a/src/core/interface.c b/src/core/interface.c
index 34a4180..ea06068 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 0faf329..269359e 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 19f58a4..d2fa819 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,14 +214,39 @@ 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)
*
* @v intf Object interface
@@ -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 */