Commit f13b572cb38ec8c74a0670b3554d48e7cbf20b4b
Committed by
Anthony Liguori
1 parent
1a609520
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>
Showing
3 changed files
with
60 additions
and
16 deletions
net.c
| @@ -907,23 +907,56 @@ static int net_slirp_init(Monitor *mon, VLANState *vlan, const char *model, | @@ -907,23 +907,56 @@ static int net_slirp_init(Monitor *mon, VLANState *vlan, const char *model, | ||
| 907 | return 0; | 907 | return 0; |
| 908 | } | 908 | } |
| 909 | 909 | ||
| 910 | -void net_slirp_hostfwd_remove(Monitor *mon, const char *src_str) | 910 | +static SlirpState *slirp_lookup(Monitor *mon, const char *vlan, |
| 911 | + const char *stack) | ||
| 912 | +{ | ||
| 913 | + VLANClientState *vc; | ||
| 914 | + | ||
| 915 | + if (vlan) { | ||
| 916 | + vc = qemu_find_vlan_client_by_name(mon, strtol(vlan, NULL, 0), stack); | ||
| 917 | + if (!vc) { | ||
| 918 | + return NULL; | ||
| 919 | + } | ||
| 920 | + if (strcmp(vc->model, "user")) { | ||
| 921 | + monitor_printf(mon, "invalid device specified\n"); | ||
| 922 | + return NULL; | ||
| 923 | + } | ||
| 924 | + return vc->opaque; | ||
| 925 | + } else { | ||
| 926 | + if (TAILQ_EMPTY(&slirp_stacks)) { | ||
| 927 | + monitor_printf(mon, "user mode network stack not in use\n"); | ||
| 928 | + return NULL; | ||
| 929 | + } | ||
| 930 | + return TAILQ_FIRST(&slirp_stacks); | ||
| 931 | + } | ||
| 932 | +} | ||
| 933 | + | ||
| 934 | +void net_slirp_hostfwd_remove(Monitor *mon, const char *arg1, | ||
| 935 | + const char *arg2, const char *arg3) | ||
| 911 | { | 936 | { |
| 912 | struct in_addr host_addr = { .s_addr = INADDR_ANY }; | 937 | struct in_addr host_addr = { .s_addr = INADDR_ANY }; |
| 913 | int host_port; | 938 | int host_port; |
| 914 | char buf[256] = ""; | 939 | char buf[256] = ""; |
| 915 | - const char *p = src_str; | 940 | + const char *src_str, *p; |
| 941 | + SlirpState *s; | ||
| 916 | int is_udp = 0; | 942 | int is_udp = 0; |
| 917 | int err; | 943 | int err; |
| 918 | 944 | ||
| 919 | - if (TAILQ_EMPTY(&slirp_stacks)) { | ||
| 920 | - monitor_printf(mon, "user mode network stack not in use\n"); | 945 | + if (arg2) { |
| 946 | + s = slirp_lookup(mon, arg1, arg2); | ||
| 947 | + src_str = arg3; | ||
| 948 | + } else { | ||
| 949 | + s = slirp_lookup(mon, NULL, NULL); | ||
| 950 | + src_str = arg1; | ||
| 951 | + } | ||
| 952 | + if (!s) { | ||
| 921 | return; | 953 | return; |
| 922 | } | 954 | } |
| 923 | 955 | ||
| 924 | if (!src_str || !src_str[0]) | 956 | if (!src_str || !src_str[0]) |
| 925 | goto fail_syntax; | 957 | goto fail_syntax; |
| 926 | 958 | ||
| 959 | + p = src_str; | ||
| 927 | get_str_sep(buf, sizeof(buf), &p, ':'); | 960 | get_str_sep(buf, sizeof(buf), &p, ':'); |
| 928 | 961 | ||
| 929 | if (!strcmp(buf, "tcp") || buf[0] == '\0') { | 962 | if (!strcmp(buf, "tcp") || buf[0] == '\0') { |
| @@ -966,7 +999,7 @@ static void slirp_hostfwd(SlirpState *s, Monitor *mon, const char *redir_str, | @@ -966,7 +999,7 @@ static void slirp_hostfwd(SlirpState *s, Monitor *mon, const char *redir_str, | ||
| 966 | char *end; | 999 | char *end; |
| 967 | 1000 | ||
| 968 | p = redir_str; | 1001 | p = redir_str; |
| 969 | - if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) { | 1002 | + if (!p || get_str_sep(buf, sizeof(buf), &p, ':') < 0) { |
| 970 | goto fail_syntax; | 1003 | goto fail_syntax; |
| 971 | } | 1004 | } |
| 972 | if (!strcmp(buf, "tcp") || buf[0] == '\0') { | 1005 | if (!strcmp(buf, "tcp") || buf[0] == '\0') { |
| @@ -1017,14 +1050,23 @@ static void slirp_hostfwd(SlirpState *s, Monitor *mon, const char *redir_str, | @@ -1017,14 +1050,23 @@ static void slirp_hostfwd(SlirpState *s, Monitor *mon, const char *redir_str, | ||
| 1017 | config_error(mon, "invalid host forwarding rule '%s'\n", redir_str); | 1050 | config_error(mon, "invalid host forwarding rule '%s'\n", redir_str); |
| 1018 | } | 1051 | } |
| 1019 | 1052 | ||
| 1020 | -void net_slirp_hostfwd_add(Monitor *mon, const char *redir_str) | 1053 | +void net_slirp_hostfwd_add(Monitor *mon, const char *arg1, |
| 1054 | + const char *arg2, const char *arg3) | ||
| 1021 | { | 1055 | { |
| 1022 | - if (TAILQ_EMPTY(&slirp_stacks)) { | ||
| 1023 | - monitor_printf(mon, "user mode network stack not in use\n"); | ||
| 1024 | - return; | 1056 | + const char *redir_str; |
| 1057 | + SlirpState *s; | ||
| 1058 | + | ||
| 1059 | + if (arg2) { | ||
| 1060 | + s = slirp_lookup(mon, arg1, arg2); | ||
| 1061 | + redir_str = arg3; | ||
| 1062 | + } else { | ||
| 1063 | + s = slirp_lookup(mon, NULL, NULL); | ||
| 1064 | + redir_str = arg1; | ||
| 1065 | + } | ||
| 1066 | + if (s) { | ||
| 1067 | + slirp_hostfwd(s, mon, redir_str, 0); | ||
| 1025 | } | 1068 | } |
| 1026 | 1069 | ||
| 1027 | - slirp_hostfwd(TAILQ_FIRST(&slirp_stacks), mon, redir_str, 0); | ||
| 1028 | } | 1070 | } |
| 1029 | 1071 | ||
| 1030 | void net_slirp_redir(const char *redir_str) | 1072 | void net_slirp_redir(const char *redir_str) |
net.h
| @@ -134,8 +134,10 @@ int net_client_init(Monitor *mon, const char *device, const char *p); | @@ -134,8 +134,10 @@ int net_client_init(Monitor *mon, const char *device, const char *p); | ||
| 134 | void net_client_uninit(NICInfo *nd); | 134 | void net_client_uninit(NICInfo *nd); |
| 135 | int net_client_parse(const char *str); | 135 | int net_client_parse(const char *str); |
| 136 | void net_slirp_smb(const char *exported_dir); | 136 | void net_slirp_smb(const char *exported_dir); |
| 137 | -void net_slirp_hostfwd_add(Monitor *mon, const char *redir_str); | ||
| 138 | -void net_slirp_hostfwd_remove(Monitor *mon, const char *src_str); | 137 | +void net_slirp_hostfwd_add(Monitor *mon, const char *arg1, |
| 138 | + const char *arg2, const char *arg3); | ||
| 139 | +void net_slirp_hostfwd_remove(Monitor *mon, const char *arg1, | ||
| 140 | + const char *arg2, const char *arg3); | ||
| 139 | void net_slirp_redir(const char *redir_str); | 141 | void net_slirp_redir(const char *redir_str); |
| 140 | void net_cleanup(void); | 142 | void net_cleanup(void); |
| 141 | void net_client_check(void); | 143 | void net_client_check(void); |
qemu-monitor.hx
| @@ -536,11 +536,11 @@ Remove host VLAN client. | @@ -536,11 +536,11 @@ Remove host VLAN client. | ||
| 536 | ETEXI | 536 | ETEXI |
| 537 | 537 | ||
| 538 | #ifdef CONFIG_SLIRP | 538 | #ifdef CONFIG_SLIRP |
| 539 | - { "hostfwd_add", "s", net_slirp_hostfwd_add, | ||
| 540 | - "[tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport", | 539 | + { "hostfwd_add", "ss?s?", net_slirp_hostfwd_add, |
| 540 | + "[vlan_id name] [tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport", | ||
| 541 | "redirect TCP or UDP connections from host to guest (requires -net user)" }, | 541 | "redirect TCP or UDP connections from host to guest (requires -net user)" }, |
| 542 | - { "hostfwd_remove", "s", net_slirp_hostfwd_remove, | ||
| 543 | - "[tcp|udp]:[hostaddr]:hostport", | 542 | + { "hostfwd_remove", "ss?s?", net_slirp_hostfwd_remove, |
| 543 | + "[vlan_id name] [tcp|udp]:[hostaddr]:hostport", | ||
| 544 | "remove host-to-guest TCP or UDP redirection" }, | 544 | "remove host-to-guest TCP or UDP redirection" }, |
| 545 | #endif | 545 | #endif |
| 546 | STEXI | 546 | STEXI |