[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 26/31] slirp: improve send_packet() callback
From: |
Samuel Thibault |
Subject: |
[Qemu-devel] [PULL 26/31] slirp: improve send_packet() callback |
Date: |
Sun, 27 Jan 2019 13:05:21 +0100 |
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 | 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 <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..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
--
2.20.1
- [Qemu-devel] [PULL 21/31] slirp: replace net/eth.h inclusion with own defines, (continued)
- [Qemu-devel] [PULL 21/31] slirp: replace net/eth.h inclusion with own defines, Samuel Thibault, 2019/01/27
- [Qemu-devel] [PULL 11/31] slirp: replace most qemu socket utilities with slirp own version, Samuel Thibault, 2019/01/27
- [Qemu-devel] [PULL 20/31] slirp: remove now useless QEMU headers inclusions, Samuel Thibault, 2019/01/27
- [Qemu-devel] [PULL 31/31] slirp: API is extern C, Samuel Thibault, 2019/01/27
- [Qemu-devel] [PULL 29/31] slirp: use polling callbacks, drop glib requirement, Samuel Thibault, 2019/01/27
- [Qemu-devel] [PULL 30/31] slirp: pass opaque to all callbacks, Samuel Thibault, 2019/01/27
- [Qemu-devel] [PULL 27/31] slirp: replace global polling with per-instance & notifier, Samuel Thibault, 2019/01/27
- [Qemu-devel] [PULL 24/31] slirp: replace remaining qemu headers dependency, Samuel Thibault, 2019/01/27
- [Qemu-devel] [PULL 22/31] slirp: replace qemu qtailq with slirp own copy, Samuel Thibault, 2019/01/27
- [Qemu-devel] [PULL 25/31] slirp: prefer c99 types over BSD kind, Samuel Thibault, 2019/01/27
- [Qemu-devel] [PULL 26/31] slirp: improve send_packet() callback,
Samuel Thibault <=
- Re: [Qemu-devel] [PULL 00/31] More work towards libslirp, Peter Maydell, 2019/01/28
- Re: [Qemu-devel] [PULL 00/31] More work towards libslirp, no-reply, 2019/01/31