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 551  
552 552 /* slirp network adapter */
553 553  
  554 +struct slirp_config_str {
  555 + struct slirp_config_str *next;
  556 + const char *str;
  557 +};
  558 +
554 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 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 569 int slirp_can_output(void)
560 570 {
561 571 return !slirp_vc || qemu_can_send_packet(slirp_vc);
... ... @@ -593,7 +603,8 @@ static void net_slirp_cleanup(VLANClientState *vc)
593 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 609 if (slirp_in_use) {
599 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 612 }
602 613 if (!slirp_inited) {
603 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 633 slirp_vc->info_str[0] = '\0';
609 634 slirp_in_use = 1;
610 635 return 0;
... ... @@ -685,32 +710,18 @@ static void net_slirp_redir_rm(Monitor *mon, const char *port_str)
685 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 715 struct in_addr guest_addr;
694 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 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 723 goto fail_syntax;
  724 + }
714 725 if (!strcmp(buf, "tcp") || buf[0] == '\0') {
715 726 is_udp = 0;
716 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 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 734 goto fail_syntax;
  735 + }
724 736 host_port = strtol(buf, &r, 0);
725   - if (r == buf)
  737 + if (r == buf) {
726 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 742 goto fail_syntax;
  743 + }
730 744 if (buf[0] == '\0') {
731 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 748 goto fail_syntax;
  749 + }
735 750  
736 751 guest_port = strtol(p, &r, 0);
737   - if (r == p)
  752 + if (r == p) {
738 753 goto fail_syntax;
  754 + }
739 755  
740 756 if (slirp_redir(is_udp, host_port, guest_addr, guest_port) < 0) {
741 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 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 794 #ifndef _WIN32
750 795  
751 796 static char smb_dir[1024];
... ... @@ -781,18 +826,12 @@ static void smb_exit(void)
781 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 831 char smb_conf[1024];
788 832 char smb_cmdline[1024];
789 833 FILE *f;
790 834  
791   - if (!slirp_inited) {
792   - slirp_inited = 1;
793   - slirp_init(slirp_restrict, slirp_ip);
794   - }
795   -
796 835 /* XXX: better tmp dir construction */
797 836 snprintf(smb_dir, sizeof(smb_dir), "/tmp/qemu-smb.%ld", (long)getpid());
798 837 if (mkdir(smb_dir, 0700) < 0) {
... ... @@ -836,7 +875,21 @@ void net_slirp_smb(const char *exported_dir)
836 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 891 #endif /* !defined(_WIN32) */
  892 +
840 893 void do_info_slirp(Monitor *mon)
841 894 {
842 895 slirp_stats();
... ... @@ -1970,6 +2023,9 @@ int net_client_init(Monitor *mon, const char *device, const char *p)
1970 2023 static const char * const slirp_params[] = {
1971 2024 "vlan", "name", "hostname", "restrict", "ip", NULL
1972 2025 };
  2026 + int restricted = 0;
  2027 + char *ip = NULL;
  2028 +
1973 2029 if (check_params(buf, sizeof(buf), slirp_params, p) < 0) {
1974 2030 config_error(mon, "invalid parameter '%s' in '%s'\n", buf, p);
1975 2031 ret = -1;
... ... @@ -1979,13 +2035,14 @@ int net_client_init(Monitor *mon, const char *device, const char *p)
1979 2035 pstrcpy(slirp_hostname, sizeof(slirp_hostname), buf);
1980 2036 }
1981 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 2040 if (get_param_value(buf, sizeof(buf), "ip", p)) {
1985   - slirp_ip = strdup(buf);
  2041 + ip = qemu_strdup(buf);
1986 2042 }
1987 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 2046 } else if (!strcmp(device, "channel")) {
1990 2047 long port;
1991 2048 char name[20], *devname;
... ...
slirp/libslirp.h
... ... @@ -5,7 +5,7 @@
5 5 extern "C" {
6 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 10 void slirp_select_fill(int *pnfds,
11 11 fd_set *readfds, fd_set *writefds, fd_set *xfds);
... ...
slirp/slirp.c
... ... @@ -171,7 +171,7 @@ static void slirp_cleanup(void)
171 171 static void slirp_state_save(QEMUFile *f, void *opaque);
172 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 176 // debug_init("/tmp/slirp.log", DEBUG_DEFAULT);
177 177  
... ...