Commit f13b572cb38ec8c74a0670b3554d48e7cbf20b4b

Authored by Jan Kiszka
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>
@@ -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)
@@ -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