};
typedef struct SlirpState {
+ TAILQ_ENTRY(SlirpState) entry;
VLANClientState *vc;
Slirp *slirp;
} 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);
SlirpState *s = vc->opaque;
slirp_cleanup(s->slirp);
- slirp_state = NULL;
+ TAILQ_REMOVE(&slirp_stacks, s, entry);
qemu_free(s);
}
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;
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;
}
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,
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;
return;
}
- slirp_hostfwd(slirp_state, NULL, redir_str, 1);
+ slirp_hostfwd(TAILQ_FIRST(&slirp_stacks), NULL, redir_str, 1);
}
#ifndef _WIN32
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);
}
}
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 */
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));
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
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
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)
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;
}
*/
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;
UPD_NFDS(so->s);
}
}
+ }
*pnfds = nfds;
}
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;
}
/* Update time */
updtime();
+ TAILQ_FOREACH(slirp, &slirp_instances, entry) {
/*
* See if anything has timed out
*/
if (slirp->if_queued) {
if_start(slirp);
}
+ }
/* clear global file descriptor sets.
* these reside on the stack in vl.c