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; |