#include "monitor/monitor.h"
#include "qemu/error-report.h"
#include "qemu/sockets.h"
-#include "slirp/libslirp.h"
+#include <libslirp.h>
#include "chardev/char-fe.h"
#include "sysemu/sysemu.h"
#include "qemu/cutils.h"
#include "qapi/error.h"
#include "qapi/qmp/qdict.h"
#include "util.h"
+#include "migration/register.h"
+#include "migration/qemu-file-types.h"
static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
{
g_slist_free_full(s->fwd, slirp_free_fwd);
main_loop_poll_remove_notifier(&s->poll_notifier);
+ unregister_savevm(NULL, "slirp", s->slirp);
slirp_cleanup(s->slirp);
if (s->exit_notifier.notify) {
qemu_remove_exit_notifier(&s->exit_notifier);
}
}
+static ssize_t
+net_slirp_stream_read(void *buf, size_t size, void *opaque)
+{
+ QEMUFile *f = opaque;
+
+ return qemu_get_buffer(f, buf, size);
+}
+
+static ssize_t
+net_slirp_stream_write(const void *buf, size_t size, void *opaque)
+{
+ QEMUFile *f = opaque;
+
+ qemu_put_buffer(f, buf, size);
+ if (qemu_file_get_error(f)) {
+ return -1;
+ }
+
+ return size;
+}
+
+static int net_slirp_state_load(QEMUFile *f, void *opaque, int version_id)
+{
+ Slirp *slirp = opaque;
+
+ return slirp_state_load(slirp, version_id, net_slirp_stream_read, f);
+}
+
+static void net_slirp_state_save(QEMUFile *f, void *opaque)
+{
+ Slirp *slirp = opaque;
+
+ slirp_state_save(slirp, net_slirp_stream_write, f);
+}
+
+static SaveVMHandlers savevm_slirp_state = {
+ .save_state = net_slirp_state_save,
+ .load_state = net_slirp_state_load,
+};
+
static int net_slirp_init(NetClientState *peer, const char *model,
const char *name, int restricted,
bool ipv4, const char *vnetwork, const char *vhost,
error_setg(errp, "Failed to parse DNS");
return -1;
}
- if ((dns.s_addr & mask.s_addr) != net.s_addr) {
+ if (restricted && (dns.s_addr & mask.s_addr) != net.s_addr) {
error_setg(errp, "DNS doesn't belong to network");
return -1;
}
}
if (vprefix6_len < 0 || vprefix6_len > 126) {
error_setg(errp,
- "Invalid prefix provided (prefix len must be in range 0-126");
+ "Invalid IPv6 prefix provided "
+ "(IPv6 prefix length must be between 0 and 126)");
return -1;
}
error_setg(errp, "Failed to parse IPv6 DNS");
return -1;
}
- if (!in6_equal_net(&ip6_prefix, &ip6_dns, vprefix6_len)) {
+ if (restricted && !in6_equal_net(&ip6_prefix, &ip6_dns, vprefix6_len)) {
error_setg(errp, "IPv6 DNS doesn't belong to network");
return -1;
}
&slirp_cb, s);
QTAILQ_INSERT_TAIL(&slirp_stacks, s, entry);
+ /*
+ * Make sure the current bitstream version of slirp is 4, to avoid
+ * QEMU migration incompatibilities, if upstream slirp bumped the
+ * version.
+ *
+ * FIXME: use bitfields of features? teach libslirp to save with
+ * specific version?
+ */
+ g_assert(slirp_state_version() == 4);
+ register_savevm_live("slirp", 0, slirp_state_version(),
+ &savevm_slirp_state, s->slirp);
+
s->poll_notifier.notify = net_slirp_poll_notify;
main_loop_poll_add_notifier(&s->poll_notifier);
static int slirp_guestfwd(SlirpState *s, const char *config_str, Error **errp)
{
+ /* TODO: IPv6 */
struct in_addr server = { .s_addr = 0 };
struct GuestFwd *fwd;
const char *p;
* FIXME: sure we want to support implicit
* muxed monitors here?
*/
- Chardev *chr = qemu_chr_new_mux_mon(buf, p);
+ Chardev *chr = qemu_chr_new_mux_mon(buf, p, NULL);
if (!chr) {
error_setg(errp, "Could not open guest forwarding device '%s'",