From 6222e55d134162e87062326a773eb7c9f9d13834 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 11 Apr 2022 09:39:16 +0200 Subject: [PATCH] net: slirp: add support for CFI-friendly timer API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit libslirp 4.7 introduces a CFI-friendly version of the .timer_new callback. The new callback replaces the function pointer with an enum; invoking the callback is done with a new function slirp_handle_timer. Support the new API so that CFI can be made compatible with using a system libslirp. Reviewed-by: Samuel Thibault Reviewed-by: Marc-André Lureau Signed-off-by: Paolo Bonzini --- net/slirp.c | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/net/slirp.c b/net/slirp.c index b7464be86b..8679be6444 100644 --- a/net/slirp.c +++ b/net/slirp.c @@ -184,10 +184,43 @@ static int64_t net_slirp_clock_get_ns(void *opaque) return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); } +typedef struct SlirpTimer SlirpTimer; struct SlirpTimer { QEMUTimer timer; +#if SLIRP_CHECK_VERSION(4,7,0) + Slirp *slirp; + SlirpTimerId id; + void *cb_opaque; +#endif +}; + +#if SLIRP_CHECK_VERSION(4,7,0) +static void net_slirp_init_completed(Slirp *slirp, void *opaque) +{ + SlirpState *s = opaque; + s->slirp = slirp; } +static void net_slirp_timer_cb(void *opaque) +{ + SlirpTimer *t = opaque; + slirp_handle_timer(t->slirp, t->id, t->cb_opaque); +} + +static void *net_slirp_timer_new_opaque(SlirpTimerId id, + void *cb_opaque, void *opaque) +{ + SlirpState *s = opaque; + SlirpTimer *t = g_new(SlirpTimer, 1); + t->slirp = s->slirp; + t->id = id; + t->cb_opaque = cb_opaque; + timer_init_full(&t->timer, NULL, QEMU_CLOCK_VIRTUAL, + SCALE_MS, QEMU_TIMER_ATTR_EXTERNAL, + net_slirp_timer_cb, t); + return t; +} +#else static void *net_slirp_timer_new(SlirpTimerCb cb, void *cb_opaque, void *opaque) { @@ -197,6 +230,7 @@ static void *net_slirp_timer_new(SlirpTimerCb cb, cb, cb_opaque); return t; } +#endif static void net_slirp_timer_free(void *timer, void *opaque) { @@ -231,7 +265,12 @@ static const SlirpCb slirp_cb = { .send_packet = net_slirp_send_packet, .guest_error = net_slirp_guest_error, .clock_get_ns = net_slirp_clock_get_ns, +#if SLIRP_CHECK_VERSION(4,7,0) + .init_completed = net_slirp_init_completed, + .timer_new_opaque = net_slirp_timer_new_opaque, +#else .timer_new = net_slirp_timer_new, +#endif .timer_free = net_slirp_timer_free, .timer_mod = net_slirp_timer_mod, .register_poll_fd = net_slirp_register_poll_fd, @@ -578,7 +617,7 @@ static int net_slirp_init(NetClientState *peer, const char *model, s = DO_UPCAST(SlirpState, nc, nc); - cfg.version = 1; + cfg.version = SLIRP_CHECK_VERSION(4,7,0) ? 4 : 1; cfg.restricted = restricted; cfg.in_enabled = ipv4; cfg.vnetwork = net;