diff options
-rw-r--r-- | net.c | 37 | ||||
-rw-r--r-- | slirp/slirp.c | 23 | ||||
-rw-r--r-- | slirp/slirp.h | 4 |
3 files changed, 37 insertions, 27 deletions
@@ -678,6 +678,7 @@ struct slirp_config_str { }; typedef struct SlirpState { + TAILQ_ENTRY(SlirpState) entry; VLANClientState *vc; Slirp *slirp; } SlirpState; @@ -685,7 +686,8 @@ typedef struct SlirpState { static struct slirp_config_str *slirp_configs; const char *legacy_tftp_prefix; const char *legacy_bootp_filename; -static SlirpState *slirp_state; +static TAILQ_HEAD(slirp_stacks, SlirpState) slirp_stacks = + TAILQ_HEAD_INITIALIZER(slirp_stacks); static void slirp_hostfwd(SlirpState *s, Monitor *mon, const char *redir_str, int legacy_format); @@ -734,7 +736,7 @@ static void net_slirp_cleanup(VLANClientState *vc) SlirpState *s = vc->opaque; slirp_cleanup(s->slirp); - slirp_state = NULL; + TAILQ_REMOVE(&slirp_stacks, s, entry); qemu_free(s); } @@ -842,7 +844,7 @@ static int net_slirp_init(Monitor *mon, VLANState *vlan, const char *model, s = qemu_mallocz(sizeof(SlirpState)); s->slirp = slirp_init(restricted, net, mask, host, vhostname, tftp_export, bootfile, dhcp, dns, s); - slirp_state = s; + TAILQ_INSERT_TAIL(&slirp_stacks, s, entry); while (slirp_configs) { struct slirp_config_str *config = slirp_configs; @@ -881,7 +883,7 @@ void net_slirp_hostfwd_remove(Monitor *mon, const char *src_str) int is_udp = 0; int err; - if (!slirp_state) { + if (TAILQ_EMPTY(&slirp_stacks)) { monitor_printf(mon, "user mode network stack not in use\n"); return; } @@ -908,7 +910,7 @@ void net_slirp_hostfwd_remove(Monitor *mon, const char *src_str) host_port = atoi(p); - err = slirp_remove_hostfwd(slirp_state->slirp, is_udp, + err = slirp_remove_hostfwd(TAILQ_FIRST(&slirp_stacks)->slirp, is_udp, host_addr, host_port); monitor_printf(mon, "host forwarding rule for %s %s\n", src_str, @@ -984,19 +986,19 @@ static void slirp_hostfwd(SlirpState *s, Monitor *mon, const char *redir_str, void net_slirp_hostfwd_add(Monitor *mon, const char *redir_str) { - if (!slirp_state) { + if (TAILQ_EMPTY(&slirp_stacks)) { monitor_printf(mon, "user mode network stack not in use\n"); return; } - slirp_hostfwd(slirp_state, mon, redir_str, 0); + slirp_hostfwd(TAILQ_FIRST(&slirp_stacks), mon, redir_str, 0); } void net_slirp_redir(const char *redir_str) { struct slirp_config_str *config; - if (!slirp_state) { + if (TAILQ_EMPTY(&slirp_stacks)) { config = qemu_malloc(sizeof(*config)); pstrcpy(config->str, sizeof(config->str), redir_str); config->flags = SLIRP_CFG_HOSTFWD | SLIRP_CFG_LEGACY; @@ -1005,7 +1007,7 @@ void net_slirp_redir(const char *redir_str) return; } - slirp_hostfwd(slirp_state, NULL, redir_str, 1); + slirp_hostfwd(TAILQ_FIRST(&slirp_stacks), NULL, redir_str, 1); } #ifndef _WIN32 @@ -1106,8 +1108,8 @@ void net_slirp_smb(const char *exported_dir) exit(1); } legacy_smb_export = exported_dir; - if (slirp_state) { - slirp_smb(slirp_state, exported_dir, vserver_addr); + if (!TAILQ_EMPTY(&slirp_stacks)) { + slirp_smb(TAILQ_FIRST(&slirp_stacks), exported_dir, vserver_addr); } } @@ -1198,13 +1200,12 @@ static void slirp_guestfwd(SlirpState *s, Monitor *mon, const char *config_str, void do_info_usernet(Monitor *mon) { - SlirpState *s = slirp_state; + SlirpState *s; - if (!s) { - return; + TAILQ_FOREACH(s, &slirp_stacks, entry) { + monitor_printf(mon, "VLAN %d (%s):\n", s->vc->vlan->id, s->vc->name); + slirp_connection_info(s->slirp, mon); } - monitor_printf(mon, "VLAN %d (%s):\n", s->vc->vlan->id, s->vc->name); - slirp_connection_info(s->slirp, mon); } #endif /* CONFIG_SLIRP */ @@ -2515,7 +2516,7 @@ int net_client_init(Monitor *mon, const char *device, const char *p) qemu_free(smb_export); qemu_free(vsmbsrv); } else if (!strcmp(device, "channel")) { - if (!slirp_state) { + if (TAILQ_EMPTY(&slirp_stacks)) { struct slirp_config_str *config; config = qemu_malloc(sizeof(*config)); @@ -2524,7 +2525,7 @@ int net_client_init(Monitor *mon, const char *device, const char *p) config->next = slirp_configs; slirp_configs = config; } else { - slirp_guestfwd(slirp_state, mon, p, 1); + slirp_guestfwd(TAILQ_FIRST(&slirp_stacks), mon, p, 1); } ret = 0; } else diff --git a/slirp/slirp.c b/slirp/slirp.c index 43aba3d152..fb666e6569 100644 --- a/slirp/slirp.c +++ b/slirp/slirp.c @@ -47,7 +47,8 @@ u_int curtime; static u_int time_fasttimo, last_slowtimo; static int do_slowtimo; -Slirp *slirp_instance; +TAILQ_HEAD(slirp_instances, Slirp) slirp_instances = + TAILQ_HEAD_INITIALIZER(slirp_instances); #ifdef _WIN32 @@ -223,20 +224,20 @@ Slirp *slirp_init(int restricted, struct in_addr vnetwork, register_savevm("slirp", 0, 2, slirp_state_save, slirp_state_load, slirp); - slirp_instance = slirp; + TAILQ_INSERT_TAIL(&slirp_instances, slirp, entry); return slirp; } void slirp_cleanup(Slirp *slirp) { + TAILQ_REMOVE(&slirp_instances, slirp, entry); + unregister_savevm("slirp", slirp); qemu_free(slirp->tftp_prefix); qemu_free(slirp->bootp_filename); qemu_free(slirp); - - slirp_instance = NULL; } #define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED) @@ -269,11 +270,11 @@ static void updtime(void) void slirp_select_fill(int *pnfds, fd_set *readfds, fd_set *writefds, fd_set *xfds) { - Slirp *slirp = slirp_instance; + Slirp *slirp; struct socket *so, *so_next; int nfds; - if (!slirp_instance) { + if (TAILQ_EMPTY(&slirp_instances)) { return; } @@ -288,11 +289,12 @@ void slirp_select_fill(int *pnfds, */ do_slowtimo = 0; + TAILQ_FOREACH(slirp, &slirp_instances, entry) { /* * *_slowtimo needs calling if there are IP fragments * in the fragment queue, or there are TCP connections active */ - do_slowtimo = ((slirp->tcb.so_next != &slirp->tcb) || + do_slowtimo |= ((slirp->tcb.so_next != &slirp->tcb) || (&slirp->ipq.ip_link != slirp->ipq.ip_link.next)); for (so = slirp->tcb.so_next; so != &slirp->tcb; @@ -383,6 +385,7 @@ void slirp_select_fill(int *pnfds, UPD_NFDS(so->s); } } + } *pnfds = nfds; } @@ -390,11 +393,11 @@ void slirp_select_fill(int *pnfds, void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds, int select_error) { - Slirp *slirp = slirp_instance; + Slirp *slirp; struct socket *so, *so_next; int ret; - if (!slirp_instance) { + if (TAILQ_EMPTY(&slirp_instances)) { return; } @@ -405,6 +408,7 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds, /* Update time */ updtime(); + TAILQ_FOREACH(slirp, &slirp_instances, entry) { /* * See if anything has timed out */ @@ -559,6 +563,7 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds, if (slirp->if_queued) { if_start(slirp); } + } /* clear global file descriptor sets. * these reside on the stack in vl.c diff --git a/slirp/slirp.h b/slirp/slirp.h index 5d8861ceb5..920d7a6213 100644 --- a/slirp/slirp.h +++ b/slirp/slirp.h @@ -185,6 +185,8 @@ int inet_aton _P((const char *cp, struct in_addr *ia)); #include "debug.h" +#include "sys-queue.h" + #include "libslirp.h" #include "ip.h" #include "tcp.h" @@ -207,6 +209,8 @@ int inet_aton _P((const char *cp, struct in_addr *ia)); #include "tftp.h" struct Slirp { + TAILQ_ENTRY(Slirp) entry; + /* virtual network configuration */ struct in_addr vnetwork_addr; struct in_addr vnetwork_mask; |