diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2022-04-11 12:24:58 +0200 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2022-04-11 12:36:41 +0200 |
commit | ec7c62a2715fef8d267a037166cd38d756e62188 (patch) | |
tree | 0032ea2b8e3f34b114e052e808b06a152a513a58 | |
parent | e7721e7fa54e4380533cf03875faadc5a67af4b7 (diff) | |
download | slirp-ec7c62a2715fef8d267a037166cd38d756e62188.zip slirp-ec7c62a2715fef8d267a037166cd38d756e62188.tar.gz slirp-ec7c62a2715fef8d267a037166cd38d756e62188.tar.bz2 |
slirp: invoke client callback before creating timers
The introduction of .timer_new_opaque adds an interesting conundrum.
The Slirp* needs to be stored in .timer_new_opaque so that it can be
passed back to slirp_handle_timer, but it is not returned by slirp_new
and slirp_init until after the first call to .timer_new_opaque (which
is in ip6_init). This is a problem for programs that, like QEMU, use
more than one Slirp*.
Fix them by passing the Slirp* to a callback before slirp_new returns,
and initializing the timer afterwards.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | src/ip6_icmp.c | 2 | ||||
-rw-r--r-- | src/ip6_icmp.h | 2 | ||||
-rw-r--r-- | src/ip6_input.c | 4 | ||||
-rw-r--r-- | src/libslirp.h | 2 | ||||
-rw-r--r-- | src/slirp.c | 6 | ||||
-rw-r--r-- | src/slirp.h | 2 |
6 files changed, 12 insertions, 6 deletions
diff --git a/src/ip6_icmp.c b/src/ip6_icmp.c index 181989c..0d7ee69 100644 --- a/src/ip6_icmp.c +++ b/src/ip6_icmp.c @@ -10,7 +10,7 @@ #define NDP_Interval \ g_rand_int_range(slirp->grand, NDP_MinRtrAdvInterval, NDP_MaxRtrAdvInterval) -void icmp6_init(Slirp *slirp) +void icmp6_post_init(Slirp *slirp) { if (!slirp->in6_enabled) { return; diff --git a/src/ip6_icmp.h b/src/ip6_icmp.h index 4420841..9f378f1 100644 --- a/src/ip6_icmp.h +++ b/src/ip6_icmp.h @@ -209,7 +209,7 @@ struct ndpopt { #define NDP_AdvPrefLifetime 14400 #define NDP_AdvAutonomousFlag 1 -void icmp6_init(Slirp *slirp); +void icmp6_post_init(Slirp *slirp); void icmp6_cleanup(Slirp *slirp); void icmp6_input(struct mbuf *); void icmp6_forward_error(struct mbuf *m, uint8_t type, uint8_t code, struct in6_addr *src); diff --git a/src/ip6_input.c b/src/ip6_input.c index b3d9865..4aca082 100644 --- a/src/ip6_input.c +++ b/src/ip6_input.c @@ -11,9 +11,9 @@ * IP initialization: fill in IP protocol switch table. * All protocols not implemented in kernel go to raw IP protocol handler. */ -void ip6_init(Slirp *slirp) +void ip6_post_init(Slirp *slirp) { - icmp6_init(slirp); + icmp6_post_init(slirp); } void ip6_cleanup(Slirp *slirp) diff --git a/src/libslirp.h b/src/libslirp.h index 8eb47a0..77396f0 100644 --- a/src/libslirp.h +++ b/src/libslirp.h @@ -82,6 +82,8 @@ typedef struct SlirpCb { * Fields introduced in SlirpConfig version 4 begin */ + /* Initialization has completed and a Slirp* has been created. */ + void (*init_completed)(Slirp *slirp, void *opaque); /* Create a new timer. When the timer fires, the application passes * the SlirpTimerId and cb_opaque to slirp_handle_timer. */ void *(*timer_new_opaque)(SlirpTimerId id, void *cb_opaque, void *opaque); diff --git a/src/slirp.c b/src/slirp.c index c92a9a9..1423b01 100644 --- a/src/slirp.c +++ b/src/slirp.c @@ -595,7 +595,6 @@ Slirp *slirp_new(const SlirpConfig *cfg, const SlirpCb *callbacks, void *opaque) if_init(slirp); ip_init(slirp); - ip6_init(slirp); m_init(slirp); @@ -645,6 +644,11 @@ Slirp *slirp_new(const SlirpConfig *cfg, const SlirpCb *callbacks, void *opaque) slirp->disable_dhcp = false; } + if (slirp->cfg_version >= 4 && slirp->cb->init_completed) { + slirp->cb->init_completed(slirp, slirp->opaque); + } + + ip6_post_init(slirp); return slirp; } diff --git a/src/slirp.h b/src/slirp.h index 50e33a5..35c2be3 100644 --- a/src/slirp.h +++ b/src/slirp.h @@ -246,7 +246,7 @@ void ip_stripoptions(register struct mbuf *, struct mbuf *); int ip_output(struct socket *, struct mbuf *); /* ip6_input.c */ -void ip6_init(Slirp *); +void ip6_post_init(Slirp *); void ip6_cleanup(Slirp *); void ip6_input(struct mbuf *); |