aboutsummaryrefslogtreecommitdiff
path: root/net.c
diff options
context:
space:
mode:
authorJan Kiszka <jan.kiszka@siemens.com>2009-06-24 14:42:31 +0200
committerAnthony Liguori <aliguori@us.ibm.com>2009-06-29 08:52:50 -0500
commitb1c99fcdf57ae4c3e8da22af13013a3aca69ef5e (patch)
treec47ba7360ba52b9e8fc65357b66f03fe1a7bd486 /net.c
parentad0d8c4c326c87ee3f193f90f31ec4af0fce5598 (diff)
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 'net.c')
-rw-r--r--net.c37
1 files changed, 19 insertions, 18 deletions
diff --git a/net.c b/net.c
index 389be4a6ad..f180b33c71 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 */
@@ -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