aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2022-04-11 12:24:58 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2022-04-11 12:36:41 +0200
commitec7c62a2715fef8d267a037166cd38d756e62188 (patch)
tree0032ea2b8e3f34b114e052e808b06a152a513a58
parente7721e7fa54e4380533cf03875faadc5a67af4b7 (diff)
downloadslirp-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.c2
-rw-r--r--src/ip6_icmp.h2
-rw-r--r--src/ip6_input.c4
-rw-r--r--src/libslirp.h2
-rw-r--r--src/slirp.c6
-rw-r--r--src/slirp.h2
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 *);