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.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
net/slirp.c | 41 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 40 insertions(+), 1 deletion(-)
diff --git a/net/slirp.c b/net/slirp.c
index b3a92d6e38..57af42299d 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 = 3;
+ cfg.version = SLIRP_CHECK_VERSION(4,7,0) ? 4 : 3;
cfg.restricted = restricted;
cfg.in_enabled = ipv4;
cfg.vnetwork = net;
--
2.35.1
Paolo Bonzini, le mar. 12 avril 2022 14:13:36 +0200, a ecrit:
> 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.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
> ---
> net/slirp.c | 41 ++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 40 insertions(+), 1 deletion(-)
>
> diff --git a/net/slirp.c b/net/slirp.c
> index b3a92d6e38..57af42299d 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 = 3;
> + cfg.version = SLIRP_CHECK_VERSION(4,7,0) ? 4 : 3;
> cfg.restricted = restricted;
> cfg.in_enabled = ipv4;
> cfg.vnetwork = net;
> --
> 2.35.1
>
>
--
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.
© 2016 - 2026 Red Hat, Inc.