]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[interface] Convert all name-resolution interfaces to generic interfaces
authorMichael Brown <mcb30@ipxe.org>
Fri, 13 Jun 2008 02:36:24 +0000 (03:36 +0100)
committerMichael Brown <mcb30@ipxe.org>
Tue, 22 Jun 2010 14:45:57 +0000 (15:45 +0100)
Remove name-resolution as an interface type, and replace
name-resolution interfaces with generic interfaces supporting the
resolv_done() method.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/arch/i386/interface/syslinux/comboot_resolv.c
src/core/resolv.c
src/include/ipxe/resolv.h
src/net/udp/dns.c

index c505d96b48abd01ae0f50549e9aac60ae8782a85..03bbfd04abaf29407342176a65d6a9c0d83daa32 100644 (file)
@@ -7,54 +7,55 @@
 
 FILE_LICENCE ( GPL2_OR_LATER );
 
-static int comboot_resolv_rc;
-static struct in_addr comboot_resolv_addr;
-
-static void comboot_resolv_done ( struct resolv_interface *resolv,
-                                 struct sockaddr *sa, int rc ) {
-       struct sockaddr_in *sin;
+struct comboot_resolver {
+       struct interface intf;
+       int rc;
+       struct in_addr addr;
+};
 
-       resolv_unplug ( resolv );
+static void comboot_resolv_close ( struct comboot_resolver *comboot_resolver,
+                                  int rc ) {
+       comboot_resolver->rc = rc;
+       intf_shutdown ( &comboot_resolver->intf, rc );
+}
 
-       if ( rc != 0 ) {
-               comboot_resolv_rc = rc;
-               return;
-       }
+static void comboot_resolv_done ( struct comboot_resolver *comboot_resolver,
+                                 struct sockaddr *sa ) {
+       struct sockaddr_in *sin;
 
-       if ( sa->sa_family != AF_INET ) {
-               comboot_resolv_rc = -EAFNOSUPPORT;
-               return;
+       if ( sa->sa_family == AF_INET ) {
+               sin = ( ( struct sockaddr_in * ) sa );
+               comboot_resolver->addr = sin->sin_addr;
        }
-
-       sin = ( ( struct sockaddr_in * ) sa );
-       comboot_resolv_addr = sin->sin_addr;
-
-       comboot_resolv_rc = 0;
 }
 
-static struct resolv_interface_operations comboot_resolv_ops = {
-       .done = comboot_resolv_done,
+static struct interface_operation comboot_resolv_op[] = {
+       INTF_OP ( intf_close, struct comboot_resolver *, comboot_resolv_close ),
+       INTF_OP ( resolv_done, struct comboot_resolver *, comboot_resolv_done ),
 };
 
-static struct resolv_interface comboot_resolver = {
-       .intf = {
-               .dest = &null_resolv.intf,
-               .refcnt = NULL,
-       },
-       .op = &comboot_resolv_ops,
+static struct interface_descriptor comboot_resolv_desc =
+       INTF_DESC ( struct comboot_resolver, intf, comboot_resolv_op );
+
+static struct comboot_resolver comboot_resolver = {
+       .intf = INTF_INIT ( comboot_resolv_desc ),
 };
 
 int comboot_resolv ( const char *name, struct in_addr *address ) {
        int rc;
 
-       comboot_resolv_rc = -EINPROGRESS;
+       comboot_resolver.rc = -EINPROGRESS;
+       comboot_resolver.addr.s_addr = 0;
 
-       if ( ( rc = resolv ( &comboot_resolver, name, NULL ) ) != 0 )
+       if ( ( rc = resolv ( &comboot_resolver.intf, name, NULL ) ) != 0 )
                return rc;
 
-       while ( comboot_resolv_rc == -EINPROGRESS )
+       while ( comboot_resolver.rc == -EINPROGRESS )
                step();
 
-       *address = comboot_resolv_addr;
-       return comboot_resolv_rc;
+       if ( ! comboot_resolver.addr.s_addr )
+               return -EAFNOSUPPORT;
+
+       *address = comboot_resolver.addr;
+       return comboot_resolver.rc;
 }
index ec7a556ce56522716fb61bea5257d8399a44f792..4256de4717f5bb5f77114d7b2b611dd0ccc3258f 100644 (file)
@@ -42,47 +42,29 @@ FILE_LICENCE ( GPL2_OR_LATER );
  */
 
 /**
- * Name resolution completed
+ * Name resolved
  *
- * @v resolv           Name resolution interface
+ * @v intf             Object interface
  * @v sa               Completed socket address (if successful)
- * @v rc               Final status code
  */
-void resolv_done ( struct resolv_interface *resolv, struct sockaddr *sa,
-                  int rc ) {
-       struct resolv_interface *dest = resolv_get_dest ( resolv );
-
-       resolv_unplug ( resolv );
-       dest->op->done ( dest, sa, rc );
-       resolv_put ( dest );
-}
+void resolv_done ( struct interface *intf, struct sockaddr *sa ) {
+       struct interface *dest;
+       resolv_done_TYPE ( void * ) *op =
+               intf_get_dest_op ( intf, resolv_done, &dest );
+       void *object = intf_object ( dest );
+
+       DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " resolv_done\n",
+              INTF_INTF_DBG ( intf, dest ) );
+
+       if ( op ) {
+               op ( object, sa );
+       } else {
+               /* Default is to ignore resolutions */
+       }
 
-/**
- * Ignore name resolution done() event
- *
- * @v resolv           Name resolution interface
- * @v sa               Completed socket address (if successful)
- * @v rc               Final status code
- */
-void ignore_resolv_done ( struct resolv_interface *resolv __unused,
-                         struct sockaddr *sa __unused, int rc __unused ) {
-       /* Do nothing */
+       intf_put ( dest );
 }
 
-/** Null name resolution interface operations */
-struct resolv_interface_operations null_resolv_ops = {
-       .done           = ignore_resolv_done,
-};
-
-/** Null name resolution interface */
-struct resolv_interface null_resolv = {
-       .intf = {
-               .dest = &null_resolv.intf,
-               .refcnt = NULL,
-       },
-       .op = &null_resolv_ops,
-};
-
 /***************************************************************************
  *
  * Numeric name resolver
@@ -95,7 +77,7 @@ struct numeric_resolv {
        /** Reference counter */
        struct refcnt refcnt;
        /** Name resolution interface */
-       struct resolv_interface resolv;
+       struct interface resolv;
        /** Process */
        struct process process;
        /** Completed socket address */
@@ -107,12 +89,14 @@ struct numeric_resolv {
 static void numeric_step ( struct process *process ) {
        struct numeric_resolv *numeric =
                container_of ( process, struct numeric_resolv, process );
-       
-       resolv_done ( &numeric->resolv, &numeric->sa, numeric->rc );
+
        process_del ( process );
+       if ( numeric->rc == 0 )
+               resolv_done ( &numeric->resolv, &numeric->sa );
+       intf_shutdown ( &numeric->resolv, numeric->rc );
 }
 
-static int numeric_resolv ( struct resolv_interface *resolv,
+static int numeric_resolv ( struct interface *resolv,
                            const char *name, struct sockaddr *sa ) {
        struct numeric_resolv *numeric;
        struct sockaddr_in *sin;
@@ -122,7 +106,7 @@ static int numeric_resolv ( struct resolv_interface *resolv,
        if ( ! numeric )
                return -ENOMEM;
        ref_init ( &numeric->refcnt, NULL );
-       resolv_init ( &numeric->resolv, &null_resolv_ops, &numeric->refcnt );
+       intf_init ( &numeric->resolv, &null_intf_desc, &numeric->refcnt );
        process_init ( &numeric->process, numeric_step, &numeric->refcnt );
        memcpy ( &numeric->sa, sa, sizeof ( numeric->sa ) );
 
@@ -131,12 +115,14 @@ static int numeric_resolv ( struct resolv_interface *resolv,
 
        /* Attempt to resolve name */
        sin = ( ( struct sockaddr_in * ) &numeric->sa );
-       sin->sin_family = AF_INET;
-       if ( inet_aton ( name, &sin->sin_addr ) == 0 )
+       if ( inet_aton ( name, &sin->sin_addr ) != 0 ) {
+               sin->sin_family = AF_INET;
+       } else {
                numeric->rc = -EINVAL;
+       }
 
        /* Attach to parent interface, mortalise self, and return */
-       resolv_plug_plug ( &numeric->resolv, resolv );
+       intf_plug_plug ( &numeric->resolv, resolv );
        ref_put ( &numeric->refcnt );
        return 0;
 }
@@ -158,10 +144,10 @@ struct resolv_mux {
        /** Reference counter */
        struct refcnt refcnt;
        /** Parent name resolution interface */
-       struct resolv_interface parent;
+       struct interface parent;
 
        /** Child name resolution interface */
-       struct resolv_interface child;
+       struct interface child;
        /** Current child resolver */
        struct resolver *resolver;
 
@@ -180,7 +166,7 @@ struct resolv_mux {
  * @v mux              Name resolution multiplexer
  * @ret rc             Return status code
  */
-static int resolv_mux_try ( struct resolv_mux *mux ) {
+static int resmux_try ( struct resolv_mux *mux ) {
        struct resolver *resolver = mux->resolver;
        int rc;
 
@@ -197,19 +183,31 @@ static int resolv_mux_try ( struct resolv_mux *mux ) {
 }
 
 /**
- * Handle done() event from child name resolver
+ * Child resolved name
  *
- * @v resolv           Child name resolution interface
- * @v sa               Completed socket address (if successful)
- * @v rc               Final status code
+ * @v mux              Name resolution multiplexer
+ * @v sa               Completed socket address
  */
-static void resolv_mux_done ( struct resolv_interface *resolv,
-                             struct sockaddr *sa, int rc ) {
-       struct resolv_mux *mux =
-               container_of ( resolv, struct resolv_mux, child );
+static void resmux_child_resolv_done ( struct resolv_mux *mux,
+                                      struct sockaddr *sa ) {
 
-       /* Unplug child */
-       resolv_unplug ( &mux->child );
+       DBGC ( mux, "RESOLV %p resolved \"%s\" using method %s\n",
+              mux, mux->name, mux->resolver->name );
+
+       /* Pass resolution to parent */
+       resolv_done ( &mux->parent, sa );
+}
+
+/**
+ * Child finished resolution
+ *
+ * @v mux              Name resolution multiplexer
+ * @v rc               Return status code
+ */
+static void resmux_child_close ( struct resolv_mux *mux, int rc ) {
+
+       /* Restart child interface */
+       intf_restart ( &mux->child, rc );
 
        /* If this resolution succeeded, stop now */
        if ( rc == 0 ) {
@@ -224,21 +222,26 @@ static void resolv_mux_done ( struct resolv_interface *resolv,
                DBGC ( mux, "RESOLV %p failed to resolve name\n", mux );
                goto finished;
        }
-       if ( ( rc = resolv_mux_try ( mux ) ) != 0 )
+       if ( ( rc = resmux_try ( mux ) ) != 0 )
                goto finished;
 
        /* Next resolver is now running */
        return;
-       
+
  finished:
-       resolv_done ( &mux->parent, sa, rc );
+       intf_shutdown ( &mux->parent, rc );
 }
 
-/** Name resolution multiplexer operations */
-static struct resolv_interface_operations resolv_mux_child_ops = {
-       .done           = resolv_mux_done,
+/** Name resolution multiplexer child interface operations */
+static struct interface_operation resmux_child_op[] = {
+       INTF_OP ( resolv_done, struct resolv_mux *, resmux_child_resolv_done ),
+       INTF_OP ( intf_close, struct resolv_mux *, resmux_child_close ),
 };
 
+/** Name resolution multiplexer child interface descriptor */
+static struct interface_descriptor resmux_child_desc =
+       INTF_DESC ( struct resolv_mux, child, resmux_child_op );
+
 /**
  * Start name resolution
  *
@@ -247,7 +250,7 @@ static struct resolv_interface_operations resolv_mux_child_ops = {
  * @v sa               Socket address to complete
  * @ret rc             Return status code
  */
-int resolv ( struct resolv_interface *resolv, const char *name,
+int resolv ( struct interface *resolv, const char *name,
             struct sockaddr *sa ) {
        struct resolv_mux *mux;
        size_t name_len = ( strlen ( name ) + 1 );
@@ -258,10 +261,11 @@ int resolv ( struct resolv_interface *resolv, const char *name,
        if ( ! mux )
                return -ENOMEM;
        ref_init ( &mux->refcnt, NULL );
-       resolv_init ( &mux->parent, &null_resolv_ops, &mux->refcnt );
-       resolv_init ( &mux->child, &resolv_mux_child_ops, &mux->refcnt );
+       intf_init ( &mux->parent, &null_intf_desc, &mux->refcnt );
+       intf_init ( &mux->child, &resmux_child_desc, &mux->refcnt );
        mux->resolver = table_start ( RESOLVERS );
-       memcpy ( &mux->sa, sa, sizeof ( mux->sa ) );
+       if ( sa )
+               memcpy ( &mux->sa, sa, sizeof ( mux->sa ) );
        memcpy ( mux->name, name, name_len );
 
        DBGC ( mux, "RESOLV %p attempting to resolve \"%s\"\n", mux, name );
@@ -270,11 +274,11 @@ int resolv ( struct resolv_interface *resolv, const char *name,
         * least one resolver (the numeric resolver), so no need to
         * check for the zero-resolvers-available case.
         */
-       if ( ( rc = resolv_mux_try ( mux ) ) != 0 )
+       if ( ( rc = resmux_try ( mux ) ) != 0 )
                goto err;
 
        /* Attach parent interface, mortalise self, and return */
-       resolv_plug_plug ( &mux->parent, resolv );
+       intf_plug_plug ( &mux->parent, resolv );
        ref_put ( &mux->refcnt );
        return 0;
 
@@ -297,7 +301,7 @@ struct named_socket {
        /** Data transfer interface */
        struct xfer_interface xfer;
        /** Name resolution interface */
-       struct resolv_interface resolv;
+       struct interface resolv;
        /** Communication semantics (e.g. SOCK_STREAM) */
        int semantics;
        /** Stored local socket address, if applicable */
@@ -307,15 +311,14 @@ struct named_socket {
 };
 
 /**
- * Finish using named socket
+ * Terminate named socket opener
  *
  * @v named            Named socket
- * @v rc               Reason for finish
+ * @v rc               Reason for termination
  */
-static void named_done ( struct named_socket *named, int rc ) {
-
-       /* Close all interfaces */
-       resolv_nullify ( &named->resolv );
+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 );
 }
@@ -330,7 +333,7 @@ static void named_xfer_close ( struct xfer_interface *xfer, int rc ) {
        struct named_socket *named =
                container_of ( xfer, struct named_socket, xfer );
 
-       named_done ( named, rc );
+       named_close ( named, rc );
 }
 
 /** Named socket opener data transfer interface operations */
@@ -344,34 +347,46 @@ static struct xfer_interface_operations named_xfer_ops = {
 };
 
 /**
- * Handle done() event
+ * Name resolved
  *
- * @v resolv           Name resolution interface
- * @v sa               Completed socket address (if successful)
- * @v rc               Final status code
+ * @v named            Named socket
+ * @v sa               Completed socket address
  */
-static void named_resolv_done ( struct resolv_interface *resolv,
-                               struct sockaddr *sa, int rc ) {
-       struct named_socket *named =
-               container_of ( resolv, struct named_socket, resolv );
+static void named_resolv_done ( struct named_socket *named,
+                               struct sockaddr *sa ) {
+       int rc;
 
-       /* Redirect if name resolution was successful */
-       if ( rc == 0 ) {
-               rc = xfer_redirect ( &named->xfer, LOCATION_SOCKET,
-                                    named->semantics, sa,
-                                    ( named->have_local ?
-                                      &named->local : NULL ) );
+       /* Nullify data transfer interface */
+       xfer_nullify ( &named->xfer );
+
+       /* Redirect data-xfer interface */
+       if ( ( rc = xfer_redirect ( &named->xfer, LOCATION_SOCKET,
+                                   named->semantics, sa,
+                                   ( named->have_local ?
+                                     &named->local : NULL ) ) ) != 0 ) {
+               /* Redirection failed - do not unplug data-xfer interface */
+               DBGC ( named, "NAMED %p could not redirect: %s\n",
+                      named, strerror ( rc ) );
+       } else {
+               /* Redirection succeeded - unplug data-xfer interface */
+               DBGC ( named, "NAMED %p redirected successfully\n", named );
+               xfer_unplug ( &named->xfer );
        }
 
-       /* Terminate resolution */
-       named_done ( named, rc );
+       /* Terminate named socket opener */
+       named_close ( named, rc );
 }
 
-/** Named socket opener name resolution interface operations */
-static struct resolv_interface_operations named_resolv_ops = {
-       .done           = named_resolv_done,
+/** Named socket opener resolver interface operations */
+static struct interface_operation named_resolv_op[] = {
+       INTF_OP ( intf_close, struct named_socket *, named_close ),
+       INTF_OP ( resolv_done, struct named_socket *, named_resolv_done ),
 };
 
+/** Named socket opener resolver interface descriptor */
+static struct interface_descriptor named_resolv_desc =
+       INTF_DESC ( struct named_socket, resolv, named_resolv_op );
+
 /**
  * Open named socket
  *
@@ -393,14 +408,14 @@ int xfer_open_named_socket ( struct xfer_interface *xfer, int semantics,
                return -ENOMEM;
        ref_init ( &named->refcnt, NULL );
        xfer_init ( &named->xfer, &named_xfer_ops, &named->refcnt );
-       resolv_init ( &named->resolv, &named_resolv_ops, &named->refcnt );
+       intf_init ( &named->resolv, &named_resolv_desc, &named->refcnt );
        named->semantics = semantics;
        if ( local ) {
                memcpy ( &named->local, local, sizeof ( named->local ) );
                named->have_local = 1;
        }
 
-       DBGC ( named, "RESOLV %p opening named socket \"%s\"\n",
+       DBGC ( named, "NAMED %p opening \"%s\"\n",
               named, name );
 
        /* Start name resolution */
index 767614bd2544f60f6562c2d588844631384b3cd2..d9868a5d76d56ec9e6ceac823f6acdc70767e805 100644 (file)
 
 FILE_LICENCE ( GPL2_OR_LATER );
 
-#include <ipxe/refcnt.h>
 #include <ipxe/interface.h>
 #include <ipxe/tables.h>
-#include <ipxe/socket.h>
 
-struct resolv_interface;
-
-/** Name resolution interface operations */
-struct resolv_interface_operations {
-       /** Name resolution completed
-        *
-        * @v resolv            Name resolution interface
-        * @v sa                Completed socket address (if successful)
-        * @v rc                Final status code
-        */
-       void ( * done ) ( struct resolv_interface *resolv,
-                         struct sockaddr *sa, int rc );
-};
-
-/** A name resolution interface */
-struct resolv_interface {
-       /** Generic object communication interface */
-       struct interface intf;
-       /** Operations for received messages */
-       struct resolv_interface_operations *op;
-};
-
-extern struct resolv_interface null_resolv;
-extern struct resolv_interface_operations null_resolv_ops;
-
-/**
- * Initialise a name resolution interface
- *
- * @v resolv           Name resolution interface
- * @v op               Name resolution interface operations
- * @v refcnt           Containing object reference counter, or NULL
- */
-static inline void resolv_init ( struct resolv_interface *resolv,
-                                struct resolv_interface_operations *op,
-                                struct refcnt *refcnt ) {
-       resolv->intf.dest = &null_resolv.intf;
-       resolv->intf.refcnt = refcnt;
-       resolv->op = op;
-}
-
-/**
- * Get name resolution interface from generic object communication interface
- *
- * @v intf             Generic object communication interface
- * @ret resolv         Name resolution interface
- */
-static inline __attribute__ (( always_inline )) struct resolv_interface *
-intf_to_resolv ( struct interface *intf ) {
-       return container_of ( intf, struct resolv_interface, intf );
-}
-
-/**
- * Get reference to destination name resolution interface
- *
- * @v resolv           Name resolution interface
- * @ret dest           Destination interface
- */
-static inline __attribute__ (( always_inline )) struct resolv_interface *
-resolv_get_dest ( struct resolv_interface *resolv ) {
-       return intf_to_resolv ( intf_get ( resolv->intf.dest ) );
-}
-
-/**
- * Drop reference to name resolution interface
- *
- * @v resolv           name resolution interface
- */
-static inline __attribute__ (( always_inline )) void
-resolv_put ( struct resolv_interface *resolv ) {
-       intf_put ( &resolv->intf );
-}
-
-/**
- * Plug a name resolution interface into a new destination interface
- *
- * @v resolv           Name resolution interface
- * @v dest             New destination interface
- */
-static inline __attribute__ (( always_inline )) void
-resolv_plug ( struct resolv_interface *resolv, struct resolv_interface *dest ) {
-       intf_plug ( &resolv->intf, &dest->intf );
-}
-
-/**
- * Plug two name resolution interfaces together
- *
- * @v a                        Name resolution interface A
- * @v b                        Name resolution interface B
- */
-static inline __attribute__ (( always_inline )) void
-resolv_plug_plug ( struct resolv_interface *a, struct resolv_interface *b ) {
-       intf_plug_plug ( &a->intf, &b->intf );
-}
-
-/**
- * Unplug a name resolution interface
- *
- * @v resolv           Name resolution interface
- */
-static inline __attribute__ (( always_inline )) void
-resolv_unplug ( struct resolv_interface *resolv ) {
-       intf_plug ( &resolv->intf, &null_resolv.intf );
-}
-
-/**
- * Stop using a name resolution interface
- *
- * @v resolv           Name resolution interface
- *
- * After calling this method, no further messages will be received via
- * the interface.
- */
-static inline void resolv_nullify ( struct resolv_interface *resolv ) {
-       resolv->op = &null_resolv_ops;
-};
+struct sockaddr;
 
 /** A name resolver */
 struct resolver {
@@ -141,7 +25,7 @@ struct resolver {
         * @v sa                Socket address to complete
         * @ret rc              Return status code
         */
-       int ( * resolv ) ( struct resolv_interface *resolv, const char *name,
+       int ( * resolv ) ( struct interface *resolv, const char *name,
                           struct sockaddr *sa );
 };
 
@@ -157,14 +41,11 @@ struct resolver {
 /** Register as a name resolver */
 #define __resolver( resolv_order ) __table_entry ( RESOLVERS, resolv_order )
 
-extern void resolv_done ( struct resolv_interface *resolv,
-                         struct sockaddr *sa, int rc );
-extern void ignore_resolv_done ( struct resolv_interface *resolv,
-                         struct sockaddr *sa, int rc );
-extern struct resolv_interface_operations null_resolv_ops;
-extern struct resolv_interface null_resolv;
+extern void resolv_done ( struct interface *intf, struct sockaddr *sa );
+#define resolv_done_TYPE( object_type ) \
+       typeof ( void ( object_type, struct sockaddr *sa ) )
 
-extern int resolv ( struct resolv_interface *resolv, const char *name,
+extern int resolv ( struct interface *resolv, const char *name,
                    struct sockaddr *sa );
 
 #endif /* _IPXE_RESOLV_H */
index 35ead0c7431e9210247a94b9da4dda64b478e776..fd1ea0a28e03f6ee15023e8f28477abb364e17d9 100644 (file)
@@ -58,7 +58,7 @@ struct dns_request {
        /** Reference counter */
        struct refcnt refcnt;
        /** Name resolution interface */
-       struct resolv_interface resolv;
+       struct interface resolv;
        /** Data transfer interface */
        struct xfer_interface socket;
        /** Retry timer */
@@ -93,8 +93,8 @@ static void dns_done ( struct dns_request *dns, int rc ) {
        xfer_nullify ( &dns->socket );
        xfer_close ( &dns->socket, rc );
 
-       /* Mark name resolution as complete */
-       resolv_done ( &dns->resolv, &dns->sa, rc );
+       /* Shut down interfaces */
+       intf_shutdown ( &dns->resolv, rc );
 }
 
 /**
@@ -377,6 +377,9 @@ static int dns_xfer_deliver_raw ( struct xfer_interface *socket,
                        sin->sin_family = AF_INET;
                        sin->sin_addr = rr_info->a.in_addr;
 
+                       /* Return resolved address */
+                       resolv_done ( &dns->resolv, &dns->sa );
+
                        /* Mark operation as complete */
                        dns_done ( dns, 0 );
                        return 0;
@@ -468,6 +471,15 @@ static struct xfer_interface_operations dns_socket_operations = {
        .deliver_raw    = dns_xfer_deliver_raw,
 };
 
+/** DNS resolver interface operations */
+static struct interface_operation dns_resolv_op[] = {
+       INTF_OP ( intf_close, struct dns_request *, dns_done ),
+};
+
+/** DNS resolver interface descriptor */
+static struct interface_descriptor dns_resolv_desc =
+       INTF_DESC ( struct dns_request, resolv, dns_resolv_op );
+
 /**
  * Resolve name using DNS
  *
@@ -476,7 +488,7 @@ static struct xfer_interface_operations dns_socket_operations = {
  * @v sa               Socket address to fill in
  * @ret rc             Return status code
  */
-static int dns_resolv ( struct resolv_interface *resolv,
+static int dns_resolv ( struct interface *resolv,
                        const char *name, struct sockaddr *sa ) {
        struct dns_request *dns;
        char *fqdn;
@@ -504,7 +516,7 @@ static int dns_resolv ( struct resolv_interface *resolv,
                goto err_alloc_dns;
        }
        ref_init ( &dns->refcnt, NULL );
-       resolv_init ( &dns->resolv, &null_resolv_ops, &dns->refcnt );
+       intf_init ( &dns->resolv, &dns_resolv_desc, &dns->refcnt );
        xfer_init ( &dns->socket, &dns_socket_operations, &dns->refcnt );
        timer_init ( &dns->timer, dns_timer_expired );
        memcpy ( &dns->sa, sa, sizeof ( dns->sa ) );
@@ -530,7 +542,7 @@ static int dns_resolv ( struct resolv_interface *resolv,
        dns_send_packet ( dns );
 
        /* Attach parent interface, mortalise self, and return */
-       resolv_plug_plug ( &dns->resolv, resolv );
+       intf_plug_plug ( &dns->resolv, resolv );
        ref_put ( &dns->refcnt );
        free ( fqdn );
        return 0;