Commit 9f8bd0421dc03b2640ac2d0a4d702354a218b2ab

Authored by Jan Kiszka
Committed by Anthony Liguori
1 parent 460fec67

slirp: Use internal state in interface

This now also exports the internal state to the slirp users in qemu,
returning it from slirp_init and expecting it along with service
invocations. Additionally provide an opaque value interface for the
callbacks from slirp into the qemu core.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
@@ -677,44 +677,55 @@ struct slirp_config_str { @@ -677,44 +677,55 @@ struct slirp_config_str {
677 int legacy_format; 677 int legacy_format;
678 }; 678 };
679 679
680 -static int slirp_inited; 680 +typedef struct SlirpState {
  681 + VLANClientState *vc;
  682 + Slirp *slirp;
  683 +} SlirpState;
  684 +
681 static struct slirp_config_str *slirp_configs; 685 static struct slirp_config_str *slirp_configs;
682 const char *legacy_tftp_prefix; 686 const char *legacy_tftp_prefix;
683 const char *legacy_bootp_filename; 687 const char *legacy_bootp_filename;
684 -static VLANClientState *slirp_vc; 688 +static SlirpState *slirp_state;
685 689
686 -static void slirp_hostfwd(Monitor *mon, const char *redir_str, 690 +static void slirp_hostfwd(SlirpState *s, Monitor *mon, const char *redir_str,
687 int legacy_format); 691 int legacy_format);
688 -static void slirp_guestfwd(Monitor *mon, const char *config_str, 692 +static void slirp_guestfwd(SlirpState *s, Monitor *mon, const char *config_str,
689 int legacy_format); 693 int legacy_format);
690 694
691 #ifndef _WIN32 695 #ifndef _WIN32
692 static const char *legacy_smb_export; 696 static const char *legacy_smb_export;
693 697
694 -static void slirp_smb(const char *exported_dir, struct in_addr vserver_addr); 698 +static void slirp_smb(SlirpState *s, const char *exported_dir,
  699 + struct in_addr vserver_addr);
695 #endif 700 #endif
696 701
697 -int slirp_can_output(void) 702 +int slirp_can_output(void *opaque)
698 { 703 {
699 - return qemu_can_send_packet(slirp_vc); 704 + SlirpState *s = opaque;
  705 +
  706 + return qemu_can_send_packet(s->vc);
700 } 707 }
701 708
702 -void slirp_output(const uint8_t *pkt, int pkt_len) 709 +void slirp_output(void *opaque, const uint8_t *pkt, int pkt_len)
703 { 710 {
  711 + SlirpState *s = opaque;
  712 +
704 #ifdef DEBUG_SLIRP 713 #ifdef DEBUG_SLIRP
705 printf("slirp output:\n"); 714 printf("slirp output:\n");
706 hex_dump(stdout, pkt, pkt_len); 715 hex_dump(stdout, pkt, pkt_len);
707 #endif 716 #endif
708 - qemu_send_packet(slirp_vc, pkt, pkt_len); 717 + qemu_send_packet(s->vc, pkt, pkt_len);
709 } 718 }
710 719
711 static ssize_t slirp_receive(VLANClientState *vc, const uint8_t *buf, size_t size) 720 static ssize_t slirp_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
712 { 721 {
  722 + SlirpState *s = vc->opaque;
  723 +
713 #ifdef DEBUG_SLIRP 724 #ifdef DEBUG_SLIRP
714 printf("slirp input:\n"); 725 printf("slirp input:\n");
715 hex_dump(stdout, buf, size); 726 hex_dump(stdout, buf, size);
716 #endif 727 #endif
717 - slirp_input(buf, size); 728 + slirp_input(s->slirp, buf, size);
718 return size; 729 return size;
719 } 730 }
720 731
@@ -733,11 +744,13 @@ static int net_slirp_init(Monitor *mon, VLANState *vlan, const char *model, @@ -733,11 +744,13 @@ static int net_slirp_init(Monitor *mon, VLANState *vlan, const char *model,
733 const char *vnameserver, const char *smb_export, 744 const char *vnameserver, const char *smb_export,
734 const char *vsmbserver) 745 const char *vsmbserver)
735 { 746 {
  747 + SlirpState *s = slirp_state;
  748 +
736 if (slirp_in_use) { 749 if (slirp_in_use) {
737 /* slirp only supports a single instance so far */ 750 /* slirp only supports a single instance so far */
738 return -1; 751 return -1;
739 } 752 }
740 - if (!slirp_inited) { 753 + if (!s) {
741 /* default settings according to historic slirp */ 754 /* default settings according to historic slirp */
742 struct in_addr net = { .s_addr = htonl(0x0a000000) }; /* 10.0.0.0 */ 755 struct in_addr net = { .s_addr = htonl(0x0a000000) }; /* 10.0.0.0 */
743 struct in_addr mask = { .s_addr = htonl(0xff000000) }; /* 255.0.0.0 */ 756 struct in_addr mask = { .s_addr = htonl(0xff000000) }; /* 255.0.0.0 */
@@ -830,18 +843,19 @@ static int net_slirp_init(Monitor *mon, VLANState *vlan, const char *model, @@ -830,18 +843,19 @@ static int net_slirp_init(Monitor *mon, VLANState *vlan, const char *model,
830 } 843 }
831 #endif 844 #endif
832 845
833 - slirp_init(restricted, net, mask, host, vhostname, tftp_export,  
834 - bootfile, dhcp, dns);  
835 - slirp_inited = 1; 846 + s = qemu_mallocz(sizeof(SlirpState));
  847 + s->slirp = slirp_init(restricted, net, mask, host, vhostname,
  848 + tftp_export, bootfile, dhcp, dns, s);
  849 + slirp_state = s;
836 850
837 while (slirp_configs) { 851 while (slirp_configs) {
838 struct slirp_config_str *config = slirp_configs; 852 struct slirp_config_str *config = slirp_configs;
839 853
840 if (config->flags & SLIRP_CFG_HOSTFWD) { 854 if (config->flags & SLIRP_CFG_HOSTFWD) {
841 - slirp_hostfwd(mon, config->str, 855 + slirp_hostfwd(s, mon, config->str,
842 config->flags & SLIRP_CFG_LEGACY); 856 config->flags & SLIRP_CFG_LEGACY);
843 } else { 857 } else {
844 - slirp_guestfwd(mon, config->str, 858 + slirp_guestfwd(s, mon, config->str,
845 config->flags & SLIRP_CFG_LEGACY); 859 config->flags & SLIRP_CFG_LEGACY);
846 } 860 }
847 slirp_configs = config->next; 861 slirp_configs = config->next;
@@ -852,14 +866,14 @@ static int net_slirp_init(Monitor *mon, VLANState *vlan, const char *model, @@ -852,14 +866,14 @@ static int net_slirp_init(Monitor *mon, VLANState *vlan, const char *model,
852 smb_export = legacy_smb_export; 866 smb_export = legacy_smb_export;
853 } 867 }
854 if (smb_export) { 868 if (smb_export) {
855 - slirp_smb(smb_export, smbsrv); 869 + slirp_smb(s, smb_export, smbsrv);
856 } 870 }
857 #endif 871 #endif
858 } 872 }
859 873
860 - slirp_vc = qemu_new_vlan_client(vlan, model, name, NULL, slirp_receive,  
861 - NULL, net_slirp_cleanup, NULL);  
862 - slirp_vc->info_str[0] = '\0'; 874 + s->vc = qemu_new_vlan_client(vlan, model, name, NULL, slirp_receive, NULL,
  875 + net_slirp_cleanup, s);
  876 + s->vc->info_str[0] = '\0';
863 slirp_in_use = 1; 877 slirp_in_use = 1;
864 return 0; 878 return 0;
865 } 879 }
@@ -873,7 +887,7 @@ void net_slirp_hostfwd_remove(Monitor *mon, const char *src_str) @@ -873,7 +887,7 @@ void net_slirp_hostfwd_remove(Monitor *mon, const char *src_str)
873 int is_udp = 0; 887 int is_udp = 0;
874 int err; 888 int err;
875 889
876 - if (!slirp_inited) { 890 + if (!slirp_state) {
877 monitor_printf(mon, "user mode network stack not in use\n"); 891 monitor_printf(mon, "user mode network stack not in use\n");
878 return; 892 return;
879 } 893 }
@@ -900,7 +914,8 @@ void net_slirp_hostfwd_remove(Monitor *mon, const char *src_str) @@ -900,7 +914,8 @@ void net_slirp_hostfwd_remove(Monitor *mon, const char *src_str)
900 914
901 host_port = atoi(p); 915 host_port = atoi(p);
902 916
903 - err = slirp_remove_hostfwd(is_udp, host_addr, host_port); 917 + err = slirp_remove_hostfwd(slirp_state->slirp, is_udp,
  918 + host_addr, host_port);
904 919
905 monitor_printf(mon, "host forwarding rule for %s %s\n", src_str, 920 monitor_printf(mon, "host forwarding rule for %s %s\n", src_str,
906 err ? "removed" : "not found"); 921 err ? "removed" : "not found");
@@ -910,7 +925,7 @@ void net_slirp_hostfwd_remove(Monitor *mon, const char *src_str) @@ -910,7 +925,7 @@ void net_slirp_hostfwd_remove(Monitor *mon, const char *src_str)
910 monitor_printf(mon, "invalid format\n"); 925 monitor_printf(mon, "invalid format\n");
911 } 926 }
912 927
913 -static void slirp_hostfwd(Monitor *mon, const char *redir_str, 928 +static void slirp_hostfwd(SlirpState *s, Monitor *mon, const char *redir_str,
914 int legacy_format) 929 int legacy_format)
915 { 930 {
916 struct in_addr host_addr = { .s_addr = INADDR_ANY }; 931 struct in_addr host_addr = { .s_addr = INADDR_ANY };
@@ -962,8 +977,8 @@ static void slirp_hostfwd(Monitor *mon, const char *redir_str, @@ -962,8 +977,8 @@ static void slirp_hostfwd(Monitor *mon, const char *redir_str,
962 goto fail_syntax; 977 goto fail_syntax;
963 } 978 }
964 979
965 - if (slirp_add_hostfwd(is_udp, host_addr, host_port,  
966 - guest_addr, guest_port) < 0) { 980 + if (slirp_add_hostfwd(s->slirp, is_udp, host_addr, host_port, guest_addr,
  981 + guest_port) < 0) {
967 config_error(mon, "could not set up host forwarding rule '%s'\n", 982 config_error(mon, "could not set up host forwarding rule '%s'\n",
968 redir_str); 983 redir_str);
969 } 984 }
@@ -975,19 +990,19 @@ static void slirp_hostfwd(Monitor *mon, const char *redir_str, @@ -975,19 +990,19 @@ static void slirp_hostfwd(Monitor *mon, const char *redir_str,
975 990
976 void net_slirp_hostfwd_add(Monitor *mon, const char *redir_str) 991 void net_slirp_hostfwd_add(Monitor *mon, const char *redir_str)
977 { 992 {
978 - if (!slirp_inited) { 993 + if (!slirp_state) {
979 monitor_printf(mon, "user mode network stack not in use\n"); 994 monitor_printf(mon, "user mode network stack not in use\n");
980 return; 995 return;
981 } 996 }
982 997
983 - slirp_hostfwd(mon, redir_str, 0); 998 + slirp_hostfwd(slirp_state, mon, redir_str, 0);
984 } 999 }
985 1000
986 void net_slirp_redir(const char *redir_str) 1001 void net_slirp_redir(const char *redir_str)
987 { 1002 {
988 struct slirp_config_str *config; 1003 struct slirp_config_str *config;
989 1004
990 - if (!slirp_inited) { 1005 + if (!slirp_state) {
991 config = qemu_malloc(sizeof(*config)); 1006 config = qemu_malloc(sizeof(*config));
992 pstrcpy(config->str, sizeof(config->str), redir_str); 1007 pstrcpy(config->str, sizeof(config->str), redir_str);
993 config->flags = SLIRP_CFG_HOSTFWD | SLIRP_CFG_LEGACY; 1008 config->flags = SLIRP_CFG_HOSTFWD | SLIRP_CFG_LEGACY;
@@ -996,7 +1011,7 @@ void net_slirp_redir(const char *redir_str) @@ -996,7 +1011,7 @@ void net_slirp_redir(const char *redir_str)
996 return; 1011 return;
997 } 1012 }
998 1013
999 - slirp_hostfwd(NULL, redir_str, 1); 1014 + slirp_hostfwd(slirp_state, NULL, redir_str, 1);
1000 } 1015 }
1001 1016
1002 #ifndef _WIN32 1017 #ifndef _WIN32
@@ -1034,7 +1049,8 @@ static void smb_exit(void) @@ -1034,7 +1049,8 @@ static void smb_exit(void)
1034 erase_dir(smb_dir); 1049 erase_dir(smb_dir);
1035 } 1050 }
1036 1051
1037 -static void slirp_smb(const char *exported_dir, struct in_addr vserver_addr) 1052 +static void slirp_smb(SlirpState* s, const char *exported_dir,
  1053 + struct in_addr vserver_addr)
1038 { 1054 {
1039 char smb_conf[1024]; 1055 char smb_conf[1024];
1040 char smb_cmdline[1024]; 1056 char smb_cmdline[1024];
@@ -1080,7 +1096,7 @@ static void slirp_smb(const char *exported_dir, struct in_addr vserver_addr) @@ -1080,7 +1096,7 @@ static void slirp_smb(const char *exported_dir, struct in_addr vserver_addr)
1080 snprintf(smb_cmdline, sizeof(smb_cmdline), "%s -s %s", 1096 snprintf(smb_cmdline, sizeof(smb_cmdline), "%s -s %s",
1081 SMBD_COMMAND, smb_conf); 1097 SMBD_COMMAND, smb_conf);
1082 1098
1083 - if (slirp_add_exec(0, smb_cmdline, vserver_addr, 139) < 0) { 1099 + if (slirp_add_exec(s->slirp, 0, smb_cmdline, vserver_addr, 139) < 0) {
1084 fprintf(stderr, "conflicting/invalid smbserver address\n"); 1100 fprintf(stderr, "conflicting/invalid smbserver address\n");
1085 exit(1); 1101 exit(1);
1086 } 1102 }
@@ -1096,8 +1112,8 @@ void net_slirp_smb(const char *exported_dir) @@ -1096,8 +1112,8 @@ void net_slirp_smb(const char *exported_dir)
1096 exit(1); 1112 exit(1);
1097 } 1113 }
1098 legacy_smb_export = exported_dir; 1114 legacy_smb_export = exported_dir;
1099 - if (slirp_inited) {  
1100 - slirp_smb(exported_dir, vserver_addr); 1115 + if (slirp_state) {
  1116 + slirp_smb(slirp_state, exported_dir, vserver_addr);
1101 } 1117 }
1102 } 1118 }
1103 1119
@@ -1107,21 +1123,22 @@ struct GuestFwd { @@ -1107,21 +1123,22 @@ struct GuestFwd {
1107 CharDriverState *hd; 1123 CharDriverState *hd;
1108 struct in_addr server; 1124 struct in_addr server;
1109 int port; 1125 int port;
  1126 + Slirp *slirp;
1110 }; 1127 };
1111 1128
1112 static int guestfwd_can_read(void *opaque) 1129 static int guestfwd_can_read(void *opaque)
1113 { 1130 {
1114 struct GuestFwd *fwd = opaque; 1131 struct GuestFwd *fwd = opaque;
1115 - return slirp_socket_can_recv(fwd->server, fwd->port); 1132 + return slirp_socket_can_recv(fwd->slirp, fwd->server, fwd->port);
1116 } 1133 }
1117 1134
1118 static void guestfwd_read(void *opaque, const uint8_t *buf, int size) 1135 static void guestfwd_read(void *opaque, const uint8_t *buf, int size)
1119 { 1136 {
1120 struct GuestFwd *fwd = opaque; 1137 struct GuestFwd *fwd = opaque;
1121 - slirp_socket_recv(fwd->server, fwd->port, buf, size); 1138 + slirp_socket_recv(fwd->slirp, fwd->server, fwd->port, buf, size);
1122 } 1139 }
1123 1140
1124 -static void slirp_guestfwd(Monitor *mon, const char *config_str, 1141 +static void slirp_guestfwd(SlirpState *s, Monitor *mon, const char *config_str,
1125 int legacy_format) 1142 int legacy_format)
1126 { 1143 {
1127 struct in_addr server = { .s_addr = 0 }; 1144 struct in_addr server = { .s_addr = 0 };
@@ -1169,8 +1186,9 @@ static void slirp_guestfwd(Monitor *mon, const char *config_str, @@ -1169,8 +1186,9 @@ static void slirp_guestfwd(Monitor *mon, const char *config_str,
1169 } 1186 }
1170 fwd->server = server; 1187 fwd->server = server;
1171 fwd->port = port; 1188 fwd->port = port;
  1189 + fwd->slirp = s->slirp;
1172 1190
1173 - if (slirp_add_exec(3, fwd->hd, server, port) < 0) { 1191 + if (slirp_add_exec(s->slirp, 3, fwd->hd, server, port) < 0) {
1174 config_error(mon, "conflicting/invalid host:port in guest forwarding " 1192 config_error(mon, "conflicting/invalid host:port in guest forwarding "
1175 "rule '%s'\n", config_str); 1193 "rule '%s'\n", config_str);
1176 qemu_free(fwd); 1194 qemu_free(fwd);
@@ -1186,8 +1204,13 @@ static void slirp_guestfwd(Monitor *mon, const char *config_str, @@ -1186,8 +1204,13 @@ static void slirp_guestfwd(Monitor *mon, const char *config_str,
1186 1204
1187 void do_info_usernet(Monitor *mon) 1205 void do_info_usernet(Monitor *mon)
1188 { 1206 {
1189 - monitor_printf(mon, "VLAN %d (%s):\n", slirp_vc->vlan->id, slirp_vc->name);  
1190 - slirp_connection_info(mon); 1207 + SlirpState *s = slirp_state;
  1208 +
  1209 + if (!s) {
  1210 + return;
  1211 + }
  1212 + monitor_printf(mon, "VLAN %d (%s):\n", s->vc->vlan->id, s->vc->name);
  1213 + slirp_connection_info(s->slirp, mon);
1191 } 1214 }
1192 1215
1193 #endif /* CONFIG_SLIRP */ 1216 #endif /* CONFIG_SLIRP */
@@ -2498,7 +2521,7 @@ int net_client_init(Monitor *mon, const char *device, const char *p) @@ -2498,7 +2521,7 @@ int net_client_init(Monitor *mon, const char *device, const char *p)
2498 qemu_free(smb_export); 2521 qemu_free(smb_export);
2499 qemu_free(vsmbsrv); 2522 qemu_free(vsmbsrv);
2500 } else if (!strcmp(device, "channel")) { 2523 } else if (!strcmp(device, "channel")) {
2501 - if (!slirp_inited) { 2524 + if (!slirp_state) {
2502 struct slirp_config_str *config; 2525 struct slirp_config_str *config;
2503 2526
2504 config = qemu_malloc(sizeof(*config)); 2527 config = qemu_malloc(sizeof(*config));
@@ -2507,7 +2530,7 @@ int net_client_init(Monitor *mon, const char *device, const char *p) @@ -2507,7 +2530,7 @@ int net_client_init(Monitor *mon, const char *device, const char *p)
2507 config->next = slirp_configs; 2530 config->next = slirp_configs;
2508 slirp_configs = config; 2531 slirp_configs = config;
2509 } else { 2532 } else {
2510 - slirp_guestfwd(mon, p, 1); 2533 + slirp_guestfwd(slirp_state, mon, p, 1);
2511 } 2534 }
2512 ret = 0; 2535 ret = 0;
2513 } else 2536 } else
slirp/if.c
@@ -162,7 +162,7 @@ if_start(Slirp *slirp) @@ -162,7 +162,7 @@ if_start(Slirp *slirp)
162 162
163 again: 163 again:
164 /* check if we can really output */ 164 /* check if we can really output */
165 - if (!slirp_can_output()) 165 + if (!slirp_can_output(slirp->opaque))
166 return; 166 return;
167 167
168 /* 168 /*
slirp/libslirp.h
@@ -8,11 +8,11 @@ @@ -8,11 +8,11 @@
8 struct Slirp; 8 struct Slirp;
9 typedef struct Slirp Slirp; 9 typedef struct Slirp Slirp;
10 10
11 -void slirp_init(int restricted, struct in_addr vnetwork,  
12 - struct in_addr vnetmask, struct in_addr vhost,  
13 - const char *vhostname, const char *tftp_path,  
14 - const char *bootfile, struct in_addr vdhcp_start,  
15 - struct in_addr vnameserver); 11 +Slirp *slirp_init(int restricted, struct in_addr vnetwork,
  12 + struct in_addr vnetmask, struct in_addr vhost,
  13 + const char *vhostname, const char *tftp_path,
  14 + const char *bootfile, struct in_addr vdhcp_start,
  15 + struct in_addr vnameserver, void *opaque);
16 16
17 void slirp_select_fill(int *pnfds, 17 void slirp_select_fill(int *pnfds,
18 fd_set *readfds, fd_set *writefds, fd_set *xfds); 18 fd_set *readfds, fd_set *writefds, fd_set *xfds);
@@ -20,23 +20,26 @@ void slirp_select_fill(int *pnfds, @@ -20,23 +20,26 @@ void slirp_select_fill(int *pnfds,
20 void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds, 20 void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
21 int select_error); 21 int select_error);
22 22
23 -void slirp_input(const uint8_t *pkt, int pkt_len); 23 +void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len);
24 24
25 /* you must provide the following functions: */ 25 /* you must provide the following functions: */
26 -int slirp_can_output(void);  
27 -void slirp_output(const uint8_t *pkt, int pkt_len); 26 +int slirp_can_output(void *opaque);
  27 +void slirp_output(void *opaque, const uint8_t *pkt, int pkt_len);
28 28
29 -int slirp_add_hostfwd(int is_udp, struct in_addr host_addr, int host_port, 29 +int slirp_add_hostfwd(Slirp *slirp, int is_udp,
  30 + struct in_addr host_addr, int host_port,
30 struct in_addr guest_addr, int guest_port); 31 struct in_addr guest_addr, int guest_port);
31 -int slirp_remove_hostfwd(int is_udp, struct in_addr host_addr, int host_port);  
32 -int slirp_add_exec(int do_pty, const void *args, struct in_addr guest_addr,  
33 - int guest_port); 32 +int slirp_remove_hostfwd(Slirp *slirp, int is_udp,
  33 + struct in_addr host_addr, int host_port);
  34 +int slirp_add_exec(Slirp *slirp, int do_pty, const void *args,
  35 + struct in_addr guest_addr, int guest_port);
34 36
35 -void slirp_connection_info(Monitor *mon); 37 +void slirp_connection_info(Slirp *slirp, Monitor *mon);
36 38
37 -void slirp_socket_recv(struct in_addr guest_addr, int guest_port,  
38 - const uint8_t *buf, int size);  
39 -size_t slirp_socket_can_recv(struct in_addr guest_addr, int guest_port); 39 +void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr,
  40 + int guest_port, const uint8_t *buf, int size);
  41 +size_t slirp_socket_can_recv(Slirp *slirp, struct in_addr guest_addr,
  42 + int guest_port);
40 43
41 #else /* !CONFIG_SLIRP */ 44 #else /* !CONFIG_SLIRP */
42 45
slirp/misc.c
@@ -370,7 +370,7 @@ fd_block(int fd) @@ -370,7 +370,7 @@ fd_block(int fd)
370 #endif 370 #endif
371 } 371 }
372 372
373 -void slirp_connection_info(Monitor *mon) 373 +void slirp_connection_info(Slirp *slirp, Monitor *mon)
374 { 374 {
375 const char * const tcpstates[] = { 375 const char * const tcpstates[] = {
376 [TCPS_CLOSED] = "CLOSED", 376 [TCPS_CLOSED] = "CLOSED",
@@ -385,7 +385,6 @@ void slirp_connection_info(Monitor *mon) @@ -385,7 +385,6 @@ void slirp_connection_info(Monitor *mon)
385 [TCPS_FIN_WAIT_2] = "FIN_WAIT_2", 385 [TCPS_FIN_WAIT_2] = "FIN_WAIT_2",
386 [TCPS_TIME_WAIT] = "TIME_WAIT", 386 [TCPS_TIME_WAIT] = "TIME_WAIT",
387 }; 387 };
388 - Slirp *slirp = &slirp_instance;  
389 struct in_addr dst_addr; 388 struct in_addr dst_addr;
390 struct sockaddr_in src; 389 struct sockaddr_in src;
391 socklen_t src_len; 390 socklen_t src_len;
slirp/slirp.c
@@ -187,11 +187,11 @@ static void slirp_init_once(void) @@ -187,11 +187,11 @@ static void slirp_init_once(void)
187 static void slirp_state_save(QEMUFile *f, void *opaque); 187 static void slirp_state_save(QEMUFile *f, void *opaque);
188 static int slirp_state_load(QEMUFile *f, void *opaque, int version_id); 188 static int slirp_state_load(QEMUFile *f, void *opaque, int version_id);
189 189
190 -void slirp_init(int restricted, struct in_addr vnetwork,  
191 - struct in_addr vnetmask, struct in_addr vhost,  
192 - const char *vhostname, const char *tftp_path,  
193 - const char *bootfile, struct in_addr vdhcp_start,  
194 - struct in_addr vnameserver) 190 +Slirp *slirp_init(int restricted, struct in_addr vnetwork,
  191 + struct in_addr vnetmask, struct in_addr vhost,
  192 + const char *vhostname, const char *tftp_path,
  193 + const char *bootfile, struct in_addr vdhcp_start,
  194 + struct in_addr vnameserver, void *opaque)
195 { 195 {
196 Slirp *slirp = &slirp_instance; 196 Slirp *slirp = &slirp_instance;
197 197
@@ -226,7 +226,11 @@ void slirp_init(int restricted, struct in_addr vnetwork, @@ -226,7 +226,11 @@ void slirp_init(int restricted, struct in_addr vnetwork,
226 slirp->vdhcp_startaddr = vdhcp_start; 226 slirp->vdhcp_startaddr = vdhcp_start;
227 slirp->vnameserver_addr = vnameserver; 227 slirp->vnameserver_addr = vnameserver;
228 228
  229 + slirp->opaque = opaque;
  230 +
229 register_savevm("slirp", 0, 2, slirp_state_save, slirp_state_load, slirp); 231 register_savevm("slirp", 0, 2, slirp_state_save, slirp_state_load, slirp);
  232 +
  233 + return slirp;
230 } 234 }
231 235
232 #define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED) 236 #define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
@@ -635,7 +639,7 @@ static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len) @@ -635,7 +639,7 @@ static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
635 rah->ar_sip = ah->ar_tip; 639 rah->ar_sip = ah->ar_tip;
636 memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN); 640 memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
637 rah->ar_tip = ah->ar_sip; 641 rah->ar_tip = ah->ar_sip;
638 - slirp_output(arp_reply, sizeof(arp_reply)); 642 + slirp_output(slirp->opaque, arp_reply, sizeof(arp_reply));
639 } 643 }
640 break; 644 break;
641 case ARPOP_REPLY: 645 case ARPOP_REPLY:
@@ -650,9 +654,8 @@ static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len) @@ -650,9 +654,8 @@ static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
650 } 654 }
651 } 655 }
652 656
653 -void slirp_input(const uint8_t *pkt, int pkt_len) 657 +void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
654 { 658 {
655 - Slirp *slirp = &slirp_instance;  
656 struct mbuf *m; 659 struct mbuf *m;
657 int proto; 660 int proto;
658 661
@@ -724,7 +727,7 @@ void if_encap(Slirp *slirp, const uint8_t *ip_data, int ip_data_len) @@ -724,7 +727,7 @@ void if_encap(Slirp *slirp, const uint8_t *ip_data, int ip_data_len)
724 /* target IP */ 727 /* target IP */
725 rah->ar_tip = iph->ip_dst.s_addr; 728 rah->ar_tip = iph->ip_dst.s_addr;
726 slirp->client_ipaddr = iph->ip_dst; 729 slirp->client_ipaddr = iph->ip_dst;
727 - slirp_output(arp_req, sizeof(arp_req)); 730 + slirp_output(slirp->opaque, arp_req, sizeof(arp_req));
728 } else { 731 } else {
729 memcpy(eh->h_dest, slirp->client_ethaddr, ETH_ALEN); 732 memcpy(eh->h_dest, slirp->client_ethaddr, ETH_ALEN);
730 memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 4); 733 memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 4);
@@ -732,14 +735,14 @@ void if_encap(Slirp *slirp, const uint8_t *ip_data, int ip_data_len) @@ -732,14 +735,14 @@ void if_encap(Slirp *slirp, const uint8_t *ip_data, int ip_data_len)
732 memcpy(&eh->h_source[2], &slirp->vhost_addr, 4); 735 memcpy(&eh->h_source[2], &slirp->vhost_addr, 4);
733 eh->h_proto = htons(ETH_P_IP); 736 eh->h_proto = htons(ETH_P_IP);
734 memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len); 737 memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len);
735 - slirp_output(buf, ip_data_len + ETH_HLEN); 738 + slirp_output(slirp->opaque, buf, ip_data_len + ETH_HLEN);
736 } 739 }
737 } 740 }
738 741
739 /* Drop host forwarding rule, return 0 if found. */ 742 /* Drop host forwarding rule, return 0 if found. */
740 -int slirp_remove_hostfwd(int is_udp, struct in_addr host_addr, int host_port) 743 +int slirp_remove_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr,
  744 + int host_port)
741 { 745 {
742 - Slirp *slirp = &slirp_instance;  
743 struct socket *so; 746 struct socket *so;
744 struct socket *head = (is_udp ? &slirp->udb : &slirp->tcb); 747 struct socket *head = (is_udp ? &slirp->udb : &slirp->tcb);
745 struct sockaddr_in addr; 748 struct sockaddr_in addr;
@@ -761,11 +764,9 @@ int slirp_remove_hostfwd(int is_udp, struct in_addr host_addr, int host_port) @@ -761,11 +764,9 @@ int slirp_remove_hostfwd(int is_udp, struct in_addr host_addr, int host_port)
761 return -1; 764 return -1;
762 } 765 }
763 766
764 -int slirp_add_hostfwd(int is_udp, struct in_addr host_addr, int host_port,  
765 - struct in_addr guest_addr, int guest_port) 767 +int slirp_add_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr,
  768 + int host_port, struct in_addr guest_addr, int guest_port)
766 { 769 {
767 - Slirp *slirp = &slirp_instance;  
768 -  
769 if (!guest_addr.s_addr) { 770 if (!guest_addr.s_addr) {
770 guest_addr = slirp->vdhcp_startaddr; 771 guest_addr = slirp->vdhcp_startaddr;
771 } 772 }
@@ -781,11 +782,9 @@ int slirp_add_hostfwd(int is_udp, struct in_addr host_addr, int host_port, @@ -781,11 +782,9 @@ int slirp_add_hostfwd(int is_udp, struct in_addr host_addr, int host_port,
781 return 0; 782 return 0;
782 } 783 }
783 784
784 -int slirp_add_exec(int do_pty, const void *args, struct in_addr guest_addr,  
785 - int guest_port) 785 +int slirp_add_exec(Slirp *slirp, int do_pty, const void *args,
  786 + struct in_addr guest_addr, int guest_port)
786 { 787 {
787 - Slirp *slirp = &slirp_instance;  
788 -  
789 if (!guest_addr.s_addr) { 788 if (!guest_addr.s_addr) {
790 guest_addr.s_addr = slirp->vnetwork_addr.s_addr | 789 guest_addr.s_addr = slirp->vnetwork_addr.s_addr |
791 (htonl(0x0204) & ~slirp->vnetwork_mask.s_addr); 790 (htonl(0x0204) & ~slirp->vnetwork_mask.s_addr);
@@ -824,9 +823,9 @@ slirp_find_ctl_socket(Slirp *slirp, struct in_addr guest_addr, int guest_port) @@ -824,9 +823,9 @@ slirp_find_ctl_socket(Slirp *slirp, struct in_addr guest_addr, int guest_port)
824 return NULL; 823 return NULL;
825 } 824 }
826 825
827 -size_t slirp_socket_can_recv(struct in_addr guest_addr, int guest_port) 826 +size_t slirp_socket_can_recv(Slirp *slirp, struct in_addr guest_addr,
  827 + int guest_port)
828 { 828 {
829 - Slirp *slirp = &slirp_instance;  
830 struct iovec iov[2]; 829 struct iovec iov[2];
831 struct socket *so; 830 struct socket *so;
832 831
@@ -841,10 +840,9 @@ size_t slirp_socket_can_recv(struct in_addr guest_addr, int guest_port) @@ -841,10 +840,9 @@ size_t slirp_socket_can_recv(struct in_addr guest_addr, int guest_port)
841 return sopreprbuf(so, iov, NULL); 840 return sopreprbuf(so, iov, NULL);
842 } 841 }
843 842
844 -void slirp_socket_recv(struct in_addr guest_addr, int guest_port, 843 +void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr, int guest_port,
845 const uint8_t *buf, int size) 844 const uint8_t *buf, int size)
846 { 845 {
847 - Slirp *slirp = &slirp_instance;  
848 int ret; 846 int ret;
849 struct socket *so = slirp_find_ctl_socket(slirp, guest_addr, guest_port); 847 struct socket *so = slirp_find_ctl_socket(slirp, guest_addr, guest_port);
850 848
slirp/slirp.h
@@ -256,6 +256,7 @@ struct Slirp { @@ -256,6 +256,7 @@ struct Slirp {
256 char *tftp_prefix; 256 char *tftp_prefix;
257 struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX]; 257 struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX];
258 258
  259 + void *opaque;
259 }; 260 };
260 261
261 extern Slirp slirp_instance; 262 extern Slirp slirp_instance;