diff options
author | Marc-André Lureau <marcandre.lureau@gmail.com> | 2022-04-25 08:36:12 +0000 |
---|---|---|
committer | Marc-André Lureau <marcandre.lureau@gmail.com> | 2022-04-25 08:36:12 +0000 |
commit | 3b521f531f7b85d9d101b8d7dfa729c8f2d9208d (patch) | |
tree | ade86112b5f0bb1c6209ef720921904bcb933648 | |
parent | 888ddad6bde1dc6d7dbfc8daa7d015251b72e02c (diff) | |
parent | f65862ff117447bc69b137d36237ef1ea8868121 (diff) | |
download | slirp-3b521f531f7b85d9d101b8d7dfa729c8f2d9208d.zip slirp-3b521f531f7b85d9d101b8d7dfa729c8f2d9208d.tar.gz slirp-3b521f531f7b85d9d101b8d7dfa729c8f2d9208d.tar.bz2 |
Merge branch 'opaque-timer' into 'master'
Support for CFI
See merge request slirp/libslirp!117
-rw-r--r-- | meson.build | 6 | ||||
-rw-r--r-- | src/ip6_icmp.c | 26 | ||||
-rw-r--r-- | src/ip6_icmp.h | 4 | ||||
-rw-r--r-- | src/ip6_input.c | 4 | ||||
-rw-r--r-- | src/libslirp.h | 23 | ||||
-rw-r--r-- | src/libslirp.map | 4 | ||||
-rw-r--r-- | src/slirp.c | 44 | ||||
-rw-r--r-- | src/slirp.h | 5 | ||||
-rw-r--r-- | test/pingtest.c | 16 |
9 files changed, 100 insertions, 32 deletions
diff --git a/meson.build b/meson.build index 37d3bf4..1fb2cd3 100644 --- a/meson.build +++ b/meson.build @@ -44,9 +44,9 @@ conf.set_quoted('SLIRP_VERSION_STRING', full_version + get_option('version_suffi # - If the interface is the same as the previous version, but bugs are # fixed, change: # REVISION += 1 -lt_current = 3 -lt_revision = 1 -lt_age = 3 +lt_current = 4 +lt_revision = 0 +lt_age = 4 lt_version = '@0@.@1@.@2@'.format(lt_current - lt_age, lt_age, lt_revision) host_system = host_machine.system() diff --git a/src/ip6_icmp.c b/src/ip6_icmp.c index 738b40f..0d7ee69 100644 --- a/src/ip6_icmp.c +++ b/src/ip6_icmp.c @@ -10,25 +10,14 @@ #define NDP_Interval \ g_rand_int_range(slirp->grand, NDP_MinRtrAdvInterval, NDP_MaxRtrAdvInterval) -static void ra_timer_handler(void *opaque) -{ - Slirp *slirp = opaque; - - slirp->cb->timer_mod(slirp->ra_timer, - slirp->cb->clock_get_ns(slirp->opaque) / SCALE_MS + - NDP_Interval, - slirp->opaque); - ndp_send_ra(slirp); -} - -void icmp6_init(Slirp *slirp) +void icmp6_post_init(Slirp *slirp) { if (!slirp->in6_enabled) { return; } slirp->ra_timer = - slirp->cb->timer_new(ra_timer_handler, slirp, slirp->opaque); + slirp_timer_new(slirp, SLIRP_TIMER_RA, NULL); slirp->cb->timer_mod(slirp->ra_timer, slirp->cb->clock_get_ns(slirp->opaque) / SCALE_MS + NDP_Interval, @@ -140,7 +129,7 @@ void icmp6_send_error(struct mbuf *m, uint8_t type, uint8_t code) /* * Send NDP Router Advertisement */ -void ndp_send_ra(Slirp *slirp) +static void ndp_send_ra(Slirp *slirp) { DEBUG_CALL("ndp_send_ra"); @@ -219,6 +208,15 @@ void ndp_send_ra(Slirp *slirp) ip6_output(NULL, t, 0); } +void ra_timer_handler(Slirp *slirp, void *unused) +{ + slirp->cb->timer_mod(slirp->ra_timer, + slirp->cb->clock_get_ns(slirp->opaque) / SCALE_MS + + NDP_Interval, + slirp->opaque); + ndp_send_ra(slirp); +} + /* * Send NDP Neighbor Solitication */ diff --git a/src/ip6_icmp.h b/src/ip6_icmp.h index 9070999..9f378f1 100644 --- a/src/ip6_icmp.h +++ b/src/ip6_icmp.h @@ -209,12 +209,12 @@ 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); void icmp6_send_error(struct mbuf *m, uint8_t type, uint8_t code); -void ndp_send_ra(Slirp *slirp); void ndp_send_ns(Slirp *slirp, struct in6_addr addr); +void ra_timer_handler(Slirp *slirp, void *unused); #endif 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 1e75501..77396f0 100644 --- a/src/libslirp.h +++ b/src/libslirp.h @@ -39,6 +39,11 @@ typedef void (*SlirpTimerCb)(void *opaque); typedef int (*SlirpAddPollCb)(int fd, int events, void *opaque); typedef int (*SlirpGetREventsCb)(int idx, void *opaque); +typedef enum SlirpTimerId { + SLIRP_TIMER_RA, + SLIRP_TIMER_NUM, +} SlirpTimerId; + /* * Callbacks from slirp, to be set by the application. * @@ -58,7 +63,8 @@ typedef struct SlirpCb { void (*guest_error)(const char *msg, void *opaque); /* Return the virtual clock value in nanoseconds */ int64_t (*clock_get_ns)(void *opaque); - /* Create a new timer with the given callback and opaque data */ + /* Create a new timer with the given callback and opaque data. Not + * needed if timer_new_opaque is provided. */ void *(*timer_new)(SlirpTimerCb cb, void *cb_opaque, void *opaque); /* Remove and free a timer */ void (*timer_free)(void *timer, void *opaque); @@ -71,6 +77,16 @@ typedef struct SlirpCb { /* Kick the io-thread, to signal that new events may be processed because some TCP buffer * can now receive more data, i.e. slirp_socket_can_recv will return 1. */ void (*notify)(void *opaque); + + /* + * 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); } SlirpCb; #define SLIRP_CONFIG_VERSION_MIN 1 @@ -166,6 +182,11 @@ void slirp_pollfds_poll(Slirp *slirp, int select_error, * guest network, to be interpreted by slirp. */ void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len); +/* This is called by the application when a timer expires, if it provides + * the timer_new_opaque callback. It is not needed if the application only + * uses timer_new. */ +void slirp_handle_timer(Slirp *slirp, SlirpTimerId id, void *cb_opaque); + /* These set up / remove port forwarding between a host port in the real world * and the guest network. */ int slirp_add_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr, diff --git a/src/libslirp.map b/src/libslirp.map index 792b0a9..3921f8a 100644 --- a/src/libslirp.map +++ b/src/libslirp.map @@ -34,3 +34,7 @@ SLIRP_4.5 { slirp_remove_hostxfwd; slirp_neighbor_info; } SLIRP_4.2; + +SLIRP_4.7 { + slirp_handle_timer; +} SLIRP_4.5; diff --git a/src/slirp.c b/src/slirp.c index 5e08b53..1423b01 100644 --- a/src/slirp.c +++ b/src/slirp.c @@ -528,6 +528,43 @@ static void slirp_init_once(void) } } +static void ra_timer_handler_cb(void *opaque) +{ + Slirp *slirp = opaque; + + return ra_timer_handler(slirp, NULL); +} + +void slirp_handle_timer(Slirp *slirp, SlirpTimerId id, void *cb_opaque) +{ + g_return_if_fail(id >= 0 && id < SLIRP_TIMER_NUM); + + switch (id) { + case SLIRP_TIMER_RA: + return ra_timer_handler(slirp, cb_opaque); + default: + abort(); + } +} + +void *slirp_timer_new(Slirp *slirp, SlirpTimerId id, void *cb_opaque) +{ + g_return_val_if_fail(id >= 0 && id < SLIRP_TIMER_NUM, NULL); + + if (slirp->cfg_version >= 4 && slirp->cb->timer_new_opaque) { + return slirp->cb->timer_new_opaque(id, cb_opaque, slirp->opaque); + } + + switch (id) { + case SLIRP_TIMER_RA: + g_return_val_if_fail(cb_opaque == NULL, NULL); + return slirp->cb->timer_new(ra_timer_handler_cb, slirp, slirp->opaque); + + default: + abort(); + } +} + Slirp *slirp_new(const SlirpConfig *cfg, const SlirpCb *callbacks, void *opaque) { Slirp *slirp; @@ -547,6 +584,7 @@ Slirp *slirp_new(const SlirpConfig *cfg, const SlirpCb *callbacks, void *opaque) slirp_init_once(); + slirp->cfg_version = cfg->version; slirp->opaque = opaque; slirp->cb = callbacks; slirp->grand = g_rand_new(); @@ -557,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); @@ -607,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 239d570..35c2be3 100644 --- a/src/slirp.h +++ b/src/slirp.h @@ -120,6 +120,8 @@ bool ndp_table_search(Slirp *slirp, struct in6_addr ip_addr, uint8_t out_ethaddr[ETH_ALEN]); struct Slirp { + int cfg_version; + unsigned time_fasttimo; unsigned last_slowtimo; bool do_slowtimo; @@ -244,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 *); @@ -280,5 +282,6 @@ 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); +void *slirp_timer_new(Slirp *slirp, SlirpTimerId id, void *cb_opaque); #endif diff --git a/test/pingtest.c b/test/pingtest.c index 15249f0..3bb0488 100644 --- a/test/pingtest.c +++ b/test/pingtest.c @@ -196,7 +196,7 @@ static int64_t clock_get_ns(void *opaque) { } struct timer { - SlirpTimerCb cb; + SlirpTimerId id; void *cb_opaque; int64_t expire; struct timer *next; @@ -204,9 +204,9 @@ struct timer { static struct timer *timer_queue; -static void *timer_new(SlirpTimerCb cb, void *cb_opaque, void *opaque) { +static void *timer_new_opaque(SlirpTimerId id, void *cb_opaque, void *opaque) { struct timer *new_timer = malloc(sizeof(*new_timer)); - new_timer->cb = cb; + new_timer->id = id; new_timer->cb_opaque = cb_opaque; new_timer->next = NULL; return new_timer; @@ -242,14 +242,14 @@ static void timer_mod(void *_timer, int64_t expire_time, void *opaque) { *t = timer; } -static void timer_check(void) { +static void timer_check(Slirp *slirp) { while (timer_queue && timer_queue->expire <= mytime) { struct timer *t = timer_queue; printf("handling %p at time %lu\n", t, (unsigned long) timer_queue->expire); timer_queue = t->next; - t->cb(t->cb_opaque); + slirp_handle_timer(slirp, t->id, t->cb_opaque); } } @@ -378,7 +378,7 @@ static struct SlirpCb callbacks = { .send_packet = send_packet, .guest_error = guest_error, .clock_get_ns = clock_get_ns, - .timer_new = timer_new, + .timer_new_opaque = timer_new_opaque, .timer_free = timer_free, .timer_mod = timer_mod, .register_poll_fd = register_poll_fd, @@ -389,7 +389,7 @@ static struct SlirpCb callbacks = { int main(int argc, char *argv[]) { SlirpConfig config = { - .version = 3, + .version = 4, .restricted = false, .in_enabled = true, .vnetwork.s_addr = htonl(0x0a000200), @@ -472,7 +472,7 @@ int main(int argc, char *argv[]) { while (!done) { printf("time %lu\n", (unsigned long) mytime); - timer_check(); + timer_check(slirp); /* Here we make the virtual time wait like the real time, but we could * make it wait differently */ timeout = timer_timeout(); |