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