[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PULLv4 27/32] slirp: improve send_packet() callback
From: |
Philippe Mathieu-Daudé |
Subject: |
Re: [Qemu-devel] [PULLv4 27/32] slirp: improve send_packet() callback |
Date: |
Thu, 7 Feb 2019 19:31:49 +0100 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.4.0 |
Hi Samuel,
On 2/7/19 3:03 PM, Samuel Thibault wrote:
> From: Marc-André Lureau <address@hidden>
>
> 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 <address@hidden>
> Signed-off-by: Samuel Thibault <address@hidden>
> ---
> include/net/net.h | 2 +-
> net/net.c | 4 ++--
> net/slirp.c | 9 +++++----
> slirp/libslirp.h | 11 +++++++----
> slirp/ncsi.c | 2 +-
> slirp/slirp.c | 18 +++++++++++++++---
> slirp/slirp.h | 2 ++
> 7 files changed, 33 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 <len (no
> + * buffering is done on libslirp side, so the data will be dropped
> + * in this case). <0 reports an IO error.
> */
> - void (*output)(void *opaque, const uint8_t *pkt, int pkt_len);
> + SlirpWriteCb send_packet;
> /* Print a message for an error due to guest misbehavior. */
> void (*guest_error)(const char *msg);
> /* Return the virtual clock value in nanoseconds */
> diff --git a/slirp/ncsi.c b/slirp/ncsi.c
> index 327f17543c..359f52c284 100644
> --- a/slirp/ncsi.c
> +++ b/slirp/ncsi.c
> @@ -162,5 +162,5 @@ void ncsi_input(Slirp *slirp, const uint8_t *pkt, int
> pkt_len)
> *pchecksum = htonl(checksum);
> ncsi_rsp_len += 4;
>
> - slirp->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..2bc53e3e12 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,15 @@ 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: %ld", (long) ret);
>From the v3 discussion [*] I thought send_packet() would return a
gssize, then we'd use G_GSSIZE_FORMAT here (and similarly use gssize
instead ssize_t in this series).
Anyway your fix is simpler. And we can still do this on top of this PR.
[*] https://lists.gnu.org/archive/html/qemu-devel/2019-02/msg01841.html
> + } else if (ret < len) {
> + DEBUG_ERROR("send_packet() didn't send all data: %ld < %lu",
> + (long) ret, (unsigned long) 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
>
- [Qemu-devel] [PULLv4 31/32] slirp: pass opaque to all callbacks, (continued)
- [Qemu-devel] [PULLv4 31/32] slirp: pass opaque to all callbacks, Samuel Thibault, 2019/02/07
- [Qemu-devel] [PULLv4 18/32] slirp: add slirp own version of pstrcpy, Samuel Thibault, 2019/02/07
- [Qemu-devel] [PULLv4 25/32] slirp: replace remaining qemu headers dependency, Samuel Thibault, 2019/02/07
- [Qemu-devel] [PULLv4 30/32] slirp: use polling callbacks, drop glib requirement, Samuel Thibault, 2019/02/07
- [Qemu-devel] [PULLv4 22/32] slirp: replace qemu qtailq with slirp own copy, Samuel Thibault, 2019/02/07
- [Qemu-devel] [PULLv4 26/32] slirp: prefer c99 types over BSD kind, Samuel Thibault, 2019/02/07
- [Qemu-devel] [PULLv4 32/32] slirp: API is extern C, Samuel Thibault, 2019/02/07
- [Qemu-devel] [PULLv4 28/32] slirp: replace global polling with per-instance & notifier, Samuel Thibault, 2019/02/07
- [Qemu-devel] [PULLv4 12/32] slirp: replace qemu_set_nonblock(), Samuel Thibault, 2019/02/07
- [Qemu-devel] [PULLv4 27/32] slirp: improve send_packet() callback, Samuel Thibault, 2019/02/07
- Re: [Qemu-devel] [PULLv4 27/32] slirp: improve send_packet() callback,
Philippe Mathieu-Daudé <=
- [Qemu-devel] [PULLv4 17/32] slirp: improve windows headers inclusion, Samuel Thibault, 2019/02/07
- [Qemu-devel] [PULLv4 29/32] slirp: remove slirp_instances list, Samuel Thibault, 2019/02/07
- Re: [Qemu-devel] [PULLv4 00/32] More work towards libslirp, no-reply, 2019/02/07
- Re: [Qemu-devel] [PULLv4 00/32] More work towards libslirp, Peter Maydell, 2019/02/08