From nobody Mon Feb 9 02:12:12 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1491240242719774.2557797937336; Mon, 3 Apr 2017 10:24:02 -0700 (PDT) Received: from localhost ([::1]:60419 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cv5hw-0004Ph-Sb for importer@patchew.org; Mon, 03 Apr 2017 13:24:00 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55063) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cv5d0-0000Qw-MP for qemu-devel@nongnu.org; Mon, 03 Apr 2017 13:18:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cv5cy-0003lp-Sh for qemu-devel@nongnu.org; Mon, 03 Apr 2017 13:18:54 -0400 Received: from mx1.redhat.com ([209.132.183.28]:40820) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cv5cy-0003kx-Kl for qemu-devel@nongnu.org; Mon, 03 Apr 2017 13:18:52 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id AA7E2E9A30; Mon, 3 Apr 2017 17:18:51 +0000 (UTC) Received: from dgilbert-t530.redhat.com (ovpn-117-210.ams2.redhat.com [10.36.117.210]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6C820A0A33; Mon, 3 Apr 2017 17:18:50 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com AA7E2E9A30 Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=dgilbert@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com AA7E2E9A30 From: "Dr. David Alan Gilbert (git)" To: qemu-devel@nongnu.org, samuel.thibault@gnu.org, jan.kiszka@siemens.com Date: Mon, 3 Apr 2017 18:18:42 +0100 Message-Id: <20170403171843.3363-5-dgilbert@redhat.com> In-Reply-To: <20170403171843.3363-1-dgilbert@redhat.com> References: <20170403171843.3363-1-dgilbert@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Mon, 03 Apr 2017 17:18:51 +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 v5 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: quintela@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: "Dr. David Alan Gilbert" Working up the stack, this replaces the slirp_socket_load/save with VMState definitions. A place holder for IPv6 support is added as a comment; it needs testing once the rest of the IPv6 code is there. Signed-off-by: Dr. David Alan Gilbert --- slirp/slirp.c | 219 +++++++++++++++++++++++++++++++++++++----------------= ---- slirp/socket.h | 6 +- 2 files changed, 145 insertions(+), 80 deletions(-) diff --git a/slirp/slirp.c b/slirp/slirp.c index 2b834af..2de97b6 100644 --- a/slirp/slirp.c +++ b/slirp/slirp.c @@ -1250,40 +1250,154 @@ static const VMStateDescription vmstate_slirp_sbuf= =3D { } }; =20 +static bool slirp_older_than_v4(void *opaque, int version_id) +{ + return version_id < 4; +} =20 -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"); + union slirp_sockaddr *ssa =3D (union slirp_sockaddr *)opaque; + return ssa->ss.ss_family =3D=3D AF_INET; +} + +static int slirp_socket_pre_load(void *opaque) +{ + struct socket *so =3D opaque; + if (tcp_attach(so) < 0) { + return -ENOMEM; } - 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); + /* Older versions don't load these fields */ + so->so_ffamily =3D AF_INET; + so->so_lfamily =3D AF_INET; + return 0; +} + +#ifndef _WIN32 +#define VMSTATE_SIN4_ADDR(f, s, t) VMSTATE_UINT32_TEST(f, s, t) +#else +/* Win uses u_long rather than uint32_t - but it's still 32bits long */ +#define VMSTATE_SIN4_ADDR(f, s, t) VMSTATE_SINGLE_TEST(f, s, t, 0, \ + vmstate_info_uint32, u_long) +#endif + +/* The OS provided ss_family field isn't that portable; it's size + * and type varies (16/8 bit, signed, unsigned) + * and the values it contains aren't fully portable. + */ +typedef struct SS_FamilyTmpStruct { + union slirp_sockaddr *parent; + uint16_t portable_family; +} SS_FamilyTmpStruct; + +#define SS_FAMILY_MIG_IPV4 2 /* Linux, BSD, Win... */ +#define SS_FAMILY_MIG_IPV6 10 /* Linux */ +#define SS_FAMILY_MIG_OTHER 0xffff + +static void ss_family_pre_save(void *opaque) +{ + SS_FamilyTmpStruct *tss =3D opaque; + + tss->portable_family =3D SS_FAMILY_MIG_OTHER; + + if (tss->parent->ss.ss_family =3D=3D AF_INET) { + tss->portable_family =3D SS_FAMILY_MIG_IPV4; + } else if (tss->parent->ss.ss_family =3D=3D AF_INET6) { + tss->portable_family =3D SS_FAMILY_MIG_IPV6; + } +} + +static int ss_family_post_load(void *opaque, int version_id) +{ + SS_FamilyTmpStruct *tss =3D opaque; + + switch (tss->portable_family) { + case SS_FAMILY_MIG_IPV4: + tss->parent->ss.ss_family =3D AF_INET; + break; + case SS_FAMILY_MIG_IPV6: + case 23: /* compatibility: AF_INET6 from mingw */ + case 28: /* compatibility: AF_INET6 from FreeBSD sys/socket.h */ + tss->parent->ss.ss_family =3D AF_INET6; break; default: - error_report("so_ffamily unknown, unable to save so_laddr and" - " so_lport"); + error_report("invalid ss_family type %x", tss->portable_family); + return -EINVAL; } - 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); + + return 0; } =20 +static const VMStateDescription vmstate_slirp_ss_family =3D { + .name =3D "slirp-socket-addr/ss_family", + .pre_save =3D ss_family_pre_save, + .post_load =3D ss_family_post_load, + .fields =3D (VMStateField[]) { + VMSTATE_UINT16(portable_family, SS_FamilyTmpStruct), + VMSTATE_END_OF_LIST() + } +}; + +static const VMStateDescription vmstate_slirp_socket_addr =3D { + .name =3D "slirp-socket-addr", + .version_id =3D 4, + .fields =3D (VMStateField[]) { + VMSTATE_WITH_TMP(union slirp_sockaddr, SS_FamilyTmpStruct, + vmstate_slirp_ss_family), + VMSTATE_SIN4_ADDR(sin.sin_addr.s_addr, union slirp_sockaddr, + slirp_family_inet), + VMSTATE_UINT16_TEST(sin.sin_port, union slirp_sockaddr, + slirp_family_inet), + +#if 0 + /* Untested: Needs checking by someone with IPv6 test */ + VMSTATE_BUFFER_TEST(sin6.sin6_addr, union slirp_sockaddr, + slirp_family_inet6), + VMSTATE_UINT16_TEST(sin6.sin6_port, union slirp_sockaddr, + slirp_family_inet6), + VMSTATE_UINT32_TEST(sin6.sin6_flowinfo, union slirp_sockaddr, + slirp_family_inet6), + VMSTATE_UINT32_TEST(sin6.sin6_scope_id, union slirp_sockaddr, + slirp_family_inet6), +#endif + + VMSTATE_END_OF_LIST() + } +}; + +static const VMStateDescription vmstate_slirp_socket =3D { + .name =3D "slirp-socket", + .version_id =3D 4, + .pre_load =3D slirp_socket_pre_load, + .fields =3D (VMStateField[]) { + VMSTATE_UINT32(so_urgc, struct socket), + /* Pre-v4 versions */ + VMSTATE_SIN4_ADDR(so_faddr.s_addr, struct socket, + slirp_older_than_v4), + VMSTATE_SIN4_ADDR(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 +1422,7 @@ static void slirp_state_save(QEMUFile *f, void *opaqu= e) continue; =20 qemu_put_byte(f, 42); - slirp_socket_save(f, so); + vmstate_save_state(f, &vmstate_slirp_socket, so, NULL); } qemu_put_byte(f, 0); =20 @@ -1317,55 +1431,6 @@ static void slirp_state_save(QEMUFile *f, void *opaq= ue) slirp_bootp_save(f, slirp); } =20 -static int slirp_socket_load(QEMUFile *f, struct socket *so, int version_i= d) -{ - int ret =3D 0; - if (tcp_attach(so) < 0) - return -ENOMEM; - - so->so_urgc =3D qemu_get_be32(f); - if (version_id <=3D 3) { - so->so_ffamily =3D AF_INET; - so->so_faddr.s_addr =3D qemu_get_be32(f); - so->so_laddr.s_addr =3D qemu_get_be32(f); - so->so_fport =3D qemu_get_be16(f); - so->so_lport =3D qemu_get_be16(f); - } else { - so->so_ffamily =3D qemu_get_be16(f); - switch (so->so_ffamily) { - case AF_INET: - so->so_faddr.s_addr =3D qemu_get_be32(f); - so->so_fport =3D qemu_get_be16(f); - break; - default: - error_report( - "so_ffamily unknown, unable to restore so_faddr and so_lpo= rt"); - } - so->so_lfamily =3D qemu_get_be16(f); - switch (so->so_lfamily) { - case AF_INET: - so->so_laddr.s_addr =3D qemu_get_be32(f); - so->so_lport =3D qemu_get_be16(f); - break; - default: - error_report( - "so_ffamily unknown, unable to restore so_laddr and so_lpo= rt"); - } - } - so->so_iptos =3D qemu_get_byte(f); - so->so_emu =3D qemu_get_byte(f); - so->so_type =3D qemu_get_byte(f); - so->so_state =3D qemu_get_be32(f); - /* TODO: VMState at this level */ - ret =3D vmstate_load_state(f, &vmstate_slirp_sbuf, &so->so_rcv, 0); - if (!ret) { - ret =3D vmstate_load_state(f, &vmstate_slirp_sbuf, &so->so_snd, 0); - } - if (!ret) { - ret =3D vmstate_load_state(f, &vmstate_slirp_tcp, so->so_tcpcb, 0); - } - return ret; -} =20 static void slirp_bootp_load(QEMUFile *f, Slirp *slirp) { @@ -1389,7 +1454,7 @@ static int slirp_state_load(QEMUFile *f, void *opaque= , int version_id) if (!so) return -ENOMEM; =20 - ret =3D slirp_socket_load(f, so, version_id); + ret =3D vmstate_load_state(f, &vmstate_slirp_socket, so, version_i= d); =20 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? */ =20 - 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 */ =20 struct tcpcb *so_tcpcb; /* pointer to TCP protocol control block */ u_int so_expire; /* When the socket will expire */ --=20 2.9.3