diff options
author | Jan Kiszka <jan.kiszka@siemens.com> | 2009-06-24 14:42:31 +0200 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2009-06-29 08:52:50 -0500 |
commit | b1c99fcdf57ae4c3e8da22af13013a3aca69ef5e (patch) | |
tree | c47ba7360ba52b9e8fc65357b66f03fe1a7bd486 /slirp/slirp.c | |
parent | slirp: Allocate/free stack instance dynamically (diff) | |
download | qemu-kvm-b1c99fcdf57ae4c3e8da22af13013a3aca69ef5e.tar.gz qemu-kvm-b1c99fcdf57ae4c3e8da22af13013a3aca69ef5e.tar.bz2 qemu-kvm-b1c99fcdf57ae4c3e8da22af13013a3aca69ef5e.zip |
slirp: Enable multiple instances
Once again this was a long journey to reach the destination: Allow to
instantiate slirp multiple times. But as in the past, the journey was
worthwhile, cleaning up, fixing and enhancing various parts of the user
space network stack along the way.
What is this particular change good for? Multiple slirps instances
allow separated user space networks for guests with multiple NICs. This
is already possible, but without any slirp support for the second
network, ie. without a chance to talk to that network from the host via
IP. We have a legacy guest system here that benefits from this slirp
enhancement, allowing us to run both of its NICs purely over
unprivileged user space IP stacks.
Another benefit of this patch is that it simply removes an artificial
restriction of the configuration space qemu is providing, avoiding
another source of surprises that users may face when playing with
possible setups.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'slirp/slirp.c')
-rw-r--r-- | slirp/slirp.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/slirp/slirp.c b/slirp/slirp.c index 43aba3d15..fb666e656 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 |