Commit 9f8bd0421dc03b2640ac2d0a4d702354a218b2ab
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>
Showing
6 changed files
with
108 additions
and
84 deletions
net.c
| @@ -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; |