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 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 685 static struct slirp_config_str *slirp_configs;
682 686 const char *legacy_tftp_prefix;
683 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 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 693 int legacy_format);
690 694  
691 695 #ifndef _WIN32
692 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 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 713 #ifdef DEBUG_SLIRP
705 714 printf("slirp output:\n");
706 715 hex_dump(stdout, pkt, pkt_len);
707 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 720 static ssize_t slirp_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
712 721 {
  722 + SlirpState *s = vc->opaque;
  723 +
713 724 #ifdef DEBUG_SLIRP
714 725 printf("slirp input:\n");
715 726 hex_dump(stdout, buf, size);
716 727 #endif
717   - slirp_input(buf, size);
  728 + slirp_input(s->slirp, buf, size);
718 729 return size;
719 730 }
720 731  
... ... @@ -733,11 +744,13 @@ static int net_slirp_init(Monitor *mon, VLANState *vlan, const char *model,
733 744 const char *vnameserver, const char *smb_export,
734 745 const char *vsmbserver)
735 746 {
  747 + SlirpState *s = slirp_state;
  748 +
736 749 if (slirp_in_use) {
737 750 /* slirp only supports a single instance so far */
738 751 return -1;
739 752 }
740   - if (!slirp_inited) {
  753 + if (!s) {
741 754 /* default settings according to historic slirp */
742 755 struct in_addr net = { .s_addr = htonl(0x0a000000) }; /* 10.0.0.0 */
743 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 843 }
831 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 851 while (slirp_configs) {
838 852 struct slirp_config_str *config = slirp_configs;
839 853  
840 854 if (config->flags & SLIRP_CFG_HOSTFWD) {
841   - slirp_hostfwd(mon, config->str,
  855 + slirp_hostfwd(s, mon, config->str,
842 856 config->flags & SLIRP_CFG_LEGACY);
843 857 } else {
844   - slirp_guestfwd(mon, config->str,
  858 + slirp_guestfwd(s, mon, config->str,
845 859 config->flags & SLIRP_CFG_LEGACY);
846 860 }
847 861 slirp_configs = config->next;
... ... @@ -852,14 +866,14 @@ static int net_slirp_init(Monitor *mon, VLANState *vlan, const char *model,
852 866 smb_export = legacy_smb_export;
853 867 }
854 868 if (smb_export) {
855   - slirp_smb(smb_export, smbsrv);
  869 + slirp_smb(s, smb_export, smbsrv);
856 870 }
857 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 877 slirp_in_use = 1;
864 878 return 0;
865 879 }
... ... @@ -873,7 +887,7 @@ void net_slirp_hostfwd_remove(Monitor *mon, const char *src_str)
873 887 int is_udp = 0;
874 888 int err;
875 889  
876   - if (!slirp_inited) {
  890 + if (!slirp_state) {
877 891 monitor_printf(mon, "user mode network stack not in use\n");
878 892 return;
879 893 }
... ... @@ -900,7 +914,8 @@ void net_slirp_hostfwd_remove(Monitor *mon, const char *src_str)
900 914  
901 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 920 monitor_printf(mon, "host forwarding rule for %s %s\n", src_str,
906 921 err ? "removed" : "not found");
... ... @@ -910,7 +925,7 @@ void net_slirp_hostfwd_remove(Monitor *mon, const char *src_str)
910 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 929 int legacy_format)
915 930 {
916 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 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 982 config_error(mon, "could not set up host forwarding rule '%s'\n",
968 983 redir_str);
969 984 }
... ... @@ -975,19 +990,19 @@ static void slirp_hostfwd(Monitor *mon, const char *redir_str,
975 990  
976 991 void net_slirp_hostfwd_add(Monitor *mon, const char *redir_str)
977 992 {
978   - if (!slirp_inited) {
  993 + if (!slirp_state) {
979 994 monitor_printf(mon, "user mode network stack not in use\n");
980 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 1001 void net_slirp_redir(const char *redir_str)
987 1002 {
988 1003 struct slirp_config_str *config;
989 1004  
990   - if (!slirp_inited) {
  1005 + if (!slirp_state) {
991 1006 config = qemu_malloc(sizeof(*config));
992 1007 pstrcpy(config->str, sizeof(config->str), redir_str);
993 1008 config->flags = SLIRP_CFG_HOSTFWD | SLIRP_CFG_LEGACY;
... ... @@ -996,7 +1011,7 @@ void net_slirp_redir(const char *redir_str)
996 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 1017 #ifndef _WIN32
... ... @@ -1034,7 +1049,8 @@ static void smb_exit(void)
1034 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 1055 char smb_conf[1024];
1040 1056 char smb_cmdline[1024];
... ... @@ -1080,7 +1096,7 @@ static void slirp_smb(const char *exported_dir, struct in_addr vserver_addr)
1080 1096 snprintf(smb_cmdline, sizeof(smb_cmdline), "%s -s %s",
1081 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 1100 fprintf(stderr, "conflicting/invalid smbserver address\n");
1085 1101 exit(1);
1086 1102 }
... ... @@ -1096,8 +1112,8 @@ void net_slirp_smb(const char *exported_dir)
1096 1112 exit(1);
1097 1113 }
1098 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 1123 CharDriverState *hd;
1108 1124 struct in_addr server;
1109 1125 int port;
  1126 + Slirp *slirp;
1110 1127 };
1111 1128  
1112 1129 static int guestfwd_can_read(void *opaque)
1113 1130 {
1114 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 1135 static void guestfwd_read(void *opaque, const uint8_t *buf, int size)
1119 1136 {
1120 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 1142 int legacy_format)
1126 1143 {
1127 1144 struct in_addr server = { .s_addr = 0 };
... ... @@ -1169,8 +1186,9 @@ static void slirp_guestfwd(Monitor *mon, const char *config_str,
1169 1186 }
1170 1187 fwd->server = server;
1171 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 1192 config_error(mon, "conflicting/invalid host:port in guest forwarding "
1175 1193 "rule '%s'\n", config_str);
1176 1194 qemu_free(fwd);
... ... @@ -1186,8 +1204,13 @@ static void slirp_guestfwd(Monitor *mon, const char *config_str,
1186 1204  
1187 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 1216 #endif /* CONFIG_SLIRP */
... ... @@ -2498,7 +2521,7 @@ int net_client_init(Monitor *mon, const char *device, const char *p)
2498 2521 qemu_free(smb_export);
2499 2522 qemu_free(vsmbsrv);
2500 2523 } else if (!strcmp(device, "channel")) {
2501   - if (!slirp_inited) {
  2524 + if (!slirp_state) {
2502 2525 struct slirp_config_str *config;
2503 2526  
2504 2527 config = qemu_malloc(sizeof(*config));
... ... @@ -2507,7 +2530,7 @@ int net_client_init(Monitor *mon, const char *device, const char *p)
2507 2530 config->next = slirp_configs;
2508 2531 slirp_configs = config;
2509 2532 } else {
2510   - slirp_guestfwd(mon, p, 1);
  2533 + slirp_guestfwd(slirp_state, mon, p, 1);
2511 2534 }
2512 2535 ret = 0;
2513 2536 } else
... ...
slirp/if.c
... ... @@ -162,7 +162,7 @@ if_start(Slirp *slirp)
162 162  
163 163 again:
164 164 /* check if we can really output */
165   - if (!slirp_can_output())
  165 + if (!slirp_can_output(slirp->opaque))
166 166 return;
167 167  
168 168 /*
... ...
slirp/libslirp.h
... ... @@ -8,11 +8,11 @@
8 8 struct Slirp;
9 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 17 void slirp_select_fill(int *pnfds,
18 18 fd_set *readfds, fd_set *writefds, fd_set *xfds);
... ... @@ -20,23 +20,26 @@ void slirp_select_fill(int *pnfds,
20 20 void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
21 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 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 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 44 #else /* !CONFIG_SLIRP */
42 45  
... ...
slirp/misc.c
... ... @@ -370,7 +370,7 @@ fd_block(int fd)
370 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 375 const char * const tcpstates[] = {
376 376 [TCPS_CLOSED] = "CLOSED",
... ... @@ -385,7 +385,6 @@ void slirp_connection_info(Monitor *mon)
385 385 [TCPS_FIN_WAIT_2] = "FIN_WAIT_2",
386 386 [TCPS_TIME_WAIT] = "TIME_WAIT",
387 387 };
388   - Slirp *slirp = &slirp_instance;
389 388 struct in_addr dst_addr;
390 389 struct sockaddr_in src;
391 390 socklen_t src_len;
... ...
slirp/slirp.c
... ... @@ -187,11 +187,11 @@ static void slirp_init_once(void)
187 187 static void slirp_state_save(QEMUFile *f, void *opaque);
188 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 196 Slirp *slirp = &slirp_instance;
197 197  
... ... @@ -226,7 +226,11 @@ void slirp_init(int restricted, struct in_addr vnetwork,
226 226 slirp->vdhcp_startaddr = vdhcp_start;
227 227 slirp->vnameserver_addr = vnameserver;
228 228  
  229 + slirp->opaque = opaque;
  230 +
229 231 register_savevm("slirp", 0, 2, slirp_state_save, slirp_state_load, slirp);
  232 +
  233 + return slirp;
230 234 }
231 235  
232 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 639 rah->ar_sip = ah->ar_tip;
636 640 memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
637 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 644 break;
641 645 case ARPOP_REPLY:
... ... @@ -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 659 struct mbuf *m;
657 660 int proto;
658 661  
... ... @@ -724,7 +727,7 @@ void if_encap(Slirp *slirp, const uint8_t *ip_data, int ip_data_len)
724 727 /* target IP */
725 728 rah->ar_tip = iph->ip_dst.s_addr;
726 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 731 } else {
729 732 memcpy(eh->h_dest, slirp->client_ethaddr, ETH_ALEN);
730 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 735 memcpy(&eh->h_source[2], &slirp->vhost_addr, 4);
733 736 eh->h_proto = htons(ETH_P_IP);
734 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 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 746 struct socket *so;
744 747 struct socket *head = (is_udp ? &slirp->udb : &slirp->tcb);
745 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 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 770 if (!guest_addr.s_addr) {
770 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 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 788 if (!guest_addr.s_addr) {
790 789 guest_addr.s_addr = slirp->vnetwork_addr.s_addr |
791 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 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 829 struct iovec iov[2];
831 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 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 844 const uint8_t *buf, int size)
846 845 {
847   - Slirp *slirp = &slirp_instance;
848 846 int ret;
849 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 256 char *tftp_prefix;
257 257 struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX];
258 258  
  259 + void *opaque;
259 260 };
260 261  
261 262 extern Slirp slirp_instance;
... ...