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 | ... | ... |