From patchwork Wed Nov 23 18:52:57 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Dr. David Alan Gilbert" X-Patchwork-Id: 698483 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3tPBN41vZjz9t1T for ; Thu, 24 Nov 2016 05:54:44 +1100 (AEDT) Received: from localhost ([::1]:35710 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1c9cgr-0003QK-OL for incoming@patchwork.ozlabs.org; Wed, 23 Nov 2016 13:54:41 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44163) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1c9cfM-0002Dr-9A for qemu-devel@nongnu.org; Wed, 23 Nov 2016 13:53:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1c9cfK-0002vn-UT for qemu-devel@nongnu.org; Wed, 23 Nov 2016 13:53:08 -0500 Received: from mx1.redhat.com ([209.132.183.28]:56950) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1c9cfK-0002tT-Le for qemu-devel@nongnu.org; Wed, 23 Nov 2016 13:53:06 -0500 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id BD376C04B944; Wed, 23 Nov 2016 18:53:05 +0000 (UTC) Received: from dgilbert-t530.redhat.com ([10.33.36.2]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id uANIqxfY002961; Wed, 23 Nov 2016 13:53:04 -0500 From: "Dr. David Alan Gilbert (git)" To: qemu-devel@nongnu.org, samuel.thibault@ens-lyon.org Date: Wed, 23 Nov 2016 18:52:57 +0000 Message-Id: <20161123185258.771-5-dgilbert@redhat.com> In-Reply-To: <20161123185258.771-1-dgilbert@redhat.com> References: <20161123185258.771-1-dgilbert@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Wed, 23 Nov 2016 18:53:05 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v2 4/5] slirp: VMStatify socket level X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: amit.shah@redhat.com, quintela@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: "Dr. David Alan Gilbert" Working up the stack, this replaces the slirp_socket_load/save with VMState definitions. Signed-off-by: Dr. David Alan Gilbert --- slirp/slirp.c | 146 ++++++++++++++++++++++++++------------------------------- slirp/socket.h | 6 +-- 2 files changed, 69 insertions(+), 83 deletions(-) diff --git a/slirp/slirp.c b/slirp/slirp.c index 2f7802e..c631338 100644 --- a/slirp/slirp.c +++ b/slirp/slirp.c @@ -1250,40 +1250,75 @@ static const VMStateDescription vmstate_slirp_sbuf = { } }; +static bool slirp_older_than_v4(void *opaque, int version_id) +{ + return version_id < 4; +} -static void slirp_socket_save(QEMUFile *f, struct socket *so) +static bool slirp_family_inet(void *opaque, int version_id) { - qemu_put_be32(f, so->so_urgc); - qemu_put_be16(f, so->so_ffamily); - switch (so->so_ffamily) { - case AF_INET: - qemu_put_be32(f, so->so_faddr.s_addr); - qemu_put_be16(f, so->so_fport); - break; - default: - error_report("so_ffamily unknown, unable to save so_faddr and" - " so_fport"); - } - qemu_put_be16(f, so->so_lfamily); - switch (so->so_lfamily) { - case AF_INET: - qemu_put_be32(f, so->so_laddr.s_addr); - qemu_put_be16(f, so->so_lport); - break; - default: - error_report("so_ffamily unknown, unable to save so_laddr and" - " so_lport"); + union slirp_sockaddr *ssa = (union slirp_sockaddr *)opaque; + return ssa->ss.ss_family == AF_INET; +} + +static int slirp_socket_pre_load(void *opaque) +{ + struct socket *so = opaque; + if (tcp_attach(so) < 0) { + return -ENOMEM; } - qemu_put_byte(f, so->so_iptos); - qemu_put_byte(f, so->so_emu); - qemu_put_byte(f, so->so_type); - qemu_put_be32(f, so->so_state); - /* TODO: Build vmstate at this level */ - vmstate_save_state(f, &vmstate_slirp_sbuf, &so->so_rcv, 0); - vmstate_save_state(f, &vmstate_slirp_sbuf, &so->so_snd, 0); - vmstate_save_state(f, &vmstate_slirp_tcp, so->so_tcpcb, 0); + /* Older versions don't load these fields */ + so->so_ffamily = AF_INET; + so->so_lfamily = AF_INET; + return 0; } +static const VMStateDescription vmstate_slirp_socket_addr = { + .name = "slirp-socket-addr", + .version_id = 4, + .fields = (VMStateField[]) { + VMSTATE_UINT16(ss.ss_family, union slirp_sockaddr), + VMSTATE_UINT32_TEST(sin.sin_addr.s_addr, union slirp_sockaddr, + slirp_family_inet), + VMSTATE_UINT16_TEST(sin.sin_port, union slirp_sockaddr, + slirp_family_inet), + VMSTATE_END_OF_LIST() + } +}; + +static const VMStateDescription vmstate_slirp_socket = { + .name = "slirp-socket", + .version_id = 4, + .pre_load = slirp_socket_pre_load, + .fields = (VMStateField[]) { + VMSTATE_UINT32(so_urgc, struct socket), + /* Pre-v4 versions */ + VMSTATE_UINT32_TEST(so_faddr.s_addr, struct socket, + slirp_older_than_v4), + VMSTATE_UINT32_TEST(so_laddr.s_addr, struct socket, + slirp_older_than_v4), + VMSTATE_UINT16_TEST(so_fport, struct socket, slirp_older_than_v4), + VMSTATE_UINT16_TEST(so_lport, struct socket, slirp_older_than_v4), + /* v4 and newer */ + VMSTATE_STRUCT(fhost, struct socket, 4, vmstate_slirp_socket_addr, + union slirp_sockaddr), + VMSTATE_STRUCT(lhost, struct socket, 4, vmstate_slirp_socket_addr, + union slirp_sockaddr), + + VMSTATE_UINT8(so_iptos, struct socket), + VMSTATE_UINT8(so_emu, struct socket), + VMSTATE_UINT8(so_type, struct socket), + VMSTATE_INT32(so_state, struct socket), + VMSTATE_STRUCT(so_rcv, struct socket, 0, vmstate_slirp_sbuf, + struct sbuf), + VMSTATE_STRUCT(so_snd, struct socket, 0, vmstate_slirp_sbuf, + struct sbuf), + VMSTATE_STRUCT_POINTER(so_tcpcb, struct socket, vmstate_slirp_tcp, + struct tcpcb), + VMSTATE_END_OF_LIST() + } +}; + static void slirp_bootp_save(QEMUFile *f, Slirp *slirp) { int i; @@ -1308,7 +1343,7 @@ static void slirp_state_save(QEMUFile *f, void *opaque) continue; qemu_put_byte(f, 42); - slirp_socket_save(f, so); + vmstate_save_state(f, &vmstate_slirp_socket, so, NULL); } qemu_put_byte(f, 0); @@ -1317,55 +1352,6 @@ static void slirp_state_save(QEMUFile *f, void *opaque) slirp_bootp_save(f, slirp); } -static int slirp_socket_load(QEMUFile *f, struct socket *so, int version_id) -{ - int ret = 0; - if (tcp_attach(so) < 0) - return -ENOMEM; - - so->so_urgc = qemu_get_be32(f); - if (version_id <= 3) { - so->so_ffamily = AF_INET; - so->so_faddr.s_addr = qemu_get_be32(f); - so->so_laddr.s_addr = qemu_get_be32(f); - so->so_fport = qemu_get_be16(f); - so->so_lport = qemu_get_be16(f); - } else { - so->so_ffamily = qemu_get_be16(f); - switch (so->so_ffamily) { - case AF_INET: - so->so_faddr.s_addr = qemu_get_be32(f); - so->so_fport = qemu_get_be16(f); - break; - default: - error_report( - "so_ffamily unknown, unable to restore so_faddr and so_lport"); - } - so->so_lfamily = qemu_get_be16(f); - switch (so->so_lfamily) { - case AF_INET: - so->so_laddr.s_addr = qemu_get_be32(f); - so->so_lport = qemu_get_be16(f); - break; - default: - error_report( - "so_ffamily unknown, unable to restore so_laddr and so_lport"); - } - } - so->so_iptos = qemu_get_byte(f); - so->so_emu = qemu_get_byte(f); - so->so_type = qemu_get_byte(f); - so->so_state = qemu_get_be32(f); - /* TODO: VMState at this level */ - ret = vmstate_load_state(f, &vmstate_slirp_sbuf, &so->so_rcv, 0); - if (!ret) { - ret = vmstate_load_state(f, &vmstate_slirp_sbuf, &so->so_snd, 0); - } - if (!ret) { - ret = vmstate_load_state(f, &vmstate_slirp_tcp, so->so_tcpcb, 0); - } - return ret; -} static void slirp_bootp_load(QEMUFile *f, Slirp *slirp) { @@ -1389,7 +1375,7 @@ static int slirp_state_load(QEMUFile *f, void *opaque, int version_id) if (!so) return -ENOMEM; - ret = slirp_socket_load(f, so, version_id); + ret = vmstate_load_state(f, &vmstate_slirp_socket, so, version_id); if (ret < 0) return ret; diff --git a/slirp/socket.h b/slirp/socket.h index c1be77e..2f224bc 100644 --- a/slirp/socket.h +++ b/slirp/socket.h @@ -36,7 +36,7 @@ struct socket { * PING reply's */ struct tcpiphdr *so_ti; /* Pointer to the original ti within * so_mconn, for non-blocking connections */ - int so_urgc; + uint32_t so_urgc; union slirp_sockaddr fhost; /* Foreign host */ #define so_faddr fhost.sin.sin_addr #define so_fport fhost.sin.sin_port @@ -54,8 +54,8 @@ struct socket { uint8_t so_iptos; /* Type of service */ uint8_t so_emu; /* Is the socket emulated? */ - u_char so_type; /* Type of socket, UDP or TCP */ - int so_state; /* internal state flags SS_*, below */ + uint8_t so_type; /* Type of socket, UDP or TCP */ + int32_t so_state; /* internal state flags SS_*, below */ struct tcpcb *so_tcpcb; /* pointer to TCP protocol control block */ u_int so_expire; /* When the socket will expire */