diff options
Diffstat (limited to 'src/net')
| -rw-r--r-- | src/net/infiniband/ib_cmrc.c | 58 | ||||
| -rw-r--r-- | src/net/tcp.c | 52 | ||||
| -rw-r--r-- | src/net/tcp/ftp.c | 144 | ||||
| -rw-r--r-- | src/net/tcp/http.c | 95 | ||||
| -rw-r--r-- | src/net/tcp/https.c | 2 | ||||
| -rw-r--r-- | src/net/tcp/iscsi.c | 75 | ||||
| -rw-r--r-- | src/net/tls.c | 164 | ||||
| -rw-r--r-- | src/net/udp.c | 68 | ||||
| -rw-r--r-- | src/net/udp/dhcp.c | 37 | ||||
| -rw-r--r-- | src/net/udp/dns.c | 81 | ||||
| -rw-r--r-- | src/net/udp/slam.c | 134 | ||||
| -rw-r--r-- | src/net/udp/tftp.c | 134 |
12 files changed, 408 insertions, 636 deletions
diff --git a/src/net/infiniband/ib_cmrc.c b/src/net/infiniband/ib_cmrc.c index b7b9cd819..f596c36dc 100644 --- a/src/net/infiniband/ib_cmrc.c +++ b/src/net/infiniband/ib_cmrc.c @@ -70,7 +70,7 @@ struct ib_cmrc_connection { /** Reference count */ struct refcnt refcnt; /** Data transfer interface */ - struct xfer_interface xfer; + struct interface xfer; /** Infiniband device */ struct ib_device *ibdev; /** Completion queue */ @@ -135,8 +135,7 @@ static void ib_cmrc_shutdown ( struct process *process ) { static void ib_cmrc_close ( struct ib_cmrc_connection *cmrc, int rc ) { /* Close data transfer interface */ - xfer_nullify ( &cmrc->xfer ); - xfer_close ( &cmrc->xfer, rc ); + intf_shutdown ( &cmrc->xfer, rc ); /* Schedule shutdown process */ process_add ( &cmrc->shutdown ); @@ -263,16 +262,14 @@ static struct ib_completion_queue_operations ib_cmrc_completion_ops = { /** * Send data via CMRC * - * @v xfer Data transfer interface + * @v cmrc CMRC connection * @v iobuf Datagram I/O buffer * @v meta Data transfer metadata * @ret rc Return status code */ -static int ib_cmrc_xfer_deliver_iob ( struct xfer_interface *xfer, - struct io_buffer *iobuf, - struct xfer_metadata *meta __unused ) { - struct ib_cmrc_connection *cmrc = - container_of ( xfer, struct ib_cmrc_connection, xfer ); +static int ib_cmrc_xfer_deliver ( struct ib_cmrc_connection *cmrc, + struct io_buffer *iobuf, + struct xfer_metadata *meta __unused ) { int rc; /* If no connection has yet been attempted, send this datagram @@ -326,12 +323,10 @@ static int ib_cmrc_xfer_deliver_iob ( struct xfer_interface *xfer, /** * Check CMRC flow control window * - * @v xfer Data transfer interface + * @v cmrc CMRC connection * @ret len Length of window */ -static size_t ib_cmrc_xfer_window ( struct xfer_interface *xfer ) { - struct ib_cmrc_connection *cmrc = - container_of ( xfer, struct ib_cmrc_connection, xfer ); +static size_t ib_cmrc_xfer_window ( struct ib_cmrc_connection *cmrc ) { /* We indicate a window only when we are successfully * connected. @@ -339,30 +334,19 @@ static size_t ib_cmrc_xfer_window ( struct xfer_interface *xfer ) { return ( cmrc->connected ? IB_MAX_PAYLOAD_SIZE : 0 ); } -/** - * Close CMRC data-transfer interface - * - * @v xfer Data transfer interface - * @v rc Reason for close - */ -static void ib_cmrc_xfer_close ( struct xfer_interface *xfer, int rc ) { - struct ib_cmrc_connection *cmrc = - container_of ( xfer, struct ib_cmrc_connection, xfer ); - - DBGC ( cmrc, "CMRC %p closed: %s\n", cmrc, strerror ( rc ) ); - ib_cmrc_close ( cmrc, rc ); -} - /** CMRC data transfer interface operations */ -static struct xfer_interface_operations ib_cmrc_xfer_operations = { - .close = ib_cmrc_xfer_close, - .vredirect = ignore_xfer_vredirect, - .window = ib_cmrc_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = ib_cmrc_xfer_deliver_iob, - .deliver_raw = xfer_deliver_as_iob, +static struct interface_operation ib_cmrc_xfer_operations[] = { + INTF_OP ( xfer_deliver, struct ib_cmrc_connection *, + ib_cmrc_xfer_deliver ), + INTF_OP ( xfer_window, struct ib_cmrc_connection *, + ib_cmrc_xfer_window ), + INTF_OP ( intf_close, struct ib_cmrc_connection *, ib_cmrc_close ), }; +/** CMRC data transfer interface descriptor */ +static struct interface_descriptor ib_cmrc_xfer_desc = + INTF_DESC ( struct ib_cmrc_connection, xfer, ib_cmrc_xfer_operations ); + /** * Open CMRC connection * @@ -372,7 +356,7 @@ static struct xfer_interface_operations ib_cmrc_xfer_operations = { * @v service_id Service ID * @ret rc Returns status code */ -int ib_cmrc_open ( struct xfer_interface *xfer, struct ib_device *ibdev, +int ib_cmrc_open ( struct interface *xfer, struct ib_device *ibdev, struct ib_gid *dgid, struct ib_gid_half *service_id ) { struct ib_cmrc_connection *cmrc; int rc; @@ -384,7 +368,7 @@ int ib_cmrc_open ( struct xfer_interface *xfer, struct ib_device *ibdev, goto err_alloc; } ref_init ( &cmrc->refcnt, NULL ); - xfer_init ( &cmrc->xfer, &ib_cmrc_xfer_operations, &cmrc->refcnt ); + intf_init ( &cmrc->xfer, &ib_cmrc_xfer_desc, &cmrc->refcnt ); cmrc->ibdev = ibdev; memcpy ( &cmrc->dgid, dgid, sizeof ( cmrc->dgid ) ); memcpy ( &cmrc->service_id, service_id, sizeof ( cmrc->service_id ) ); @@ -422,7 +406,7 @@ int ib_cmrc_open ( struct xfer_interface *xfer, struct ib_device *ibdev, /* Attach to parent interface, transfer reference (implicitly) * to our shutdown process, and return. */ - xfer_plug_plug ( &cmrc->xfer, xfer ); + intf_plug_plug ( &cmrc->xfer, xfer ); return 0; ib_destroy_qp ( ibdev, cmrc->qp ); diff --git a/src/net/tcp.c b/src/net/tcp.c index b5b9ff608..d64153f3e 100644 --- a/src/net/tcp.c +++ b/src/net/tcp.c @@ -31,7 +31,7 @@ struct tcp_connection { struct list_head list; /** Data transfer interface */ - struct xfer_interface xfer; + struct interface xfer; /** Data transfer interface closed flag */ int xfer_closed; @@ -92,7 +92,7 @@ struct tcp_connection { static LIST_HEAD ( tcp_conns ); /* Forward declarations */ -static struct xfer_interface_operations tcp_xfer_operations; +static struct interface_descriptor tcp_xfer_desc; static void tcp_expired ( struct retry_timer *timer, int over ); static int tcp_rx_ack ( struct tcp_connection *tcp, uint32_t ack, uint32_t win ); @@ -211,7 +211,7 @@ static int tcp_bind ( struct tcp_connection *tcp, unsigned int port ) { * @v local Local socket address, or NULL * @ret rc Return status code */ -static int tcp_open ( struct xfer_interface *xfer, struct sockaddr *peer, +static int tcp_open ( struct interface *xfer, struct sockaddr *peer, struct sockaddr *local ) { struct sockaddr_tcpip *st_peer = ( struct sockaddr_tcpip * ) peer; struct sockaddr_tcpip *st_local = ( struct sockaddr_tcpip * ) local; @@ -225,7 +225,7 @@ static int tcp_open ( struct xfer_interface *xfer, struct sockaddr *peer, return -ENOMEM; DBGC ( tcp, "TCP %p allocated\n", tcp ); ref_init ( &tcp->refcnt, NULL ); - xfer_init ( &tcp->xfer, &tcp_xfer_operations, &tcp->refcnt ); + intf_init ( &tcp->xfer, &tcp_xfer_desc, &tcp->refcnt ); timer_init ( &tcp->timer, tcp_expired ); tcp->prev_tcp_state = TCP_CLOSED; tcp->tcp_state = TCP_STATE_SENT ( TCP_SYN ); @@ -245,7 +245,7 @@ static int tcp_open ( struct xfer_interface *xfer, struct sockaddr *peer, /* Attach parent interface, transfer reference to connection * list and return */ - xfer_plug_plug ( &tcp->xfer, xfer ); + intf_plug_plug ( &tcp->xfer, xfer ); list_add ( &tcp->list, &tcp_conns ); return 0; @@ -268,8 +268,7 @@ static void tcp_close ( struct tcp_connection *tcp, int rc ) { struct io_buffer *tmp; /* Close data transfer interface */ - xfer_nullify ( &tcp->xfer ); - xfer_close ( &tcp->xfer, rc ); + intf_shutdown ( &tcp->xfer, rc ); tcp->xfer_closed = 1; /* If we are in CLOSED, or have otherwise not yet received a @@ -1044,12 +1043,10 @@ struct tcpip_protocol tcp_protocol __tcpip_protocol = { /** * Close interface * - * @v xfer Data transfer interface + * @v tcp TCP connection * @v rc Reason for close */ -static void tcp_xfer_close ( struct xfer_interface *xfer, int rc ) { - struct tcp_connection *tcp = - container_of ( xfer, struct tcp_connection, xfer ); +static void tcp_xfer_close ( struct tcp_connection *tcp, int rc ) { /* Close data transfer interface */ tcp_close ( tcp, rc ); @@ -1061,12 +1058,10 @@ static void tcp_xfer_close ( struct xfer_interface *xfer, int rc ) { /** * Check flow control window * - * @v xfer Data transfer interface + * @v tcp TCP connection * @ret len Length of window */ -static size_t tcp_xfer_window ( struct xfer_interface *xfer ) { - struct tcp_connection *tcp = - container_of ( xfer, struct tcp_connection, xfer ); +static size_t tcp_xfer_window ( struct tcp_connection *tcp ) { /* Not ready if data queue is non-empty. This imposes a limit * of only one unACKed packet in the TX queue at any time; we @@ -1082,16 +1077,14 @@ static size_t tcp_xfer_window ( struct xfer_interface *xfer ) { /** * Deliver datagram as I/O buffer * - * @v xfer Data transfer interface + * @v tcp TCP connection * @v iobuf Datagram I/O buffer * @v meta Data transfer metadata * @ret rc Return status code */ -static int tcp_xfer_deliver_iob ( struct xfer_interface *xfer, - struct io_buffer *iobuf, - struct xfer_metadata *meta __unused ) { - struct tcp_connection *tcp = - container_of ( xfer, struct tcp_connection, xfer ); +static int tcp_xfer_deliver ( struct tcp_connection *tcp, + struct io_buffer *iobuf, + struct xfer_metadata *meta __unused ) { /* Enqueue packet */ list_add_tail ( &iobuf->list, &tcp->queue ); @@ -1103,15 +1096,16 @@ static int tcp_xfer_deliver_iob ( struct xfer_interface *xfer, } /** TCP data transfer interface operations */ -static struct xfer_interface_operations tcp_xfer_operations = { - .close = tcp_xfer_close, - .vredirect = ignore_xfer_vredirect, - .window = tcp_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = tcp_xfer_deliver_iob, - .deliver_raw = xfer_deliver_as_iob, +static struct interface_operation tcp_xfer_operations[] = { + INTF_OP ( xfer_deliver, struct tcp_connection *, tcp_xfer_deliver ), + INTF_OP ( xfer_window, struct tcp_connection *, tcp_xfer_window ), + INTF_OP ( intf_close, struct tcp_connection *, tcp_xfer_close ), }; +/** TCP data transfer interface descriptor */ +static struct interface_descriptor tcp_xfer_desc = + INTF_DESC ( struct tcp_connection, xfer, tcp_xfer_operations ); + /*************************************************************************** * * Openers @@ -1136,7 +1130,7 @@ int tcp_sock_stream = TCP_SOCK_STREAM; * @v uri URI * @ret rc Return status code */ -static int tcp_open_uri ( struct xfer_interface *xfer, struct uri *uri ) { +static int tcp_open_uri ( struct interface *xfer, struct uri *uri ) { struct sockaddr_tcpip peer; /* Sanity check */ diff --git a/src/net/tcp/ftp.c b/src/net/tcp/ftp.c index 58794c8b2..957f05cc8 100644 --- a/src/net/tcp/ftp.c +++ b/src/net/tcp/ftp.c @@ -8,6 +8,7 @@ #include <ipxe/socket.h> #include <ipxe/tcpip.h> #include <ipxe/in.h> +#include <ipxe/iobuf.h> #include <ipxe/xfer.h> #include <ipxe/open.h> #include <ipxe/uri.h> @@ -48,14 +49,14 @@ struct ftp_request { /** Reference counter */ struct refcnt refcnt; /** Data transfer interface */ - struct xfer_interface xfer; + struct interface xfer; /** URI being fetched */ struct uri *uri; /** FTP control channel interface */ - struct xfer_interface control; + struct interface control; /** FTP data channel interface */ - struct xfer_interface data; + struct interface data; /** Current state */ enum ftp_state state; @@ -95,12 +96,9 @@ static void ftp_done ( struct ftp_request *ftp, int rc ) { DBGC ( ftp, "FTP %p completed (%s)\n", ftp, strerror ( rc ) ); /* Close all data transfer interfaces */ - xfer_nullify ( &ftp->xfer ); - xfer_close ( &ftp->xfer, rc ); - xfer_nullify ( &ftp->control ); - xfer_close ( &ftp->control, rc ); - xfer_nullify ( &ftp->data ); - xfer_close ( &ftp->data, rc ); + intf_shutdown ( &ftp->data, rc ); + intf_shutdown ( &ftp->control, rc ); + intf_shutdown ( &ftp->xfer, rc ); } /***************************************************************************** @@ -167,26 +165,6 @@ static struct ftp_control_string ftp_strings[] = { }; /** - * Handle control channel being closed - * - * @v control FTP control channel interface - * @v rc Reason for close - * - * When the control channel is closed, the data channel must also be - * closed, if it is currently open. - */ -static void ftp_control_close ( struct xfer_interface *control, int rc ) { - struct ftp_request *ftp = - container_of ( control, struct ftp_request, control ); - - DBGC ( ftp, "FTP %p control connection closed: %s\n", - ftp, strerror ( rc ) ); - - /* Complete FTP operation */ - ftp_done ( ftp, rc ); -} - -/** * Parse FTP byte sequence value * * @v text Text string @@ -298,23 +276,25 @@ static void ftp_reply ( struct ftp_request *ftp ) { /** * Handle new data arriving on FTP control channel * - * @v control FTP control channel interface - * @v data New data - * @v len Length of new data + * @v ftp FTP request + * @v iob I/O buffer + * @v meta Data transfer metadata + * @ret rc Return status code * * Data is collected until a complete line is received, at which point * its information is passed to ftp_reply(). */ -static int ftp_control_deliver_raw ( struct xfer_interface *control, - const void *data, size_t len ) { - struct ftp_request *ftp = - container_of ( control, struct ftp_request, control ); +static int ftp_control_deliver ( struct ftp_request *ftp, + struct io_buffer *iobuf, + struct xfer_metadata *meta __unused ) { + char *data = iobuf->data; + size_t len = iob_len ( iobuf ); char *recvbuf = ftp->recvbuf; size_t recvsize = ftp->recvsize; char c; while ( len-- ) { - c = * ( ( char * ) data++ ); + c = *(data++); switch ( c ) { case '\r' : case '\n' : @@ -351,19 +331,22 @@ static int ftp_control_deliver_raw ( struct xfer_interface *control, ftp->recvbuf = recvbuf; ftp->recvsize = recvsize; + /* Free I/O buffer */ + free_iob ( iobuf ); + return 0; } -/** FTP control channel operations */ -static struct xfer_interface_operations ftp_control_operations = { - .close = ftp_control_close, - .vredirect = xfer_vreopen, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = xfer_deliver_as_raw, - .deliver_raw = ftp_control_deliver_raw, +/** FTP control channel interface operations */ +static struct interface_operation ftp_control_operations[] = { + INTF_OP ( xfer_deliver, struct ftp_request *, ftp_control_deliver ), + INTF_OP ( intf_close, struct ftp_request *, ftp_done ), }; +/** FTP control channel interface descriptor */ +static struct interface_descriptor ftp_control_desc = + INTF_DESC ( struct ftp_request, control, ftp_control_operations ); + /***************************************************************************** * * FTP data channel @@ -373,7 +356,7 @@ static struct xfer_interface_operations ftp_control_operations = { /** * Handle FTP data channel being closed * - * @v data FTP data channel interface + * @v ftp FTP request * @v rc Reason for closure * * When the data channel is closed, the control channel should be left @@ -382,9 +365,7 @@ static struct xfer_interface_operations ftp_control_operations = { * * If the data channel is closed due to an error, we abort the request. */ -static void ftp_data_closed ( struct xfer_interface *data, int rc ) { - struct ftp_request *ftp = - container_of ( data, struct ftp_request, data ); +static void ftp_data_closed ( struct ftp_request *ftp, int rc ) { DBGC ( ftp, "FTP %p data connection closed: %s\n", ftp, strerror ( rc ) ); @@ -400,16 +381,14 @@ static void ftp_data_closed ( struct xfer_interface *data, int rc ) { /** * Handle data delivery via FTP data channel * - * @v xfer FTP data channel interface + * @v ftp FTP request * @v iobuf I/O buffer * @v meta Data transfer metadata * @ret rc Return status code */ -static int ftp_data_deliver_iob ( struct xfer_interface *data, - struct io_buffer *iobuf, - struct xfer_metadata *meta __unused ) { - struct ftp_request *ftp = - container_of ( data, struct ftp_request, data ); +static int ftp_data_deliver ( struct ftp_request *ftp, + struct io_buffer *iobuf, + struct xfer_metadata *meta __unused ) { int rc; if ( ( rc = xfer_deliver_iob ( &ftp->xfer, iobuf ) ) != 0 ) { @@ -421,48 +400,31 @@ static int ftp_data_deliver_iob ( struct xfer_interface *data, return 0; } -/** FTP data channel operations */ -static struct xfer_interface_operations ftp_data_operations = { - .close = ftp_data_closed, - .vredirect = xfer_vreopen, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = ftp_data_deliver_iob, - .deliver_raw = xfer_deliver_as_iob, +/** FTP data channel interface operations */ +static struct interface_operation ftp_data_operations[] = { + INTF_OP ( xfer_deliver, struct ftp_request *, ftp_data_deliver ), + INTF_OP ( intf_close, struct ftp_request *, ftp_data_closed ), }; +/** FTP data channel interface descriptor */ +static struct interface_descriptor ftp_data_desc = + INTF_DESC ( struct ftp_request, data, ftp_data_operations ); + /***************************************************************************** * * Data transfer interface * */ -/** - * Close FTP data transfer interface - * - * @v xfer FTP data transfer interface - * @v rc Reason for close - */ -static void ftp_xfer_closed ( struct xfer_interface *xfer, int rc ) { - struct ftp_request *ftp = - container_of ( xfer, struct ftp_request, xfer ); - - DBGC ( ftp, "FTP %p data transfer interface closed: %s\n", - ftp, strerror ( rc ) ); - - ftp_done ( ftp, rc ); -} - /** FTP data transfer interface operations */ -static struct xfer_interface_operations ftp_xfer_operations = { - .close = ftp_xfer_closed, - .vredirect = ignore_xfer_vredirect, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = xfer_deliver_as_raw, - .deliver_raw = ignore_xfer_deliver_raw, +static struct interface_operation ftp_xfer_operations[] = { + INTF_OP ( intf_close, struct ftp_request *, ftp_done ), }; +/** FTP data transfer interface descriptor */ +static struct interface_descriptor ftp_xfer_desc = + INTF_DESC ( struct ftp_request, xfer, ftp_xfer_operations ); + /***************************************************************************** * * URI opener @@ -476,7 +438,7 @@ static struct xfer_interface_operations ftp_xfer_operations = { * @v uri Uniform Resource Identifier * @ret rc Return status code */ -static int ftp_open ( struct xfer_interface *xfer, struct uri *uri ) { +static int ftp_open ( struct interface *xfer, struct uri *uri ) { struct ftp_request *ftp; struct sockaddr_tcpip server; int rc; @@ -492,10 +454,10 @@ static int ftp_open ( struct xfer_interface *xfer, struct uri *uri ) { if ( ! ftp ) return -ENOMEM; ref_init ( &ftp->refcnt, ftp_free ); - xfer_init ( &ftp->xfer, &ftp_xfer_operations, &ftp->refcnt ); + intf_init ( &ftp->xfer, &ftp_xfer_desc, &ftp->refcnt ); + intf_init ( &ftp->control, &ftp_control_desc, &ftp->refcnt ); + intf_init ( &ftp->data, &ftp_data_desc, &ftp->refcnt ); ftp->uri = uri_get ( uri ); - xfer_init ( &ftp->control, &ftp_control_operations, &ftp->refcnt ); - xfer_init ( &ftp->data, &ftp_data_operations, &ftp->refcnt ); ftp->recvbuf = ftp->status_text; ftp->recvsize = sizeof ( ftp->status_text ) - 1; @@ -510,7 +472,7 @@ static int ftp_open ( struct xfer_interface *xfer, struct uri *uri ) { goto err; /* Attach to parent interface, mortalise self, and return */ - xfer_plug_plug ( &ftp->xfer, xfer ); + intf_plug_plug ( &ftp->xfer, xfer ); ref_put ( &ftp->refcnt ); return 0; diff --git a/src/net/tcp/http.c b/src/net/tcp/http.c index d6a9fad7e..13c500d50 100644 --- a/src/net/tcp/http.c +++ b/src/net/tcp/http.c @@ -64,12 +64,12 @@ struct http_request { /** Reference count */ struct refcnt refcnt; /** Data transfer interface */ - struct xfer_interface xfer; + struct interface xfer; /** URI being fetched */ struct uri *uri; /** Transport layer interface */ - struct xfer_interface socket; + struct interface socket; /** TX process */ struct process process; @@ -125,10 +125,8 @@ static void http_done ( struct http_request *http, int rc ) { process_del ( &http->process ); /* Close all data transfer interfaces */ - xfer_nullify ( &http->socket ); - xfer_close ( &http->socket, rc ); - xfer_nullify ( &http->xfer ); - xfer_close ( &http->xfer, rc ); + intf_shutdown ( &http->socket, rc ); + intf_shutdown ( &http->xfer, rc ); } /** @@ -349,16 +347,14 @@ static int http_rx_data ( struct http_request *http, /** * Handle new data arriving via HTTP connection * - * @v socket Transport layer interface + * @v http HTTP request * @v iobuf I/O buffer * @v meta Data transfer metadata * @ret rc Return status code */ -static int http_socket_deliver_iob ( struct xfer_interface *socket, - struct io_buffer *iobuf, - struct xfer_metadata *meta __unused ) { - struct http_request *http = - container_of ( socket, struct http_request, socket ); +static int http_socket_deliver ( struct http_request *http, + struct io_buffer *iobuf, + struct xfer_metadata *meta __unused ) { struct http_line_handler *lh; char *line; ssize_t len; @@ -469,58 +465,25 @@ static void http_step ( struct process *process ) { } } -/** - * HTTP connection closed by network stack - * - * @v socket Transport layer interface - * @v rc Reason for close - */ -static void http_socket_close ( struct xfer_interface *socket, int rc ) { - struct http_request *http = - container_of ( socket, struct http_request, socket ); - - DBGC ( http, "HTTP %p socket closed: %s\n", - http, strerror ( rc ) ); - - http_done ( http, rc ); -} - -/** HTTP socket operations */ -static struct xfer_interface_operations http_socket_operations = { - .close = http_socket_close, - .vredirect = xfer_vreopen, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = http_socket_deliver_iob, - .deliver_raw = xfer_deliver_as_iob, +/** HTTP socket interface operations */ +static struct interface_operation http_socket_operations[] = { + INTF_OP ( xfer_deliver, struct http_request *, http_socket_deliver ), + INTF_OP ( intf_close, struct http_request *, http_done ), }; -/** - * Close HTTP data transfer interface - * - * @v xfer Data transfer interface - * @v rc Reason for close - */ -static void http_xfer_close ( struct xfer_interface *xfer, int rc ) { - struct http_request *http = - container_of ( xfer, struct http_request, xfer ); - - DBGC ( http, "HTTP %p interface closed: %s\n", - http, strerror ( rc ) ); - - http_done ( http, rc ); -} +/** HTTP socket interface descriptor */ +static struct interface_descriptor http_socket_desc = + INTF_DESC ( struct http_request, socket, http_socket_operations ); /** HTTP data transfer interface operations */ -static struct xfer_interface_operations http_xfer_operations = { - .close = http_xfer_close, - .vredirect = ignore_xfer_vredirect, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = xfer_deliver_as_raw, - .deliver_raw = ignore_xfer_deliver_raw, +static struct interface_operation http_xfer_operations[] = { + INTF_OP ( intf_close, struct http_request *, http_done ), }; +/** HTTP data transfer interface descriptor */ +static struct interface_descriptor http_xfer_desc = + INTF_DESC ( struct http_request, xfer, http_xfer_operations ); + /** * Initiate an HTTP connection, with optional filter * @@ -530,13 +493,13 @@ static struct xfer_interface_operations http_xfer_operations = { * @v filter Filter to apply to socket, or NULL * @ret rc Return status code */ -int http_open_filter ( struct xfer_interface *xfer, struct uri *uri, +int http_open_filter ( struct interface *xfer, struct uri *uri, unsigned int default_port, - int ( * filter ) ( struct xfer_interface *xfer, - struct xfer_interface **next ) ) { + int ( * filter ) ( struct interface *xfer, + struct interface **next ) ) { struct http_request *http; struct sockaddr_tcpip server; - struct xfer_interface *socket; + struct interface *socket; int rc; /* Sanity checks */ @@ -548,9 +511,9 @@ int http_open_filter ( struct xfer_interface *xfer, struct uri *uri, if ( ! http ) return -ENOMEM; ref_init ( &http->refcnt, http_free ); - xfer_init ( &http->xfer, &http_xfer_operations, &http->refcnt ); + intf_init ( &http->xfer, &http_xfer_desc, &http->refcnt ); http->uri = uri_get ( uri ); - xfer_init ( &http->socket, &http_socket_operations, &http->refcnt ); + intf_init ( &http->socket, &http_socket_desc, &http->refcnt ); process_init ( &http->process, http_step, &http->refcnt ); /* Open socket */ @@ -567,7 +530,7 @@ int http_open_filter ( struct xfer_interface *xfer, struct uri *uri, goto err; /* Attach to parent interface, mortalise self, and return */ - xfer_plug_plug ( &http->xfer, xfer ); + intf_plug_plug ( &http->xfer, xfer ); ref_put ( &http->refcnt ); return 0; @@ -586,7 +549,7 @@ int http_open_filter ( struct xfer_interface *xfer, struct uri *uri, * @v uri Uniform Resource Identifier * @ret rc Return status code */ -static int http_open ( struct xfer_interface *xfer, struct uri *uri ) { +static int http_open ( struct interface *xfer, struct uri *uri ) { return http_open_filter ( xfer, uri, HTTP_PORT, NULL ); } diff --git a/src/net/tcp/https.c b/src/net/tcp/https.c index b738f4167..805d108bb 100644 --- a/src/net/tcp/https.c +++ b/src/net/tcp/https.c @@ -40,7 +40,7 @@ FEATURE ( FEATURE_PROTOCOL, "HTTPS", DHCP_EB_FEATURE_HTTPS, 1 ); * @v uri Uniform Resource Identifier * @ret rc Return status code */ -static int https_open ( struct xfer_interface *xfer, struct uri *uri ) { +static int https_open ( struct interface *xfer, struct uri *uri ) { return http_open_filter ( xfer, uri, HTTPS_PORT, add_tls ); } diff --git a/src/net/tcp/iscsi.c b/src/net/tcp/iscsi.c index 24cbda2c5..80c63a6b1 100644 --- a/src/net/tcp/iscsi.c +++ b/src/net/tcp/iscsi.c @@ -27,6 +27,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include <byteswap.h> #include <ipxe/vsprintf.h> #include <ipxe/socket.h> +#include <ipxe/iobuf.h> #include <ipxe/xfer.h> #include <ipxe/open.h> #include <ipxe/scsi.h> @@ -199,7 +200,7 @@ static int iscsi_open_connection ( struct iscsi_session *iscsi ) { static void iscsi_close_connection ( struct iscsi_session *iscsi, int rc ) { /* Close all data transfer interfaces */ - xfer_close ( &iscsi->socket, rc ); + intf_restart ( &iscsi->socket, rc ); /* Clear connection status */ iscsi->status = 0; @@ -1435,9 +1436,9 @@ static int iscsi_rx_data ( struct iscsi_session *iscsi, const void *data, /** * Receive new data * - * @v socket Transport layer interface - * @v data Received data - * @v len Length of received data + * @v iscsi iSCSI session + * @v iobuf I/O buffer + * @v meta Data transfer metadata * @ret rc Return status code * * This handles received PDUs. The receive strategy is to fill in @@ -1447,10 +1448,9 @@ static int iscsi_rx_data ( struct iscsi_session *iscsi, const void *data, * always has a full copy of the BHS available, even for portions of * the data in different packets to the BHS. */ -static int iscsi_socket_deliver_raw ( struct xfer_interface *socket, - const void *data, size_t len ) { - struct iscsi_session *iscsi = - container_of ( socket, struct iscsi_session, socket ); +static int iscsi_socket_deliver ( struct iscsi_session *iscsi, + struct io_buffer *iobuf, + struct xfer_metadata *meta __unused ) { struct iscsi_bhs_common *common = &iscsi->rx_bhs.common; int ( * rx ) ( struct iscsi_session *iscsi, const void *data, size_t len, size_t remaining ); @@ -1483,48 +1483,52 @@ static int iscsi_socket_deliver_raw ( struct xfer_interface *socket, break; default: assert ( 0 ); - return -EINVAL; + rc = -EINVAL; + goto done; } frag_len = iscsi->rx_len - iscsi->rx_offset; - if ( frag_len > len ) - frag_len = len; + if ( frag_len > iob_len ( iobuf ) ) + frag_len = iob_len ( iobuf ); remaining = iscsi->rx_len - iscsi->rx_offset - frag_len; - if ( ( rc = rx ( iscsi, data, frag_len, remaining ) ) != 0 ) { + if ( ( rc = rx ( iscsi, iobuf->data, frag_len, + remaining ) ) != 0 ) { DBGC ( iscsi, "iSCSI %p could not process received " "data: %s\n", iscsi, strerror ( rc ) ); iscsi_close_connection ( iscsi, rc ); iscsi_scsi_done ( iscsi, rc ); - return rc; + goto done; } iscsi->rx_offset += frag_len; - data += frag_len; - len -= frag_len; + iob_pull ( iobuf, frag_len ); /* If all the data for this state has not yet been * received, stay in this state for now. */ - if ( iscsi->rx_offset != iscsi->rx_len ) - return 0; + if ( iscsi->rx_offset != iscsi->rx_len ) { + rc = 0; + goto done; + } iscsi->rx_state = next_state; iscsi->rx_offset = 0; } - return 0; + done: + /* Free I/O buffer */ + free_iob ( iobuf ); + return rc; } /** * Handle stream connection closure * - * @v socket Transport layer interface + * @v iscsi iSCSI session * @v rc Reason for close * */ -static void iscsi_socket_close ( struct xfer_interface *socket, int rc ) { - struct iscsi_session *iscsi = - container_of ( socket, struct iscsi_session, socket ); +static void iscsi_socket_close ( struct iscsi_session *iscsi, int rc ) { /* Even a graceful close counts as an error for iSCSI */ if ( ! rc ) @@ -1552,15 +1556,13 @@ static void iscsi_socket_close ( struct xfer_interface *socket, int rc ) { /** * Handle redirection event * - * @v socket Transport layer interface + * @v iscsi iSCSI session * @v type Location type * @v args Remaining arguments depend upon location type * @ret rc Return status code */ -static int iscsi_vredirect ( struct xfer_interface *socket, int type, +static int iscsi_vredirect ( struct iscsi_session *iscsi, int type, va_list args ) { - struct iscsi_session *iscsi = - container_of ( socket, struct iscsi_session, socket ); va_list tmp; struct sockaddr *peer; @@ -1578,20 +1580,20 @@ static int iscsi_vredirect ( struct xfer_interface *socket, int type, va_end ( tmp ); } - return xfer_vreopen ( socket, type, args ); + return xfer_vreopen ( &iscsi->socket, type, args ); } -/** iSCSI socket operations */ -static struct xfer_interface_operations iscsi_socket_operations = { - .close = iscsi_socket_close, - .vredirect = iscsi_vredirect, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = xfer_deliver_as_raw, - .deliver_raw = iscsi_socket_deliver_raw, +/** iSCSI socket interface operations */ +static struct interface_operation iscsi_socket_operations[] = { + INTF_OP ( xfer_deliver, struct iscsi_session *, iscsi_socket_deliver ), + INTF_OP ( xfer_vredirect, struct iscsi_session *, iscsi_vredirect ), + INTF_OP ( intf_close, struct iscsi_session *, iscsi_socket_close ), }; +/** iSCSI socket interface descriptor */ +static struct interface_descriptor iscsi_socket_desc = + INTF_DESC ( struct iscsi_session, socket, iscsi_socket_operations ); /**************************************************************************** * @@ -1641,7 +1643,6 @@ void iscsi_detach ( struct scsi_device *scsi ) { struct iscsi_session *iscsi = container_of ( scsi->backend, struct iscsi_session, refcnt ); - xfer_nullify ( &iscsi->socket ); iscsi_close_connection ( iscsi, 0 ); process_del ( &iscsi->process ); scsi->command = scsi_detached_command; @@ -1793,7 +1794,7 @@ int iscsi_attach ( struct scsi_device *scsi, const char *root_path ) { if ( ! iscsi ) return -ENOMEM; ref_init ( &iscsi->refcnt, iscsi_free ); - xfer_init ( &iscsi->socket, &iscsi_socket_operations, &iscsi->refcnt ); + intf_init ( &iscsi->socket, &iscsi_socket_desc, &iscsi->refcnt ); process_init ( &iscsi->process, iscsi_tx_step, &iscsi->refcnt ); /* Parse root path */ diff --git a/src/net/tls.c b/src/net/tls.c index 8825c5c13..a9d627588 100644 --- a/src/net/tls.c +++ b/src/net/tls.c @@ -35,9 +35,9 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include <ipxe/sha1.h> #include <ipxe/aes.h> #include <ipxe/rsa.h> +#include <ipxe/iobuf.h> #include <ipxe/xfer.h> #include <ipxe/open.h> -#include <ipxe/filter.h> #include <ipxe/asn1.h> #include <ipxe/x509.h> #include <ipxe/tls.h> @@ -107,10 +107,8 @@ static void tls_close ( struct tls_session *tls, int rc ) { process_del ( &tls->process ); /* Close ciphertext and plaintext streams */ - xfer_nullify ( &tls->cipherstream.xfer ); - xfer_close ( &tls->cipherstream.xfer, rc ); - xfer_nullify ( &tls->plainstream.xfer ); - xfer_close ( &tls->plainstream.xfer, rc ); + intf_shutdown ( &tls->cipherstream, rc ); + intf_shutdown ( &tls->plainstream, rc ); } /****************************************************************************** @@ -1030,7 +1028,7 @@ static int tls_new_record ( struct tls_session *tls, case TLS_TYPE_HANDSHAKE: return tls_new_handshake ( tls, data, len ); case TLS_TYPE_DATA: - return xfer_deliver_raw ( &tls->plainstream.xfer, data, len ); + return xfer_deliver_raw ( &tls->plainstream, data, len ); default: /* RFC4346 says that we should just ignore unknown * record types. @@ -1209,8 +1207,7 @@ static int tls_send_plaintext ( struct tls_session *tls, unsigned int type, /* Allocate ciphertext */ ciphertext_len = ( sizeof ( *tlshdr ) + plaintext_len ); - ciphertext = xfer_alloc_iob ( &tls->cipherstream.xfer, - ciphertext_len ); + ciphertext = xfer_alloc_iob ( &tls->cipherstream, ciphertext_len ); if ( ! ciphertext ) { DBGC ( tls, "TLS %p could not allocate %zd bytes for " "ciphertext\n", tls, ciphertext_len ); @@ -1234,9 +1231,8 @@ static int tls_send_plaintext ( struct tls_session *tls, unsigned int type, plaintext = NULL; /* Send ciphertext */ - rc = xfer_deliver_iob ( &tls->cipherstream.xfer, ciphertext ); - ciphertext = NULL; - if ( rc != 0 ) { + if ( ( rc = xfer_deliver_iob ( &tls->cipherstream, + iob_disown ( ciphertext ) ) ) != 0 ) { DBGC ( tls, "TLS %p could not deliver ciphertext: %s\n", tls, strerror ( rc ) ); goto done; @@ -1436,65 +1432,60 @@ static int tls_new_ciphertext ( struct tls_session *tls, */ /** - * Close interface - * - * @v xfer Plainstream data transfer interface - * @v rc Reason for close - */ -static void tls_plainstream_close ( struct xfer_interface *xfer, int rc ) { - struct tls_session *tls = - container_of ( xfer, struct tls_session, plainstream.xfer ); - - tls_close ( tls, rc ); -} - -/** * Check flow control window * - * @v xfer Plainstream data transfer interface + * @v tls TLS session * @ret len Length of window */ -static size_t tls_plainstream_window ( struct xfer_interface *xfer ) { - struct tls_session *tls = - container_of ( xfer, struct tls_session, plainstream.xfer ); +static size_t tls_plainstream_window ( struct tls_session *tls ) { /* Block window unless we are ready to accept data */ if ( tls->tx_state != TLS_TX_DATA ) return 0; - return filter_window ( xfer ); + return xfer_window ( &tls->cipherstream ); } /** * Deliver datagram as raw data * - * @v xfer Plainstream data transfer interface - * @v data Data buffer - * @v len Length of data buffer + * @v tls TLS session + * @v iobuf I/O buffer + * @v meta Data transfer metadata * @ret rc Return status code */ -static int tls_plainstream_deliver_raw ( struct xfer_interface *xfer, - const void *data, size_t len ) { - struct tls_session *tls = - container_of ( xfer, struct tls_session, plainstream.xfer ); +static int tls_plainstream_deliver ( struct tls_session *tls, + struct io_buffer *iobuf, + struct xfer_metadata *meta __unused ) { + int rc; /* Refuse unless we are ready to accept data */ - if ( tls->tx_state != TLS_TX_DATA ) - return -ENOTCONN; + if ( tls->tx_state != TLS_TX_DATA ) { + rc = -ENOTCONN; + goto done; + } + + if ( ( rc = tls_send_plaintext ( tls, TLS_TYPE_DATA, iobuf->data, + iob_len ( iobuf ) ) ) != 0 ) + goto done; - return tls_send_plaintext ( tls, TLS_TYPE_DATA, data, len ); + done: + free_iob ( iobuf ); + return rc; } -/** TLS plaintext stream operations */ -static struct xfer_interface_operations tls_plainstream_operations = { - .close = tls_plainstream_close, - .vredirect = ignore_xfer_vredirect, - .window = tls_plainstream_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = xfer_deliver_as_raw, - .deliver_raw = tls_plainstream_deliver_raw, +/** TLS plaintext stream interface operations */ +static struct interface_operation tls_plainstream_ops[] = { + INTF_OP ( xfer_deliver, struct tls_session *, tls_plainstream_deliver ), + INTF_OP ( xfer_window, struct tls_session *, tls_plainstream_window ), + INTF_OP ( intf_close, struct tls_session *, tls_close ), }; +/** TLS plaintext stream interface descriptor */ +static struct interface_descriptor tls_plainstream_desc = + INTF_DESC_PASSTHRU ( struct tls_session, plainstream, + tls_plainstream_ops, cipherstream ); + /****************************************************************************** * * Ciphertext stream operations @@ -1503,19 +1494,6 @@ static struct xfer_interface_operations tls_plainstream_operations = { */ /** - * Close interface - * - * @v xfer Plainstream data transfer interface - * @v rc Reason for close - */ -static void tls_cipherstream_close ( struct xfer_interface *xfer, int rc ) { - struct tls_session *tls = - container_of ( xfer, struct tls_session, cipherstream.xfer ); - - tls_close ( tls, rc ); -} - -/** * Handle received TLS header * * @v tls TLS session @@ -1569,22 +1547,21 @@ static int tls_newdata_process_data ( struct tls_session *tls ) { /** * Receive new ciphertext * - * @v app Stream application - * @v data Data received - * @v len Length of received data + * @v tls TLS session + * @v iobuf I/O buffer + * @v meta Data transfer metadat * @ret rc Return status code */ -static int tls_cipherstream_deliver_raw ( struct xfer_interface *xfer, - const void *data, size_t len ) { - struct tls_session *tls = - container_of ( xfer, struct tls_session, cipherstream.xfer ); +static int tls_cipherstream_deliver ( struct tls_session *tls, + struct io_buffer *iobuf, + struct xfer_metadata *xfer __unused ) { size_t frag_len; void *buf; size_t buf_len; int ( * process ) ( struct tls_session *tls ); int rc; - while ( len ) { + while ( iob_len ( iobuf ) ) { /* Select buffer according to current state */ switch ( tls->rx_state ) { case TLS_RX_HEADER: @@ -1599,41 +1576,46 @@ static int tls_cipherstream_deliver_raw ( struct xfer_interface *xfer, break; default: assert ( 0 ); - return -EINVAL; + rc = -EINVAL; + goto done; } /* Copy data portion to buffer */ frag_len = ( buf_len - tls->rx_rcvd ); - if ( frag_len > len ) - frag_len = len; - memcpy ( ( buf + tls->rx_rcvd ), data, frag_len ); + if ( frag_len > iob_len ( iobuf ) ) + frag_len = iob_len ( iobuf ); + memcpy ( ( buf + tls->rx_rcvd ), iobuf->data, frag_len ); tls->rx_rcvd += frag_len; - data += frag_len; - len -= frag_len; + iob_pull ( iobuf, frag_len ); /* Process data if buffer is now full */ if ( tls->rx_rcvd == buf_len ) { if ( ( rc = process ( tls ) ) != 0 ) { tls_close ( tls, rc ); - return rc; + goto done; } tls->rx_rcvd = 0; } } + rc = 0; - return 0; + done: + free_iob ( iobuf ); + return rc; } -/** TLS ciphertext stream operations */ -static struct xfer_interface_operations tls_cipherstream_operations = { - .close = tls_cipherstream_close, - .vredirect = xfer_vreopen, - .window = filter_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = xfer_deliver_as_raw, - .deliver_raw = tls_cipherstream_deliver_raw, +/** TLS ciphertext stream interface operations */ +static struct interface_operation tls_cipherstream_ops[] = { + INTF_OP ( xfer_deliver, struct tls_session *, + tls_cipherstream_deliver ), + INTF_OP ( intf_close, struct tls_session *, tls_close ), }; +/** TLS ciphertext stream interface descriptor */ +static struct interface_descriptor tls_cipherstream_desc = + INTF_DESC_PASSTHRU ( struct tls_session, cipherstream, + tls_cipherstream_ops, plainstream ); + /****************************************************************************** * * Controlling process @@ -1652,7 +1634,7 @@ static void tls_step ( struct process *process ) { int rc; /* Wait for cipherstream to become ready */ - if ( ! xfer_window ( &tls->cipherstream.xfer ) ) + if ( ! xfer_window ( &tls->cipherstream ) ) return; switch ( tls->tx_state ) { @@ -1723,7 +1705,7 @@ static void tls_step ( struct process *process ) { ****************************************************************************** */ -int add_tls ( struct xfer_interface *xfer, struct xfer_interface **next ) { +int add_tls ( struct interface *xfer, struct interface **next ) { struct tls_session *tls; /* Allocate and initialise TLS structure */ @@ -1732,9 +1714,8 @@ int add_tls ( struct xfer_interface *xfer, struct xfer_interface **next ) { return -ENOMEM; memset ( tls, 0, sizeof ( *tls ) ); ref_init ( &tls->refcnt, free_tls ); - filter_init ( &tls->plainstream, &tls_plainstream_operations, - &tls->cipherstream, &tls_cipherstream_operations, - &tls->refcnt ); + intf_init ( &tls->plainstream, &tls_plainstream_desc, &tls->refcnt ); + intf_init ( &tls->cipherstream, &tls_cipherstream_desc, &tls->refcnt ); tls_clear_cipher ( tls, &tls->tx_cipherspec ); tls_clear_cipher ( tls, &tls->tx_cipherspec_pending ); tls_clear_cipher ( tls, &tls->rx_cipherspec ); @@ -1751,9 +1732,8 @@ int add_tls ( struct xfer_interface *xfer, struct xfer_interface **next ) { process_init ( &tls->process, tls_step, &tls->refcnt ); /* Attach to parent interface, mortalise self, and return */ - xfer_plug_plug ( &tls->plainstream.xfer, xfer ); - *next = &tls->cipherstream.xfer; + intf_plug_plug ( &tls->plainstream, xfer ); + *next = &tls->cipherstream; ref_put ( &tls->refcnt ); return 0; } - diff --git a/src/net/udp.c b/src/net/udp.c index dcc69c36c..0ed1503a2 100644 --- a/src/net/udp.c +++ b/src/net/udp.c @@ -29,7 +29,7 @@ struct udp_connection { struct list_head list; /** Data transfer interface */ - struct xfer_interface xfer; + struct interface xfer; /** Local socket address */ struct sockaddr_tcpip local; @@ -43,7 +43,7 @@ struct udp_connection { static LIST_HEAD ( udp_conns ); /* Forward declatations */ -static struct xfer_interface_operations udp_xfer_operations; +static struct interface_descriptor udp_xfer_desc; struct tcpip_protocol udp_protocol; /** @@ -97,7 +97,7 @@ static int udp_bind ( struct udp_connection *udp ) { * @v promisc Socket is promiscuous * @ret rc Return status code */ -static int udp_open_common ( struct xfer_interface *xfer, +static int udp_open_common ( struct interface *xfer, struct sockaddr *peer, struct sockaddr *local, int promisc ) { struct sockaddr_tcpip *st_peer = ( struct sockaddr_tcpip * ) peer; @@ -111,7 +111,7 @@ static int udp_open_common ( struct xfer_interface *xfer, return -ENOMEM; DBGC ( udp, "UDP %p allocated\n", udp ); ref_init ( &udp->refcnt, NULL ); - xfer_init ( &udp->xfer, &udp_xfer_operations, &udp->refcnt ); + intf_init ( &udp->xfer, &udp_xfer_desc, &udp->refcnt ); if ( st_peer ) memcpy ( &udp->peer, st_peer, sizeof ( udp->peer ) ); if ( st_local ) @@ -126,7 +126,7 @@ static int udp_open_common ( struct xfer_interface *xfer, /* Attach parent interface, transfer reference to connection * list and return */ - xfer_plug_plug ( &udp->xfer, xfer ); + intf_plug_plug ( &udp->xfer, xfer ); list_add ( &udp->list, &udp_conns ); return 0; @@ -143,7 +143,7 @@ static int udp_open_common ( struct xfer_interface *xfer, * @v local Local socket address, or NULL * @ret rc Return status code */ -int udp_open ( struct xfer_interface *xfer, struct sockaddr *peer, +int udp_open ( struct interface *xfer, struct sockaddr *peer, struct sockaddr *local ) { return udp_open_common ( xfer, peer, local, 0 ); } @@ -157,7 +157,7 @@ int udp_open ( struct xfer_interface *xfer, struct sockaddr *peer, * Promiscuous UDP connections are required in order to support the * PXE API. */ -int udp_open_promisc ( struct xfer_interface *xfer ) { +int udp_open_promisc ( struct interface *xfer ) { return udp_open_common ( xfer, NULL, NULL, 1 ); } @@ -170,8 +170,7 @@ int udp_open_promisc ( struct xfer_interface *xfer ) { static void udp_close ( struct udp_connection *udp, int rc ) { /* Close data transfer interface */ - xfer_nullify ( &udp->xfer ); - xfer_close ( &udp->xfer, rc ); + intf_shutdown ( &udp->xfer, rc ); /* Remove from list of connections and drop list's reference */ list_del ( &udp->list ); @@ -331,7 +330,7 @@ static int udp_rx ( struct io_buffer *iobuf, struct sockaddr_tcpip *st_src, memset ( &meta, 0, sizeof ( meta ) ); meta.src = ( struct sockaddr * ) st_src; meta.dest = ( struct sockaddr * ) st_dest; - rc = xfer_deliver_iob_meta ( &udp->xfer, iob_disown ( iobuf ), &meta ); + rc = xfer_deliver ( &udp->xfer, iob_disown ( iobuf ), &meta ); done: free_iob ( iobuf ); @@ -352,30 +351,14 @@ struct tcpip_protocol udp_protocol __tcpip_protocol = { */ /** - * Close interface - * - * @v xfer Data transfer interface - * @v rc Reason for close - */ -static void udp_xfer_close ( struct xfer_interface *xfer, int rc ) { - struct udp_connection *udp = - container_of ( xfer, struct udp_connection, xfer ); - - /* Close connection */ - udp_close ( udp, rc ); -} - -/** * Allocate I/O buffer for UDP * - * @v xfer Data transfer interface + * @v udp UDP connection * @v len Payload size * @ret iobuf I/O buffer, or NULL */ -static struct io_buffer * udp_alloc_iob ( struct xfer_interface *xfer, - size_t len ) { - struct udp_connection *udp = - container_of ( xfer, struct udp_connection, xfer ); +static struct io_buffer * udp_xfer_alloc_iob ( struct udp_connection *udp, + size_t len ) { struct io_buffer *iobuf; iobuf = alloc_iob ( UDP_MAX_HLEN + len ); @@ -391,16 +374,14 @@ static struct io_buffer * udp_alloc_iob ( struct xfer_interface *xfer, /** * Deliver datagram as I/O buffer * - * @v xfer Data transfer interface + * @v udp UDP connection * @v iobuf Datagram I/O buffer * @v meta Data transfer metadata * @ret rc Return status code */ -static int udp_xfer_deliver_iob ( struct xfer_interface *xfer, - struct io_buffer *iobuf, - struct xfer_metadata *meta ) { - struct udp_connection *udp = - container_of ( xfer, struct udp_connection, xfer ); +static int udp_xfer_deliver ( struct udp_connection *udp, + struct io_buffer *iobuf, + struct xfer_metadata *meta ) { /* Transmit data, if possible */ udp_tx ( udp, iobuf, ( ( struct sockaddr_tcpip * ) meta->src ), @@ -410,15 +391,16 @@ static int udp_xfer_deliver_iob ( struct xfer_interface *xfer, } /** UDP data transfer interface operations */ -static struct xfer_interface_operations udp_xfer_operations = { - .close = udp_xfer_close, - .vredirect = ignore_xfer_vredirect, - .window = unlimited_xfer_window, - .alloc_iob = udp_alloc_iob, - .deliver_iob = udp_xfer_deliver_iob, - .deliver_raw = xfer_deliver_as_iob, +static struct interface_operation udp_xfer_operations[] = { + INTF_OP ( xfer_deliver, struct udp_connection *, udp_xfer_deliver ), + INTF_OP ( xfer_alloc_iob, struct udp_connection *, udp_xfer_alloc_iob ), + INTF_OP ( intf_close, struct udp_connection *, udp_close ), }; +/** UDP data transfer interface descriptor */ +static struct interface_descriptor udp_xfer_desc = + INTF_DESC ( struct udp_connection, xfer, udp_xfer_operations ); + /*************************************************************************** * * Openers @@ -443,7 +425,7 @@ int udp_sock_dgram = UDP_SOCK_DGRAM; * @v uri URI * @ret rc Return status code */ -static int udp_open_uri ( struct xfer_interface *xfer, struct uri *uri ) { +static int udp_open_uri ( struct interface *xfer, struct uri *uri ) { struct sockaddr_tcpip peer; /* Sanity check */ diff --git a/src/net/udp/dhcp.c b/src/net/udp/dhcp.c index 991983197..fb62bef53 100644 --- a/src/net/udp/dhcp.c +++ b/src/net/udp/dhcp.c @@ -26,6 +26,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include <assert.h> #include <byteswap.h> #include <ipxe/if_ether.h> +#include <ipxe/iobuf.h> #include <ipxe/netdevice.h> #include <ipxe/device.h> #include <ipxe/xfer.h> @@ -240,7 +241,7 @@ struct dhcp_session { /** Job control interface */ struct interface job; /** Data transfer interface */ - struct xfer_interface xfer; + struct interface xfer; /** Network device being configured */ struct net_device *netdev; @@ -298,8 +299,7 @@ static void dhcp_finished ( struct dhcp_session *dhcp, int rc ) { stop_timer ( &dhcp->timer ); /* Shut down interfaces */ - xfer_nullify ( &dhcp->xfer ); - xfer_close ( &dhcp->xfer, rc ); + intf_shutdown ( &dhcp->xfer, rc ); intf_shutdown ( &dhcp->job, rc ); } @@ -1241,8 +1241,8 @@ static int dhcp_tx ( struct dhcp_session *dhcp ) { /* Transmit the packet */ iob_put ( iobuf, dhcppkt.len ); - if ( ( rc = xfer_deliver_iob_meta ( &dhcp->xfer, iob_disown ( iobuf ), - &meta ) ) != 0 ) { + if ( ( rc = xfer_deliver ( &dhcp->xfer, iob_disown ( iobuf ), + &meta ) ) != 0 ) { DBGC ( dhcp, "DHCP %p could not transmit UDP packet: %s\n", dhcp, strerror ( rc ) ); goto done; @@ -1256,16 +1256,14 @@ static int dhcp_tx ( struct dhcp_session *dhcp ) { /** * Receive new data * - * @v xfer Data transfer interface + * @v dhcp DHCP session * @v iobuf I/O buffer * @v meta Transfer metadata * @ret rc Return status code */ -static int dhcp_deliver_iob ( struct xfer_interface *xfer, - struct io_buffer *iobuf, - struct xfer_metadata *meta ) { - struct dhcp_session *dhcp = - container_of ( xfer, struct dhcp_session, xfer ); +static int dhcp_deliver ( struct dhcp_session *dhcp, + struct io_buffer *iobuf, + struct xfer_metadata *meta ) { struct sockaddr_in *peer; size_t data_len; struct dhcp_packet *dhcppkt; @@ -1328,15 +1326,14 @@ static int dhcp_deliver_iob ( struct xfer_interface *xfer, } /** DHCP data transfer interface operations */ -static struct xfer_interface_operations dhcp_xfer_operations = { - .close = ignore_xfer_close, - .vredirect = xfer_vreopen, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = dhcp_deliver_iob, - .deliver_raw = xfer_deliver_as_iob, +static struct interface_operation dhcp_xfer_operations[] = { + INTF_OP ( xfer_deliver, struct dhcp_session *, dhcp_deliver ), }; +/** DHCP data transfer interface descriptor */ +static struct interface_descriptor dhcp_xfer_desc = + INTF_DESC ( struct dhcp_session, xfer, dhcp_xfer_operations ); + /** * Handle DHCP retry timer expiry * @@ -1427,7 +1424,7 @@ int start_dhcp ( struct interface *job, struct net_device *netdev ) { return -ENOMEM; ref_init ( &dhcp->refcnt, dhcp_free ); intf_init ( &dhcp->job, &dhcp_job_desc, &dhcp->refcnt ); - xfer_init ( &dhcp->xfer, &dhcp_xfer_operations, &dhcp->refcnt ); + intf_init ( &dhcp->xfer, &dhcp_xfer_desc, &dhcp->refcnt ); timer_init ( &dhcp->timer, dhcp_timer_expired ); dhcp->netdev = netdev_get ( netdev ); dhcp->local.sin_family = AF_INET; @@ -1530,7 +1527,7 @@ int start_pxebs ( struct interface *job, struct net_device *netdev, return -ENOMEM; ref_init ( &dhcp->refcnt, dhcp_free ); intf_init ( &dhcp->job, &dhcp_job_desc, &dhcp->refcnt ); - xfer_init ( &dhcp->xfer, &dhcp_xfer_operations, &dhcp->refcnt ); + intf_init ( &dhcp->xfer, &dhcp_xfer_desc, &dhcp->refcnt ); timer_init ( &dhcp->timer, dhcp_timer_expired ); dhcp->netdev = netdev_get ( netdev ); dhcp->local.sin_family = AF_INET; diff --git a/src/net/udp/dns.c b/src/net/udp/dns.c index fd1ea0a28..8283e6fba 100644 --- a/src/net/udp/dns.c +++ b/src/net/udp/dns.c @@ -28,6 +28,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include <errno.h> #include <byteswap.h> #include <ipxe/refcnt.h> +#include <ipxe/iobuf.h> #include <ipxe/xfer.h> #include <ipxe/open.h> #include <ipxe/resolv.h> @@ -60,7 +61,7 @@ struct dns_request { /** Name resolution interface */ struct interface resolv; /** Data transfer interface */ - struct xfer_interface socket; + struct interface socket; /** Retry timer */ struct retry_timer timer; @@ -89,11 +90,8 @@ static void dns_done ( struct dns_request *dns, int rc ) { /* Stop the retry timer */ stop_timer ( &dns->timer ); - /* Close data transfer interface */ - xfer_nullify ( &dns->socket ); - xfer_close ( &dns->socket, rc ); - /* Shut down interfaces */ + intf_shutdown ( &dns->socket, rc ); intf_shutdown ( &dns->resolv, rc ); } @@ -322,25 +320,26 @@ static void dns_timer_expired ( struct retry_timer *timer, int fail ) { /** * Receive new data * - * @v socket UDP socket - * @v data DNS reply - * @v len Length of DNS reply + * @v dns DNS request + * @v iobuf I/O buffer + * @v meta Data transfer metadata * @ret rc Return status code */ -static int dns_xfer_deliver_raw ( struct xfer_interface *socket, - const void *data, size_t len ) { - struct dns_request *dns = - container_of ( socket, struct dns_request, socket ); - const struct dns_header *reply = data; +static int dns_xfer_deliver ( struct dns_request *dns, + struct io_buffer *iobuf, + struct xfer_metadata *meta __unused ) { + const struct dns_header *reply = iobuf->data; union dns_rr_info *rr_info; struct sockaddr_in *sin; unsigned int qtype = dns->qinfo->qtype; + int rc; /* Sanity check */ - if ( len < sizeof ( *reply ) ) { + if ( iob_len ( iobuf ) < sizeof ( *reply ) ) { DBGC ( dns, "DNS %p received underlength packet length %zd\n", - dns, len ); - return -EINVAL; + dns, iob_len ( iobuf ) ); + rc = -EINVAL; + goto done; } /* Check reply ID matches query ID */ @@ -348,7 +347,8 @@ static int dns_xfer_deliver_raw ( struct xfer_interface *socket, DBGC ( dns, "DNS %p received unexpected reply ID %d " "(wanted %d)\n", dns, ntohs ( reply->id ), ntohs ( dns->query.dns.id ) ); - return -EINVAL; + rc = -EINVAL; + goto done; } DBGC ( dns, "DNS %p received reply ID %d\n", dns, ntohs ( reply->id )); @@ -382,7 +382,8 @@ static int dns_xfer_deliver_raw ( struct xfer_interface *socket, /* Mark operation as complete */ dns_done ( dns, 0 ); - return 0; + rc = 0; + goto done; case htons ( DNS_TYPE_CNAME ): @@ -399,7 +400,8 @@ static int dns_xfer_deliver_raw ( struct xfer_interface *socket, DBGC ( dns, "DNS %p recursion exceeded\n", dns ); dns_done ( dns, -ELOOP ); - return 0; + rc = 0; + goto done; } break; @@ -422,7 +424,8 @@ static int dns_xfer_deliver_raw ( struct xfer_interface *socket, DBGC ( dns, "DNS %p found no A record; trying CNAME\n", dns ); dns->qinfo->qtype = htons ( DNS_TYPE_CNAME ); dns_send_packet ( dns ); - return 0; + rc = 0; + goto done; case htons ( DNS_TYPE_CNAME ): /* We asked for a CNAME record. If we got a response @@ -431,29 +434,35 @@ static int dns_xfer_deliver_raw ( struct xfer_interface *socket, */ if ( dns->qinfo->qtype == htons ( DNS_TYPE_A ) ) { dns_send_packet ( dns ); - return 0; + rc = 0; + goto done; } else { DBGC ( dns, "DNS %p found no CNAME record\n", dns ); dns_done ( dns, -ENXIO ); - return 0; + rc = 0; + goto done; } default: assert ( 0 ); dns_done ( dns, -EINVAL ); - return 0; + rc = -EINVAL; + goto done; } + + done: + /* Free I/O buffer */ + free_iob ( iobuf ); + return rc; } /** * Receive new data * - * @v socket UDP socket + * @v dns DNS request * @v rc Reason for close */ -static void dns_xfer_close ( struct xfer_interface *socket, int rc ) { - struct dns_request *dns = - container_of ( socket, struct dns_request, socket ); +static void dns_xfer_close ( struct dns_request *dns, int rc ) { if ( ! rc ) rc = -ECONNABORTED; @@ -461,16 +470,16 @@ static void dns_xfer_close ( struct xfer_interface *socket, int rc ) { dns_done ( dns, rc ); } -/** DNS socket operations */ -static struct xfer_interface_operations dns_socket_operations = { - .close = dns_xfer_close, - .vredirect = xfer_vreopen, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = xfer_deliver_as_raw, - .deliver_raw = dns_xfer_deliver_raw, +/** DNS socket interface operations */ +static struct interface_operation dns_socket_operations[] = { + INTF_OP ( xfer_deliver, struct dns_request *, dns_xfer_deliver ), + INTF_OP ( intf_close, struct dns_request *, dns_xfer_close ), }; +/** DNS socket interface descriptor */ +static struct interface_descriptor dns_socket_desc = + INTF_DESC ( struct dns_request, socket, dns_socket_operations ); + /** DNS resolver interface operations */ static struct interface_operation dns_resolv_op[] = { INTF_OP ( intf_close, struct dns_request *, dns_done ), @@ -517,7 +526,7 @@ static int dns_resolv ( struct interface *resolv, } ref_init ( &dns->refcnt, NULL ); intf_init ( &dns->resolv, &dns_resolv_desc, &dns->refcnt ); - xfer_init ( &dns->socket, &dns_socket_operations, &dns->refcnt ); + intf_init ( &dns->socket, &dns_socket_desc, &dns->refcnt ); timer_init ( &dns->timer, dns_timer_expired ); memcpy ( &dns->sa, sa, sizeof ( dns->sa ) ); diff --git a/src/net/udp/slam.c b/src/net/udp/slam.c index a5a2421fa..84bb9cba3 100644 --- a/src/net/udp/slam.c +++ b/src/net/udp/slam.c @@ -119,11 +119,11 @@ struct slam_request { struct refcnt refcnt; /** Data transfer interface */ - struct xfer_interface xfer; + struct interface xfer; /** Unicast socket */ - struct xfer_interface socket; + struct interface socket; /** Multicast socket */ - struct xfer_interface mc_socket; + struct interface mc_socket; /** Master client retry timer */ struct retry_timer master_timer; @@ -184,12 +184,9 @@ static void slam_finished ( struct slam_request *slam, int rc ) { stop_timer ( &slam->slave_timer ); /* Close all data transfer interfaces */ - xfer_nullify ( &slam->socket ); - xfer_close ( &slam->socket, rc ); - xfer_nullify ( &slam->mc_socket ); - xfer_close ( &slam->mc_socket, rc ); - xfer_nullify ( &slam->xfer ); - xfer_close ( &slam->xfer, rc ); + intf_shutdown ( &slam->socket, rc ); + intf_shutdown ( &slam->mc_socket, rc ); + intf_shutdown ( &slam->xfer, rc ); } /**************************************************************************** @@ -473,15 +470,13 @@ static int slam_pull_header ( struct slam_request *slam, /** * Receive SLAM data packet * - * @v mc_socket SLAM multicast socket + * @v slam SLAM request * @v iobuf I/O buffer * @ret rc Return status code */ -static int slam_mc_socket_deliver ( struct xfer_interface *mc_socket, +static int slam_mc_socket_deliver ( struct slam_request *slam, struct io_buffer *iobuf, struct xfer_metadata *rx_meta __unused ) { - struct slam_request *slam = - container_of ( mc_socket, struct slam_request, mc_socket ); struct xfer_metadata meta; unsigned long packet; size_t len; @@ -533,8 +528,7 @@ static int slam_mc_socket_deliver ( struct xfer_interface *mc_socket, memset ( &meta, 0, sizeof ( meta ) ); meta.whence = SEEK_SET; meta.offset = ( packet * slam->block_size ); - if ( ( rc = xfer_deliver_iob_meta ( &slam->xfer, iobuf, - &meta ) ) != 0 ) + if ( ( rc = xfer_deliver ( &slam->xfer, iobuf, &meta ) ) != 0 ) goto err; /* Mark block as received */ @@ -556,15 +550,13 @@ static int slam_mc_socket_deliver ( struct xfer_interface *mc_socket, /** * Receive SLAM non-data packet * - * @v socket SLAM unicast socket + * @v slam SLAM request * @v iobuf I/O buffer * @ret rc Return status code */ -static int slam_socket_deliver ( struct xfer_interface *socket, +static int slam_socket_deliver ( struct slam_request *slam, struct io_buffer *iobuf, struct xfer_metadata *rx_meta __unused ) { - struct slam_request *slam = - container_of ( socket, struct slam_request, socket ); int rc; /* Restart the master client timer */ @@ -597,90 +589,41 @@ static int slam_socket_deliver ( struct xfer_interface *socket, } -/** - * Close SLAM unicast socket - * - * @v socket SLAM unicast socket - * @v rc Reason for close - */ -static void slam_socket_close ( struct xfer_interface *socket, int rc ) { - struct slam_request *slam = - container_of ( socket, struct slam_request, socket ); - - DBGC ( slam, "SLAM %p unicast socket closed: %s\n", - slam, strerror ( rc ) ); - - slam_finished ( slam, rc ); -} - -/** SLAM unicast socket data transfer operations */ -static struct xfer_interface_operations slam_socket_operations = { - .close = slam_socket_close, - .vredirect = xfer_vreopen, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = slam_socket_deliver, - .deliver_raw = xfer_deliver_as_iob, +/** SLAM unicast socket interface operations */ +static struct interface_operation slam_socket_operations[] = { + INTF_OP ( xfer_deliver, struct slam_request *, slam_socket_deliver ), + INTF_OP ( intf_close, struct slam_request *, slam_finished ), }; -/** - * Close SLAM multicast socket - * - * @v mc_socket SLAM multicast socket - * @v rc Reason for close - */ -static void slam_mc_socket_close ( struct xfer_interface *mc_socket, int rc ){ - struct slam_request *slam = - container_of ( mc_socket, struct slam_request, mc_socket ); - - DBGC ( slam, "SLAM %p multicast socket closed: %s\n", - slam, strerror ( rc ) ); - - slam_finished ( slam, rc ); -} +/** SLAM unicast socket interface descriptor */ +static struct interface_descriptor slam_socket_desc = + INTF_DESC ( struct slam_request, socket, slam_socket_operations ); -/** SLAM multicast socket data transfer operations */ -static struct xfer_interface_operations slam_mc_socket_operations = { - .close = slam_mc_socket_close, - .vredirect = xfer_vreopen, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = slam_mc_socket_deliver, - .deliver_raw = xfer_deliver_as_iob, +/** SLAM multicast socket interface operations */ +static struct interface_operation slam_mc_socket_operations[] = { + INTF_OP ( xfer_deliver, struct slam_request *, slam_mc_socket_deliver ), + INTF_OP ( intf_close, struct slam_request *, slam_finished ), }; +/** SLAM multicast socket interface descriptor */ +static struct interface_descriptor slam_mc_socket_desc = + INTF_DESC ( struct slam_request, mc_socket, slam_mc_socket_operations ); + /**************************************************************************** * * Data transfer interface * */ -/** - * Close SLAM data transfer interface - * - * @v xfer SLAM data transfer interface - * @v rc Reason for close - */ -static void slam_xfer_close ( struct xfer_interface *xfer, int rc ) { - struct slam_request *slam = - container_of ( xfer, struct slam_request, xfer ); - - DBGC ( slam, "SLAM %p data transfer interface closed: %s\n", - slam, strerror ( rc ) ); - - slam_finished ( slam, rc ); -} - -/** SLAM data transfer operations */ -static struct xfer_interface_operations slam_xfer_operations = { - .close = slam_xfer_close, - .vredirect = ignore_xfer_vredirect, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = xfer_deliver_as_raw, - .deliver_raw = ignore_xfer_deliver_raw, +/** SLAM data transfer interface operations */ +static struct interface_operation slam_xfer_operations[] = { + INTF_OP ( intf_close, struct slam_request *, slam_finished ), }; +/** SLAM data transfer interface descriptor */ +static struct interface_descriptor slam_xfer_desc = + INTF_DESC ( struct slam_request, xfer, slam_xfer_operations ); + /** * Parse SLAM URI multicast address * @@ -729,7 +672,7 @@ static int slam_parse_multicast_address ( struct slam_request *slam, * @v uri Uniform Resource Identifier * @ret rc Return status code */ -static int slam_open ( struct xfer_interface *xfer, struct uri *uri ) { +static int slam_open ( struct interface *xfer, struct uri *uri ) { static const struct sockaddr_in default_multicast = { .sin_family = AF_INET, .sin_port = htons ( SLAM_DEFAULT_MULTICAST_PORT ), @@ -749,10 +692,9 @@ static int slam_open ( struct xfer_interface *xfer, struct uri *uri ) { if ( ! slam ) return -ENOMEM; ref_init ( &slam->refcnt, slam_free ); - xfer_init ( &slam->xfer, &slam_xfer_operations, &slam->refcnt ); - xfer_init ( &slam->socket, &slam_socket_operations, &slam->refcnt ); - xfer_init ( &slam->mc_socket, &slam_mc_socket_operations, - &slam->refcnt ); + intf_init ( &slam->xfer, &slam_xfer_desc, &slam->refcnt ); + intf_init ( &slam->socket, &slam_socket_desc, &slam->refcnt ); + intf_init ( &slam->mc_socket, &slam_mc_socket_desc, &slam->refcnt ); timer_init ( &slam->master_timer, slam_master_timer_expired ); timer_init ( &slam->slave_timer, slam_slave_timer_expired ); /* Fake an invalid cached header of { 0x00, ... } */ @@ -795,7 +737,7 @@ static int slam_open ( struct xfer_interface *xfer, struct uri *uri ) { start_timer_fixed ( &slam->slave_timer, SLAM_SLAVE_TIMEOUT ); /* Attach to parent interface, mortalise self, and return */ - xfer_plug_plug ( &slam->xfer, xfer ); + intf_plug_plug ( &slam->xfer, xfer ); ref_put ( &slam->refcnt ); return 0; diff --git a/src/net/udp/tftp.c b/src/net/udp/tftp.c index 5e98f58cd..3bcd0a258 100644 --- a/src/net/udp/tftp.c +++ b/src/net/udp/tftp.c @@ -27,6 +27,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include <errno.h> #include <assert.h> #include <ipxe/refcnt.h> +#include <ipxe/iobuf.h> #include <ipxe/xfer.h> #include <ipxe/open.h> #include <ipxe/uri.h> @@ -79,14 +80,14 @@ struct tftp_request { /** Reference count */ struct refcnt refcnt; /** Data transfer interface */ - struct xfer_interface xfer; + struct interface xfer; /** URI being fetched */ struct uri *uri; /** Transport layer interface */ - struct xfer_interface socket; + struct interface socket; /** Multicast transport layer interface */ - struct xfer_interface mc_socket; + struct interface mc_socket; /** Data block size * @@ -183,12 +184,9 @@ static void tftp_done ( struct tftp_request *tftp, int rc ) { stop_timer ( &tftp->timer ); /* Close all data transfer interfaces */ - xfer_nullify ( &tftp->socket ); - xfer_close ( &tftp->socket, rc ); - xfer_nullify ( &tftp->mc_socket ); - xfer_close ( &tftp->mc_socket, rc ); - xfer_nullify ( &tftp->xfer ); - xfer_close ( &tftp->xfer, rc ); + intf_shutdown ( &tftp->socket, rc ); + intf_shutdown ( &tftp->mc_socket, rc ); + intf_shutdown ( &tftp->xfer, rc ); } /** @@ -202,7 +200,7 @@ static int tftp_reopen ( struct tftp_request *tftp ) { int rc; /* Close socket */ - xfer_close ( &tftp->socket, 0 ); + intf_restart ( &tftp->socket, 0 ); /* Disable ACK sending. */ tftp->flags &= ~TFTP_FL_SEND_ACK; @@ -236,7 +234,7 @@ static int tftp_reopen_mc ( struct tftp_request *tftp, int rc; /* Close multicast socket */ - xfer_close ( &tftp->mc_socket, 0 ); + intf_restart ( &tftp->mc_socket, 0 ); /* Open multicast socket. We never send via this socket, so * use the local address as the peer address (since the peer @@ -423,7 +421,7 @@ static int tftp_send_ack ( struct tftp_request *tftp ) { ack->block = htons ( block ); /* ACK always goes to the peer recorded from the RRQ response */ - return xfer_deliver_iob_meta ( &tftp->socket, iobuf, &meta ); + return xfer_deliver ( &tftp->socket, iobuf, &meta ); } /** @@ -459,7 +457,7 @@ static int tftp_send_error ( struct tftp_request *tftp, int errcode, strcpy ( err->errmsg, errmsg ); /* ERR always goes to the peer recorded from the RRQ response */ - return xfer_deliver_iob_meta ( &tftp->socket, iobuf, &meta ); + return xfer_deliver ( &tftp->socket, iobuf, &meta ); } /** @@ -525,7 +523,7 @@ static void tftp_timer_expired ( struct retry_timer *timer, int fail ) { tftp->flags = TFTP_FL_RRQ_SIZES; /* Close multicast socket */ - xfer_close ( &tftp->mc_socket, 0 ); + intf_restart ( &tftp->mc_socket, 0 ); /* Reset retry timer */ start_timer_nodelay ( &tftp->timer ); @@ -858,8 +856,8 @@ static int tftp_rx_data ( struct tftp_request *tftp, memset ( &meta, 0, sizeof ( meta ) ); meta.whence = SEEK_SET; meta.offset = offset; - if ( ( rc = xfer_deliver_iob_meta ( &tftp->xfer, iob_disown ( iobuf ), - &meta ) ) != 0 ) { + if ( ( rc = xfer_deliver ( &tftp->xfer, iob_disown ( iobuf ), + &meta ) ) != 0 ) { DBGC ( tftp, "TFTP %p could not deliver data: %s\n", tftp, strerror ( rc ) ); goto done; @@ -998,16 +996,14 @@ static int tftp_rx ( struct tftp_request *tftp, /** * Receive new data via socket * - * @v socket Transport layer interface + * @v tftp TFTP connection * @v iobuf I/O buffer * @v meta Transfer metadata * @ret rc Return status code */ -static int tftp_socket_deliver_iob ( struct xfer_interface *socket, - struct io_buffer *iobuf, - struct xfer_metadata *meta ) { - struct tftp_request *tftp = - container_of ( socket, struct tftp_request, socket ); +static int tftp_socket_deliver ( struct tftp_request *tftp, + struct io_buffer *iobuf, + struct xfer_metadata *meta ) { /* Enable sending ACKs when we receive a unicast packet. This * covers three cases: @@ -1030,67 +1026,30 @@ static int tftp_socket_deliver_iob ( struct xfer_interface *socket, } /** TFTP socket operations */ -static struct xfer_interface_operations tftp_socket_operations = { - .close = ignore_xfer_close, - .vredirect = xfer_vreopen, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = tftp_socket_deliver_iob, - .deliver_raw = xfer_deliver_as_iob, +static struct interface_operation tftp_socket_operations[] = { + INTF_OP ( xfer_deliver, struct tftp_request *, tftp_socket_deliver ), }; -/** - * Receive new data via multicast socket - * - * @v mc_socket Multicast transport layer interface - * @v iobuf I/O buffer - * @v meta Transfer metadata - * @ret rc Return status code - */ -static int tftp_mc_socket_deliver_iob ( struct xfer_interface *mc_socket, - struct io_buffer *iobuf, - struct xfer_metadata *meta ) { - struct tftp_request *tftp = - container_of ( mc_socket, struct tftp_request, mc_socket ); - - return tftp_rx ( tftp, iobuf, meta ); -} +/** TFTP socket interface descriptor */ +static struct interface_descriptor tftp_socket_desc = + INTF_DESC ( struct tftp_request, socket, tftp_socket_operations ); /** TFTP multicast socket operations */ -static struct xfer_interface_operations tftp_mc_socket_operations = { - .close = ignore_xfer_close, - .vredirect = xfer_vreopen, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = tftp_mc_socket_deliver_iob, - .deliver_raw = xfer_deliver_as_iob, +static struct interface_operation tftp_mc_socket_operations[] = { + INTF_OP ( xfer_deliver, struct tftp_request *, tftp_rx ), }; -/** - * Close TFTP data transfer interface - * - * @v xfer Data transfer interface - * @v rc Reason for close - */ -static void tftp_xfer_close ( struct xfer_interface *xfer, int rc ) { - struct tftp_request *tftp = - container_of ( xfer, struct tftp_request, xfer ); - - DBGC ( tftp, "TFTP %p interface closed: %s\n", - tftp, strerror ( rc ) ); - - tftp_done ( tftp, rc ); -} +/** TFTP multicast socket interface descriptor */ +static struct interface_descriptor tftp_mc_socket_desc = + INTF_DESC ( struct tftp_request, mc_socket, tftp_mc_socket_operations ); /** * Check flow control window * - * @v xfer Data transfer interface + * @v tftp TFTP connection * @ret len Length of window */ -static size_t tftp_xfer_window ( struct xfer_interface *xfer ) { - struct tftp_request *tftp = - container_of ( xfer, struct tftp_request, xfer ); +static size_t tftp_xfer_window ( struct tftp_request *tftp ) { /* We abuse this data-xfer method to convey the blocksize to * the caller. This really should be done using some kind of @@ -1101,15 +1060,15 @@ static size_t tftp_xfer_window ( struct xfer_interface *xfer ) { } /** TFTP data transfer interface operations */ -static struct xfer_interface_operations tftp_xfer_operations = { - .close = tftp_xfer_close, - .vredirect = ignore_xfer_vredirect, - .window = tftp_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = xfer_deliver_as_raw, - .deliver_raw = ignore_xfer_deliver_raw, +static struct interface_operation tftp_xfer_operations[] = { + INTF_OP ( xfer_window, struct tftp_request *, tftp_xfer_window ), + INTF_OP ( intf_close, struct tftp_request *, tftp_done ), }; +/** TFTP data transfer interface descriptor */ +static struct interface_descriptor tftp_xfer_desc = + INTF_DESC ( struct tftp_request, xfer, tftp_xfer_operations ); + /** * Initiate TFTP/TFTM/MTFTP download * @@ -1117,7 +1076,7 @@ static struct xfer_interface_operations tftp_xfer_operations = { * @v uri Uniform Resource Identifier * @ret rc Return status code */ -static int tftp_core_open ( struct xfer_interface *xfer, struct uri *uri, +static int tftp_core_open ( struct interface *xfer, struct uri *uri, unsigned int default_port, struct sockaddr *multicast, unsigned int flags ) { @@ -1135,10 +1094,9 @@ static int tftp_core_open ( struct xfer_interface *xfer, struct uri *uri, if ( ! tftp ) return -ENOMEM; ref_init ( &tftp->refcnt, tftp_free ); - xfer_init ( &tftp->xfer, &tftp_xfer_operations, &tftp->refcnt ); - xfer_init ( &tftp->socket, &tftp_socket_operations, &tftp->refcnt ); - xfer_init ( &tftp->mc_socket, &tftp_mc_socket_operations, - &tftp->refcnt ); + intf_init ( &tftp->xfer, &tftp_xfer_desc, &tftp->refcnt ); + intf_init ( &tftp->socket, &tftp_socket_desc, &tftp->refcnt ); + intf_init ( &tftp->mc_socket, &tftp_mc_socket_desc, &tftp->refcnt ); timer_init ( &tftp->timer, tftp_timer_expired ); tftp->uri = uri_get ( uri ); tftp->blksize = TFTP_DEFAULT_BLKSIZE; @@ -1159,7 +1117,7 @@ static int tftp_core_open ( struct xfer_interface *xfer, struct uri *uri, start_timer_nodelay ( &tftp->timer ); /* Attach to parent interface, mortalise self, and return */ - xfer_plug_plug ( &tftp->xfer, xfer ); + intf_plug_plug ( &tftp->xfer, xfer ); ref_put ( &tftp->refcnt ); return 0; @@ -1178,7 +1136,7 @@ static int tftp_core_open ( struct xfer_interface *xfer, struct uri *uri, * @v uri Uniform Resource Identifier * @ret rc Return status code */ -static int tftp_open ( struct xfer_interface *xfer, struct uri *uri ) { +static int tftp_open ( struct interface *xfer, struct uri *uri ) { return tftp_core_open ( xfer, uri, TFTP_PORT, NULL, TFTP_FL_RRQ_SIZES ); @@ -1197,7 +1155,7 @@ struct uri_opener tftp_uri_opener __uri_opener = { * @v uri Uniform Resource Identifier * @ret rc Return status code */ -static int tftpsize_open ( struct xfer_interface *xfer, struct uri *uri ) { +static int tftpsize_open ( struct interface *xfer, struct uri *uri ) { return tftp_core_open ( xfer, uri, TFTP_PORT, NULL, ( TFTP_FL_RRQ_SIZES | TFTP_FL_SIZEONLY ) ); @@ -1217,7 +1175,7 @@ struct uri_opener tftpsize_uri_opener __uri_opener = { * @v uri Uniform Resource Identifier * @ret rc Return status code */ -static int tftm_open ( struct xfer_interface *xfer, struct uri *uri ) { +static int tftm_open ( struct interface *xfer, struct uri *uri ) { return tftp_core_open ( xfer, uri, TFTP_PORT, NULL, ( TFTP_FL_RRQ_SIZES | TFTP_FL_RRQ_MULTICAST ) ); @@ -1237,7 +1195,7 @@ struct uri_opener tftm_uri_opener __uri_opener = { * @v uri Uniform Resource Identifier * @ret rc Return status code */ -static int mtftp_open ( struct xfer_interface *xfer, struct uri *uri ) { +static int mtftp_open ( struct interface *xfer, struct uri *uri ) { return tftp_core_open ( xfer, uri, MTFTP_PORT, ( struct sockaddr * ) &tftp_mtftp_socket, TFTP_FL_MTFTP_RECOVERY ); |
