[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 34/41] slirp: Enable multiple instances
From: |
Jan Kiszka |
Subject: |
[Qemu-devel] [PATCH 34/41] slirp: Enable multiple instances |
Date: |
Wed, 24 Jun 2009 14:42:31 +0200 |
User-agent: |
StGIT/0.14.3 |
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 <address@hidden>
---
net.c | 37 +++++++++++++++++++------------------
slirp/slirp.c | 23 ++++++++++++++---------
slirp/slirp.h | 4 ++++
3 files changed, 37 insertions(+), 27 deletions(-)
diff --git a/net.c b/net.c
index 0c58124..0c1a99b 100644
--- a/net.c
+++ b/net.c
@@ -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 */
@@ -2499,7 +2500,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));
@@ -2508,7 +2509,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 43aba3d..fb666e6 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 5d8861c..920d7a6 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;
- Re: [Qemu-devel] [PATCH 25/41] slirp: Make IP packet ID consistent, (continued)
[Qemu-devel] [PATCH 27/41] slirp: Kill slirp_is_inited, Jan Kiszka, 2009/06/24
[Qemu-devel] [PATCH 28/41] slirp: Drop redundant checks from slirp_output, Jan Kiszka, 2009/06/24
[Qemu-devel] [PATCH 36/41] slirp: Use shell to erase smb directory, Jan Kiszka, 2009/06/24
[Qemu-devel] [PATCH 35/41] slirp: Save/restore bootp client states, Jan Kiszka, 2009/06/24
[Qemu-devel] [PATCH 32/41] slirp: Use internal state in interface, Jan Kiszka, 2009/06/24
[Qemu-devel] [PATCH 33/41] slirp: Allocate/free stack instance dynamically, Jan Kiszka, 2009/06/24
[Qemu-devel] [PATCH 31/41] slirp: Factor out internal state structure, Jan Kiszka, 2009/06/24
[Qemu-devel] [PATCH 34/41] slirp: Enable multiple instances,
Jan Kiszka <=
[Qemu-devel] [PATCH 41/41] slirp: Basic VLAN client info_str, Jan Kiszka, 2009/06/24
[Qemu-devel] [PATCH 39/41] net: Provide VLAN client lookup helper, Jan Kiszka, 2009/06/24
[Qemu-devel] [PATCH 40/41] slirp: Make hostfwd_add/remove multi-instance-aware, Jan Kiszka, 2009/06/24
[Qemu-devel] [PATCH 37/41] slirp: Improve error handling in slirp_smb, Jan Kiszka, 2009/06/24
[Qemu-devel] [PATCH 38/41] slirp: Enable multi-instance support for the smb service, Jan Kiszka, 2009/06/24
[Qemu-devel] Re: [PATCH 00/41] Slirp Fixes and Enhancements - Reloaded, Anthony Liguori, 2009/06/24
[Qemu-devel] [PATCH 30/41] slirp: Drop link_up checks from if_output and slirp_socket_can_recv, Jan Kiszka, 2009/06/24
[Qemu-devel] [PATCH 22/41] slirp: tftp: Refactor tftp_handle_rrq, Jan Kiszka, 2009/06/24
[Qemu-devel] [PATCH 05/41] slirp: Move smb, redir, tftp and bootp parameters and -net channel, Jan Kiszka, 2009/06/24
[Qemu-devel] [PATCH 16/41] slirp: Drop dead code, Jan Kiszka, 2009/06/24