diff options
author | Marc-André Lureau <marcandre.lureau@redhat.com> | 2019-01-17 15:43:54 +0400 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2019-02-07 15:49:08 +0200 |
commit | 625a526b3298ce593983923b4d10fa582555f26d (patch) | |
tree | 23a61e6bd768759314f416b5674e776d5c1868c5 /slirp | |
parent | d7df0b41dc38327388c3f19fdf4246793d4a1e4b (diff) |
slirp: improve send_packet() callback
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 <marcandre.lureau@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Diffstat (limited to 'slirp')
-rw-r--r-- | slirp/libslirp.h | 11 | ||||
-rw-r--r-- | slirp/ncsi.c | 2 | ||||
-rw-r--r-- | slirp/slirp.c | 18 | ||||
-rw-r--r-- | slirp/slirp.h | 2 |
4 files changed, 25 insertions, 8 deletions
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); + } 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 |