Commit b8e8af38ee4a4d516e75c64d1c3fbcf9a81d00e4

Authored by Jan Kiszka
Committed by Mark McLoughlin
1 parent 10ae5a7a

slirp: Reorder initialization

This patch reorders the initialization of slirp itself as well as its
associated features smb and redirection. So far the first reference to
slirp triggered the initialization, independent of the actual -net user
option which may carry additional parameters. Now we save any request to
add a smb export or some redirections until the actual initialization of
the stack. This also allows to move a few parameters that were passed
via global variable into the argument list of net_slirp_init.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
@@ -551,11 +551,21 @@ static void config_error(Monitor *mon, const char *fmt, ...) @@ -551,11 +551,21 @@ static void config_error(Monitor *mon, const char *fmt, ...)
551 551
552 /* slirp network adapter */ 552 /* slirp network adapter */
553 553
  554 +struct slirp_config_str {
  555 + struct slirp_config_str *next;
  556 + const char *str;
  557 +};
  558 +
554 static int slirp_inited; 559 static int slirp_inited;
555 -static int slirp_restrict;  
556 -static char *slirp_ip; 560 +static struct slirp_config_str *slirp_redirs;
  561 +#ifndef _WIN32
  562 +static const char *slirp_smb_export;
  563 +#endif
557 static VLANClientState *slirp_vc; 564 static VLANClientState *slirp_vc;
558 565
  566 +static void slirp_smb(const char *exported_dir);
  567 +static void slirp_redirection(Monitor *mon, const char *redir_str);
  568 +
559 int slirp_can_output(void) 569 int slirp_can_output(void)
560 { 570 {
561 return !slirp_vc || qemu_can_send_packet(slirp_vc); 571 return !slirp_vc || qemu_can_send_packet(slirp_vc);
@@ -593,7 +603,8 @@ static void net_slirp_cleanup(VLANClientState *vc) @@ -593,7 +603,8 @@ static void net_slirp_cleanup(VLANClientState *vc)
593 slirp_in_use = 0; 603 slirp_in_use = 0;
594 } 604 }
595 605
596 -static int net_slirp_init(VLANState *vlan, const char *model, const char *name) 606 +static int net_slirp_init(VLANState *vlan, const char *model, const char *name,
  607 + int restricted, const char *ip)
597 { 608 {
598 if (slirp_in_use) { 609 if (slirp_in_use) {
599 /* slirp only supports a single instance so far */ 610 /* slirp only supports a single instance so far */
@@ -601,10 +612,24 @@ static int net_slirp_init(VLANState *vlan, const char *model, const char *name) @@ -601,10 +612,24 @@ static int net_slirp_init(VLANState *vlan, const char *model, const char *name)
601 } 612 }
602 if (!slirp_inited) { 613 if (!slirp_inited) {
603 slirp_inited = 1; 614 slirp_inited = 1;
604 - slirp_init(slirp_restrict, slirp_ip); 615 + slirp_init(restricted, ip);
  616 +
  617 + while (slirp_redirs) {
  618 + struct slirp_config_str *config = slirp_redirs;
  619 +
  620 + slirp_redirection(NULL, config->str);
  621 + slirp_redirs = config->next;
  622 + qemu_free(config);
  623 + }
  624 +#ifndef _WIN32
  625 + if (slirp_smb_export) {
  626 + slirp_smb(slirp_smb_export);
  627 + }
  628 +#endif
605 } 629 }
606 - slirp_vc = qemu_new_vlan_client(vlan, model, name,  
607 - slirp_receive, NULL, net_slirp_cleanup, NULL); 630 +
  631 + slirp_vc = qemu_new_vlan_client(vlan, model, name, slirp_receive,
  632 + NULL, net_slirp_cleanup, NULL);
608 slirp_vc->info_str[0] = '\0'; 633 slirp_vc->info_str[0] = '\0';
609 slirp_in_use = 1; 634 slirp_in_use = 1;
610 return 0; 635 return 0;
@@ -685,32 +710,18 @@ static void net_slirp_redir_rm(Monitor *mon, const char *port_str) @@ -685,32 +710,18 @@ static void net_slirp_redir_rm(Monitor *mon, const char *port_str)
685 monitor_printf(mon, "invalid format\n"); 710 monitor_printf(mon, "invalid format\n");
686 } 711 }
687 712
688 -void net_slirp_redir(Monitor *mon, const char *redir_str, const char *redir_opt2) 713 +static void slirp_redirection(Monitor *mon, const char *redir_str)
689 { 714 {
690 - int is_udp;  
691 - char buf[256], *r;  
692 - const char *p;  
693 struct in_addr guest_addr; 715 struct in_addr guest_addr;
694 int host_port, guest_port; 716 int host_port, guest_port;
695 -  
696 - if (!slirp_inited) {  
697 - slirp_inited = 1;  
698 - slirp_init(slirp_restrict, slirp_ip);  
699 - }  
700 -  
701 - if (!strcmp(redir_str, "remove")) {  
702 - net_slirp_redir_rm(mon, redir_opt2);  
703 - return;  
704 - }  
705 -  
706 - if (!strcmp(redir_str, "list")) {  
707 - net_slirp_redir_list(mon);  
708 - return;  
709 - } 717 + const char *p;
  718 + char buf[256], *r;
  719 + int is_udp;
710 720
711 p = redir_str; 721 p = redir_str;
712 - if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) 722 + if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
713 goto fail_syntax; 723 goto fail_syntax;
  724 + }
714 if (!strcmp(buf, "tcp") || buf[0] == '\0') { 725 if (!strcmp(buf, "tcp") || buf[0] == '\0') {
715 is_udp = 0; 726 is_udp = 0;
716 } else if (!strcmp(buf, "udp")) { 727 } else if (!strcmp(buf, "udp")) {
@@ -719,23 +730,28 @@ void net_slirp_redir(Monitor *mon, const char *redir_str, const char *redir_opt2 @@ -719,23 +730,28 @@ void net_slirp_redir(Monitor *mon, const char *redir_str, const char *redir_opt2
719 goto fail_syntax; 730 goto fail_syntax;
720 } 731 }
721 732
722 - if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) 733 + if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
723 goto fail_syntax; 734 goto fail_syntax;
  735 + }
724 host_port = strtol(buf, &r, 0); 736 host_port = strtol(buf, &r, 0);
725 - if (r == buf) 737 + if (r == buf) {
726 goto fail_syntax; 738 goto fail_syntax;
  739 + }
727 740
728 - if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) 741 + if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
729 goto fail_syntax; 742 goto fail_syntax;
  743 + }
730 if (buf[0] == '\0') { 744 if (buf[0] == '\0') {
731 pstrcpy(buf, sizeof(buf), "10.0.2.15"); 745 pstrcpy(buf, sizeof(buf), "10.0.2.15");
732 } 746 }
733 - if (!inet_aton(buf, &guest_addr)) 747 + if (!inet_aton(buf, &guest_addr)) {
734 goto fail_syntax; 748 goto fail_syntax;
  749 + }
735 750
736 guest_port = strtol(p, &r, 0); 751 guest_port = strtol(p, &r, 0);
737 - if (r == p) 752 + if (r == p) {
738 goto fail_syntax; 753 goto fail_syntax;
  754 + }
739 755
740 if (slirp_redir(is_udp, host_port, guest_addr, guest_port) < 0) { 756 if (slirp_redir(is_udp, host_port, guest_addr, guest_port) < 0) {
741 config_error(mon, "could not set up redirection '%s'\n", redir_str); 757 config_error(mon, "could not set up redirection '%s'\n", redir_str);
@@ -746,6 +762,35 @@ void net_slirp_redir(Monitor *mon, const char *redir_str, const char *redir_opt2 @@ -746,6 +762,35 @@ void net_slirp_redir(Monitor *mon, const char *redir_str, const char *redir_opt2
746 config_error(mon, "invalid redirection format '%s'\n", redir_str); 762 config_error(mon, "invalid redirection format '%s'\n", redir_str);
747 } 763 }
748 764
  765 +void net_slirp_redir(Monitor *mon, const char *redir_str, const char *redir_opt2)
  766 +{
  767 + struct slirp_config_str *config;
  768 +
  769 + if (!slirp_inited) {
  770 + if (mon) {
  771 + monitor_printf(mon, "user mode network stack not in use\n");
  772 + } else {
  773 + config = qemu_malloc(sizeof(*config));
  774 + config->str = redir_str;
  775 + config->next = slirp_redirs;
  776 + slirp_redirs = config;
  777 + }
  778 + return;
  779 + }
  780 +
  781 + if (!strcmp(redir_str, "remove")) {
  782 + net_slirp_redir_rm(mon, redir_opt2);
  783 + return;
  784 + }
  785 +
  786 + if (!strcmp(redir_str, "list")) {
  787 + net_slirp_redir_list(mon);
  788 + return;
  789 + }
  790 +
  791 + slirp_redirection(mon, redir_str);
  792 +}
  793 +
749 #ifndef _WIN32 794 #ifndef _WIN32
750 795
751 static char smb_dir[1024]; 796 static char smb_dir[1024];
@@ -781,18 +826,12 @@ static void smb_exit(void) @@ -781,18 +826,12 @@ static void smb_exit(void)
781 erase_dir(smb_dir); 826 erase_dir(smb_dir);
782 } 827 }
783 828
784 -/* automatic user mode samba server configuration */  
785 -void net_slirp_smb(const char *exported_dir) 829 +static void slirp_smb(const char *exported_dir)
786 { 830 {
787 char smb_conf[1024]; 831 char smb_conf[1024];
788 char smb_cmdline[1024]; 832 char smb_cmdline[1024];
789 FILE *f; 833 FILE *f;
790 834
791 - if (!slirp_inited) {  
792 - slirp_inited = 1;  
793 - slirp_init(slirp_restrict, slirp_ip);  
794 - }  
795 -  
796 /* XXX: better tmp dir construction */ 835 /* XXX: better tmp dir construction */
797 snprintf(smb_dir, sizeof(smb_dir), "/tmp/qemu-smb.%ld", (long)getpid()); 836 snprintf(smb_dir, sizeof(smb_dir), "/tmp/qemu-smb.%ld", (long)getpid());
798 if (mkdir(smb_dir, 0700) < 0) { 837 if (mkdir(smb_dir, 0700) < 0) {
@@ -836,7 +875,21 @@ void net_slirp_smb(const char *exported_dir) @@ -836,7 +875,21 @@ void net_slirp_smb(const char *exported_dir)
836 slirp_add_exec(0, smb_cmdline, 4, 139); 875 slirp_add_exec(0, smb_cmdline, 4, 139);
837 } 876 }
838 877
  878 +/* automatic user mode samba server configuration */
  879 +void net_slirp_smb(const char *exported_dir)
  880 +{
  881 + if (slirp_smb_export) {
  882 + fprintf(stderr, "-smb given twice\n");
  883 + exit(1);
  884 + }
  885 + slirp_smb_export = exported_dir;
  886 + if (slirp_inited) {
  887 + slirp_smb(exported_dir);
  888 + }
  889 +}
  890 +
839 #endif /* !defined(_WIN32) */ 891 #endif /* !defined(_WIN32) */
  892 +
840 void do_info_slirp(Monitor *mon) 893 void do_info_slirp(Monitor *mon)
841 { 894 {
842 slirp_stats(); 895 slirp_stats();
@@ -1970,6 +2023,9 @@ int net_client_init(Monitor *mon, const char *device, const char *p) @@ -1970,6 +2023,9 @@ int net_client_init(Monitor *mon, const char *device, const char *p)
1970 static const char * const slirp_params[] = { 2023 static const char * const slirp_params[] = {
1971 "vlan", "name", "hostname", "restrict", "ip", NULL 2024 "vlan", "name", "hostname", "restrict", "ip", NULL
1972 }; 2025 };
  2026 + int restricted = 0;
  2027 + char *ip = NULL;
  2028 +
1973 if (check_params(buf, sizeof(buf), slirp_params, p) < 0) { 2029 if (check_params(buf, sizeof(buf), slirp_params, p) < 0) {
1974 config_error(mon, "invalid parameter '%s' in '%s'\n", buf, p); 2030 config_error(mon, "invalid parameter '%s' in '%s'\n", buf, p);
1975 ret = -1; 2031 ret = -1;
@@ -1979,13 +2035,14 @@ int net_client_init(Monitor *mon, const char *device, const char *p) @@ -1979,13 +2035,14 @@ int net_client_init(Monitor *mon, const char *device, const char *p)
1979 pstrcpy(slirp_hostname, sizeof(slirp_hostname), buf); 2035 pstrcpy(slirp_hostname, sizeof(slirp_hostname), buf);
1980 } 2036 }
1981 if (get_param_value(buf, sizeof(buf), "restrict", p)) { 2037 if (get_param_value(buf, sizeof(buf), "restrict", p)) {
1982 - slirp_restrict = (buf[0] == 'y') ? 1 : 0; 2038 + restricted = (buf[0] == 'y') ? 1 : 0;
1983 } 2039 }
1984 if (get_param_value(buf, sizeof(buf), "ip", p)) { 2040 if (get_param_value(buf, sizeof(buf), "ip", p)) {
1985 - slirp_ip = strdup(buf); 2041 + ip = qemu_strdup(buf);
1986 } 2042 }
1987 vlan->nb_host_devs++; 2043 vlan->nb_host_devs++;
1988 - ret = net_slirp_init(vlan, device, name); 2044 + ret = net_slirp_init(vlan, device, name, restricted, ip);
  2045 + qemu_free(ip);
1989 } else if (!strcmp(device, "channel")) { 2046 } else if (!strcmp(device, "channel")) {
1990 long port; 2047 long port;
1991 char name[20], *devname; 2048 char name[20], *devname;
slirp/libslirp.h
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 extern "C" { 5 extern "C" {
6 #endif 6 #endif
7 7
8 -void slirp_init(int restricted, char *special_ip); 8 +void slirp_init(int restricted, const char *special_ip);
9 9
10 void slirp_select_fill(int *pnfds, 10 void slirp_select_fill(int *pnfds,
11 fd_set *readfds, fd_set *writefds, fd_set *xfds); 11 fd_set *readfds, fd_set *writefds, fd_set *xfds);
slirp/slirp.c
@@ -171,7 +171,7 @@ static void slirp_cleanup(void) @@ -171,7 +171,7 @@ static void slirp_cleanup(void)
171 static void slirp_state_save(QEMUFile *f, void *opaque); 171 static void slirp_state_save(QEMUFile *f, void *opaque);
172 static int slirp_state_load(QEMUFile *f, void *opaque, int version_id); 172 static int slirp_state_load(QEMUFile *f, void *opaque, int version_id);
173 173
174 -void slirp_init(int restricted, char *special_ip) 174 +void slirp_init(int restricted, const char *special_ip)
175 { 175 {
176 // debug_init("/tmp/slirp.log", DEBUG_DEFAULT); 176 // debug_init("/tmp/slirp.log", DEBUG_DEFAULT);
177 177