#include "net/slirp.h"
-#if defined(CONFIG_SLIRP_SMBD)
+#if defined(CONFIG_SMBD_COMMAND)
#include <pwd.h>
#include <sys/wait.h>
#endif
#include "qapi/qmp/qdict.h"
#include "util.h"
#include "migration/register.h"
+#include "migration/vmstate.h"
#include "migration/qemu-file-types.h"
static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
Slirp *slirp;
Notifier poll_notifier;
Notifier exit_notifier;
-#if defined(CONFIG_SLIRP_SMBD)
+#if defined(CONFIG_SMBD_COMMAND)
gchar *smb_dir;
#endif
GSList *fwd;
static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp);
static int slirp_guestfwd(SlirpState *s, const char *config_str, Error **errp);
-#if defined(CONFIG_SLIRP_SMBD)
+#if defined(CONFIG_SMBD_COMMAND)
static int slirp_smb(SlirpState *s, const char *exported_dir,
struct in_addr vserver_addr, Error **errp);
static void slirp_smb_cleanup(SlirpState *s);
return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
}
+typedef struct SlirpTimer SlirpTimer;
+struct SlirpTimer {
+ QEMUTimer timer;
+#if SLIRP_CHECK_VERSION(4,7,0)
+ Slirp *slirp;
+ SlirpTimerId id;
+ void *cb_opaque;
+#endif
+};
+
+#if SLIRP_CHECK_VERSION(4,7,0)
+static void net_slirp_init_completed(Slirp *slirp, void *opaque)
+{
+ SlirpState *s = opaque;
+ s->slirp = slirp;
+}
+
+static void net_slirp_timer_cb(void *opaque)
+{
+ SlirpTimer *t = opaque;
+ slirp_handle_timer(t->slirp, t->id, t->cb_opaque);
+}
+
+static void *net_slirp_timer_new_opaque(SlirpTimerId id,
+ void *cb_opaque, void *opaque)
+{
+ SlirpState *s = opaque;
+ SlirpTimer *t = g_new(SlirpTimer, 1);
+ t->slirp = s->slirp;
+ t->id = id;
+ t->cb_opaque = cb_opaque;
+ timer_init_full(&t->timer, NULL, QEMU_CLOCK_VIRTUAL,
+ SCALE_MS, QEMU_TIMER_ATTR_EXTERNAL,
+ net_slirp_timer_cb, t);
+ return t;
+}
+#else
static void *net_slirp_timer_new(SlirpTimerCb cb,
void *cb_opaque, void *opaque)
{
- return timer_new_full(NULL, QEMU_CLOCK_VIRTUAL,
- SCALE_MS, QEMU_TIMER_ATTR_EXTERNAL,
- cb, cb_opaque);
+ SlirpTimer *t = g_new(SlirpTimer, 1);
+ timer_init_full(&t->timer, NULL, QEMU_CLOCK_VIRTUAL,
+ SCALE_MS, QEMU_TIMER_ATTR_EXTERNAL,
+ cb, cb_opaque);
+ return t;
}
+#endif
static void net_slirp_timer_free(void *timer, void *opaque)
{
- timer_free(timer);
+ SlirpTimer *t = timer;
+ timer_del(&t->timer);
+ g_free(t);
}
static void net_slirp_timer_mod(void *timer, int64_t expire_timer,
void *opaque)
{
- timer_mod(timer, expire_timer);
+ SlirpTimer *t = timer;
+ timer_mod(&t->timer, expire_timer);
}
static void net_slirp_register_poll_fd(int fd, void *opaque)
{
- qemu_fd_register(fd);
+#ifdef WIN32
+ AioContext *ctxt = qemu_get_aio_context();
+
+ if (WSAEventSelect(fd, event_notifier_get_handle(&ctxt->notifier),
+ FD_READ | FD_ACCEPT | FD_CLOSE |
+ FD_CONNECT | FD_WRITE | FD_OOB) != 0) {
+ error_setg_win32(&error_warn, WSAGetLastError(), "failed to WSAEventSelect()");
+ }
+#endif
}
static void net_slirp_unregister_poll_fd(int fd, void *opaque)
{
- /* no qemu_fd_unregister */
+#ifdef WIN32
+ if (WSAEventSelect(fd, NULL, 0) != 0) {
+ error_setg_win32(&error_warn, WSAGetLastError(), "failed to WSAEventSelect()");
+ }
+#endif
}
static void net_slirp_notify(void *opaque)
.send_packet = net_slirp_send_packet,
.guest_error = net_slirp_guest_error,
.clock_get_ns = net_slirp_clock_get_ns,
+#if SLIRP_CHECK_VERSION(4,7,0)
+ .init_completed = net_slirp_init_completed,
+ .timer_new_opaque = net_slirp_timer_new_opaque,
+#else
.timer_new = net_slirp_timer_new,
+#endif
.timer_free = net_slirp_timer_free,
.timer_mod = net_slirp_timer_mod,
.register_poll_fd = net_slirp_register_poll_fd,
struct in6_addr ip6_prefix;
struct in6_addr ip6_host;
struct in6_addr ip6_dns;
-#if defined(CONFIG_SLIRP_SMBD)
+#if defined(CONFIG_SMBD_COMMAND)
struct in_addr smbsrv = { .s_addr = 0 };
#endif
+ SlirpConfig cfg = { 0 };
NetClientState *nc;
SlirpState *s;
char buf[20];
return -1;
}
-#if defined(CONFIG_SLIRP_SMBD)
+#if defined(CONFIG_SMBD_COMMAND)
if (vsmbserver && !inet_aton(vsmbserver, &smbsrv)) {
error_setg(errp, "Failed to parse SMB address");
return -1;
nc = qemu_new_net_client(&net_slirp_info, peer, model, name);
- snprintf(nc->info_str, sizeof(nc->info_str),
- "net=%s,restrict=%s", inet_ntoa(net),
- restricted ? "on" : "off");
+ qemu_set_info_str(nc, "net=%s,restrict=%s", inet_ntoa(net),
+ restricted ? "on" : "off");
s = DO_UPCAST(SlirpState, nc, nc);
- s->slirp = slirp_init(restricted, ipv4, net, mask, host,
- ipv6, ip6_prefix, vprefix6_len, ip6_host,
- vhostname, tftp_server_name,
- tftp_export, bootfile, dhcp,
- dns, ip6_dns, dnssearch, vdomainname,
- &slirp_cb, s);
+ cfg.version = SLIRP_CHECK_VERSION(4,7,0) ? 4 : 1;
+ cfg.restricted = restricted;
+ cfg.in_enabled = ipv4;
+ cfg.vnetwork = net;
+ cfg.vnetmask = mask;
+ cfg.vhost = host;
+ cfg.in6_enabled = ipv6;
+ cfg.vprefix_addr6 = ip6_prefix;
+ cfg.vprefix_len = vprefix6_len;
+ cfg.vhost6 = ip6_host;
+ cfg.vhostname = vhostname;
+ cfg.tftp_server_name = tftp_server_name;
+ cfg.tftp_path = tftp_export;
+ cfg.bootfile = bootfile;
+ cfg.vdhcp_start = dhcp;
+ cfg.vnameserver = dns;
+ cfg.vnameserver6 = ip6_dns;
+ cfg.vdnssearch = dnssearch;
+ cfg.vdomainname = vdomainname;
+ s->slirp = slirp_new(&cfg, &slirp_cb, s);
QTAILQ_INSERT_TAIL(&slirp_stacks, s, entry);
/*
* specific version?
*/
g_assert(slirp_state_version() == 4);
- register_savevm_live("slirp", 0, slirp_state_version(),
- &savevm_slirp_state, s->slirp);
+ register_savevm_live("slirp", VMSTATE_INSTANCE_ID_ANY,
+ slirp_state_version(), &savevm_slirp_state, s->slirp);
s->poll_notifier.notify = net_slirp_poll_notify;
main_loop_poll_add_notifier(&s->poll_notifier);
}
}
}
-#if defined(CONFIG_SLIRP_SMBD)
+#if defined(CONFIG_SMBD_COMMAND)
if (smb_export) {
if (slirp_smb(s, smb_export, smbsrv, errp) < 0) {
goto error;
}
-#if defined(CONFIG_SLIRP_SMBD)
+#if defined(CONFIG_SMBD_COMMAND)
/* automatic user mode samba server configuration */
static void slirp_smb_cleanup(SlirpState *s)
return 0;
}
-#endif /* defined(CONFIG_SLIRP_SMBD) */
+#endif /* defined(CONFIG_SMBD_COMMAND) */
static int guestfwd_can_read(void *opaque)
{
ipv6 = 0;
}
- vnet = user->has_net ? g_strdup(user->net) :
- user->has_ip ? g_strdup_printf("%s/24", user->ip) :
+ vnet = user->net ? g_strdup(user->net) :
+ user->ip ? g_strdup_printf("%s/24", user->ip) :
NULL;
dnssearch = slirp_dnssearch(user->dnssearch);