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