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 | 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 | 937 | struct in_addr host_addr = { .s_addr = INADDR_ANY }; |
| 913 | 938 | int host_port; |
| 914 | 939 | char buf[256] = ""; |
| 915 | - const char *p = src_str; | |
| 940 | + const char *src_str, *p; | |
| 941 | + SlirpState *s; | |
| 916 | 942 | int is_udp = 0; |
| 917 | 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 | 953 | return; |
| 922 | 954 | } |
| 923 | 955 | |
| 924 | 956 | if (!src_str || !src_str[0]) |
| 925 | 957 | goto fail_syntax; |
| 926 | 958 | |
| 959 | + p = src_str; | |
| 927 | 960 | get_str_sep(buf, sizeof(buf), &p, ':'); |
| 928 | 961 | |
| 929 | 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 | 999 | char *end; |
| 967 | 1000 | |
| 968 | 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 | 1003 | goto fail_syntax; |
| 971 | 1004 | } |
| 972 | 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 | 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 | 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 | 134 | void net_client_uninit(NICInfo *nd); |
| 135 | 135 | int net_client_parse(const char *str); |
| 136 | 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 | 141 | void net_slirp_redir(const char *redir_str); |
| 140 | 142 | void net_cleanup(void); |
| 141 | 143 | void net_client_check(void); | ... | ... |
qemu-monitor.hx
| ... | ... | @@ -536,11 +536,11 @@ Remove host VLAN client. |
| 536 | 536 | ETEXI |
| 537 | 537 | |
| 538 | 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 | 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 | 544 | "remove host-to-guest TCP or UDP redirection" }, |
| 545 | 545 | #endif |
| 546 | 546 | STEXI | ... | ... |