From patchwork Tue Feb 5 16:59:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Samuel Thibault X-Patchwork-Id: 10797807 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AE898922 for ; Tue, 5 Feb 2019 17:22:28 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 976472C54C for ; Tue, 5 Feb 2019 17:22:28 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 891562C55E; Tue, 5 Feb 2019 17:22:28 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id DF3EF2C54C for ; Tue, 5 Feb 2019 17:22:27 +0000 (UTC) Received: from localhost ([127.0.0.1]:35376 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gr4QV-0006Po-6V for patchwork-qemu-devel@patchwork.kernel.org; Tue, 05 Feb 2019 12:22:27 -0500 Received: from eggs.gnu.org ([209.51.188.92]:33529) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gr44x-0005z7-Fz for qemu-devel@nongnu.org; Tue, 05 Feb 2019 12:00:18 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gr44v-0006A2-1e for qemu-devel@nongnu.org; Tue, 05 Feb 2019 12:00:11 -0500 Received: from hera.aquilenet.fr ([185.233.100.1]:60850) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gr44s-00060C-U4 for qemu-devel@nongnu.org; Tue, 05 Feb 2019 12:00:07 -0500 Received: from localhost (localhost [127.0.0.1]) by hera.aquilenet.fr (Postfix) with ESMTP id 17FDBC032; Tue, 5 Feb 2019 17:59:49 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at aquilenet.fr Received: from hera.aquilenet.fr ([127.0.0.1]) by localhost (hera.aquilenet.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 6i1Zx-nax5Nm; Tue, 5 Feb 2019 17:59:48 +0100 (CET) Received: from function (unknown [188.164.201.34]) by hera.aquilenet.fr (Postfix) with ESMTPSA id 2A1ADC057; Tue, 5 Feb 2019 17:59:33 +0100 (CET) Received: from samy by function with local (Exim 4.92-RC4) (envelope-from ) id 1gr44I-0006z1-01; Tue, 05 Feb 2019 17:59:30 +0100 From: Samuel Thibault To: qemu-devel@nongnu.org, peter.maydell@linaro.org Date: Tue, 5 Feb 2019 18:59:22 +0200 Message-Id: <20190205165927.26599-28-samuel.thibault@ens-lyon.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190205165927.26599-1-samuel.thibault@ens-lyon.org> References: <20190205165927.26599-1-samuel.thibault@ens-lyon.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 185.233.100.1 Subject: [Qemu-devel] [PULLv2 27/32] slirp: improve send_packet() callback X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Samuel Thibault , stefanha@redhat.com, jan.kiszka@siemens.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Marc-André Lureau Use a more descriptive name for the callback. Reuse the SlirpWriteCb type. Wrap it to check that all data has been written. Return a ssize_t for potential error handling and data-loss reporting. Signed-off-by: Marc-André Lureau Signed-off-by: Samuel Thibault --- include/net/net.h | 2 +- net/net.c | 4 ++-- net/slirp.c | 9 +++++---- slirp/libslirp.h | 11 +++++++---- slirp/ncsi.c | 2 +- slirp/slirp.c | 17 ++++++++++++++--- slirp/slirp.h | 2 ++ 7 files changed, 32 insertions(+), 15 deletions(-) diff --git a/include/net/net.h b/include/net/net.h index 643295d163..075cc01267 100644 --- a/include/net/net.h +++ b/include/net/net.h @@ -146,7 +146,7 @@ ssize_t qemu_sendv_packet(NetClientState *nc, const struct iovec *iov, int iovcnt); ssize_t qemu_sendv_packet_async(NetClientState *nc, const struct iovec *iov, int iovcnt, NetPacketSent *sent_cb); -void qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size); +ssize_t qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size); ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int size); ssize_t qemu_send_packet_async(NetClientState *nc, const uint8_t *buf, int size, NetPacketSent *sent_cb); diff --git a/net/net.c b/net/net.c index 3acbdccd61..5dcff7fe2a 100644 --- a/net/net.c +++ b/net/net.c @@ -668,9 +668,9 @@ ssize_t qemu_send_packet_async(NetClientState *sender, buf, size, sent_cb); } -void qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size) +ssize_t qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size) { - qemu_send_packet_async(nc, buf, size, NULL); + return qemu_send_packet_async(nc, buf, size, NULL); } ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int size) diff --git a/net/slirp.c b/net/slirp.c index 7b4f9f5c5e..664ff1c002 100644 --- a/net/slirp.c +++ b/net/slirp.c @@ -108,11 +108,12 @@ static void slirp_smb_cleanup(SlirpState *s); static inline void slirp_smb_cleanup(SlirpState *s) { } #endif -static void net_slirp_output(void *opaque, const uint8_t *pkt, int pkt_len) +static ssize_t net_slirp_send_packet(const void *pkt, size_t pkt_len, + void *opaque) { SlirpState *s = opaque; - qemu_send_packet(&s->nc, pkt, pkt_len); + return qemu_send_packet(&s->nc, pkt, pkt_len); } static ssize_t net_slirp_receive(NetClientState *nc, const uint8_t *buf, size_t size) @@ -197,7 +198,7 @@ static void net_slirp_unregister_poll_fd(int fd) } static const SlirpCb slirp_cb = { - .output = net_slirp_output, + .send_packet = net_slirp_send_packet, .guest_error = net_slirp_guest_error, .clock_get_ns = net_slirp_clock_get_ns, .timer_new = net_slirp_timer_new, @@ -780,7 +781,7 @@ static void guestfwd_read(void *opaque, const uint8_t *buf, int size) slirp_socket_recv(fwd->slirp, fwd->server, fwd->port, buf, size); } -static int guestfwd_write(const void *buf, size_t len, void *chr) +static ssize_t guestfwd_write(const void *buf, size_t len, void *chr) { return qemu_chr_fe_write_all(chr, buf, len); } diff --git a/slirp/libslirp.h b/slirp/libslirp.h index 02cbec9f8b..8e5d4ed11b 100644 --- a/slirp/libslirp.h +++ b/slirp/libslirp.h @@ -15,7 +15,7 @@ typedef struct Slirp Slirp; -typedef int (*SlirpWriteCb)(const void *buf, size_t len, void *opaque); +typedef ssize_t (*SlirpWriteCb)(const void *buf, size_t len, void *opaque); typedef void (*SlirpTimerCb)(void *opaque); /* @@ -23,10 +23,13 @@ typedef void (*SlirpTimerCb)(void *opaque); */ typedef struct SlirpCb { /* - * Send an ethernet frame to the guest network. The opaque parameter - * is the one given to slirp_init(). + * Send an ethernet frame to the guest network. The opaque + * parameter is the one given to slirp_init(). The function + * doesn't need to send all the data and may return cb->output(slirp->opaque, ncsi_reply, ETH_HLEN + ncsi_rsp_len); + slirp_send_packet_all(slirp, ncsi_reply, ETH_HLEN + ncsi_rsp_len); } diff --git a/slirp/slirp.c b/slirp/slirp.c index 3304c83001..60cd8249bf 100644 --- a/slirp/slirp.c +++ b/slirp/slirp.c @@ -800,7 +800,7 @@ static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len) rah->ar_sip = ah->ar_tip; memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN); rah->ar_tip = ah->ar_sip; - slirp->cb->output(slirp->opaque, arp_reply, sizeof(arp_reply)); + slirp_send_packet_all(slirp, arp_reply, sizeof(arp_reply)); } break; case ARPOP_REPLY: @@ -900,7 +900,7 @@ static int if_encap4(Slirp *slirp, struct mbuf *ifm, struct ethhdr *eh, /* target IP */ rah->ar_tip = iph->ip_dst.s_addr; slirp->client_ipaddr = iph->ip_dst; - slirp->cb->output(slirp->opaque, arp_req, sizeof(arp_req)); + slirp_send_packet_all(slirp, arp_req, sizeof(arp_req)); ifm->resolution_requested = true; /* Expire request and drop outgoing packet after 1 second */ @@ -985,7 +985,7 @@ int if_encap(Slirp *slirp, struct mbuf *ifm) eh->h_dest[0], eh->h_dest[1], eh->h_dest[2], eh->h_dest[3], eh->h_dest[4], eh->h_dest[5]); memcpy(buf + sizeof(struct ethhdr), ifm->m_data, ifm->m_len); - slirp->cb->output(slirp->opaque, buf, ifm->m_len + ETH_HLEN); + slirp_send_packet_all(slirp, buf, ifm->m_len + ETH_HLEN); return 1; } @@ -1152,3 +1152,14 @@ void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr, int guest_port, if (ret > 0) tcp_output(sototcpcb(so)); } + +void slirp_send_packet_all(Slirp *slirp, const void *buf, size_t len) +{ + ssize_t ret = slirp->cb->send_packet(buf, len, slirp->opaque); + + if (ret < 0) { + g_critical("Failed to send packet, ret: %zd", ret); + } else if (ret < len) { + DEBUG_ERROR("send_packet() didn't send all data: %zd < %zu", ret, len); + } +} diff --git a/slirp/slirp.h b/slirp/slirp.h index 05b8364c07..752a4cd8c8 100644 --- a/slirp/slirp.h +++ b/slirp/slirp.h @@ -269,4 +269,6 @@ struct tcpcb *tcp_drop(struct tcpcb *tp, int err); struct socket * slirp_find_ctl_socket(Slirp *slirp, struct in_addr guest_addr, int guest_port); +void slirp_send_packet_all(Slirp *slirp, const void *buf, size_t len); + #endif