{ "host_net_remove", "is", net_host_device_remove,
"vlan_id name", "remove host VLAN client" },
#ifdef CONFIG_SLIRP
- { "host_net_redir", "s", net_slirp_redir,
- "[tcp|udp]:host-port:[guest-host]:guest-port", "redirect TCP or UDP connections from host to guest (requires -net user)" },
+ { "host_net_redir", "ss?", net_slirp_redir,
+ "[tcp|udp]:host-port:[guest-host]:guest-port", "redirect TCP or UDP connections from host to guest (requires -net user)\n"
+ "host_net_redir remove [tcp:|udp:]host-port -- remove redirection" },
#endif
{ "balloon", "i", do_balloon,
"target", "request VM to change it's memory allocation (in MB)" },
return 0;
}
-void net_slirp_redir(Monitor *mon, const char *redir_str)
+static void net_slirp_redir_rm(Monitor *mon, const char *port_str)
+{
+ int host_port;
+ char buf[256] = "";
+ const char *p = port_str;
+ int is_udp = 0;
+ int n;
+
+ if (!mon)
+ return;
+
+ if (!port_str || !port_str[0])
+ goto fail_syntax;
+
+ get_str_sep(buf, sizeof(buf), &p, ':');
+
+ if (!strcmp(buf, "tcp") || buf[0] == '\0') {
+ is_udp = 0;
+ } else if (!strcmp(buf, "udp")) {
+ is_udp = 1;
+ } else {
+ goto fail_syntax;
+ }
+
+ host_port = atoi(p);
+
+ n = slirp_redir_rm(is_udp, host_port);
+
+ monitor_printf(mon, "removed %d redirections to %s port %d\n", n,
+ is_udp ? "udp" : "tcp", host_port);
+ return;
+
+ fail_syntax:
+ monitor_printf(mon, "invalid format\n");
+}
+
+void net_slirp_redir(Monitor *mon, const char *redir_str, const char *redir_opt2)
{
int is_udp;
char buf[256], *r;
slirp_init(slirp_restrict, slirp_ip);
}
+ if (!strcmp(redir_str, "remove")) {
+ net_slirp_redir_rm(mon, redir_opt2);
+ return;
+ }
+
p = redir_str;
if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
goto fail_syntax;
void net_client_uninit(NICInfo *nd);
int net_client_parse(const char *str);
void net_slirp_smb(const char *exported_dir);
-void net_slirp_redir(Monitor *mon, const char *redir_str);
+void net_slirp_redir(Monitor *mon, const char *redir_str, const char *redir_opt2);
void net_cleanup(void);
int slirp_is_inited(void);
void net_client_check(void);
int slirp_can_output(void);
void slirp_output(const uint8_t *pkt, int pkt_len);
+int slirp_redir_rm(int is_udp, int host_port);
int slirp_redir(int is_udp, int host_port,
struct in_addr guest_addr, int guest_port);
int slirp_add_exec(int do_pty, const void *args, int addr_low_byte,
}
}
+/* Unlistens a redirection
+ *
+ * Return value: number of redirs removed */
+int slirp_redir_rm(int is_udp, int host_port)
+{
+ struct socket *so;
+ struct socket *head = (is_udp ? &udb : &tcb);
+ int fport = htons(host_port);
+ int n = 0;
+
+ loop_again:
+ for (so = head->so_next; so != head; so = so->so_next) {
+ if (so->so_fport == fport) {
+ close(so->s);
+ sofree(so);
+ n++;
+ goto loop_again;
+ }
+ }
+
+ return n;
+}
+
int slirp_redir(int is_udp, int host_port,
struct in_addr guest_addr, int guest_port)
{
break;
#endif
case QEMU_OPTION_redir:
- net_slirp_redir(NULL, optarg);
+ net_slirp_redir(NULL, optarg, NULL);
break;
#endif
case QEMU_OPTION_bt: