Commit c1261d8d1617d8cf5722039a59ebb66c310f3aea
Committed by
Anthony Liguori
1 parent
8a43b1ea
User Networking: Enable removal of redirections
Using the new host_net_redir command you can easily create redirections on the fly while your VM is running. While that's great, it's missing the removal of redirections, in case you want to have a port closed again at a later point in time. This patch adds support for removal of redirections. Signed-off-by: Alexander Graf <agraf@suse.de> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Showing
6 changed files
with
71 additions
and
5 deletions
monitor.c
... | ... | @@ -1759,8 +1759,9 @@ static const mon_cmd_t mon_cmds[] = { |
1759 | 1759 | { "host_net_remove", "is", net_host_device_remove, |
1760 | 1760 | "vlan_id name", "remove host VLAN client" }, |
1761 | 1761 | #ifdef CONFIG_SLIRP |
1762 | - { "host_net_redir", "s", net_slirp_redir, | |
1763 | - "[tcp|udp]:host-port:[guest-host]:guest-port", "redirect TCP or UDP connections from host to guest (requires -net user)" }, | |
1762 | + { "host_net_redir", "ss?", net_slirp_redir, | |
1763 | + "[tcp|udp]:host-port:[guest-host]:guest-port", "redirect TCP or UDP connections from host to guest (requires -net user)\n" | |
1764 | + "host_net_redir remove [tcp:|udp:]host-port -- remove redirection" }, | |
1764 | 1765 | #endif |
1765 | 1766 | { "balloon", "i", do_balloon, |
1766 | 1767 | "target", "request VM to change it's memory allocation (in MB)" }, | ... | ... |
net.c
... | ... | @@ -568,7 +568,43 @@ static int net_slirp_init(VLANState *vlan, const char *model, const char *name) |
568 | 568 | return 0; |
569 | 569 | } |
570 | 570 | |
571 | -void net_slirp_redir(Monitor *mon, const char *redir_str) | |
571 | +static void net_slirp_redir_rm(Monitor *mon, const char *port_str) | |
572 | +{ | |
573 | + int host_port; | |
574 | + char buf[256] = ""; | |
575 | + const char *p = port_str; | |
576 | + int is_udp = 0; | |
577 | + int n; | |
578 | + | |
579 | + if (!mon) | |
580 | + return; | |
581 | + | |
582 | + if (!port_str || !port_str[0]) | |
583 | + goto fail_syntax; | |
584 | + | |
585 | + get_str_sep(buf, sizeof(buf), &p, ':'); | |
586 | + | |
587 | + if (!strcmp(buf, "tcp") || buf[0] == '\0') { | |
588 | + is_udp = 0; | |
589 | + } else if (!strcmp(buf, "udp")) { | |
590 | + is_udp = 1; | |
591 | + } else { | |
592 | + goto fail_syntax; | |
593 | + } | |
594 | + | |
595 | + host_port = atoi(p); | |
596 | + | |
597 | + n = slirp_redir_rm(is_udp, host_port); | |
598 | + | |
599 | + monitor_printf(mon, "removed %d redirections to %s port %d\n", n, | |
600 | + is_udp ? "udp" : "tcp", host_port); | |
601 | + return; | |
602 | + | |
603 | + fail_syntax: | |
604 | + monitor_printf(mon, "invalid format\n"); | |
605 | +} | |
606 | + | |
607 | +void net_slirp_redir(Monitor *mon, const char *redir_str, const char *redir_opt2) | |
572 | 608 | { |
573 | 609 | int is_udp; |
574 | 610 | char buf[256], *r; |
... | ... | @@ -581,6 +617,11 @@ void net_slirp_redir(Monitor *mon, const char *redir_str) |
581 | 617 | slirp_init(slirp_restrict, slirp_ip); |
582 | 618 | } |
583 | 619 | |
620 | + if (!strcmp(redir_str, "remove")) { | |
621 | + net_slirp_redir_rm(mon, redir_opt2); | |
622 | + return; | |
623 | + } | |
624 | + | |
584 | 625 | p = redir_str; |
585 | 626 | if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) |
586 | 627 | goto fail_syntax; | ... | ... |
net.h
... | ... | @@ -112,7 +112,7 @@ int net_client_init(const char *device, const char *p); |
112 | 112 | void net_client_uninit(NICInfo *nd); |
113 | 113 | int net_client_parse(const char *str); |
114 | 114 | void net_slirp_smb(const char *exported_dir); |
115 | -void net_slirp_redir(Monitor *mon, const char *redir_str); | |
115 | +void net_slirp_redir(Monitor *mon, const char *redir_str, const char *redir_opt2); | |
116 | 116 | void net_cleanup(void); |
117 | 117 | int slirp_is_inited(void); |
118 | 118 | void net_client_check(void); | ... | ... |
slirp/libslirp.h
... | ... | @@ -18,6 +18,7 @@ void slirp_input(const uint8_t *pkt, int pkt_len); |
18 | 18 | int slirp_can_output(void); |
19 | 19 | void slirp_output(const uint8_t *pkt, int pkt_len); |
20 | 20 | |
21 | +int slirp_redir_rm(int is_udp, int host_port); | |
21 | 22 | int slirp_redir(int is_udp, int host_port, |
22 | 23 | struct in_addr guest_addr, int guest_port); |
23 | 24 | int slirp_add_exec(int do_pty, const void *args, int addr_low_byte, | ... | ... |
slirp/slirp.c
... | ... | @@ -734,6 +734,29 @@ void if_encap(const uint8_t *ip_data, int ip_data_len) |
734 | 734 | } |
735 | 735 | } |
736 | 736 | |
737 | +/* Unlistens a redirection | |
738 | + * | |
739 | + * Return value: number of redirs removed */ | |
740 | +int slirp_redir_rm(int is_udp, int host_port) | |
741 | +{ | |
742 | + struct socket *so; | |
743 | + struct socket *head = (is_udp ? &udb : &tcb); | |
744 | + int fport = htons(host_port); | |
745 | + int n = 0; | |
746 | + | |
747 | + loop_again: | |
748 | + for (so = head->so_next; so != head; so = so->so_next) { | |
749 | + if (so->so_fport == fport) { | |
750 | + close(so->s); | |
751 | + sofree(so); | |
752 | + n++; | |
753 | + goto loop_again; | |
754 | + } | |
755 | + } | |
756 | + | |
757 | + return n; | |
758 | +} | |
759 | + | |
737 | 760 | int slirp_redir(int is_udp, int host_port, |
738 | 761 | struct in_addr guest_addr, int guest_port) |
739 | 762 | { | ... | ... |
vl.c