slirp: Make hostfwd_add/remove multi-instance-aware

Extend the syntax of hostfwd_add/remove to optionally take a tuple of
VLAN ID and slirp stack name. If those are omitted, the commands will
continue to work on the first registered slirp stack.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
Jan Kiszka 2009-06-24 14:42:32 +02:00 committed by Anthony Liguori
parent 1a60952027
commit f13b572cb3
3 changed files with 60 additions and 16 deletions

62
net.c
View File

@ -907,23 +907,56 @@ static int net_slirp_init(Monitor *mon, VLANState *vlan, const char *model,
return 0; return 0;
} }
void net_slirp_hostfwd_remove(Monitor *mon, const char *src_str) static SlirpState *slirp_lookup(Monitor *mon, const char *vlan,
const char *stack)
{
VLANClientState *vc;
if (vlan) {
vc = qemu_find_vlan_client_by_name(mon, strtol(vlan, NULL, 0), stack);
if (!vc) {
return NULL;
}
if (strcmp(vc->model, "user")) {
monitor_printf(mon, "invalid device specified\n");
return NULL;
}
return vc->opaque;
} else {
if (TAILQ_EMPTY(&slirp_stacks)) {
monitor_printf(mon, "user mode network stack not in use\n");
return NULL;
}
return TAILQ_FIRST(&slirp_stacks);
}
}
void net_slirp_hostfwd_remove(Monitor *mon, const char *arg1,
const char *arg2, const char *arg3)
{ {
struct in_addr host_addr = { .s_addr = INADDR_ANY }; struct in_addr host_addr = { .s_addr = INADDR_ANY };
int host_port; int host_port;
char buf[256] = ""; char buf[256] = "";
const char *p = src_str; const char *src_str, *p;
SlirpState *s;
int is_udp = 0; int is_udp = 0;
int err; int err;
if (TAILQ_EMPTY(&slirp_stacks)) { if (arg2) {
monitor_printf(mon, "user mode network stack not in use\n"); s = slirp_lookup(mon, arg1, arg2);
src_str = arg3;
} else {
s = slirp_lookup(mon, NULL, NULL);
src_str = arg1;
}
if (!s) {
return; return;
} }
if (!src_str || !src_str[0]) if (!src_str || !src_str[0])
goto fail_syntax; goto fail_syntax;
p = src_str;
get_str_sep(buf, sizeof(buf), &p, ':'); get_str_sep(buf, sizeof(buf), &p, ':');
if (!strcmp(buf, "tcp") || buf[0] == '\0') { if (!strcmp(buf, "tcp") || buf[0] == '\0') {
@ -966,7 +999,7 @@ static void slirp_hostfwd(SlirpState *s, Monitor *mon, const char *redir_str,
char *end; char *end;
p = redir_str; p = redir_str;
if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) { if (!p || get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
goto fail_syntax; goto fail_syntax;
} }
if (!strcmp(buf, "tcp") || buf[0] == '\0') { if (!strcmp(buf, "tcp") || buf[0] == '\0') {
@ -1017,14 +1050,23 @@ static void slirp_hostfwd(SlirpState *s, Monitor *mon, const char *redir_str,
config_error(mon, "invalid host forwarding rule '%s'\n", redir_str); config_error(mon, "invalid host forwarding rule '%s'\n", redir_str);
} }
void net_slirp_hostfwd_add(Monitor *mon, const char *redir_str) void net_slirp_hostfwd_add(Monitor *mon, const char *arg1,
const char *arg2, const char *arg3)
{ {
if (TAILQ_EMPTY(&slirp_stacks)) { const char *redir_str;
monitor_printf(mon, "user mode network stack not in use\n"); SlirpState *s;
return;
if (arg2) {
s = slirp_lookup(mon, arg1, arg2);
redir_str = arg3;
} else {
s = slirp_lookup(mon, NULL, NULL);
redir_str = arg1;
}
if (s) {
slirp_hostfwd(s, mon, redir_str, 0);
} }
slirp_hostfwd(TAILQ_FIRST(&slirp_stacks), mon, redir_str, 0);
} }
void net_slirp_redir(const char *redir_str) void net_slirp_redir(const char *redir_str)

6
net.h
View File

@ -134,8 +134,10 @@ int net_client_init(Monitor *mon, const char *device, const char *p);
void net_client_uninit(NICInfo *nd); void net_client_uninit(NICInfo *nd);
int net_client_parse(const char *str); int net_client_parse(const char *str);
void net_slirp_smb(const char *exported_dir); void net_slirp_smb(const char *exported_dir);
void net_slirp_hostfwd_add(Monitor *mon, const char *redir_str); void net_slirp_hostfwd_add(Monitor *mon, const char *arg1,
void net_slirp_hostfwd_remove(Monitor *mon, const char *src_str); const char *arg2, const char *arg3);
void net_slirp_hostfwd_remove(Monitor *mon, const char *arg1,
const char *arg2, const char *arg3);
void net_slirp_redir(const char *redir_str); void net_slirp_redir(const char *redir_str);
void net_cleanup(void); void net_cleanup(void);
void net_client_check(void); void net_client_check(void);

View File

@ -536,11 +536,11 @@ Remove host VLAN client.
ETEXI ETEXI
#ifdef CONFIG_SLIRP #ifdef CONFIG_SLIRP
{ "hostfwd_add", "s", net_slirp_hostfwd_add, { "hostfwd_add", "ss?s?", net_slirp_hostfwd_add,
"[tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport", "[vlan_id name] [tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport",
"redirect TCP or UDP connections from host to guest (requires -net user)" }, "redirect TCP or UDP connections from host to guest (requires -net user)" },
{ "hostfwd_remove", "s", net_slirp_hostfwd_remove, { "hostfwd_remove", "ss?s?", net_slirp_hostfwd_remove,
"[tcp|udp]:[hostaddr]:hostport", "[vlan_id name] [tcp|udp]:[hostaddr]:hostport",
"remove host-to-guest TCP or UDP redirection" }, "remove host-to-guest TCP or UDP redirection" },
#endif #endif
STEXI STEXI