All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULLv4 00/32] More work towards libslirp
@ 2019-02-07 14:02 Samuel Thibault
  2019-02-07 14:02 ` [Qemu-devel] [PULLv4 01/32] slirp: Avoid unaligned 16bit memory access Samuel Thibault
                   ` (33 more replies)
  0 siblings, 34 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:02 UTC (permalink / raw)
  To: qemu-devel, peter.maydell; +Cc: Samuel Thibault, stefanha, jan.kiszka

The following changes since commit 713acc316ddca119fe168e72846f1d2dd0548430:

  Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20190206' into staging (2019-02-07 11:46:40 +0000)

are available in the Git repository at:

  https://people.debian.org/~sthibault/qemu.git tags/samuel-thibault

for you to fetch changes up to ee261c02332ea856352f250b295a8ecd1eeb748e:

  slirp: API is extern C (2019-02-07 15:49:08 +0200)

----------------------------------------------------------------
More work towards libslirp

Marc-André Lureau (27):
  slirp: generalize guestfwd with a callback based approach
  net/slirp: simplify checking for cmd: prefix
  net/slirp: free forwarding rules on cleanup
  net/slirp: fix leaks on forwarding rule registration error
  slirp: add callbacks for timer
  slirp: replace trace functions with DEBUG calls
  slirp: replace QEMU_PACKED with SLIRP_PACKED
  slirp: replace most qemu socket utilities with slirp own version
  slirp: replace qemu_set_nonblock()
  slirp: add unregister_poll_fd() callback
  slirp: replace qemu_notify_event() with a callback
  slirp: move QEMU state saving to a separate unit
  slirp: do not include qemu headers in libslirp.h public API header
  slirp: improve windows headers inclusion
  slirp: add slirp own version of pstrcpy
  slirp: remove qemu timer.h dependency
  slirp: remove now useless QEMU headers inclusions
  slirp: replace net/eth.h inclusion with own defines
  slirp: replace qemu qtailq with slirp own copy
  slirp: replace remaining qemu headers dependency
  slirp: prefer c99 types over BSD kind
  slirp: improve send_packet() callback
  slirp: replace global polling with per-instance & notifier
  slirp: remove slirp_instances list
  slirp: use polling callbacks, drop glib requirement
  slirp: pass opaque to all callbacks
  slirp: API is extern C

Peter Maydell (2):
  slirp: Avoid marking naturally packed structs as QEMU_PACKED
  slirp: Don't mark struct ipq or struct ipasfrag as packed

Samuel Thibault (3):
  slirp: Avoid unaligned 16bit memory access
  slirp: replace QEMU_BUILD_BUG_ON with G_STATIC_ASSERT
  slirp: Move g_spawn_async_with_fds_qemu compatibility to slirp/

----------------------------------------------------------------
Marc-André Lureau (27):
      slirp: generalize guestfwd with a callback based approach
      net/slirp: simplify checking for cmd: prefix
      net/slirp: free forwarding rules on cleanup
      net/slirp: fix leaks on forwarding rule registration error
      slirp: add callbacks for timer
      slirp: replace trace functions with DEBUG calls
      slirp: replace QEMU_PACKED with SLIRP_PACKED
      slirp: replace most qemu socket utilities with slirp own version
      slirp: replace qemu_set_nonblock()
      slirp: add unregister_poll_fd() callback
      slirp: replace qemu_notify_event() with a callback
      slirp: move QEMU state saving to a separate unit
      slirp: do not include qemu headers in libslirp.h public API header
      slirp: improve windows headers inclusion
      slirp: add slirp own version of pstrcpy
      slirp: remove qemu timer.h dependency
      slirp: remove now useless QEMU headers inclusions
      slirp: replace net/eth.h inclusion with own defines
      slirp: replace qemu qtailq with slirp own copy
      slirp: replace remaining qemu headers dependency
      slirp: prefer c99 types over BSD kind
      slirp: improve send_packet() callback
      slirp: replace global polling with per-instance & notifier
      slirp: remove slirp_instances list
      slirp: use polling callbacks, drop glib requirement
      slirp: pass opaque to all callbacks
      slirp: API is extern C

Peter Maydell (2):
      slirp: Avoid marking naturally packed structs as QEMU_PACKED
      slirp: Don't mark struct ipq or struct ipasfrag as packed

Samuel Thibault (3):
      slirp: Avoid unaligned 16bit memory access
      slirp: replace QEMU_BUILD_BUG_ON with G_STATIC_ASSERT
      slirp: Move g_spawn_async_with_fds_qemu compatibility to slirp/

 Makefile.objs            |   1 -
 include/glib-compat.h    |  57 ---
 include/net/net.h        |   2 +-
 include/qemu/main-loop.h |  15 +
 net/net.c                |   4 +-
 net/slirp.c              | 185 ++++++++-
 slirp/Makefile.objs      |   4 +-
 slirp/arp_table.c        |   3 +-
 slirp/bootp.c            |   1 -
 slirp/cksum.c            |   1 -
 slirp/debug.h            |  13 +-
 slirp/dhcpv6.c           |   4 +-
 slirp/dnssearch.c        |   1 -
 slirp/if.c               |   4 +-
 slirp/ip.h               |  17 +-
 slirp/ip6.h              |  14 +-
 slirp/ip6_icmp.c         |  27 +-
 slirp/ip6_icmp.h         |  26 +-
 slirp/ip6_input.c        |   1 -
 slirp/ip6_output.c       |   2 -
 slirp/ip_icmp.c          |  14 +-
 slirp/ip_icmp.h          |  18 +-
 slirp/ip_input.c         |   5 +-
 slirp/ip_output.c        |   1 -
 slirp/libslirp.h         |  71 +++-
 slirp/main.h             |   2 +-
 slirp/mbuf.c             |   1 -
 slirp/mbuf.h             |   2 +-
 slirp/misc.c             | 126 ++++--
 slirp/misc.h             |  15 +-
 slirp/ncsi.c             |   3 +-
 slirp/ndp_table.c        |   2 -
 slirp/qtailq.h           | 193 ++++++++++
 slirp/sbuf.c             |   8 +-
 slirp/sbuf.h             |   2 +-
 slirp/slirp.c            | 981 +++++++++++++++--------------------------------
 slirp/slirp.h            |  45 +--
 slirp/socket.c           |  33 +-
 slirp/socket.h           |   9 +-
 slirp/state.c            | 394 +++++++++++++++++++
 slirp/state.h            |   9 +
 slirp/tcp_input.c        |  29 +-
 slirp/tcp_output.c       |  13 +-
 slirp/tcp_subr.c         |  49 +--
 slirp/tcp_timer.c        |   3 +-
 slirp/tcp_var.h          |  14 +-
 slirp/tftp.c             |  16 +-
 slirp/trace-events       |   5 -
 slirp/udp.c              |  16 +-
 slirp/udp.h              |   2 +-
 slirp/udp6.c             |   2 -
 slirp/util.c             | 207 ++++++++++
 slirp/util.h             | 127 ++++++
 stubs/Makefile.objs      |   3 +-
 stubs/slirp.c            |  13 -
 util/main-loop.c         |  30 +-
 util/osdep.c             |   2 +-
 57 files changed, 1828 insertions(+), 1019 deletions(-)
 create mode 100644 slirp/qtailq.h
 create mode 100644 slirp/state.c
 create mode 100644 slirp/state.h
 delete mode 100644 slirp/trace-events
 create mode 100644 slirp/util.c
 create mode 100644 slirp/util.h
 delete mode 100644 stubs/slirp.c

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 01/32] slirp: Avoid unaligned 16bit memory access
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
@ 2019-02-07 14:02 ` Samuel Thibault
  2019-02-07 14:02 ` [Qemu-devel] [PULLv4 02/32] slirp: Avoid marking naturally packed structs as QEMU_PACKED Samuel Thibault
                   ` (32 subsequent siblings)
  33 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:02 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Samuel Thibault, stefanha, jan.kiszka, Richard Henderson

pkt parameter may be unaligned, so we must access it byte-wise.

This fixes sparc64 host SIGBUS during pxe boot.

Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 slirp/slirp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/slirp/slirp.c b/slirp/slirp.c
index a9674ab090..739f364770 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -829,7 +829,7 @@ void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
     if (pkt_len < ETH_HLEN)
         return;
 
-    proto = ntohs(*(uint16_t *)(pkt + 12));
+    proto = (((uint16_t) pkt[12]) << 8) + pkt[13];
     switch(proto) {
     case ETH_P_ARP:
         arp_input(slirp, pkt, pkt_len);
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 02/32] slirp: Avoid marking naturally packed structs as QEMU_PACKED
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
  2019-02-07 14:02 ` [Qemu-devel] [PULLv4 01/32] slirp: Avoid unaligned 16bit memory access Samuel Thibault
@ 2019-02-07 14:02 ` Samuel Thibault
  2019-02-07 14:02 ` [Qemu-devel] [PULLv4 03/32] slirp: Don't mark struct ipq or struct ipasfrag as packed Samuel Thibault
                   ` (31 subsequent siblings)
  33 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:02 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: stefanha, jan.kiszka, Eric Blake, Samuel Thibault

From: Peter Maydell <peter.maydell@linaro.org>

Various ipv6 structs in the slirp headers are marked QEMU_PACKED,
but they are actually naturally aligned and will have no padding
in them. Instead of marking them with the 'packed' attribute,
assert at compile time that they are the size we expect. This
allows us to take the address of fields within the structs
without risking undefined behaviour, and suppresses clang
-Waddress-of-packed-member warnings.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 slirp/ip6.h      | 12 ++++++++++--
 slirp/ip6_icmp.h | 20 +++++++++++++++-----
 2 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/slirp/ip6.h b/slirp/ip6.h
index 14e9c78735..1e3e329ce6 100644
--- a/slirp/ip6.h
+++ b/slirp/ip6.h
@@ -133,7 +133,7 @@ struct ip6 {
     uint8_t     ip_nh;               /* next header */
     uint8_t     ip_hl;               /* hop limit */
     struct in6_addr ip_src, ip_dst;  /* source and dest address */
-} QEMU_PACKED;
+};
 
 /*
  * IPv6 pseudo-header used by upper-layer protocols
@@ -145,7 +145,15 @@ struct ip6_pseudohdr {
     uint16_t    ih_zero_hi;       /* zero */
     uint8_t     ih_zero_lo;       /* zero */
     uint8_t     ih_nh;            /* next header */
-} QEMU_PACKED;
+};
 
+/*
+ * We don't want to mark these ip6 structs as packed as they are naturally
+ * correctly aligned; instead assert that there is no stray padding.
+ * If we marked the struct as packed then we would be unable to take
+ * the address of any of the fields in it.
+ */
+QEMU_BUILD_BUG_ON(sizeof(struct ip6) != 40);
+QEMU_BUILD_BUG_ON(sizeof(struct ip6_pseudohdr) != 40);
 
 #endif
diff --git a/slirp/ip6_icmp.h b/slirp/ip6_icmp.h
index 32b0914055..2ad2b75e67 100644
--- a/slirp/ip6_icmp.h
+++ b/slirp/ip6_icmp.h
@@ -48,12 +48,16 @@ struct ndp_ra {     /* Router Advertisement Message */
     uint16_t lifetime;      /* Router Lifetime */
     uint32_t reach_time;    /* Reachable Time */
     uint32_t retrans_time;  /* Retrans Timer */
-} QEMU_PACKED;
+};
+
+QEMU_BUILD_BUG_ON(sizeof(struct ndp_ra) != 12);
 
 struct ndp_ns {     /* Neighbor Solicitation Message */
     uint32_t reserved;
     struct in6_addr target; /* Target Address */
-} QEMU_PACKED;
+};
+
+QEMU_BUILD_BUG_ON(sizeof(struct ndp_ns) != 20);
 
 struct ndp_na {     /* Neighbor Advertisement Message */
 #if G_BYTE_ORDER == G_BIG_ENDIAN
@@ -72,13 +76,17 @@ struct ndp_na {     /* Neighbor Advertisement Message */
         reserved_lo:24;
 #endif
     struct in6_addr target; /* Target Address */
-} QEMU_PACKED;
+};
+
+QEMU_BUILD_BUG_ON(sizeof(struct ndp_na) != 20);
 
 struct ndp_redirect {
     uint32_t reserved;
     struct in6_addr target; /* Target Address */
     struct in6_addr dest;   /* Destination Address */
-} QEMU_PACKED;
+};
+
+QEMU_BUILD_BUG_ON(sizeof(struct ndp_redirect) != 36);
 
 /*
  * Structure of an icmpv6 header.
@@ -103,7 +111,9 @@ struct icmp6 {
 #define icmp6_nns icmp6_body.ndp_ns
 #define icmp6_nna icmp6_body.ndp_na
 #define icmp6_redirect icmp6_body.ndp_redirect
-} QEMU_PACKED;
+};
+
+QEMU_BUILD_BUG_ON(sizeof(struct icmp6) != 40);
 
 #define ICMP6_MINLEN    4
 #define ICMP6_ERROR_MINLEN  8
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 03/32] slirp: Don't mark struct ipq or struct ipasfrag as packed
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
  2019-02-07 14:02 ` [Qemu-devel] [PULLv4 01/32] slirp: Avoid unaligned 16bit memory access Samuel Thibault
  2019-02-07 14:02 ` [Qemu-devel] [PULLv4 02/32] slirp: Avoid marking naturally packed structs as QEMU_PACKED Samuel Thibault
@ 2019-02-07 14:02 ` Samuel Thibault
  2019-02-07 14:02 ` [Qemu-devel] [PULLv4 04/32] slirp: generalize guestfwd with a callback based approach Samuel Thibault
                   ` (30 subsequent siblings)
  33 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:02 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: stefanha, jan.kiszka, Eric Blake, Samuel Thibault

From: Peter Maydell <peter.maydell@linaro.org>

There is no reason to mark the struct ipq and struct ipasfrag as
packed: they are naturally aligned anyway, and are not representing
any on-the-wire packet format.  Indeed they vary in size depending on
the size of pointers on the host system, because the 'struct qlink'
members include 'void *' fields.

Dropping the 'packed' annotation fixes clang -Waddress-of-packed-member
warnings and probably lets the compiler generate better code too.

The only thing we do care about in the layout of the struct is
that the frag_link matches up with the ipf_link of the struct
ipasfrag, as documented in the comment on that struct; assert
at build time that this is the case.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 slirp/ip.h | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/slirp/ip.h b/slirp/ip.h
index 243b6c8b24..20614f3b53 100644
--- a/slirp/ip.h
+++ b/slirp/ip.h
@@ -217,7 +217,7 @@ struct ipq {
 	uint8_t	ipq_p;			/* protocol of this fragment */
 	uint16_t	ipq_id;			/* sequence id for reassembly */
 	struct	in_addr ipq_src,ipq_dst;
-} QEMU_PACKED;
+};
 
 /*
  * Ip header, when holding a fragment.
@@ -227,7 +227,10 @@ struct ipq {
 struct	ipasfrag {
 	struct qlink ipf_link;
 	struct ip ipf_ip;
-} QEMU_PACKED;
+};
+
+QEMU_BUILD_BUG_ON(offsetof(struct ipq, frag_link) !=
+                  offsetof(struct ipasfrag, ipf_link));
 
 #define ipf_off      ipf_ip.ip_off
 #define ipf_tos      ipf_ip.ip_tos
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 04/32] slirp: generalize guestfwd with a callback based approach
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
                   ` (2 preceding siblings ...)
  2019-02-07 14:02 ` [Qemu-devel] [PULLv4 03/32] slirp: Don't mark struct ipq or struct ipasfrag as packed Samuel Thibault
@ 2019-02-07 14:02 ` Samuel Thibault
  2019-02-07 14:02 ` [Qemu-devel] [PULLv4 05/32] net/slirp: simplify checking for cmd: prefix Samuel Thibault
                   ` (29 subsequent siblings)
  33 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:02 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Marc-André Lureau, stefanha, jan.kiszka, Samuel Thibault

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Instead of calling into QEMU chardev directly, and mixing it with
slirp_add_exec() handling, add a new function slirp_add_guestfwd()
which takes a write callback.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 net/slirp.c      | 14 ++++++++++----
 slirp/libslirp.h |  6 +++++-
 slirp/misc.c     | 37 +++++++++++++++++++++++--------------
 slirp/misc.h     | 15 +++++++++++++--
 slirp/slirp.c    | 27 +++++++++++++++++++--------
 slirp/socket.h   |  4 +++-
 slirp/tcp_subr.c |  4 ++--
 7 files changed, 75 insertions(+), 32 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index f98425ee9f..ec07f662c0 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -704,8 +704,8 @@ static int slirp_smb(SlirpState* s, const char *exported_dir,
              CONFIG_SMBD_COMMAND, s->smb_dir, smb_conf);
     g_free(smb_conf);
 
-    if (slirp_add_exec(s->slirp, NULL, smb_cmdline, &vserver_addr, 139) < 0 ||
-        slirp_add_exec(s->slirp, NULL, smb_cmdline, &vserver_addr, 445) < 0) {
+    if (slirp_add_exec(s->slirp, smb_cmdline, &vserver_addr, 139) < 0 ||
+        slirp_add_exec(s->slirp, smb_cmdline, &vserver_addr, 445) < 0) {
         slirp_smb_cleanup(s);
         g_free(smb_cmdline);
         error_setg(errp, "Conflicting/invalid smbserver address");
@@ -736,6 +736,11 @@ static void guestfwd_read(void *opaque, const uint8_t *buf, int size)
     slirp_socket_recv(fwd->slirp, fwd->server, fwd->port, buf, size);
 }
 
+static int guestfwd_write(const void *buf, size_t len, void *chr)
+{
+    return qemu_chr_fe_write_all(chr, buf, len);
+}
+
 static int slirp_guestfwd(SlirpState *s, const char *config_str, Error **errp)
 {
     struct in_addr server = { .s_addr = 0 };
@@ -769,7 +774,7 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str, Error **errp)
     snprintf(buf, sizeof(buf), "guestfwd.tcp.%d", port);
 
     if ((strlen(p) > 4) && !strncmp(p, "cmd:", 4)) {
-        if (slirp_add_exec(s->slirp, NULL, &p[4], &server, port) < 0) {
+        if (slirp_add_exec(s->slirp, &p[4], &server, port) < 0) {
             error_setg(errp, "Conflicting/invalid host:port in guest "
                        "forwarding rule '%s'", config_str);
             return -1;
@@ -796,7 +801,8 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str, Error **errp)
             return -1;
         }
 
-        if (slirp_add_exec(s->slirp, &fwd->hd, NULL, &server, port) < 0) {
+        if (slirp_add_guestfwd(s->slirp, guestfwd_write, &fwd->hd,
+                               &server, port) < 0) {
             error_setg(errp, "Conflicting/invalid host:port in guest "
                        "forwarding rule '%s'", config_str);
             g_free(fwd);
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 4611a7447b..ea019828e8 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -5,6 +5,8 @@
 
 typedef struct Slirp Slirp;
 
+typedef int (*SlirpWriteCb)(const void *buf, size_t len, void *opaque);
+
 /*
  * Callbacks from slirp
  *
@@ -45,7 +47,9 @@ int slirp_add_hostfwd(Slirp *slirp, int is_udp,
                       struct in_addr guest_addr, int guest_port);
 int slirp_remove_hostfwd(Slirp *slirp, int is_udp,
                          struct in_addr host_addr, int host_port);
-int slirp_add_exec(Slirp *slirp, void *chardev, const char *cmdline,
+int slirp_add_exec(Slirp *slirp, const char *cmdline,
+                   struct in_addr *guest_addr, int guest_port);
+int slirp_add_guestfwd(Slirp *slirp, SlirpWriteCb write_cb, void *opaque,
                    struct in_addr *guest_addr, int guest_port);
 
 char *slirp_connection_info(Slirp *slirp);
diff --git a/slirp/misc.c b/slirp/misc.c
index eae9596a55..b8a2bf971a 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -32,24 +32,33 @@ remque(void *a)
   element->qh_rlink = NULL;
 }
 
-int add_exec(struct gfwd_list **ex_ptr, void *chardev, const char *cmdline,
+struct gfwd_list *
+add_guestfwd(struct gfwd_list **ex_ptr,
+             SlirpWriteCb write_cb, void *opaque,
              struct in_addr addr, int port)
 {
-	struct gfwd_list *tmp_ptr;
-
-	tmp_ptr = *ex_ptr;
-	*ex_ptr = g_new0(struct gfwd_list, 1);
-	(*ex_ptr)->ex_fport = port;
-	(*ex_ptr)->ex_addr = addr;
-	if (chardev) {
-		(*ex_ptr)->ex_chardev = chardev;
-	} else {
-		(*ex_ptr)->ex_exec = g_strdup(cmdline);
-	}
-	(*ex_ptr)->ex_next = tmp_ptr;
-	return 0;
+    struct gfwd_list *f = g_new0(struct gfwd_list, 1);
+
+    f->write_cb = write_cb;
+    f->opaque = opaque;
+    f->ex_fport = port;
+    f->ex_addr = addr;
+    f->ex_next = *ex_ptr;
+    *ex_ptr = f;
+
+    return f;
 }
 
+struct gfwd_list *
+add_exec(struct gfwd_list **ex_ptr, const char *cmdline,
+         struct in_addr addr, int port)
+{
+    struct gfwd_list *f = add_guestfwd(ex_ptr, NULL, NULL, addr, port);
+
+    f->ex_exec = g_strdup(cmdline);
+
+    return f;
+}
 
 static int
 slirp_socketpair_with_oob(int sv[2])
diff --git a/slirp/misc.h b/slirp/misc.h
index 1df707c052..c2ceadb591 100644
--- a/slirp/misc.h
+++ b/slirp/misc.h
@@ -8,8 +8,11 @@
 #ifndef MISC_H
 #define MISC_H
 
+#include "libslirp.h"
+
 struct gfwd_list {
-	void *ex_chardev;
+	SlirpWriteCb write_cb;
+	void *opaque;
 	struct in_addr ex_addr;		/* Server address */
 	int ex_fport;                   /* Port to telnet to */
 	char *ex_exec;                  /* Command line of what to exec */
@@ -51,7 +54,15 @@ struct slirp_quehead {
 
 void slirp_insque(void *, void *);
 void slirp_remque(void *);
-int add_exec(struct gfwd_list **, void *, const char *, struct in_addr, int);
 int fork_exec(struct socket *so, const char *ex);
 
+struct gfwd_list *
+add_guestfwd(struct gfwd_list **ex_ptr,
+             SlirpWriteCb write_cb, void *opaque,
+             struct in_addr addr, int port);
+
+struct gfwd_list *
+add_exec(struct gfwd_list **ex_ptr, const char *cmdline,
+         struct in_addr addr, int port);
+
 #endif
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 739f364770..a411221914 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -25,7 +25,6 @@
 #include "qemu-common.h"
 #include "qemu/timer.h"
 #include "qemu/error-report.h"
-#include "chardev/char-fe.h"
 #include "migration/register.h"
 #include "slirp.h"
 #include "hw/hw.h"
@@ -1068,23 +1067,35 @@ check_guestfwd(Slirp *slirp, struct in_addr *guest_addr, int guest_port)
     return true;
 }
 
-int slirp_add_exec(Slirp *slirp, void *chardev, const char *cmdline,
+int slirp_add_exec(Slirp *slirp, const char *cmdline,
                    struct in_addr *guest_addr, int guest_port)
 {
     if (!check_guestfwd(slirp, guest_addr, guest_port)) {
         return -1;
     }
 
-    return add_exec(&slirp->guestfwd_list, chardev, cmdline, *guest_addr,
-                    htons(guest_port));
+    add_exec(&slirp->guestfwd_list, cmdline, *guest_addr, htons(guest_port));
+    return 0;
+}
+
+int slirp_add_guestfwd(Slirp *slirp, SlirpWriteCb write_cb, void *opaque,
+                       struct in_addr *guest_addr, int guest_port)
+{
+    if (!check_guestfwd(slirp, guest_addr, guest_port)) {
+        return -1;
+    }
+
+    add_guestfwd(&slirp->guestfwd_list, write_cb, opaque,
+                 *guest_addr, htons(guest_port));
+    return 0;
 }
 
 ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags)
 {
-    if (so->s == -1 && so->chardev) {
+    if (so->s == -1 && so->guestfwd) {
         /* XXX this blocks entire thread. Rewrite to use
          * qemu_chr_fe_write and background I/O callbacks */
-        qemu_chr_fe_write_all(so->chardev, buf, len);
+        so->guestfwd->write_cb(buf, len, so->guestfwd->opaque);
         return len;
     }
 
@@ -1449,7 +1460,7 @@ static void slirp_state_save(QEMUFile *f, void *opaque)
     struct gfwd_list *ex_ptr;
 
     for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
-        if (ex_ptr->ex_chardev) {
+        if (ex_ptr->write_cb) {
             struct socket *so;
             so = slirp_find_ctl_socket(slirp, ex_ptr->ex_addr,
                                        ntohs(ex_ptr->ex_fport));
@@ -1484,7 +1495,7 @@ static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
             return -EINVAL;
         }
         for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
-            if (ex_ptr->ex_chardev &&
+            if (ex_ptr->write_cb &&
                 so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr &&
                 so->so_fport == ex_ptr->ex_fport) {
                 break;
diff --git a/slirp/socket.h b/slirp/socket.h
index 930ed95972..fc35ca5f72 100644
--- a/slirp/socket.h
+++ b/slirp/socket.h
@@ -8,6 +8,8 @@
 #ifndef SLIRP_SOCKET_H
 #define SLIRP_SOCKET_H
 
+#include "misc.h"
+
 #define SO_EXPIRE 240000
 #define SO_EXPIREFAST 10000
 
@@ -25,6 +27,7 @@ struct socket {
   struct socket *so_next,*so_prev;      /* For a linked list of sockets */
 
   int s;                           /* The actual socket */
+  struct gfwd_list *guestfwd;
 
   int pollfds_idx;                 /* GPollFD GArray index */
 
@@ -67,7 +70,6 @@ struct socket {
 
   struct sbuf so_rcv;		/* Receive buffer */
   struct sbuf so_snd;		/* Send buffer */
-  void * chardev;
 };
 
 
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index 23a841f26e..4e81736d6f 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -964,9 +964,9 @@ int tcp_ctl(struct socket *so)
         for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
             if (ex_ptr->ex_fport == so->so_fport &&
                 so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr) {
-                if (ex_ptr->ex_chardev) {
+                if (ex_ptr->write_cb) {
                     so->s = -1;
-                    so->chardev = ex_ptr->ex_chardev;
+                    so->guestfwd = ex_ptr;
                     return 1;
                 }
                 DEBUG_MISC(" executing %s", ex_ptr->ex_exec);
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 05/32] net/slirp: simplify checking for cmd: prefix
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
                   ` (3 preceding siblings ...)
  2019-02-07 14:02 ` [Qemu-devel] [PULLv4 04/32] slirp: generalize guestfwd with a callback based approach Samuel Thibault
@ 2019-02-07 14:02 ` Samuel Thibault
  2019-02-07 14:02 ` [Qemu-devel] [PULLv4 06/32] net/slirp: free forwarding rules on cleanup Samuel Thibault
                   ` (28 subsequent siblings)
  33 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:02 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Marc-André Lureau, stefanha, jan.kiszka, Samuel Thibault

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 net/slirp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/slirp.c b/net/slirp.c
index ec07f662c0..b91741b8fc 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -773,7 +773,7 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str, Error **errp)
 
     snprintf(buf, sizeof(buf), "guestfwd.tcp.%d", port);
 
-    if ((strlen(p) > 4) && !strncmp(p, "cmd:", 4)) {
+    if (g_str_has_prefix(p, "cmd:")) {
         if (slirp_add_exec(s->slirp, &p[4], &server, port) < 0) {
             error_setg(errp, "Conflicting/invalid host:port in guest "
                        "forwarding rule '%s'", config_str);
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 06/32] net/slirp: free forwarding rules on cleanup
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
                   ` (4 preceding siblings ...)
  2019-02-07 14:02 ` [Qemu-devel] [PULLv4 05/32] net/slirp: simplify checking for cmd: prefix Samuel Thibault
@ 2019-02-07 14:02 ` Samuel Thibault
  2019-02-07 14:02 ` [Qemu-devel] [PULLv4 07/32] net/slirp: fix leaks on forwarding rule registration error Samuel Thibault
                   ` (27 subsequent siblings)
  33 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:02 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Marc-André Lureau, stefanha, jan.kiszka, Samuel Thibault

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 net/slirp.c | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index b91741b8fc..750105a466 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -75,6 +75,13 @@ struct slirp_config_str {
     char str[1024];
 };
 
+struct GuestFwd {
+    CharBackend hd;
+    struct in_addr server;
+    int port;
+    Slirp *slirp;
+};
+
 typedef struct SlirpState {
     NetClientState nc;
     QTAILQ_ENTRY(SlirpState) entry;
@@ -83,6 +90,7 @@ typedef struct SlirpState {
 #ifndef _WIN32
     gchar *smb_dir;
 #endif
+    GSList *fwd;
 } SlirpState;
 
 static struct slirp_config_str *slirp_configs;
@@ -122,10 +130,19 @@ static void slirp_smb_exit(Notifier *n, void *data)
     slirp_smb_cleanup(s);
 }
 
+static void slirp_free_fwd(gpointer data)
+{
+    struct GuestFwd *fwd = data;
+
+    qemu_chr_fe_deinit(&fwd->hd, true);
+    g_free(data);
+}
+
 static void net_slirp_cleanup(NetClientState *nc)
 {
     SlirpState *s = DO_UPCAST(SlirpState, nc, nc);
 
+    g_slist_free_full(s->fwd, slirp_free_fwd);
     slirp_cleanup(s->slirp);
     if (s->exit_notifier.notify) {
         qemu_remove_exit_notifier(&s->exit_notifier);
@@ -717,13 +734,6 @@ static int slirp_smb(SlirpState* s, const char *exported_dir,
 
 #endif /* !defined(_WIN32) */
 
-struct GuestFwd {
-    CharBackend hd;
-    struct in_addr server;
-    int port;
-    Slirp *slirp;
-};
-
 static int guestfwd_can_read(void *opaque)
 {
     struct GuestFwd *fwd = opaque;
@@ -814,6 +824,7 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str, Error **errp)
 
         qemu_chr_fe_set_handlers(&fwd->hd, guestfwd_can_read, guestfwd_read,
                                  NULL, NULL, fwd, NULL, true);
+        s->fwd = g_slist_append(s->fwd, fwd);
     }
     return 0;
 
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 07/32] net/slirp: fix leaks on forwarding rule registration error
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
                   ` (5 preceding siblings ...)
  2019-02-07 14:02 ` [Qemu-devel] [PULLv4 06/32] net/slirp: free forwarding rules on cleanup Samuel Thibault
@ 2019-02-07 14:02 ` Samuel Thibault
  2019-02-07 14:02 ` [Qemu-devel] [PULLv4 08/32] slirp: add callbacks for timer Samuel Thibault
                   ` (26 subsequent siblings)
  33 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:02 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Marc-André Lureau, stefanha, jan.kiszka, Samuel Thibault

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 net/slirp.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/slirp.c b/net/slirp.c
index 750105a466..0b15f427f5 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -807,6 +807,7 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str, Error **errp)
         qemu_chr_fe_init(&fwd->hd, chr, &err);
         if (err) {
             error_propagate(errp, err);
+            object_unparent(OBJECT(chr));
             g_free(fwd);
             return -1;
         }
@@ -815,6 +816,7 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str, Error **errp)
                                &server, port) < 0) {
             error_setg(errp, "Conflicting/invalid host:port in guest "
                        "forwarding rule '%s'", config_str);
+            qemu_chr_fe_deinit(&fwd->hd, true);
             g_free(fwd);
             return -1;
         }
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 08/32] slirp: add callbacks for timer
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
                   ` (6 preceding siblings ...)
  2019-02-07 14:02 ` [Qemu-devel] [PULLv4 07/32] net/slirp: fix leaks on forwarding rule registration error Samuel Thibault
@ 2019-02-07 14:02 ` Samuel Thibault
  2019-02-07 14:02 ` [Qemu-devel] [PULLv4 09/32] slirp: replace trace functions with DEBUG calls Samuel Thibault
                   ` (25 subsequent siblings)
  33 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:02 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Marc-André Lureau, stefanha, jan.kiszka, Samuel Thibault

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 net/slirp.c      | 21 +++++++++++++++++++++
 slirp/ip6_icmp.c | 16 +++++++---------
 slirp/libslirp.h | 14 +++++++++++---
 slirp/slirp.h    |  2 +-
 4 files changed, 40 insertions(+), 13 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index 0b15f427f5..c24a779425 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -168,10 +168,31 @@ static int64_t net_slirp_clock_get_ns(void)
     return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 }
 
+static void *net_slirp_timer_new(SlirpTimerCb cb, void *opaque)
+{
+    return timer_new_full(NULL, QEMU_CLOCK_VIRTUAL,
+                          SCALE_MS, QEMU_TIMER_ATTR_EXTERNAL,
+                          cb, opaque);
+}
+
+static void net_slirp_timer_free(void *timer)
+{
+    timer_del(timer);
+    timer_free(timer);
+}
+
+static void net_slirp_timer_mod(void *timer, int64_t expire_timer)
+{
+    timer_mod(timer, expire_timer);
+}
+
 static const SlirpCb slirp_cb = {
     .output = net_slirp_output,
     .guest_error = net_slirp_guest_error,
     .clock_get_ns = net_slirp_clock_get_ns,
+    .timer_new = net_slirp_timer_new,
+    .timer_free = net_slirp_timer_free,
+    .timer_mod = net_slirp_timer_mod,
 };
 
 static int net_slirp_init(NetClientState *peer, const char *model,
diff --git a/slirp/ip6_icmp.c b/slirp/ip6_icmp.c
index 5261baae27..e72c57a81d 100644
--- a/slirp/ip6_icmp.c
+++ b/slirp/ip6_icmp.c
@@ -16,8 +16,9 @@
 static void ra_timer_handler(void *opaque)
 {
     Slirp *slirp = opaque;
-    timer_mod(slirp->ra_timer,
-              slirp->cb->clock_get_ns() / SCALE_MS + NDP_Interval);
+
+    slirp->cb->timer_mod(slirp->ra_timer,
+                         slirp->cb->clock_get_ns() / SCALE_MS + NDP_Interval);
     ndp_send_ra(slirp);
 }
 
@@ -27,11 +28,9 @@ void icmp6_init(Slirp *slirp)
         return;
     }
 
-    slirp->ra_timer = timer_new_full(NULL, QEMU_CLOCK_VIRTUAL,
-                                     SCALE_MS, QEMU_TIMER_ATTR_EXTERNAL,
-                                     ra_timer_handler, slirp);
-    timer_mod(slirp->ra_timer,
-              slirp->cb->clock_get_ns() / SCALE_MS + NDP_Interval);
+    slirp->ra_timer = slirp->cb->timer_new(ra_timer_handler, slirp);
+    slirp->cb->timer_mod(slirp->ra_timer,
+                         slirp->cb->clock_get_ns() / SCALE_MS + NDP_Interval);
 }
 
 void icmp6_cleanup(Slirp *slirp)
@@ -40,8 +39,7 @@ void icmp6_cleanup(Slirp *slirp)
         return;
     }
 
-    timer_del(slirp->ra_timer);
-    timer_free(slirp->ra_timer);
+    slirp->cb->timer_free(slirp->ra_timer);
 }
 
 static void icmp6_send_echoreply(struct mbuf *m, Slirp *slirp, struct ip6 *ip,
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index ea019828e8..3e75dadfa3 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -6,19 +6,27 @@
 typedef struct Slirp Slirp;
 
 typedef int (*SlirpWriteCb)(const void *buf, size_t len, void *opaque);
+typedef void (*SlirpTimerCb)(void *opaque);
 
 /*
  * Callbacks from slirp
- *
- * The opaque parameter comes from the opaque parameter given to slirp_init().
  */
 typedef struct SlirpCb {
-    /* Send an ethernet frame to the guest network.  */
+    /*
+     * Send an ethernet frame to the guest network. The opaque parameter
+     * is the one given to slirp_init().
+     */
     void (*output)(void *opaque, const uint8_t *pkt, int pkt_len);
     /* Print a message for an error due to guest misbehavior.  */
     void (*guest_error)(const char *msg);
     /* Return the virtual clock value in nanoseconds */
     int64_t (*clock_get_ns)(void);
+    /* Create a new timer with the given callback and opaque data */
+    void *(*timer_new)(SlirpTimerCb cb, void *opaque);
+    /* Remove and free a timer */
+    void (*timer_free)(void *timer);
+    /* Modify a timer to expire at @expire_time */
+    void (*timer_mod)(void *timer, int64_t expire_time);
 } SlirpCb;
 
 
diff --git a/slirp/slirp.h b/slirp/slirp.h
index 9aa245715d..17056f4b83 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -193,7 +193,7 @@ struct Slirp {
     NdpTable ndp_table;
 
     GRand *grand;
-    QEMUTimer *ra_timer;
+    void *ra_timer;
 
     const SlirpCb *cb;
     void *opaque;
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 09/32] slirp: replace trace functions with DEBUG calls
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
                   ` (7 preceding siblings ...)
  2019-02-07 14:02 ` [Qemu-devel] [PULLv4 08/32] slirp: add callbacks for timer Samuel Thibault
@ 2019-02-07 14:02 ` Samuel Thibault
  2019-02-07 14:02 ` [Qemu-devel] [PULLv4 10/32] slirp: replace QEMU_PACKED with SLIRP_PACKED Samuel Thibault
                   ` (24 subsequent siblings)
  33 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:02 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Marc-André Lureau, stefanha, jan.kiszka, Samuel Thibault

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Remove a dependency on QEMU. Use the existing logging facilities.
Set SLIRP_DEBUG=tftp to get tftp log.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 Makefile.objs      |  1 -
 slirp/debug.h      | 13 ++++++++++---
 slirp/slirp.c      |  1 +
 slirp/tftp.c       |  7 ++++---
 slirp/trace-events |  5 -----
 5 files changed, 15 insertions(+), 12 deletions(-)
 delete mode 100644 slirp/trace-events

diff --git a/Makefile.objs b/Makefile.objs
index 67a054b08a..b7aae33367 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -192,7 +192,6 @@ trace-events-subdirs += net
 trace-events-subdirs += qapi
 trace-events-subdirs += qom
 trace-events-subdirs += scsi
-trace-events-subdirs += slirp
 trace-events-subdirs += target/arm
 trace-events-subdirs += target/i386
 trace-events-subdirs += target/mips
diff --git a/slirp/debug.h b/slirp/debug.h
index 269d97d807..44d922df37 100644
--- a/slirp/debug.h
+++ b/slirp/debug.h
@@ -8,9 +8,10 @@
 #ifndef DEBUG_H_
 #define DEBUG_H_
 
-#define DBG_CALL 0x1
-#define DBG_MISC 0x2
-#define DBG_ERROR 0x4
+#define DBG_CALL (1 << 0)
+#define DBG_MISC (1 << 1)
+#define DBG_ERROR (1 << 2)
+#define DBG_TFTP (1 << 3)
 
 extern int slirp_debug;
 
@@ -38,4 +39,10 @@ extern int slirp_debug;
     }                                           \
 } while (0)
 
+#define DEBUG_TFTP(fmt, ...) do {               \
+    if (G_UNLIKELY(slirp_debug & DBG_TFTP)) {   \
+        g_debug(fmt, ##__VA_ARGS__);            \
+    }                                           \
+} while (0)
+
 #endif /* DEBUG_H_ */
diff --git a/slirp/slirp.c b/slirp/slirp.c
index a411221914..12677e5da7 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -270,6 +270,7 @@ static void slirp_init_once(void)
             { "call", DBG_CALL },
             { "misc", DBG_MISC },
             { "error", DBG_ERROR },
+            { "tftp", DBG_TFTP },
         };
         slirp_debug = g_parse_debug_string(debug, keys, G_N_ELEMENTS(keys));
     }
diff --git a/slirp/tftp.c b/slirp/tftp.c
index a9ba1480db..6fb381ef33 100644
--- a/slirp/tftp.c
+++ b/slirp/tftp.c
@@ -26,7 +26,6 @@
 #include "slirp.h"
 #include "qemu-common.h"
 #include "qemu/cutils.h"
-#include "trace.h"
 
 static inline int tftp_session_in_use(struct tftp_session *spt)
 {
@@ -205,7 +204,8 @@ static void tftp_send_error(struct tftp_session *spt,
   struct mbuf *m;
   struct tftp_t *tp;
 
-  trace_slirp_tftp_error(msg);
+  DEBUG_TFTP("tftp error msg: %s", msg);
+
   m = m_get(spt->slirp);
 
   if (!m) {
@@ -325,7 +325,8 @@ static void tftp_handle_rrq(Slirp *slirp, struct sockaddr_storage *srcsas,
       break;
     }
   }
-  trace_slirp_tftp_rrq(req_fname);
+
+  DEBUG_TFTP("tftp rrq file: %s", req_fname);
 
   /* check mode */
   if ((pktlen - k) < 6) {
diff --git a/slirp/trace-events b/slirp/trace-events
deleted file mode 100644
index ff8f656e8c..0000000000
--- a/slirp/trace-events
+++ /dev/null
@@ -1,5 +0,0 @@
-# See docs/devel/tracing.txt for syntax documentation.
-
-# slirp/tftp.c
-slirp_tftp_rrq(const char *file) "file: %s"
-slirp_tftp_error(const char *file) "msg: %s"
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 10/32] slirp: replace QEMU_PACKED with SLIRP_PACKED
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
                   ` (8 preceding siblings ...)
  2019-02-07 14:02 ` [Qemu-devel] [PULLv4 09/32] slirp: replace trace functions with DEBUG calls Samuel Thibault
@ 2019-02-07 14:02 ` Samuel Thibault
  2019-02-07 14:02 ` [Qemu-devel] [PULLv4 11/32] slirp: replace most qemu socket utilities with slirp own version Samuel Thibault
                   ` (23 subsequent siblings)
  33 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:02 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Marc-André Lureau, stefanha, jan.kiszka, Samuel Thibault

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 slirp/ip.h       | 10 +++++-----
 slirp/ip6_icmp.h |  6 +++---
 slirp/slirp.h    |  5 +++--
 slirp/util.h     | 32 ++++++++++++++++++++++++++++++++
 4 files changed, 43 insertions(+), 10 deletions(-)
 create mode 100644 slirp/util.h

diff --git a/slirp/ip.h b/slirp/ip.h
index 20614f3b53..2baeeb9a3a 100644
--- a/slirp/ip.h
+++ b/slirp/ip.h
@@ -89,7 +89,7 @@ struct ip {
 	uint8_t ip_p;			/* protocol */
 	uint16_t	ip_sum;			/* checksum */
 	struct	in_addr ip_src,ip_dst;	/* source and dest address */
-} QEMU_PACKED;
+} SLIRP_PACKED;
 
 #define	IP_MAXPACKET	65535		/* maximum packet size */
 
@@ -151,7 +151,7 @@ struct	ip_timestamp {
 			n_long ipt_time;
 		} ipt_ta[1];
 	} ipt_timestamp;
-} QEMU_PACKED;
+} SLIRP_PACKED;
 
 /* flag bits for ipt_flg */
 #define	IPOPT_TS_TSONLY		0		/* timestamps only */
@@ -181,11 +181,11 @@ struct	ip_timestamp {
 struct mbuf_ptr {
 	struct mbuf *mptr;
 	uint32_t dummy;
-} QEMU_PACKED;
+} SLIRP_PACKED;
 #else
 struct mbuf_ptr {
 	struct mbuf *mptr;
-} QEMU_PACKED;
+} SLIRP_PACKED;
 #endif
 struct qlink {
 	void *next, *prev;
@@ -201,7 +201,7 @@ struct ipovly {
 	uint16_t	ih_len;			/* protocol length */
 	struct	in_addr ih_src;		/* source internet address */
 	struct	in_addr ih_dst;		/* destination internet address */
-} QEMU_PACKED;
+} SLIRP_PACKED;
 
 /*
  * Ip reassembly queue structure.  Each fragment
diff --git a/slirp/ip6_icmp.h b/slirp/ip6_icmp.h
index 2ad2b75e67..3f44ed2f49 100644
--- a/slirp/ip6_icmp.h
+++ b/slirp/ip6_icmp.h
@@ -144,16 +144,16 @@ struct ndpopt {
             uint32_t    pref_lt;                /* Preferred Lifetime */
             uint32_t    reserved2;
             struct in6_addr prefix;
-        } QEMU_PACKED prefixinfo;
+        } SLIRP_PACKED prefixinfo;
 #define ndpopt_prefixinfo ndpopt_body.prefixinfo
         struct rdnss {
             uint16_t reserved;
             uint32_t lifetime;
             struct in6_addr addr;
-        } QEMU_PACKED rdnss;
+        } SLIRP_PACKED rdnss;
 #define ndpopt_rdnss ndpopt_body.rdnss
     } ndpopt_body;
-} QEMU_PACKED;
+} SLIRP_PACKED;
 
 /* NDP options type */
 #define NDPOPT_LINKLAYER_SOURCE     1   /* Source Link-Layer Address */
diff --git a/slirp/slirp.h b/slirp/slirp.h
index 17056f4b83..67ff4d610c 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -45,6 +45,7 @@ typedef char *caddr_t;
 #define quehead slirp_quehead
 
 #include "debug.h"
+#include "util.h"
 
 #include "qemu/queue.h"
 #include "qemu/sockets.h"
@@ -93,7 +94,7 @@ struct slirp_arphdr {
     uint32_t      ar_sip;           /* sender IP address       */
     unsigned char ar_tha[ETH_ALEN]; /* target hardware address */
     uint32_t      ar_tip;           /* target IP address       */
-} QEMU_PACKED;
+} SLIRP_PACKED;
 
 #define ARP_TABLE_SIZE 16
 
@@ -110,7 +111,7 @@ bool arp_table_search(Slirp *slirp, uint32_t ip_addr,
 struct ndpentry {
     unsigned char   eth_addr[ETH_ALEN];     /* sender hardware address */
     struct in6_addr ip_addr;                /* sender IP address       */
-} QEMU_PACKED;
+} SLIRP_PACKED;
 
 #define NDP_TABLE_SIZE 16
 
diff --git a/slirp/util.h b/slirp/util.h
new file mode 100644
index 0000000000..00291c30a6
--- /dev/null
+++ b/slirp/util.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ * Copyright (c) 2010-2019 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef UTIL_H_
+#define UTIL_H_
+
+#if defined(_WIN32)
+# define SLIRP_PACKED __attribute__((gcc_struct, packed))
+#else
+# define SLIRP_PACKED __attribute__((packed))
+#endif
+
+#endif
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 11/32] slirp: replace most qemu socket utilities with slirp own version
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
                   ` (9 preceding siblings ...)
  2019-02-07 14:02 ` [Qemu-devel] [PULLv4 10/32] slirp: replace QEMU_PACKED with SLIRP_PACKED Samuel Thibault
@ 2019-02-07 14:02 ` Samuel Thibault
  2019-02-07 14:02 ` [Qemu-devel] [PULLv4 12/32] slirp: replace qemu_set_nonblock() Samuel Thibault
                   ` (22 subsequent siblings)
  33 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:02 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Marc-André Lureau, stefanha, jan.kiszka, Samuel Thibault

From: Marc-André Lureau <marcandre.lureau@redhat.com>

qemu_set_nonblock() is slightly more problematic and will be dealt
with in a separate patch.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 slirp/Makefile.objs |   3 +-
 slirp/ip_icmp.c     |   6 +-
 slirp/misc.c        |  20 ++---
 slirp/socket.c      |  18 ++---
 slirp/tcp_subr.c    |  18 ++---
 slirp/udp.c         |   8 +-
 slirp/util.c        | 176 ++++++++++++++++++++++++++++++++++++++++++++
 slirp/util.h        |  61 +++++++++++++++
 8 files changed, 274 insertions(+), 36 deletions(-)
 create mode 100644 slirp/util.c

diff --git a/slirp/Makefile.objs b/slirp/Makefile.objs
index 959558c732..d2ead94b3b 100644
--- a/slirp/Makefile.objs
+++ b/slirp/Makefile.objs
@@ -27,6 +27,7 @@ slirp.mo-objs = \
 	tftp.o \
 	udp.o \
 	udp6.o \
+	util.o \
 	$(NULL)
 
-slirp.mo-cflags = -DG_LOG_DOMAIN=\"Slirp\"
+slirp.mo-cflags = -DG_LOG_DOMAIN=\"Slirp\" -DWITH_QEMU
diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
index 7c7e042049..b59daa801d 100644
--- a/slirp/ip_icmp.c
+++ b/slirp/ip_icmp.c
@@ -83,7 +83,7 @@ static int icmp_send(struct socket *so, struct mbuf *m, int hlen)
     struct ip *ip = mtod(m, struct ip *);
     struct sockaddr_in addr;
 
-    so->s = qemu_socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
+    so->s = slirp_socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
     if (so->s == -1) {
         return -1;
     }
@@ -114,7 +114,7 @@ static int icmp_send(struct socket *so, struct mbuf *m, int hlen)
 
 void icmp_detach(struct socket *so)
 {
-    closesocket(so->s);
+    slirp_closesocket(so->s);
     sofree(so);
 }
 
@@ -421,7 +421,7 @@ void icmp_receive(struct socket *so)
     icp = mtod(m, struct icmp *);
 
     id = icp->icmp_id;
-    len = qemu_recv(so->s, icp, M_ROOM(m), 0);
+    len = slirp_recv(so->s, icp, M_ROOM(m), 0);
     /*
      * The behavior of reading SOCK_DGRAM+IPPROTO_ICMP sockets is inconsistent
      * between host OSes.  On Linux, only the ICMP header and payload is
diff --git a/slirp/misc.c b/slirp/misc.c
index b8a2bf971a..32ec02a525 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -72,14 +72,14 @@ slirp_socketpair_with_oob(int sv[2])
     int ret, s;
 
     sv[1] = -1;
-    s = qemu_socket(AF_INET, SOCK_STREAM, 0);
+    s = slirp_socket(AF_INET, SOCK_STREAM, 0);
     if (s < 0 || bind(s, (struct sockaddr *)&addr, addrlen) < 0 ||
         listen(s, 1) < 0 ||
         getsockname(s, (struct sockaddr *)&addr, &addrlen) < 0) {
         goto err;
     }
 
-    sv[1] = qemu_socket(AF_INET, SOCK_STREAM, 0);
+    sv[1] = slirp_socket(AF_INET, SOCK_STREAM, 0);
     if (sv[1] < 0) {
         goto err;
     }
@@ -102,16 +102,16 @@ slirp_socketpair_with_oob(int sv[2])
         goto err;
     }
 
-    closesocket(s);
+    slirp_closesocket(s);
     return 0;
 
 err:
     g_critical("slirp_socketpair(): %s", strerror(errno));
     if (s >= 0) {
-        closesocket(s);
+        slirp_closesocket(s);
     }
     if (sv[1] >= 0) {
-        closesocket(sv[1]);
+        slirp_closesocket(sv[1]);
     }
     return -1;
 }
@@ -153,16 +153,16 @@ fork_exec(struct socket *so, const char *ex)
     if (err) {
         g_critical("fork_exec: %s", err->message);
         g_error_free(err);
-        closesocket(sp[0]);
-        closesocket(sp[1]);
+        slirp_closesocket(sp[0]);
+        slirp_closesocket(sp[1]);
         return 0;
     }
 
     so->s = sp[0];
-    closesocket(sp[1]);
-    socket_set_fast_reuse(so->s);
+    slirp_closesocket(sp[1]);
+    slirp_socket_set_fast_reuse(so->s);
     opt = 1;
-    qemu_setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
+    slirp_setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
     qemu_set_nonblock(so->s);
     return 1;
 }
diff --git a/slirp/socket.c b/slirp/socket.c
index 5ffbaa064a..5805d30f3d 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -187,7 +187,7 @@ soread(struct socket *so)
 	 */
 	sopreprbuf(so, iov, &n);
 
-	nn = qemu_recv(so->s, iov[0].iov_base, iov[0].iov_len,0);
+	nn = slirp_recv(so->s, iov[0].iov_base, iov[0].iov_len,0);
 	if (nn <= 0) {
 		if (nn < 0 && (errno == EINTR || errno == EAGAIN))
 			return 0;
@@ -203,7 +203,7 @@ soread(struct socket *so)
 				if (getpeername(so->s, paddr, &alen) < 0) {
 					err = errno;
 				} else {
-					getsockopt(so->s, SOL_SOCKET, SO_ERROR,
+					slirp_getsockopt(so->s, SOL_SOCKET, SO_ERROR,
 						&err, &elen);
 				}
 			}
@@ -233,7 +233,7 @@ soread(struct socket *so)
 	 */
 	if (n == 2 && nn == iov[0].iov_len) {
             int ret;
-            ret = qemu_recv(so->s, iov[1].iov_base, iov[1].iov_len,0);
+            ret = slirp_recv(so->s, iov[1].iov_base, iov[1].iov_len,0);
             if (ret > 0)
                 nn += ret;
         }
@@ -554,7 +554,7 @@ sorecvfrom(struct socket *so)
 	   */
 	  len = M_FREEROOM(m);
 	  /* if (so->so_fport != htons(53)) { */
-	  ioctlsocket(so->s, FIONREAD, &n);
+	  slirp_ioctlsocket(so->s, FIONREAD, &n);
 
 	  if (n > len) {
 	    n = (m->m_data - m->m_dat) + m->m_len + n + 1;
@@ -719,14 +719,14 @@ tcp_listen(Slirp *slirp, uint32_t haddr, u_int hport, uint32_t laddr,
 	addr.sin_addr.s_addr = haddr;
 	addr.sin_port = hport;
 
-	if (((s = qemu_socket(AF_INET,SOCK_STREAM,0)) < 0) ||
-	    (socket_set_fast_reuse(s) < 0) ||
+	if (((s = slirp_socket(AF_INET,SOCK_STREAM,0)) < 0) ||
+	    (slirp_socket_set_fast_reuse(s) < 0) ||
 	    (bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) ||
 	    (listen(s,1) < 0)) {
 		int tmperrno = errno; /* Don't clobber the real reason we failed */
 
                 if (s >= 0) {
-                    closesocket(s);
+                    slirp_closesocket(s);
                 }
 		sofree(so);
 		/* Restore the real errno */
@@ -737,9 +737,9 @@ tcp_listen(Slirp *slirp, uint32_t haddr, u_int hport, uint32_t laddr,
 #endif
 		return NULL;
 	}
-	qemu_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
+	slirp_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
 	opt = 1;
-	qemu_setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(int));
+	slirp_setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(int));
 
 	getsockname(s,(struct sockaddr *)&addr,&addrlen);
 	so->so_ffamily = AF_INET;
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index 4e81736d6f..3567f320ff 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -337,7 +337,7 @@ tcp_close(struct tcpcb *tp)
 	/* clobber input socket cache if we're closing the cached connection */
 	if (so == slirp->tcp_last_so)
 		slirp->tcp_last_so = &slirp->tcb;
-	closesocket(so->s);
+	slirp_closesocket(so->s);
 	sbfree(&so->so_rcv);
 	sbfree(&so->so_snd);
 	sofree(so);
@@ -407,17 +407,17 @@ int tcp_fconnect(struct socket *so, unsigned short af)
   DEBUG_CALL("tcp_fconnect");
   DEBUG_ARG("so = %p", so);
 
-  ret = so->s = qemu_socket(af, SOCK_STREAM, 0);
+  ret = so->s = slirp_socket(af, SOCK_STREAM, 0);
   if (ret >= 0) {
     int opt, s=so->s;
     struct sockaddr_storage addr;
 
     qemu_set_nonblock(s);
-    socket_set_fast_reuse(s);
+    slirp_socket_set_fast_reuse(s);
     opt = 1;
-    qemu_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(opt));
+    slirp_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(opt));
     opt = 1;
-    qemu_setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
+    slirp_setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
 
     addr = so->fhost.ss;
     DEBUG_CALL(" connect()ing");
@@ -485,10 +485,10 @@ void tcp_connect(struct socket *inso)
         return;
     }
     qemu_set_nonblock(s);
-    socket_set_fast_reuse(s);
+    slirp_socket_set_fast_reuse(s);
     opt = 1;
-    qemu_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
-    socket_set_nodelay(s);
+    slirp_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
+    slirp_socket_set_nodelay(s);
 
     so->fhost.ss = addr;
     sotranslate_accept(so);
@@ -496,7 +496,7 @@ void tcp_connect(struct socket *inso)
     /* Close the accept() socket, set right state */
     if (inso->so_state & SS_FACCEPTONCE) {
         /* If we only accept once, close the accept() socket */
-        closesocket(so->s);
+        slirp_closesocket(so->s);
 
         /* Don't select it yet, even though we have an FD */
         /* if it's not FACCEPTONCE, it's already NOFDREF */
diff --git a/slirp/udp.c b/slirp/udp.c
index 309feb9aae..6c3fb9a29f 100644
--- a/slirp/udp.c
+++ b/slirp/udp.c
@@ -281,7 +281,7 @@ int udp_output(struct socket *so, struct mbuf *m,
 int
 udp_attach(struct socket *so, unsigned short af)
 {
-  so->s = qemu_socket(af, SOCK_DGRAM, 0);
+  so->s = slirp_socket(af, SOCK_DGRAM, 0);
   if (so->s != -1) {
     so->so_expire = curtime + SO_EXPIRE;
     insque(so, &so->slirp->udb);
@@ -292,7 +292,7 @@ udp_attach(struct socket *so, unsigned short af)
 void
 udp_detach(struct socket *so)
 {
-	closesocket(so->s);
+	slirp_closesocket(so->s);
 	sofree(so);
 }
 
@@ -327,7 +327,7 @@ udp_listen(Slirp *slirp, uint32_t haddr, u_int hport, uint32_t laddr,
 	socklen_t addrlen = sizeof(struct sockaddr_in);
 
 	so = socreate(slirp);
-	so->s = qemu_socket(AF_INET,SOCK_DGRAM,0);
+	so->s = slirp_socket(AF_INET,SOCK_DGRAM,0);
         if (so->s < 0) {
             sofree(so);
             return NULL;
@@ -343,7 +343,7 @@ udp_listen(Slirp *slirp, uint32_t haddr, u_int hport, uint32_t laddr,
 		udp_detach(so);
 		return NULL;
 	}
-	socket_set_fast_reuse(so->s);
+	slirp_socket_set_fast_reuse(so->s);
 
 	getsockname(so->s,(struct sockaddr *)&addr,&addrlen);
 	so->fhost.sin = addr;
diff --git a/slirp/util.c b/slirp/util.c
new file mode 100644
index 0000000000..b1a36b27bc
--- /dev/null
+++ b/slirp/util.c
@@ -0,0 +1,176 @@
+/*
+ * util.c (mostly based on QEMU os-win32.c)
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ * Copyright (c) 2010-2016 Red Hat, Inc.
+ *
+ * QEMU library functions for win32 which are shared between QEMU and
+ * the QEMU tools.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "util.h"
+
+#include <glib.h>
+#include <fcntl.h>
+#include <stdint.h>
+
+#if defined(_WIN32) && !defined(WITH_QEMU)
+int inet_aton(const char *cp, struct in_addr *ia)
+{
+    uint32_t addr = inet_addr(cp);
+    if (addr == 0xffffffff) {
+        return 0;
+    }
+    ia->s_addr = addr;
+    return 1;
+}
+#endif
+
+static void slirp_set_cloexec(int fd)
+{
+#ifndef _WIN32
+    int f;
+    f = fcntl(fd, F_GETFD);
+    assert(f != -1);
+    f = fcntl(fd, F_SETFD, f | FD_CLOEXEC);
+    assert(f != -1);
+#endif
+}
+
+/*
+ * Opens a socket with FD_CLOEXEC set
+ */
+int slirp_socket(int domain, int type, int protocol)
+{
+    int ret;
+
+#ifdef SOCK_CLOEXEC
+    ret = socket(domain, type | SOCK_CLOEXEC, protocol);
+    if (ret != -1 || errno != EINVAL) {
+        return ret;
+    }
+#endif
+    ret = socket(domain, type, protocol);
+    if (ret >= 0) {
+        slirp_set_cloexec(ret);
+    }
+
+    return ret;
+}
+
+#ifdef _WIN32
+static int socket_error(void)
+{
+    switch (WSAGetLastError()) {
+    case 0:
+        return 0;
+    case WSAEINTR:
+        return EINTR;
+    case WSAEINVAL:
+        return EINVAL;
+    case WSA_INVALID_HANDLE:
+        return EBADF;
+    case WSA_NOT_ENOUGH_MEMORY:
+        return ENOMEM;
+    case WSA_INVALID_PARAMETER:
+        return EINVAL;
+    case WSAENAMETOOLONG:
+        return ENAMETOOLONG;
+    case WSAENOTEMPTY:
+        return ENOTEMPTY;
+    case WSAEWOULDBLOCK:
+         /* not using EWOULDBLOCK as we don't want code to have
+          * to check both EWOULDBLOCK and EAGAIN */
+        return EAGAIN;
+    case WSAEINPROGRESS:
+        return EINPROGRESS;
+    case WSAEALREADY:
+        return EALREADY;
+    case WSAENOTSOCK:
+        return ENOTSOCK;
+    case WSAEDESTADDRREQ:
+        return EDESTADDRREQ;
+    case WSAEMSGSIZE:
+        return EMSGSIZE;
+    case WSAEPROTOTYPE:
+        return EPROTOTYPE;
+    case WSAENOPROTOOPT:
+        return ENOPROTOOPT;
+    case WSAEPROTONOSUPPORT:
+        return EPROTONOSUPPORT;
+    case WSAEOPNOTSUPP:
+        return EOPNOTSUPP;
+    case WSAEAFNOSUPPORT:
+        return EAFNOSUPPORT;
+    case WSAEADDRINUSE:
+        return EADDRINUSE;
+    case WSAEADDRNOTAVAIL:
+        return EADDRNOTAVAIL;
+    case WSAENETDOWN:
+        return ENETDOWN;
+    case WSAENETUNREACH:
+        return ENETUNREACH;
+    case WSAENETRESET:
+        return ENETRESET;
+    case WSAECONNABORTED:
+        return ECONNABORTED;
+    case WSAECONNRESET:
+        return ECONNRESET;
+    case WSAENOBUFS:
+        return ENOBUFS;
+    case WSAEISCONN:
+        return EISCONN;
+    case WSAENOTCONN:
+        return ENOTCONN;
+    case WSAETIMEDOUT:
+        return ETIMEDOUT;
+    case WSAECONNREFUSED:
+        return ECONNREFUSED;
+    case WSAELOOP:
+        return ELOOP;
+    case WSAEHOSTUNREACH:
+        return EHOSTUNREACH;
+    default:
+        return EIO;
+    }
+}
+
+#undef ioctlsocket
+int slirp_ioctlsocket(int fd, int req, void *val)
+{
+    int ret;
+    ret = ioctlsocket(fd, req, val);
+    if (ret < 0) {
+        errno = socket_error();
+    }
+    return ret;
+}
+
+#undef closesocket
+int slirp_closesocket(int fd)
+{
+    int ret;
+    ret = closesocket(fd);
+    if (ret < 0) {
+        errno = socket_error();
+    }
+    return ret;
+}
+#endif /* WIN32 */
diff --git a/slirp/util.h b/slirp/util.h
index 00291c30a6..fe6f1fbb62 100644
--- a/slirp/util.h
+++ b/slirp/util.h
@@ -23,10 +23,71 @@
 #ifndef UTIL_H_
 #define UTIL_H_
 
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <inttypes.h>
+
+#ifdef _WIN32
+#include <winsock2.h>
+#include <windows.h>
+#else
+#include <sys/socket.h>
+#include <netinet/tcp.h>
+#include <netinet/in.h>
+#endif
+
 #if defined(_WIN32)
 # define SLIRP_PACKED __attribute__((gcc_struct, packed))
 #else
 # define SLIRP_PACKED __attribute__((packed))
 #endif
 
+#ifdef _WIN32
+int slirp_closesocket(int fd);
+int slirp_ioctlsocket(int fd, int req, void *val);
+#ifndef WITH_QEMU
+int inet_aton(const char *cp, struct in_addr *ia);
+#endif
+#define slirp_getsockopt(sockfd, level, optname, optval, optlen) \
+    getsockopt(sockfd, level, optname, (void *)optval, optlen)
+#define slirp_setsockopt(sockfd, level, optname, optval, optlen)        \
+    setsockopt(sockfd, level, optname, (const void *)optval, optlen)
+#define slirp_recv(sockfd, buf, len, flags) recv(sockfd, (void *)buf, len, flags)
+#else
+#define slirp_setsockopt setsockopt
+#define slirp_getsockopt getsockopt
+#define slirp_recv recv
+#define slirp_closesocket close
+#define slirp_ioctlsocket ioctl
+#endif
+
+int slirp_socket(int domain, int type, int protocol);
+
+static inline int slirp_socket_set_nodelay(int fd)
+{
+    int v = 1;
+    return slirp_setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(v));
+}
+
+static inline int slirp_socket_set_fast_reuse(int fd)
+{
+#ifndef _WIN32
+    int v = 1;
+    return slirp_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &v, sizeof(v));
+#else
+    /* Enabling the reuse of an endpoint that was used by a socket still in
+     * TIME_WAIT state is usually performed by setting SO_REUSEADDR. On Windows
+     * fast reuse is the default and SO_REUSEADDR does strange things. So we
+     * don't have to do anything here. More info can be found at:
+     * http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621.aspx */
+    return 0;
+#endif
+}
+
 #endif
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 12/32] slirp: replace qemu_set_nonblock()
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
                   ` (10 preceding siblings ...)
  2019-02-07 14:02 ` [Qemu-devel] [PULLv4 11/32] slirp: replace most qemu socket utilities with slirp own version Samuel Thibault
@ 2019-02-07 14:02 ` Samuel Thibault
  2019-02-07 14:02 ` [Qemu-devel] [PULLv4 13/32] slirp: add unregister_poll_fd() callback Samuel Thibault
                   ` (21 subsequent siblings)
  33 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:02 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Marc-André Lureau, stefanha, jan.kiszka, Samuel Thibault

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Replace qemu_set_nonblock() with slirp_set_nonblock()

qemu_set_nonblock() does some event registration with the main
loop. Add a new callback register_poll_fd() for that reason.

Always build the fd-register stub, to avoid #if WIN32.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 net/slirp.c         |  6 ++++++
 slirp/libslirp.h    |  2 ++
 slirp/misc.c        |  3 ++-
 slirp/tcp_subr.c    |  6 ++++--
 slirp/util.c        | 14 ++++++++++++++
 slirp/util.h        |  1 +
 stubs/Makefile.objs |  2 +-
 7 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index c24a779425..6f756a4dcc 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -186,6 +186,11 @@ static void net_slirp_timer_mod(void *timer, int64_t expire_timer)
     timer_mod(timer, expire_timer);
 }
 
+static void net_slirp_register_poll_fd(int fd)
+{
+    qemu_fd_register(fd);
+}
+
 static const SlirpCb slirp_cb = {
     .output = net_slirp_output,
     .guest_error = net_slirp_guest_error,
@@ -193,6 +198,7 @@ static const SlirpCb slirp_cb = {
     .timer_new = net_slirp_timer_new,
     .timer_free = net_slirp_timer_free,
     .timer_mod = net_slirp_timer_mod,
+    .register_poll_fd = net_slirp_register_poll_fd,
 };
 
 static int net_slirp_init(NetClientState *peer, const char *model,
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 3e75dadfa3..70e99139bf 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -27,6 +27,8 @@ typedef struct SlirpCb {
     void (*timer_free)(void *timer);
     /* Modify a timer to expire at @expire_time */
     void (*timer_mod)(void *timer, int64_t expire_time);
+    /* Register a fd for future polling */
+    void (*register_poll_fd)(int fd);
 } SlirpCb;
 
 
diff --git a/slirp/misc.c b/slirp/misc.c
index 32ec02a525..4ee20a10e4 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -163,7 +163,8 @@ fork_exec(struct socket *so, const char *ex)
     slirp_socket_set_fast_reuse(so->s);
     opt = 1;
     slirp_setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
-    qemu_set_nonblock(so->s);
+    slirp_set_nonblock(so->s);
+    so->slirp->cb->register_poll_fd(so->s);
     return 1;
 }
 
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index 3567f320ff..8087ffc047 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -412,7 +412,8 @@ int tcp_fconnect(struct socket *so, unsigned short af)
     int opt, s=so->s;
     struct sockaddr_storage addr;
 
-    qemu_set_nonblock(s);
+    slirp_set_nonblock(s);
+    so->slirp->cb->register_poll_fd(so->s);
     slirp_socket_set_fast_reuse(s);
     opt = 1;
     slirp_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(opt));
@@ -484,7 +485,8 @@ void tcp_connect(struct socket *inso)
         tcp_close(sototcpcb(so)); /* This will sofree() as well */
         return;
     }
-    qemu_set_nonblock(s);
+    slirp_set_nonblock(s);
+    so->slirp->cb->register_poll_fd(so->s);
     slirp_socket_set_fast_reuse(s);
     opt = 1;
     slirp_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
diff --git a/slirp/util.c b/slirp/util.c
index b1a36b27bc..59f6713c8b 100644
--- a/slirp/util.c
+++ b/slirp/util.c
@@ -43,6 +43,20 @@ int inet_aton(const char *cp, struct in_addr *ia)
 }
 #endif
 
+void slirp_set_nonblock(int fd)
+{
+#ifndef _WIN32
+    int f;
+    f = fcntl(fd, F_GETFL);
+    assert(f != -1);
+    f = fcntl(fd, F_SETFL, f | O_NONBLOCK);
+    assert(f != -1);
+#else
+    unsigned long opt = 1;
+    ioctlsocket(fd, FIONBIO, &opt);
+#endif
+}
+
 static void slirp_set_cloexec(int fd)
 {
 #ifndef _WIN32
diff --git a/slirp/util.h b/slirp/util.h
index fe6f1fbb62..4f6e80c3ed 100644
--- a/slirp/util.h
+++ b/slirp/util.h
@@ -68,6 +68,7 @@ int inet_aton(const char *cp, struct in_addr *ia);
 #endif
 
 int slirp_socket(int domain, int type, int protocol);
+void slirp_set_nonblock(int fd);
 
 static inline int slirp_socket_set_nodelay(int fd)
 {
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index 5dd0aeeec6..cda0efa4e8 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -33,7 +33,7 @@ stub-obj-y += trace-control.o
 stub-obj-y += uuid.o
 stub-obj-y += vm-stop.o
 stub-obj-y += vmstate.o
-stub-obj-$(CONFIG_WIN32) += fd-register.o
+stub-obj-y += fd-register.o
 stub-obj-y += qmp_memory_device.o
 stub-obj-y += target-monitor-defs.o
 stub-obj-y += target-get-monitor-def.o
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 13/32] slirp: add unregister_poll_fd() callback
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
                   ` (11 preceding siblings ...)
  2019-02-07 14:02 ` [Qemu-devel] [PULLv4 12/32] slirp: replace qemu_set_nonblock() Samuel Thibault
@ 2019-02-07 14:02 ` Samuel Thibault
  2019-02-07 14:02 ` [Qemu-devel] [PULLv4 14/32] slirp: replace qemu_notify_event() with a callback Samuel Thibault
                   ` (20 subsequent siblings)
  33 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:02 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Marc-André Lureau, stefanha, jan.kiszka, Paolo Bonzini,
	Samuel Thibault

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Add a counter-part to register_poll_fd() for completeness.

(so far, register_poll_fd() is called only on struct socket fd)

Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 net/slirp.c      | 6 ++++++
 slirp/ip_icmp.c  | 1 +
 slirp/libslirp.h | 2 ++
 slirp/slirp.c    | 3 ++-
 slirp/tcp_subr.c | 2 ++
 slirp/udp.c      | 1 +
 6 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/net/slirp.c b/net/slirp.c
index 6f756a4dcc..78ba96b63f 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -191,6 +191,11 @@ static void net_slirp_register_poll_fd(int fd)
     qemu_fd_register(fd);
 }
 
+static void net_slirp_unregister_poll_fd(int fd)
+{
+    /* no qemu_fd_unregister */
+}
+
 static const SlirpCb slirp_cb = {
     .output = net_slirp_output,
     .guest_error = net_slirp_guest_error,
@@ -199,6 +204,7 @@ static const SlirpCb slirp_cb = {
     .timer_free = net_slirp_timer_free,
     .timer_mod = net_slirp_timer_mod,
     .register_poll_fd = net_slirp_register_poll_fd,
+    .unregister_poll_fd = net_slirp_unregister_poll_fd,
 };
 
 static int net_slirp_init(NetClientState *peer, const char *model,
diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
index b59daa801d..19e247f773 100644
--- a/slirp/ip_icmp.c
+++ b/slirp/ip_icmp.c
@@ -114,6 +114,7 @@ static int icmp_send(struct socket *so, struct mbuf *m, int hlen)
 
 void icmp_detach(struct socket *so)
 {
+    so->slirp->cb->unregister_poll_fd(so->s);
     slirp_closesocket(so->s);
     sofree(so);
 }
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 70e99139bf..8ce69f0be3 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -29,6 +29,8 @@ typedef struct SlirpCb {
     void (*timer_mod)(void *timer, int64_t expire_time);
     /* Register a fd for future polling */
     void (*register_poll_fd)(int fd);
+    /* Unregister a fd */
+    void (*unregister_poll_fd)(int fd);
 } SlirpCb;
 
 
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 12677e5da7..f0bd59fd6f 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -1015,7 +1015,8 @@ int slirp_remove_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr,
             getsockname(so->s, (struct sockaddr *)&addr, &addr_len) == 0 &&
             addr.sin_addr.s_addr == host_addr.s_addr &&
             addr.sin_port == port) {
-            close(so->s);
+            so->slirp->cb->unregister_poll_fd(so->s);
+            slirp_closesocket(so->s);
             sofree(so);
             return 0;
         }
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index 8087ffc047..d8846a33b0 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -337,6 +337,7 @@ tcp_close(struct tcpcb *tp)
 	/* clobber input socket cache if we're closing the cached connection */
 	if (so == slirp->tcp_last_so)
 		slirp->tcp_last_so = &slirp->tcb;
+	so->slirp->cb->unregister_poll_fd(so->s);
 	slirp_closesocket(so->s);
 	sbfree(&so->so_rcv);
 	sbfree(&so->so_snd);
@@ -498,6 +499,7 @@ void tcp_connect(struct socket *inso)
     /* Close the accept() socket, set right state */
     if (inso->so_state & SS_FACCEPTONCE) {
         /* If we only accept once, close the accept() socket */
+        so->slirp->cb->unregister_poll_fd(so->s);
         slirp_closesocket(so->s);
 
         /* Don't select it yet, even though we have an FD */
diff --git a/slirp/udp.c b/slirp/udp.c
index 6c3fb9a29f..3915971b50 100644
--- a/slirp/udp.c
+++ b/slirp/udp.c
@@ -292,6 +292,7 @@ udp_attach(struct socket *so, unsigned short af)
 void
 udp_detach(struct socket *so)
 {
+	so->slirp->cb->unregister_poll_fd(so->s);
 	slirp_closesocket(so->s);
 	sofree(so);
 }
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 14/32] slirp: replace qemu_notify_event() with a callback
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
                   ` (12 preceding siblings ...)
  2019-02-07 14:02 ` [Qemu-devel] [PULLv4 13/32] slirp: add unregister_poll_fd() callback Samuel Thibault
@ 2019-02-07 14:02 ` Samuel Thibault
  2019-02-07 14:02 ` [Qemu-devel] [PULLv4 15/32] slirp: move QEMU state saving to a separate unit Samuel Thibault
                   ` (19 subsequent siblings)
  33 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:02 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Marc-André Lureau, stefanha, jan.kiszka, Samuel Thibault

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Introduce a SlirpCb callback to kick the main io-thread.

Add an intermediary sodrop() function that will call SlirpCb.notify
callback when sbdrop() returns true.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 net/slirp.c       | 1 +
 slirp/libslirp.h  | 2 ++
 slirp/sbuf.c      | 6 ++++--
 slirp/sbuf.h      | 2 +-
 slirp/socket.c    | 7 +++++++
 slirp/socket.h    | 1 +
 slirp/tcp_input.c | 6 +++---
 7 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index 78ba96b63f..7b4f9f5c5e 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -205,6 +205,7 @@ static const SlirpCb slirp_cb = {
     .timer_mod = net_slirp_timer_mod,
     .register_poll_fd = net_slirp_register_poll_fd,
     .unregister_poll_fd = net_slirp_unregister_poll_fd,
+    .notify = qemu_notify_event,
 };
 
 static int net_slirp_init(NetClientState *peer, const char *model,
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 8ce69f0be3..679a25422b 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -31,6 +31,8 @@ typedef struct SlirpCb {
     void (*register_poll_fd)(int fd);
     /* Unregister a fd */
     void (*unregister_poll_fd)(int fd);
+    /* Kick the io-thread, to signal that new events may be processed */
+    void (*notify)(void);
 } SlirpCb;
 
 
diff --git a/slirp/sbuf.c b/slirp/sbuf.c
index 912f235f65..17f28e97a6 100644
--- a/slirp/sbuf.c
+++ b/slirp/sbuf.c
@@ -17,7 +17,7 @@ sbfree(struct sbuf *sb)
 	free(sb->sb_data);
 }
 
-void
+bool
 sbdrop(struct sbuf *sb, int num)
 {
     int limit = sb->sb_datalen / 2;
@@ -34,8 +34,10 @@ sbdrop(struct sbuf *sb, int num)
 		sb->sb_rptr -= sb->sb_datalen;
 
     if (sb->sb_cc < limit && sb->sb_cc + num >= limit) {
-        qemu_notify_event();
+        return true;
     }
+
+    return false;
 }
 
 void
diff --git a/slirp/sbuf.h b/slirp/sbuf.h
index 644c201341..1cb9a42834 100644
--- a/slirp/sbuf.h
+++ b/slirp/sbuf.h
@@ -21,7 +21,7 @@ struct sbuf {
 };
 
 void sbfree(struct sbuf *);
-void sbdrop(struct sbuf *, int);
+bool sbdrop(struct sbuf *, int);
 void sbreserve(struct sbuf *, int);
 void sbappend(struct socket *, struct mbuf *);
 void sbcopy(struct sbuf *, int, int, char *);
diff --git a/slirp/socket.c b/slirp/socket.c
index 5805d30f3d..2e8dc22fb6 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -928,3 +928,10 @@ void sotranslate_accept(struct socket *so)
         break;
     }
 }
+
+void sodrop(struct socket *s, int num)
+{
+    if (sbdrop(&s->so_snd, num)) {
+        s->slirp->cb->notify();
+    }
+}
diff --git a/slirp/socket.h b/slirp/socket.h
index fc35ca5f72..1c1c8b5871 100644
--- a/slirp/socket.h
+++ b/slirp/socket.h
@@ -156,6 +156,7 @@ int soreadbuf(struct socket *so, const char *buf, int size);
 void sotranslate_out(struct socket *, struct sockaddr_storage *);
 void sotranslate_in(struct socket *, struct sockaddr_storage *);
 void sotranslate_accept(struct socket *);
+void sodrop(struct socket *, int num);
 
 
 #endif /* SLIRP_SOCKET_H */
diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
index de5b74a52b..7c1fe18fec 100644
--- a/slirp/tcp_input.c
+++ b/slirp/tcp_input.c
@@ -506,7 +506,7 @@ findso:
 				    SEQ_GT(ti->ti_ack, tp->t_rtseq))
 					tcp_xmit_timer(tp, tp->t_rtt);
 				acked = ti->ti_ack - tp->snd_una;
-				sbdrop(&so->so_snd, acked);
+				sodrop(so, acked);
 				tp->snd_una = ti->ti_ack;
 				m_free(m);
 
@@ -1118,10 +1118,10 @@ trimthenstep6:
 		}
 		if (acked > so->so_snd.sb_cc) {
 			tp->snd_wnd -= so->so_snd.sb_cc;
-			sbdrop(&so->so_snd, (int )so->so_snd.sb_cc);
+			sodrop(so, (int)so->so_snd.sb_cc);
 			ourfinisacked = 1;
 		} else {
-			sbdrop(&so->so_snd, acked);
+			sodrop(so, acked);
 			tp->snd_wnd -= acked;
 			ourfinisacked = 0;
 		}
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 15/32] slirp: move QEMU state saving to a separate unit
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
                   ` (13 preceding siblings ...)
  2019-02-07 14:02 ` [Qemu-devel] [PULLv4 14/32] slirp: replace qemu_notify_event() with a callback Samuel Thibault
@ 2019-02-07 14:02 ` Samuel Thibault
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 16/32] slirp: do not include qemu headers in libslirp.h public API header Samuel Thibault
                   ` (18 subsequent siblings)
  33 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:02 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Marc-André Lureau, stefanha, jan.kiszka, Samuel Thibault

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Make state saving optional: this will allow to build SLIRP without
QEMU. (eventually, the vmstate helpers will be extracted, so an
external project & process could save its state)

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 slirp/Makefile.objs |   1 +
 slirp/slirp.c       | 372 ++---------------------------------------
 slirp/slirp.h       |   3 +
 slirp/state.c       | 394 ++++++++++++++++++++++++++++++++++++++++++++
 slirp/state.h       |   9 +
 5 files changed, 418 insertions(+), 361 deletions(-)
 create mode 100644 slirp/state.c
 create mode 100644 slirp/state.h

diff --git a/slirp/Makefile.objs b/slirp/Makefile.objs
index d2ead94b3b..88340a583b 100644
--- a/slirp/Makefile.objs
+++ b/slirp/Makefile.objs
@@ -20,6 +20,7 @@ slirp.mo-objs = \
 	sbuf.o \
 	slirp.o \
 	socket.o \
+	state.o \
 	tcp_input.o \
 	tcp_output.o \
 	tcp_subr.o \
diff --git a/slirp/slirp.c b/slirp/slirp.c
index f0bd59fd6f..9ec1e4c62f 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -30,6 +30,10 @@
 #include "hw/hw.h"
 #include "qemu/cutils.h"
 
+#ifdef WITH_QEMU
+#include "state.h"
+#endif
+
 #ifndef _WIN32
 #include <net/if.h>
 #endif
@@ -278,14 +282,6 @@ static void slirp_init_once(void)
 
 }
 
-static void slirp_state_save(QEMUFile *f, void *opaque);
-static int slirp_state_load(QEMUFile *f, void *opaque, int version_id);
-
-static SaveVMHandlers savevm_slirp_state = {
-    .save_state = slirp_state_save,
-    .load_state = slirp_state_load,
-};
-
 Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
                   struct in_addr vnetmask, struct in_addr vhost,
                   bool in6_enabled,
@@ -341,8 +337,9 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
 
     slirp->opaque = opaque;
 
-    register_savevm_live(NULL, "slirp", 0, 4, &savevm_slirp_state, slirp);
-
+#ifdef WITH_QEMU
+    slirp_state_register(slirp);
+#endif
     QTAILQ_INSERT_TAIL(&slirp_instances, slirp, entry);
 
     return slirp;
@@ -359,9 +356,9 @@ void slirp_cleanup(Slirp *slirp)
     }
 
     QTAILQ_REMOVE(&slirp_instances, slirp, entry);
-
-    unregister_savevm(NULL, "slirp", slirp);
-
+#ifdef WITH_QEMU
+    slirp_state_unregister(slirp);
+#endif
     ip_cleanup(slirp);
     ip6_cleanup(slirp);
     m_cleanup(slirp);
@@ -1115,7 +1112,7 @@ ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags)
     return send(so->s, buf, len, flags);
 }
 
-static struct socket *
+struct socket *
 slirp_find_ctl_socket(Slirp *slirp, struct in_addr guest_addr, int guest_port)
 {
     struct socket *so;
@@ -1162,350 +1159,3 @@ void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr, int guest_port,
     if (ret > 0)
         tcp_output(sototcpcb(so));
 }
-
-static int slirp_tcp_post_load(void *opaque, int version)
-{
-    tcp_template((struct tcpcb *)opaque);
-
-    return 0;
-}
-
-static const VMStateDescription vmstate_slirp_tcp = {
-    .name = "slirp-tcp",
-    .version_id = 0,
-    .post_load = slirp_tcp_post_load,
-    .fields = (VMStateField[]) {
-        VMSTATE_INT16(t_state, struct tcpcb),
-        VMSTATE_INT16_ARRAY(t_timer, struct tcpcb, TCPT_NTIMERS),
-        VMSTATE_INT16(t_rxtshift, struct tcpcb),
-        VMSTATE_INT16(t_rxtcur, struct tcpcb),
-        VMSTATE_INT16(t_dupacks, struct tcpcb),
-        VMSTATE_UINT16(t_maxseg, struct tcpcb),
-        VMSTATE_UINT8(t_force, struct tcpcb),
-        VMSTATE_UINT16(t_flags, struct tcpcb),
-        VMSTATE_UINT32(snd_una, struct tcpcb),
-        VMSTATE_UINT32(snd_nxt, struct tcpcb),
-        VMSTATE_UINT32(snd_up, struct tcpcb),
-        VMSTATE_UINT32(snd_wl1, struct tcpcb),
-        VMSTATE_UINT32(snd_wl2, struct tcpcb),
-        VMSTATE_UINT32(iss, struct tcpcb),
-        VMSTATE_UINT32(snd_wnd, struct tcpcb),
-        VMSTATE_UINT32(rcv_wnd, struct tcpcb),
-        VMSTATE_UINT32(rcv_nxt, struct tcpcb),
-        VMSTATE_UINT32(rcv_up, struct tcpcb),
-        VMSTATE_UINT32(irs, struct tcpcb),
-        VMSTATE_UINT32(rcv_adv, struct tcpcb),
-        VMSTATE_UINT32(snd_max, struct tcpcb),
-        VMSTATE_UINT32(snd_cwnd, struct tcpcb),
-        VMSTATE_UINT32(snd_ssthresh, struct tcpcb),
-        VMSTATE_INT16(t_idle, struct tcpcb),
-        VMSTATE_INT16(t_rtt, struct tcpcb),
-        VMSTATE_UINT32(t_rtseq, struct tcpcb),
-        VMSTATE_INT16(t_srtt, struct tcpcb),
-        VMSTATE_INT16(t_rttvar, struct tcpcb),
-        VMSTATE_UINT16(t_rttmin, struct tcpcb),
-        VMSTATE_UINT32(max_sndwnd, struct tcpcb),
-        VMSTATE_UINT8(t_oobflags, struct tcpcb),
-        VMSTATE_UINT8(t_iobc, struct tcpcb),
-        VMSTATE_INT16(t_softerror, struct tcpcb),
-        VMSTATE_UINT8(snd_scale, struct tcpcb),
-        VMSTATE_UINT8(rcv_scale, struct tcpcb),
-        VMSTATE_UINT8(request_r_scale, struct tcpcb),
-        VMSTATE_UINT8(requested_s_scale, struct tcpcb),
-        VMSTATE_UINT32(ts_recent, struct tcpcb),
-        VMSTATE_UINT32(ts_recent_age, struct tcpcb),
-        VMSTATE_UINT32(last_ack_sent, struct tcpcb),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-/* The sbuf has a pair of pointers that are migrated as offsets;
- * we calculate the offsets and restore the pointers using
- * pre_save/post_load on a tmp structure.
- */
-struct sbuf_tmp {
-    struct sbuf *parent;
-    uint32_t roff, woff;
-};
-
-static int sbuf_tmp_pre_save(void *opaque)
-{
-    struct sbuf_tmp *tmp = opaque;
-    tmp->woff = tmp->parent->sb_wptr - tmp->parent->sb_data;
-    tmp->roff = tmp->parent->sb_rptr - tmp->parent->sb_data;
-
-    return 0;
-}
-
-static int sbuf_tmp_post_load(void *opaque, int version)
-{
-    struct sbuf_tmp *tmp = opaque;
-    uint32_t requested_len = tmp->parent->sb_datalen;
-
-    /* Allocate the buffer space used by the field after the tmp */
-    sbreserve(tmp->parent, tmp->parent->sb_datalen);
-
-    if (tmp->parent->sb_datalen != requested_len) {
-        return -ENOMEM;
-    }
-    if (tmp->woff >= requested_len ||
-        tmp->roff >= requested_len) {
-        g_critical("invalid sbuf offsets r/w=%u/%u len=%u",
-                   tmp->roff, tmp->woff, requested_len);
-        return -EINVAL;
-    }
-
-    tmp->parent->sb_wptr = tmp->parent->sb_data + tmp->woff;
-    tmp->parent->sb_rptr = tmp->parent->sb_data + tmp->roff;
-
-    return 0;
-}
-
-
-static const VMStateDescription vmstate_slirp_sbuf_tmp = {
-    .name = "slirp-sbuf-tmp",
-    .post_load = sbuf_tmp_post_load,
-    .pre_save  = sbuf_tmp_pre_save,
-    .version_id = 0,
-    .fields = (VMStateField[]) {
-        VMSTATE_UINT32(woff, struct sbuf_tmp),
-        VMSTATE_UINT32(roff, struct sbuf_tmp),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static const VMStateDescription vmstate_slirp_sbuf = {
-    .name = "slirp-sbuf",
-    .version_id = 0,
-    .fields = (VMStateField[]) {
-        VMSTATE_UINT32(sb_cc, struct sbuf),
-        VMSTATE_UINT32(sb_datalen, struct sbuf),
-        VMSTATE_WITH_TMP(struct sbuf, struct sbuf_tmp, vmstate_slirp_sbuf_tmp),
-        VMSTATE_VBUFFER_UINT32(sb_data, struct sbuf, 0, NULL, sb_datalen),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static bool slirp_older_than_v4(void *opaque, int version_id)
-{
-    return version_id < 4;
-}
-
-static bool slirp_family_inet(void *opaque, int version_id)
-{
-    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;
-    }
-    /* Older versions don't load these fields */
-    so->so_ffamily = AF_INET;
-    so->so_lfamily = 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 int ss_family_pre_save(void *opaque)
-{
-    SS_FamilyTmpStruct *tss = opaque;
-
-    tss->portable_family = SS_FAMILY_MIG_OTHER;
-
-    if (tss->parent->ss.ss_family == AF_INET) {
-        tss->portable_family = SS_FAMILY_MIG_IPV4;
-    } else if (tss->parent->ss.ss_family == AF_INET6) {
-        tss->portable_family = SS_FAMILY_MIG_IPV6;
-    }
-
-    return 0;
-}
-
-static int ss_family_post_load(void *opaque, int version_id)
-{
-    SS_FamilyTmpStruct *tss = opaque;
-
-    switch (tss->portable_family) {
-    case SS_FAMILY_MIG_IPV4:
-        tss->parent->ss.ss_family = 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 = AF_INET6;
-        break;
-    default:
-        g_critical("invalid ss_family type %x", tss->portable_family);
-        return -EINVAL;
-    }
-
-    return 0;
-}
-
-static const VMStateDescription vmstate_slirp_ss_family = {
-    .name = "slirp-socket-addr/ss_family",
-    .pre_save  = ss_family_pre_save,
-    .post_load = ss_family_post_load,
-    .fields = (VMStateField[]) {
-        VMSTATE_UINT16(portable_family, SS_FamilyTmpStruct),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static const VMStateDescription vmstate_slirp_socket_addr = {
-    .name = "slirp-socket-addr",
-    .version_id = 4,
-    .fields = (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 = {
-    .name = "slirp-socket",
-    .version_id = 4,
-    .pre_load = slirp_socket_pre_load,
-    .fields = (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 const VMStateDescription vmstate_slirp_bootp_client = {
-    .name = "slirp_bootpclient",
-    .fields = (VMStateField[]) {
-        VMSTATE_UINT16(allocated, BOOTPClient),
-        VMSTATE_BUFFER(macaddr, BOOTPClient),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static const VMStateDescription vmstate_slirp = {
-    .name = "slirp",
-    .version_id = 4,
-    .fields = (VMStateField[]) {
-        VMSTATE_UINT16_V(ip_id, Slirp, 2),
-        VMSTATE_STRUCT_ARRAY(bootp_clients, Slirp, NB_BOOTP_CLIENTS, 3,
-                             vmstate_slirp_bootp_client, BOOTPClient),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static void slirp_state_save(QEMUFile *f, void *opaque)
-{
-    Slirp *slirp = opaque;
-    struct gfwd_list *ex_ptr;
-
-    for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
-        if (ex_ptr->write_cb) {
-            struct socket *so;
-            so = slirp_find_ctl_socket(slirp, ex_ptr->ex_addr,
-                                       ntohs(ex_ptr->ex_fport));
-            if (!so)
-                continue;
-
-            qemu_put_byte(f, 42);
-            vmstate_save_state(f, &vmstate_slirp_socket, so, NULL);
-        }
-    qemu_put_byte(f, 0);
-
-    vmstate_save_state(f, &vmstate_slirp, slirp, NULL);
-}
-
-
-static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
-{
-    Slirp *slirp = opaque;
-    struct gfwd_list *ex_ptr;
-
-    while (qemu_get_byte(f)) {
-        int ret;
-        struct socket *so = socreate(slirp);
-
-        ret = vmstate_load_state(f, &vmstate_slirp_socket, so, version_id);
-
-        if (ret < 0)
-            return ret;
-
-        if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) !=
-            slirp->vnetwork_addr.s_addr) {
-            return -EINVAL;
-        }
-        for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
-            if (ex_ptr->write_cb &&
-                so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr &&
-                so->so_fport == ex_ptr->ex_fport) {
-                break;
-            }
-        }
-        if (!ex_ptr)
-            return -EINVAL;
-    }
-
-    return vmstate_load_state(f, &vmstate_slirp, slirp, version_id);
-}
diff --git a/slirp/slirp.h b/slirp/slirp.h
index 67ff4d610c..8d9d72ca9d 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -271,4 +271,7 @@ int tcp_emu(struct socket *, struct mbuf *);
 int tcp_ctl(struct socket *);
 struct tcpcb *tcp_drop(struct tcpcb *tp, int err);
 
+struct socket *
+slirp_find_ctl_socket(Slirp *slirp, struct in_addr guest_addr, int guest_port);
+
 #endif
diff --git a/slirp/state.c b/slirp/state.c
new file mode 100644
index 0000000000..0e5a706e87
--- /dev/null
+++ b/slirp/state.c
@@ -0,0 +1,394 @@
+/*
+ * libslirp
+ *
+ * Copyright (c) 2004-2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu/osdep.h"
+
+#include "slirp.h"
+#include "state.h"
+#include "migration/vmstate.h"
+#include "migration/qemu-file-types.h"
+#include "migration/register.h"
+
+static int slirp_tcp_post_load(void *opaque, int version)
+{
+    tcp_template((struct tcpcb *)opaque);
+
+    return 0;
+}
+
+static const VMStateDescription vmstate_slirp_tcp = {
+    .name = "slirp-tcp",
+    .version_id = 0,
+    .post_load = slirp_tcp_post_load,
+    .fields = (VMStateField[]) {
+        VMSTATE_INT16(t_state, struct tcpcb),
+        VMSTATE_INT16_ARRAY(t_timer, struct tcpcb, TCPT_NTIMERS),
+        VMSTATE_INT16(t_rxtshift, struct tcpcb),
+        VMSTATE_INT16(t_rxtcur, struct tcpcb),
+        VMSTATE_INT16(t_dupacks, struct tcpcb),
+        VMSTATE_UINT16(t_maxseg, struct tcpcb),
+        VMSTATE_UINT8(t_force, struct tcpcb),
+        VMSTATE_UINT16(t_flags, struct tcpcb),
+        VMSTATE_UINT32(snd_una, struct tcpcb),
+        VMSTATE_UINT32(snd_nxt, struct tcpcb),
+        VMSTATE_UINT32(snd_up, struct tcpcb),
+        VMSTATE_UINT32(snd_wl1, struct tcpcb),
+        VMSTATE_UINT32(snd_wl2, struct tcpcb),
+        VMSTATE_UINT32(iss, struct tcpcb),
+        VMSTATE_UINT32(snd_wnd, struct tcpcb),
+        VMSTATE_UINT32(rcv_wnd, struct tcpcb),
+        VMSTATE_UINT32(rcv_nxt, struct tcpcb),
+        VMSTATE_UINT32(rcv_up, struct tcpcb),
+        VMSTATE_UINT32(irs, struct tcpcb),
+        VMSTATE_UINT32(rcv_adv, struct tcpcb),
+        VMSTATE_UINT32(snd_max, struct tcpcb),
+        VMSTATE_UINT32(snd_cwnd, struct tcpcb),
+        VMSTATE_UINT32(snd_ssthresh, struct tcpcb),
+        VMSTATE_INT16(t_idle, struct tcpcb),
+        VMSTATE_INT16(t_rtt, struct tcpcb),
+        VMSTATE_UINT32(t_rtseq, struct tcpcb),
+        VMSTATE_INT16(t_srtt, struct tcpcb),
+        VMSTATE_INT16(t_rttvar, struct tcpcb),
+        VMSTATE_UINT16(t_rttmin, struct tcpcb),
+        VMSTATE_UINT32(max_sndwnd, struct tcpcb),
+        VMSTATE_UINT8(t_oobflags, struct tcpcb),
+        VMSTATE_UINT8(t_iobc, struct tcpcb),
+        VMSTATE_INT16(t_softerror, struct tcpcb),
+        VMSTATE_UINT8(snd_scale, struct tcpcb),
+        VMSTATE_UINT8(rcv_scale, struct tcpcb),
+        VMSTATE_UINT8(request_r_scale, struct tcpcb),
+        VMSTATE_UINT8(requested_s_scale, struct tcpcb),
+        VMSTATE_UINT32(ts_recent, struct tcpcb),
+        VMSTATE_UINT32(ts_recent_age, struct tcpcb),
+        VMSTATE_UINT32(last_ack_sent, struct tcpcb),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+/* The sbuf has a pair of pointers that are migrated as offsets;
+ * we calculate the offsets and restore the pointers using
+ * pre_save/post_load on a tmp structure.
+ */
+struct sbuf_tmp {
+    struct sbuf *parent;
+    uint32_t roff, woff;
+};
+
+static int sbuf_tmp_pre_save(void *opaque)
+{
+    struct sbuf_tmp *tmp = opaque;
+    tmp->woff = tmp->parent->sb_wptr - tmp->parent->sb_data;
+    tmp->roff = tmp->parent->sb_rptr - tmp->parent->sb_data;
+
+    return 0;
+}
+
+static int sbuf_tmp_post_load(void *opaque, int version)
+{
+    struct sbuf_tmp *tmp = opaque;
+    uint32_t requested_len = tmp->parent->sb_datalen;
+
+    /* Allocate the buffer space used by the field after the tmp */
+    sbreserve(tmp->parent, tmp->parent->sb_datalen);
+
+    if (tmp->parent->sb_datalen != requested_len) {
+        return -ENOMEM;
+    }
+    if (tmp->woff >= requested_len ||
+        tmp->roff >= requested_len) {
+        g_critical("invalid sbuf offsets r/w=%u/%u len=%u",
+                   tmp->roff, tmp->woff, requested_len);
+        return -EINVAL;
+    }
+
+    tmp->parent->sb_wptr = tmp->parent->sb_data + tmp->woff;
+    tmp->parent->sb_rptr = tmp->parent->sb_data + tmp->roff;
+
+    return 0;
+}
+
+
+static const VMStateDescription vmstate_slirp_sbuf_tmp = {
+    .name = "slirp-sbuf-tmp",
+    .post_load = sbuf_tmp_post_load,
+    .pre_save  = sbuf_tmp_pre_save,
+    .version_id = 0,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(woff, struct sbuf_tmp),
+        VMSTATE_UINT32(roff, struct sbuf_tmp),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static const VMStateDescription vmstate_slirp_sbuf = {
+    .name = "slirp-sbuf",
+    .version_id = 0,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(sb_cc, struct sbuf),
+        VMSTATE_UINT32(sb_datalen, struct sbuf),
+        VMSTATE_WITH_TMP(struct sbuf, struct sbuf_tmp, vmstate_slirp_sbuf_tmp),
+        VMSTATE_VBUFFER_UINT32(sb_data, struct sbuf, 0, NULL, sb_datalen),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static bool slirp_older_than_v4(void *opaque, int version_id)
+{
+    return version_id < 4;
+}
+
+static bool slirp_family_inet(void *opaque, int version_id)
+{
+    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;
+    }
+    /* Older versions don't load these fields */
+    so->so_ffamily = AF_INET;
+    so->so_lfamily = 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 int ss_family_pre_save(void *opaque)
+{
+    SS_FamilyTmpStruct *tss = opaque;
+
+    tss->portable_family = SS_FAMILY_MIG_OTHER;
+
+    if (tss->parent->ss.ss_family == AF_INET) {
+        tss->portable_family = SS_FAMILY_MIG_IPV4;
+    } else if (tss->parent->ss.ss_family == AF_INET6) {
+        tss->portable_family = SS_FAMILY_MIG_IPV6;
+    }
+
+    return 0;
+}
+
+static int ss_family_post_load(void *opaque, int version_id)
+{
+    SS_FamilyTmpStruct *tss = opaque;
+
+    switch (tss->portable_family) {
+    case SS_FAMILY_MIG_IPV4:
+        tss->parent->ss.ss_family = 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 = AF_INET6;
+        break;
+    default:
+        g_critical("invalid ss_family type %x", tss->portable_family);
+        return -EINVAL;
+    }
+
+    return 0;
+}
+
+static const VMStateDescription vmstate_slirp_ss_family = {
+    .name = "slirp-socket-addr/ss_family",
+    .pre_save  = ss_family_pre_save,
+    .post_load = ss_family_post_load,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT16(portable_family, SS_FamilyTmpStruct),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static const VMStateDescription vmstate_slirp_socket_addr = {
+    .name = "slirp-socket-addr",
+    .version_id = 4,
+    .fields = (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 = {
+    .name = "slirp-socket",
+    .version_id = 4,
+    .pre_load = slirp_socket_pre_load,
+    .fields = (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 const VMStateDescription vmstate_slirp_bootp_client = {
+    .name = "slirp_bootpclient",
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT16(allocated, BOOTPClient),
+        VMSTATE_BUFFER(macaddr, BOOTPClient),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static const VMStateDescription vmstate_slirp = {
+    .name = "slirp",
+    .version_id = 4,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT16_V(ip_id, Slirp, 2),
+        VMSTATE_STRUCT_ARRAY(bootp_clients, Slirp, NB_BOOTP_CLIENTS, 3,
+                             vmstate_slirp_bootp_client, BOOTPClient),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void slirp_state_save(QEMUFile *f, void *opaque)
+{
+    Slirp *slirp = opaque;
+    struct gfwd_list *ex_ptr;
+
+    for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
+        if (ex_ptr->write_cb) {
+            struct socket *so;
+            so = slirp_find_ctl_socket(slirp, ex_ptr->ex_addr,
+                                       ntohs(ex_ptr->ex_fport));
+            if (!so) {
+                continue;
+            }
+
+            qemu_put_byte(f, 42);
+            vmstate_save_state(f, &vmstate_slirp_socket, so, NULL);
+        }
+    qemu_put_byte(f, 0);
+
+    vmstate_save_state(f, &vmstate_slirp, slirp, NULL);
+}
+
+
+static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
+{
+    Slirp *slirp = opaque;
+    struct gfwd_list *ex_ptr;
+
+    while (qemu_get_byte(f)) {
+        int ret;
+        struct socket *so = socreate(slirp);
+
+        ret = vmstate_load_state(f, &vmstate_slirp_socket, so, version_id);
+        if (ret < 0) {
+            return ret;
+        }
+
+        if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) !=
+            slirp->vnetwork_addr.s_addr) {
+            return -EINVAL;
+        }
+        for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
+            if (ex_ptr->write_cb &&
+                so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr &&
+                so->so_fport == ex_ptr->ex_fport) {
+                break;
+            }
+        }
+        if (!ex_ptr) {
+            return -EINVAL;
+        }
+    }
+
+    return vmstate_load_state(f, &vmstate_slirp, slirp, version_id);
+}
+
+void slirp_state_register(Slirp *slirp)
+{
+    static SaveVMHandlers savevm_slirp_state = {
+        .save_state = slirp_state_save,
+        .load_state = slirp_state_load,
+    };
+
+    register_savevm_live(NULL, "slirp", 0, 4, &savevm_slirp_state, slirp);
+}
+
+void slirp_state_unregister(Slirp *slirp)
+{
+    unregister_savevm(NULL, "slirp", slirp);
+}
diff --git a/slirp/state.h b/slirp/state.h
new file mode 100644
index 0000000000..154866898f
--- /dev/null
+++ b/slirp/state.h
@@ -0,0 +1,9 @@
+#ifndef SLIRP_STATE_H_
+#define SLIRP_STATE_H_
+
+#include "libslirp.h"
+
+void slirp_state_register(Slirp *slirp);
+void slirp_state_unregister(Slirp *slirp);
+
+#endif /* SLIRP_STATE_H_ */
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 16/32] slirp: do not include qemu headers in libslirp.h public API header
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
                   ` (14 preceding siblings ...)
  2019-02-07 14:02 ` [Qemu-devel] [PULLv4 15/32] slirp: move QEMU state saving to a separate unit Samuel Thibault
@ 2019-02-07 14:03 ` Samuel Thibault
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 17/32] slirp: improve windows headers inclusion Samuel Thibault
                   ` (17 subsequent siblings)
  33 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Marc-André Lureau, stefanha, jan.kiszka, Samuel Thibault

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 slirp/libslirp.h | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 679a25422b..02cbec9f8b 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -1,7 +1,17 @@
 #ifndef LIBSLIRP_H
 #define LIBSLIRP_H
 
-#include "qemu-common.h"
+#include <glib.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef _WIN32
+#include <winsock2.h>
+#include <in6addr.h>
+#else
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif
 
 typedef struct Slirp Slirp;
 
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 17/32] slirp: improve windows headers inclusion
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
                   ` (15 preceding siblings ...)
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 16/32] slirp: do not include qemu headers in libslirp.h public API header Samuel Thibault
@ 2019-02-07 14:03 ` Samuel Thibault
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 18/32] slirp: add slirp own version of pstrcpy Samuel Thibault
                   ` (16 subsequent siblings)
  33 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Marc-André Lureau, stefanha, jan.kiszka, Samuel Thibault

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Our API usage requires Vista, set WIN32_LEAN_AND_MEAN to fix a number
of issues (winsock2.h include order for ex, which is better to include
first for legacy reasons).

While at it, group redundants #ifndef _WIN32 blocks.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 slirp/slirp.h | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/slirp/slirp.h b/slirp/slirp.h
index 8d9d72ca9d..5a830ddcb8 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -3,10 +3,19 @@
 
 #ifdef _WIN32
 
+/* as defined in sdkddkver.h */
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0600 /* Vista */
+#endif
+/* reduces the number of implicitly included headers */
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+
 typedef char *caddr_t;
 
-# include <windows.h>
 # include <winsock2.h>
+# include <windows.h>
 # include <ws2tcpip.h>
 # include <sys/timeb.h>
 # include <iphlpapi.h>
@@ -19,19 +28,10 @@ typedef char *caddr_t;
 
 #ifndef _WIN32
 #include <sys/uio.h>
-#endif
-
-#ifndef _WIN32
 #include <netinet/in.h>
 #include <arpa/inet.h>
-#endif
-
-#ifndef _WIN32
 #include <sys/socket.h>
-#endif
-
-#ifndef _WIN32
-# include <sys/ioctl.h>
+#include <sys/ioctl.h>
 #endif
 
 #ifdef __APPLE__
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 18/32] slirp: add slirp own version of pstrcpy
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
                   ` (16 preceding siblings ...)
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 17/32] slirp: improve windows headers inclusion Samuel Thibault
@ 2019-02-07 14:03 ` Samuel Thibault
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 19/32] slirp: remove qemu timer.h dependency Samuel Thibault
                   ` (15 subsequent siblings)
  33 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Marc-André Lureau, stefanha, jan.kiszka, Samuel Thibault

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Remove a dependency on qemu util.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 slirp/slirp.c |  4 ++--
 slirp/tftp.c  |  2 +-
 slirp/util.c  | 17 +++++++++++++++++
 slirp/util.h  |  2 ++
 4 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/slirp/slirp.c b/slirp/slirp.c
index 9ec1e4c62f..b5c4788489 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -320,8 +320,8 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
     slirp->vprefix_len = vprefix_len;
     slirp->vhost_addr6 = vhost6;
     if (vhostname) {
-        pstrcpy(slirp->client_hostname, sizeof(slirp->client_hostname),
-                vhostname);
+        slirp_pstrcpy(slirp->client_hostname, sizeof(slirp->client_hostname),
+                      vhostname);
     }
     slirp->tftp_prefix = g_strdup(tftp_path);
     slirp->bootp_filename = g_strdup(bootfile);
diff --git a/slirp/tftp.c b/slirp/tftp.c
index 6fb381ef33..f0bcc72c92 100644
--- a/slirp/tftp.c
+++ b/slirp/tftp.c
@@ -216,7 +216,7 @@ static void tftp_send_error(struct tftp_session *spt,
 
   tp->tp_op = htons(TFTP_ERROR);
   tp->x.tp_error.tp_error_code = htons(errorcode);
-  pstrcpy((char *)tp->x.tp_error.tp_msg, sizeof(tp->x.tp_error.tp_msg), msg);
+  slirp_pstrcpy((char *)tp->x.tp_error.tp_msg, sizeof(tp->x.tp_error.tp_msg), msg);
 
   m->m_len = sizeof(struct tftp_t) - (TFTP_BLOCKSIZE_MAX + 2) + 3 + strlen(msg)
              - sizeof(struct udphdr);
diff --git a/slirp/util.c b/slirp/util.c
index 59f6713c8b..84f5afdbc3 100644
--- a/slirp/util.c
+++ b/slirp/util.c
@@ -188,3 +188,20 @@ int slirp_closesocket(int fd)
     return ret;
 }
 #endif /* WIN32 */
+
+void slirp_pstrcpy(char *buf, int buf_size, const char *str)
+{
+    int c;
+    char *q = buf;
+
+    if (buf_size <= 0)
+        return;
+
+    for(;;) {
+        c = *str++;
+        if (c == 0 || q >= buf + buf_size - 1)
+            break;
+        *q++ = c;
+    }
+    *q = '\0';
+}
diff --git a/slirp/util.h b/slirp/util.h
index 4f6e80c3ed..586517bb30 100644
--- a/slirp/util.h
+++ b/slirp/util.h
@@ -91,4 +91,6 @@ static inline int slirp_socket_set_fast_reuse(int fd)
 #endif
 }
 
+void slirp_pstrcpy(char *buf, int buf_size, const char *str);
+
 #endif
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 19/32] slirp: remove qemu timer.h dependency
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
                   ` (17 preceding siblings ...)
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 18/32] slirp: add slirp own version of pstrcpy Samuel Thibault
@ 2019-02-07 14:03 ` Samuel Thibault
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 20/32] slirp: remove now useless QEMU headers inclusions Samuel Thibault
                   ` (14 subsequent siblings)
  33 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Marc-André Lureau, stefanha, jan.kiszka, Samuel Thibault

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 slirp/if.c       | 1 -
 slirp/ip6_icmp.c | 1 -
 slirp/slirp.c    | 1 -
 slirp/util.h     | 2 ++
 4 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/slirp/if.c b/slirp/if.c
index 73e3705740..90b9078687 100644
--- a/slirp/if.c
+++ b/slirp/if.c
@@ -7,7 +7,6 @@
 
 #include "qemu/osdep.h"
 #include "slirp.h"
-#include "qemu/timer.h"
 
 static void
 ifs_insque(struct mbuf *ifm, struct mbuf *ifmhead)
diff --git a/slirp/ip6_icmp.c b/slirp/ip6_icmp.c
index e72c57a81d..682597e676 100644
--- a/slirp/ip6_icmp.c
+++ b/slirp/ip6_icmp.c
@@ -6,7 +6,6 @@
 #include "qemu/osdep.h"
 #include "slirp.h"
 #include "ip6_icmp.h"
-#include "qemu/timer.h"
 #include "qemu/error-report.h"
 #include "qemu/log.h"
 
diff --git a/slirp/slirp.c b/slirp/slirp.c
index b5c4788489..7a5d97c77f 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -23,7 +23,6 @@
  */
 #include "qemu/osdep.h"
 #include "qemu-common.h"
-#include "qemu/timer.h"
 #include "qemu/error-report.h"
 #include "migration/register.h"
 #include "slirp.h"
diff --git a/slirp/util.h b/slirp/util.h
index 586517bb30..922077435e 100644
--- a/slirp/util.h
+++ b/slirp/util.h
@@ -48,6 +48,8 @@
 # define SLIRP_PACKED __attribute__((packed))
 #endif
 
+#define SCALE_MS 1000000
+
 #ifdef _WIN32
 int slirp_closesocket(int fd);
 int slirp_ioctlsocket(int fd, int req, void *val);
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 20/32] slirp: remove now useless QEMU headers inclusions
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
                   ` (18 preceding siblings ...)
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 19/32] slirp: remove qemu timer.h dependency Samuel Thibault
@ 2019-02-07 14:03 ` Samuel Thibault
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 21/32] slirp: replace net/eth.h inclusion with own defines Samuel Thibault
                   ` (13 subsequent siblings)
  33 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Marc-André Lureau, stefanha, jan.kiszka, samuel Thibault

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Some of those could have been squashed earlier, but it is easier to do
it all here.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: samuel Thibault <samuel.thibault@ens-lyon.org>
---
 slirp/dhcpv6.c   | 1 -
 slirp/ip6_icmp.c | 2 --
 slirp/misc.c     | 2 --
 slirp/sbuf.c     | 1 -
 slirp/slirp.c    | 4 ----
 slirp/slirp.h    | 1 -
 slirp/tftp.c     | 1 -
 slirp/util.h     | 2 --
 8 files changed, 14 deletions(-)

diff --git a/slirp/dhcpv6.c b/slirp/dhcpv6.c
index 752df40536..e27d9a46f8 100644
--- a/slirp/dhcpv6.c
+++ b/slirp/dhcpv6.c
@@ -21,7 +21,6 @@
  */
 
 #include "qemu/osdep.h"
-#include "qemu/log.h"
 #include "slirp.h"
 #include "dhcpv6.h"
 
diff --git a/slirp/ip6_icmp.c b/slirp/ip6_icmp.c
index 682597e676..b3b7e50a31 100644
--- a/slirp/ip6_icmp.c
+++ b/slirp/ip6_icmp.c
@@ -6,8 +6,6 @@
 #include "qemu/osdep.h"
 #include "slirp.h"
 #include "ip6_icmp.h"
-#include "qemu/error-report.h"
-#include "qemu/log.h"
 
 #define NDP_Interval g_rand_int_range(slirp->grand, \
         NDP_MinRtrAdvInterval, NDP_MaxRtrAdvInterval)
diff --git a/slirp/misc.c b/slirp/misc.c
index 4ee20a10e4..a77cc34b30 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -8,8 +8,6 @@
 #include "qemu/osdep.h"
 #include "slirp.h"
 #include "libslirp.h"
-#include "qemu/error-report.h"
-#include "qemu/main-loop.h"
 
 inline void
 insque(void *a, void *b)
diff --git a/slirp/sbuf.c b/slirp/sbuf.c
index 17f28e97a6..c83e4dd8ed 100644
--- a/slirp/sbuf.c
+++ b/slirp/sbuf.c
@@ -7,7 +7,6 @@
 
 #include "qemu/osdep.h"
 #include "slirp.h"
-#include "qemu/main-loop.h"
 
 static void sbappendsb(struct sbuf *sb, struct mbuf *m);
 
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 7a5d97c77f..ec1f606d72 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -23,11 +23,7 @@
  */
 #include "qemu/osdep.h"
 #include "qemu-common.h"
-#include "qemu/error-report.h"
-#include "migration/register.h"
 #include "slirp.h"
-#include "hw/hw.h"
-#include "qemu/cutils.h"
 
 #ifdef WITH_QEMU
 #include "state.h"
diff --git a/slirp/slirp.h b/slirp/slirp.h
index 5a830ddcb8..5707805be2 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -48,7 +48,6 @@ typedef char *caddr_t;
 #include "util.h"
 
 #include "qemu/queue.h"
-#include "qemu/sockets.h"
 #include "net/eth.h"
 
 #include "libslirp.h"
diff --git a/slirp/tftp.c b/slirp/tftp.c
index f0bcc72c92..5c31886190 100644
--- a/slirp/tftp.c
+++ b/slirp/tftp.c
@@ -25,7 +25,6 @@
 #include "qemu/osdep.h"
 #include "slirp.h"
 #include "qemu-common.h"
-#include "qemu/cutils.h"
 
 static inline int tftp_session_in_use(struct tftp_session *spt)
 {
diff --git a/slirp/util.h b/slirp/util.h
index 922077435e..4664e8159b 100644
--- a/slirp/util.h
+++ b/slirp/util.h
@@ -53,9 +53,7 @@
 #ifdef _WIN32
 int slirp_closesocket(int fd);
 int slirp_ioctlsocket(int fd, int req, void *val);
-#ifndef WITH_QEMU
 int inet_aton(const char *cp, struct in_addr *ia);
-#endif
 #define slirp_getsockopt(sockfd, level, optname, optval, optlen) \
     getsockopt(sockfd, level, optname, (void *)optval, optlen)
 #define slirp_setsockopt(sockfd, level, optname, optval, optlen)        \
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 21/32] slirp: replace net/eth.h inclusion with own defines
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
                   ` (19 preceding siblings ...)
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 20/32] slirp: remove now useless QEMU headers inclusions Samuel Thibault
@ 2019-02-07 14:03 ` Samuel Thibault
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 22/32] slirp: replace qemu qtailq with slirp own copy Samuel Thibault
                   ` (12 subsequent siblings)
  33 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Marc-André Lureau, stefanha, jan.kiszka, Samuel Thibault

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 slirp/ip6.h   |  1 -
 slirp/slirp.h |  1 -
 slirp/util.h  | 10 ++++++++++
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/slirp/ip6.h b/slirp/ip6.h
index 1e3e329ce6..4e7c366505 100644
--- a/slirp/ip6.h
+++ b/slirp/ip6.h
@@ -7,7 +7,6 @@
 #define SLIRP_IP6_H
 
 #include <glib.h>
-#include "net/eth.h"
 
 #define ALLNODES_MULTICAST  { .s6_addr = \
                             { 0xff, 0x02, 0x00, 0x00,\
diff --git a/slirp/slirp.h b/slirp/slirp.h
index 5707805be2..c9f9143801 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -48,7 +48,6 @@ typedef char *caddr_t;
 #include "util.h"
 
 #include "qemu/queue.h"
-#include "net/eth.h"
 
 #include "libslirp.h"
 #include "ip.h"
diff --git a/slirp/util.h b/slirp/util.h
index 4664e8159b..ef75804560 100644
--- a/slirp/util.h
+++ b/slirp/util.h
@@ -50,6 +50,16 @@
 
 #define SCALE_MS 1000000
 
+#define ETH_ALEN    6
+#define ETH_HLEN    14
+#define ETH_P_IP                  (0x0800)      /* Internet Protocol packet  */
+#define ETH_P_ARP                 (0x0806)      /* Address Resolution packet */
+#define ETH_P_IPV6                (0x86dd)
+#define ETH_P_VLAN                (0x8100)
+#define ETH_P_DVLAN               (0x88a8)
+#define ETH_P_NCSI                (0x88f8)
+#define ETH_P_UNKNOWN             (0xffff)
+
 #ifdef _WIN32
 int slirp_closesocket(int fd);
 int slirp_ioctlsocket(int fd, int req, void *val);
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 22/32] slirp: replace qemu qtailq with slirp own copy
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
                   ` (20 preceding siblings ...)
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 21/32] slirp: replace net/eth.h inclusion with own defines Samuel Thibault
@ 2019-02-07 14:03 ` Samuel Thibault
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 23/32] slirp: replace QEMU_BUILD_BUG_ON with G_STATIC_ASSERT Samuel Thibault
                   ` (11 subsequent siblings)
  33 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Marc-André Lureau, stefanha, jan.kiszka, Samuel Thibault

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 slirp/qtailq.h | 193 +++++++++++++++++++++++++++++++++++++++++++++++++
 slirp/slirp.h  |   3 +-
 2 files changed, 194 insertions(+), 2 deletions(-)
 create mode 100644 slirp/qtailq.h

diff --git a/slirp/qtailq.h b/slirp/qtailq.h
new file mode 100644
index 0000000000..a89b0c439a
--- /dev/null
+++ b/slirp/qtailq.h
@@ -0,0 +1,193 @@
+/*      $NetBSD: queue.h,v 1.52 2009/04/20 09:56:08 mschuett Exp $ */
+
+/*
+ * slirp version: Copy from QEMU, removed all but tail queues.
+ */
+
+/*
+ * Copyright (c) 1991, 1993
+ *      The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *      @(#)queue.h     8.5 (Berkeley) 8/20/94
+ */
+
+#ifndef QTAILQ_H
+#define QTAILQ_H
+
+/*
+ * A tail queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or
+ * after an existing element, at the head of the list, or at the end of
+ * the list. A tail queue may be traversed in either direction.
+ */
+typedef struct QTailQLink {
+    void *tql_next;
+    struct QTailQLink *tql_prev;
+} QTailQLink;
+
+/*
+ * Tail queue definitions.  The union acts as a poor man template, as if
+ * it were QTailQLink<type>.
+ */
+#define QTAILQ_HEAD(name, type)                                         \
+    union name {                                                        \
+        struct type *tqh_first;       /* first element */               \
+        QTailQLink tqh_circ;          /* link for circular backwards list */ \
+    }
+
+#define QTAILQ_HEAD_INITIALIZER(head)           \
+    { .tqh_circ = { NULL, &(head).tqh_circ } }
+
+#define QTAILQ_ENTRY(type)                                              \
+    union {                                                             \
+        struct type *tqe_next;        /* next element */                \
+        QTailQLink tqe_circ;          /* link for circular backwards list */ \
+    }
+
+#define QTAILQ_INIT(head) do {                                          \
+        (head)->tqh_first = NULL;                                       \
+        (head)->tqh_circ.tql_prev = &(head)->tqh_circ;                  \
+} while (/*CONSTCOND*/0)
+
+#define QTAILQ_INSERT_HEAD(head, elm, field) do {                       \
+        if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)        \
+            (head)->tqh_first->field.tqe_circ.tql_prev =                \
+                &(elm)->field.tqe_circ;                                 \
+        else                                                            \
+            (head)->tqh_circ.tql_prev = &(elm)->field.tqe_circ;         \
+        (head)->tqh_first = (elm);                                      \
+        (elm)->field.tqe_circ.tql_prev = &(head)->tqh_circ;             \
+} while (/*CONSTCOND*/0)
+
+#define QTAILQ_INSERT_TAIL(head, elm, field) do {                       \
+        (elm)->field.tqe_next = NULL;                                   \
+        (elm)->field.tqe_circ.tql_prev = (head)->tqh_circ.tql_prev;     \
+        (head)->tqh_circ.tql_prev->tql_next = (elm);                    \
+        (head)->tqh_circ.tql_prev = &(elm)->field.tqe_circ;             \
+} while (/*CONSTCOND*/0)
+
+#define QTAILQ_INSERT_AFTER(head, listelm, elm, field) do {             \
+        if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
+            (elm)->field.tqe_next->field.tqe_circ.tql_prev =            \
+                &(elm)->field.tqe_circ;                                 \
+        else                                                            \
+            (head)->tqh_circ.tql_prev = &(elm)->field.tqe_circ;         \
+        (listelm)->field.tqe_next = (elm);                              \
+        (elm)->field.tqe_circ.tql_prev = &(listelm)->field.tqe_circ;    \
+} while (/*CONSTCOND*/0)
+
+#define QTAILQ_INSERT_BEFORE(listelm, elm, field) do {                       \
+        (elm)->field.tqe_circ.tql_prev = (listelm)->field.tqe_circ.tql_prev; \
+        (elm)->field.tqe_next = (listelm);                                   \
+        (listelm)->field.tqe_circ.tql_prev->tql_next = (elm);                \
+        (listelm)->field.tqe_circ.tql_prev = &(elm)->field.tqe_circ;         \
+} while (/*CONSTCOND*/0)
+
+#define QTAILQ_REMOVE(head, elm, field) do {                            \
+        if (((elm)->field.tqe_next) != NULL)                            \
+            (elm)->field.tqe_next->field.tqe_circ.tql_prev =            \
+                (elm)->field.tqe_circ.tql_prev;                         \
+        else                                                            \
+            (head)->tqh_circ.tql_prev = (elm)->field.tqe_circ.tql_prev; \
+        (elm)->field.tqe_circ.tql_prev->tql_next = (elm)->field.tqe_next; \
+        (elm)->field.tqe_circ.tql_prev = NULL;                          \
+} while (/*CONSTCOND*/0)
+
+#define QTAILQ_FOREACH(var, head, field)                                \
+        for ((var) = ((head)->tqh_first);                               \
+                (var);                                                  \
+                (var) = ((var)->field.tqe_next))
+
+#define QTAILQ_FOREACH_SAFE(var, head, field, next_var)                 \
+        for ((var) = ((head)->tqh_first);                               \
+                (var) && ((next_var) = ((var)->field.tqe_next), 1);     \
+                (var) = (next_var))
+
+#define QTAILQ_FOREACH_REVERSE(var, head, field)                        \
+        for ((var) = QTAILQ_LAST(head);                                 \
+                (var);                                                  \
+                (var) = QTAILQ_PREV(var, field))
+
+#define QTAILQ_FOREACH_REVERSE_SAFE(var, head, field, prev_var)         \
+        for ((var) = QTAILQ_LAST(head);                                 \
+             (var) && ((prev_var) = QTAILQ_PREV(var, field));           \
+             (var) = (prev_var))
+
+/*
+ * Tail queue access methods.
+ */
+#define QTAILQ_EMPTY(head)               ((head)->tqh_first == NULL)
+#define QTAILQ_FIRST(head)               ((head)->tqh_first)
+#define QTAILQ_NEXT(elm, field)          ((elm)->field.tqe_next)
+#define QTAILQ_IN_USE(elm, field)        ((elm)->field.tqe_circ.tql_prev != NULL)
+
+#define QTAILQ_LINK_PREV(link)                                          \
+        ((link).tql_prev->tql_prev->tql_next)
+#define QTAILQ_LAST(head)                                               \
+        ((typeof((head)->tqh_first)) QTAILQ_LINK_PREV((head)->tqh_circ))
+#define QTAILQ_PREV(elm, field)                                         \
+        ((typeof((elm)->field.tqe_next)) QTAILQ_LINK_PREV((elm)->field.tqe_circ))
+
+#define field_at_offset(base, offset, type)                                    \
+        ((type *) (((char *) (base)) + (offset)))
+
+/*
+ * Raw access of elements of a tail queue head.  Offsets are all zero
+ * because it's a union.
+ */
+#define QTAILQ_RAW_FIRST(head)                                                 \
+        field_at_offset(head, 0, void *)
+#define QTAILQ_RAW_TQH_CIRC(head)                                              \
+        field_at_offset(head, 0, QTailQLink)
+
+/*
+ * Raw access of elements of a tail entry
+ */
+#define QTAILQ_RAW_NEXT(elm, entry)                                            \
+        field_at_offset(elm, entry, void *)
+#define QTAILQ_RAW_TQE_CIRC(elm, entry)                                        \
+        field_at_offset(elm, entry, QTailQLink)
+/*
+ * Tail queue traversal using pointer arithmetic.
+ */
+#define QTAILQ_RAW_FOREACH(elm, head, entry)                                   \
+        for ((elm) = *QTAILQ_RAW_FIRST(head);                                  \
+             (elm);                                                            \
+             (elm) = *QTAILQ_RAW_NEXT(elm, entry))
+/*
+ * Tail queue insertion using pointer arithmetic.
+ */
+#define QTAILQ_RAW_INSERT_TAIL(head, elm, entry) do {                           \
+        *QTAILQ_RAW_NEXT(elm, entry) = NULL;                                    \
+        QTAILQ_RAW_TQE_CIRC(elm, entry)->tql_prev = QTAILQ_RAW_TQH_CIRC(head)->tql_prev; \
+        QTAILQ_RAW_TQH_CIRC(head)->tql_prev->tql_next = (elm);                  \
+        QTAILQ_RAW_TQH_CIRC(head)->tql_prev = QTAILQ_RAW_TQE_CIRC(elm, entry);  \
+} while (/*CONSTCOND*/0)
+
+#endif /* QTAILQ_H */
diff --git a/slirp/slirp.h b/slirp/slirp.h
index c9f9143801..0e4d973c2a 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -46,8 +46,7 @@ typedef char *caddr_t;
 
 #include "debug.h"
 #include "util.h"
-
-#include "qemu/queue.h"
+#include "qtailq.h"
 
 #include "libslirp.h"
 #include "ip.h"
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 23/32] slirp: replace QEMU_BUILD_BUG_ON with G_STATIC_ASSERT
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
                   ` (21 preceding siblings ...)
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 22/32] slirp: replace qemu qtailq with slirp own copy Samuel Thibault
@ 2019-02-07 14:03 ` Samuel Thibault
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 24/32] slirp: Move g_spawn_async_with_fds_qemu compatibility to slirp/ Samuel Thibault
                   ` (10 subsequent siblings)
  33 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Samuel Thibault, stefanha, jan.kiszka, Marc-André Lureau,
	Richard Henderson, Stefano Garzarella, Alex Bennée

to remove another dependency on qemu.

Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
---
 slirp/ip.h       |  4 ++--
 slirp/ip6.h      |  4 ++--
 slirp/ip6_icmp.h | 10 +++++-----
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/slirp/ip.h b/slirp/ip.h
index 2baeeb9a3a..73a4d2a3d2 100644
--- a/slirp/ip.h
+++ b/slirp/ip.h
@@ -229,8 +229,8 @@ struct	ipasfrag {
 	struct ip ipf_ip;
 };
 
-QEMU_BUILD_BUG_ON(offsetof(struct ipq, frag_link) !=
-                  offsetof(struct ipasfrag, ipf_link));
+G_STATIC_ASSERT(offsetof(struct ipq, frag_link) ==
+                offsetof(struct ipasfrag, ipf_link));
 
 #define ipf_off      ipf_ip.ip_off
 #define ipf_tos      ipf_ip.ip_tos
diff --git a/slirp/ip6.h b/slirp/ip6.h
index 4e7c366505..5361bd7449 100644
--- a/slirp/ip6.h
+++ b/slirp/ip6.h
@@ -152,7 +152,7 @@ struct ip6_pseudohdr {
  * If we marked the struct as packed then we would be unable to take
  * the address of any of the fields in it.
  */
-QEMU_BUILD_BUG_ON(sizeof(struct ip6) != 40);
-QEMU_BUILD_BUG_ON(sizeof(struct ip6_pseudohdr) != 40);
+G_STATIC_ASSERT(sizeof(struct ip6) == 40);
+G_STATIC_ASSERT(sizeof(struct ip6_pseudohdr) == 40);
 
 #endif
diff --git a/slirp/ip6_icmp.h b/slirp/ip6_icmp.h
index 3f44ed2f49..e8ed753db5 100644
--- a/slirp/ip6_icmp.h
+++ b/slirp/ip6_icmp.h
@@ -50,14 +50,14 @@ struct ndp_ra {     /* Router Advertisement Message */
     uint32_t retrans_time;  /* Retrans Timer */
 };
 
-QEMU_BUILD_BUG_ON(sizeof(struct ndp_ra) != 12);
+G_STATIC_ASSERT(sizeof(struct ndp_ra) == 12);
 
 struct ndp_ns {     /* Neighbor Solicitation Message */
     uint32_t reserved;
     struct in6_addr target; /* Target Address */
 };
 
-QEMU_BUILD_BUG_ON(sizeof(struct ndp_ns) != 20);
+G_STATIC_ASSERT(sizeof(struct ndp_ns) == 20);
 
 struct ndp_na {     /* Neighbor Advertisement Message */
 #if G_BYTE_ORDER == G_BIG_ENDIAN
@@ -78,7 +78,7 @@ struct ndp_na {     /* Neighbor Advertisement Message */
     struct in6_addr target; /* Target Address */
 };
 
-QEMU_BUILD_BUG_ON(sizeof(struct ndp_na) != 20);
+G_STATIC_ASSERT(sizeof(struct ndp_na) == 20);
 
 struct ndp_redirect {
     uint32_t reserved;
@@ -86,7 +86,7 @@ struct ndp_redirect {
     struct in6_addr dest;   /* Destination Address */
 };
 
-QEMU_BUILD_BUG_ON(sizeof(struct ndp_redirect) != 36);
+G_STATIC_ASSERT(sizeof(struct ndp_redirect) == 36);
 
 /*
  * Structure of an icmpv6 header.
@@ -113,7 +113,7 @@ struct icmp6 {
 #define icmp6_redirect icmp6_body.ndp_redirect
 };
 
-QEMU_BUILD_BUG_ON(sizeof(struct icmp6) != 40);
+G_STATIC_ASSERT(sizeof(struct icmp6) == 40);
 
 #define ICMP6_MINLEN    4
 #define ICMP6_ERROR_MINLEN  8
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 24/32] slirp: Move g_spawn_async_with_fds_qemu compatibility to slirp/
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
                   ` (22 preceding siblings ...)
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 23/32] slirp: replace QEMU_BUILD_BUG_ON with G_STATIC_ASSERT Samuel Thibault
@ 2019-02-07 14:03 ` Samuel Thibault
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 25/32] slirp: replace remaining qemu headers dependency Samuel Thibault
                   ` (9 subsequent siblings)
  33 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Samuel Thibault, stefanha, jan.kiszka, Marc-André Lureau

Only slirp actually needs it, and will need it along in libslirp.

Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/glib-compat.h | 57 ---------------------------------------
 slirp/misc.c          | 62 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+), 57 deletions(-)

diff --git a/include/glib-compat.h b/include/glib-compat.h
index 8a078c5288..1291628e09 100644
--- a/include/glib-compat.h
+++ b/include/glib-compat.h
@@ -83,63 +83,6 @@ static inline gboolean g_strv_contains_qemu(const gchar *const *strv,
 }
 #define g_strv_contains(a, b) g_strv_contains_qemu(a, b)
 
-#if !GLIB_CHECK_VERSION(2, 58, 0)
-typedef struct QemuGSpawnFds {
-    GSpawnChildSetupFunc child_setup;
-    gpointer user_data;
-    gint stdin_fd;
-    gint stdout_fd;
-    gint stderr_fd;
-} QemuGSpawnFds;
-
-static inline void
-qemu_gspawn_fds_setup(gpointer user_data)
-{
-    QemuGSpawnFds *q = (QemuGSpawnFds *)user_data;
-
-    dup2(q->stdin_fd, 0);
-    dup2(q->stdout_fd, 1);
-    dup2(q->stderr_fd, 2);
-    q->child_setup(q->user_data);
-}
-#endif
-
-static inline gboolean
-g_spawn_async_with_fds_qemu(const gchar *working_directory,
-                            gchar **argv,
-                            gchar **envp,
-                            GSpawnFlags flags,
-                            GSpawnChildSetupFunc child_setup,
-                            gpointer user_data,
-                            GPid *child_pid,
-                            gint stdin_fd,
-                            gint stdout_fd,
-                            gint stderr_fd,
-                            GError **error)
-{
-#if GLIB_CHECK_VERSION(2, 58, 0)
-    return g_spawn_async_with_fds(working_directory, argv, envp, flags,
-                                  child_setup, user_data,
-                                  child_pid, stdin_fd, stdout_fd, stderr_fd,
-                                  error);
-#else
-    QemuGSpawnFds setup = {
-        .child_setup = child_setup,
-        .user_data = user_data,
-        .stdin_fd = stdin_fd,
-        .stdout_fd = stdout_fd,
-        .stderr_fd = stderr_fd,
-    };
-
-    return g_spawn_async(working_directory, argv, envp, flags,
-                         qemu_gspawn_fds_setup, &setup,
-                         child_pid, error);
-#endif
-}
-
-#define g_spawn_async_with_fds(wd, argv, env, f, c, d, p, ifd, ofd, efd, err) \
-    g_spawn_async_with_fds_qemu(wd, argv, env, f, c, d, p, ifd, ofd, efd, err)
-
 #if defined(_WIN32) && !GLIB_CHECK_VERSION(2, 50, 0)
 /*
  * g_poll has a problem on Windows when using
diff --git a/slirp/misc.c b/slirp/misc.c
index a77cc34b30..ee77aff337 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -122,6 +122,68 @@ fork_exec_child_setup(gpointer data)
 #endif
 }
 
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+
+#if !GLIB_CHECK_VERSION(2, 58, 0)
+typedef struct SlirpGSpawnFds {
+    GSpawnChildSetupFunc child_setup;
+    gpointer user_data;
+    gint stdin_fd;
+    gint stdout_fd;
+    gint stderr_fd;
+} SlirpGSpawnFds;
+
+static inline void
+slirp_gspawn_fds_setup(gpointer user_data)
+{
+    SlirpGSpawnFds *q = (SlirpGSpawnFds *)user_data;
+
+    dup2(q->stdin_fd, 0);
+    dup2(q->stdout_fd, 1);
+    dup2(q->stderr_fd, 2);
+    q->child_setup(q->user_data);
+}
+#endif
+
+static inline gboolean
+g_spawn_async_with_fds_slirp(const gchar *working_directory,
+                            gchar **argv,
+                            gchar **envp,
+                            GSpawnFlags flags,
+                            GSpawnChildSetupFunc child_setup,
+                            gpointer user_data,
+                            GPid *child_pid,
+                            gint stdin_fd,
+                            gint stdout_fd,
+                            gint stderr_fd,
+                            GError **error)
+{
+#if GLIB_CHECK_VERSION(2, 58, 0)
+    return g_spawn_async_with_fds(working_directory, argv, envp, flags,
+                                  child_setup, user_data,
+                                  child_pid, stdin_fd, stdout_fd, stderr_fd,
+                                  error);
+#else
+    SlirpGSpawnFds setup = {
+        .child_setup = child_setup,
+        .user_data = user_data,
+        .stdin_fd = stdin_fd,
+        .stdout_fd = stdout_fd,
+        .stderr_fd = stderr_fd,
+    };
+
+    return g_spawn_async(working_directory, argv, envp, flags,
+                         slirp_gspawn_fds_setup, &setup,
+                         child_pid, error);
+#endif
+}
+
+#define g_spawn_async_with_fds(wd, argv, env, f, c, d, p, ifd, ofd, efd, err) \
+    g_spawn_async_with_fds_slirp(wd, argv, env, f, c, d, p, ifd, ofd, efd, err)
+
+#pragma GCC diagnostic pop
+
 int
 fork_exec(struct socket *so, const char *ex)
 {
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 25/32] slirp: replace remaining qemu headers dependency
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
                   ` (23 preceding siblings ...)
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 24/32] slirp: Move g_spawn_async_with_fds_qemu compatibility to slirp/ Samuel Thibault
@ 2019-02-07 14:03 ` Samuel Thibault
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 26/32] slirp: prefer c99 types over BSD kind Samuel Thibault
                   ` (8 subsequent siblings)
  33 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Marc-André Lureau, stefanha, jan.kiszka, Samuel Thibault

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Except for the migration code which is gated by WITH_QEMU, only
include our own headers, so libslirp can be built standalone.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 slirp/arp_table.c  |  3 ++-
 slirp/bootp.c      |  1 -
 slirp/cksum.c      |  1 -
 slirp/dhcpv6.c     |  1 -
 slirp/dnssearch.c  |  1 -
 slirp/if.c         |  1 -
 slirp/ip6.h        |  1 +
 slirp/ip6_icmp.c   |  1 -
 slirp/ip6_input.c  |  1 -
 slirp/ip6_output.c |  2 --
 slirp/ip_icmp.c    |  1 -
 slirp/ip_input.c   |  1 -
 slirp/ip_output.c  |  1 -
 slirp/mbuf.c       |  1 -
 slirp/misc.c       |  2 --
 slirp/ncsi.c       |  1 -
 slirp/ndp_table.c  |  2 --
 slirp/sbuf.c       |  1 -
 slirp/slirp.c      |  2 --
 slirp/socket.c     |  2 --
 slirp/tcp_input.c  |  1 -
 slirp/tcp_output.c |  1 -
 slirp/tcp_subr.c   |  1 -
 slirp/tcp_timer.c  |  1 -
 slirp/tftp.c       |  6 ++++--
 slirp/udp.c        |  1 -
 slirp/udp6.c       |  2 --
 slirp/util.h       | 21 +++++++++++++++++++++
 28 files changed, 28 insertions(+), 33 deletions(-)

diff --git a/slirp/arp_table.c b/slirp/arp_table.c
index bf71b984ad..58eafdcfd8 100644
--- a/slirp/arp_table.c
+++ b/slirp/arp_table.c
@@ -22,9 +22,10 @@
  * THE SOFTWARE.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 
+#include <string.h>
+
 void arp_table_add(Slirp *slirp, uint32_t ip_addr, uint8_t ethaddr[ETH_ALEN])
 {
     const uint32_t broadcast_addr =
diff --git a/slirp/bootp.c b/slirp/bootp.c
index 4c9a77eb98..d396849a05 100644
--- a/slirp/bootp.c
+++ b/slirp/bootp.c
@@ -21,7 +21,6 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-#include "qemu/osdep.h"
 #include "slirp.h"
 
 #if defined(_WIN32)
diff --git a/slirp/cksum.c b/slirp/cksum.c
index 84c858fafb..25bfa67348 100644
--- a/slirp/cksum.c
+++ b/slirp/cksum.c
@@ -30,7 +30,6 @@
  * in_cksum.c,v 1.2 1994/08/02 07:48:16 davidg Exp
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 
 /*
diff --git a/slirp/dhcpv6.c b/slirp/dhcpv6.c
index e27d9a46f8..9ffba38e8f 100644
--- a/slirp/dhcpv6.c
+++ b/slirp/dhcpv6.c
@@ -20,7 +20,6 @@
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 #include "dhcpv6.h"
 
diff --git a/slirp/dnssearch.c b/slirp/dnssearch.c
index 8fb563321b..c459cece8d 100644
--- a/slirp/dnssearch.c
+++ b/slirp/dnssearch.c
@@ -22,7 +22,6 @@
  * THE SOFTWARE.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 
 static const uint8_t RFC3397_OPT_DOMAIN_SEARCH = 119;
diff --git a/slirp/if.c b/slirp/if.c
index 90b9078687..2ad03b8a79 100644
--- a/slirp/if.c
+++ b/slirp/if.c
@@ -5,7 +5,6 @@
  * terms and conditions of the copyright.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 
 static void
diff --git a/slirp/ip6.h b/slirp/ip6.h
index 5361bd7449..1b3364f960 100644
--- a/slirp/ip6.h
+++ b/slirp/ip6.h
@@ -7,6 +7,7 @@
 #define SLIRP_IP6_H
 
 #include <glib.h>
+#include <string.h>
 
 #define ALLNODES_MULTICAST  { .s6_addr = \
                             { 0xff, 0x02, 0x00, 0x00,\
diff --git a/slirp/ip6_icmp.c b/slirp/ip6_icmp.c
index b3b7e50a31..2a432ebbd4 100644
--- a/slirp/ip6_icmp.c
+++ b/slirp/ip6_icmp.c
@@ -3,7 +3,6 @@
  * Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 #include "ip6_icmp.h"
 
diff --git a/slirp/ip6_input.c b/slirp/ip6_input.c
index ab656a0a9d..1b8c003c66 100644
--- a/slirp/ip6_input.c
+++ b/slirp/ip6_input.c
@@ -3,7 +3,6 @@
  * Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 #include "ip6_icmp.h"
 
diff --git a/slirp/ip6_output.c b/slirp/ip6_output.c
index 52c88ad691..19d1ae7748 100644
--- a/slirp/ip6_output.c
+++ b/slirp/ip6_output.c
@@ -3,8 +3,6 @@
  * Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne.
  */
 
-#include "qemu/osdep.h"
-#include "qemu-common.h"
 #include "slirp.h"
 
 /* Number of packets queued before we start sending
diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
index 19e247f773..6b6344b776 100644
--- a/slirp/ip_icmp.c
+++ b/slirp/ip_icmp.c
@@ -30,7 +30,6 @@
  * ip_icmp.c,v 1.7 1995/05/30 08:09:42 rgrimes Exp
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 #include "ip_icmp.h"
 
diff --git a/slirp/ip_input.c b/slirp/ip_input.c
index d360620838..774ce662e6 100644
--- a/slirp/ip_input.c
+++ b/slirp/ip_input.c
@@ -38,7 +38,6 @@
  * terms and conditions of the copyright.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 #include "ip_icmp.h"
 
diff --git a/slirp/ip_output.c b/slirp/ip_output.c
index db403f04c1..f6ec141df5 100644
--- a/slirp/ip_output.c
+++ b/slirp/ip_output.c
@@ -38,7 +38,6 @@
  * terms and conditions of the copyright.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 
 /* Number of packets queued before we start sending
diff --git a/slirp/mbuf.c b/slirp/mbuf.c
index d8d275e0e7..521c02c967 100644
--- a/slirp/mbuf.c
+++ b/slirp/mbuf.c
@@ -15,7 +15,6 @@
  * the flags
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 
 #define MBUF_THRESH 30
diff --git a/slirp/misc.c b/slirp/misc.c
index ee77aff337..3c02510101 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -5,9 +5,7 @@
  * terms and conditions of the copyright.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
-#include "libslirp.h"
 
 inline void
 insque(void *a, void *b)
diff --git a/slirp/ncsi.c b/slirp/ncsi.c
index 8594382270..327f17543c 100644
--- a/slirp/ncsi.c
+++ b/slirp/ncsi.c
@@ -6,7 +6,6 @@
  * This code is licensed under the GPL version 2 or later. See the
  * COPYING file in the top-level directory.
  */
-#include "qemu/osdep.h"
 #include "slirp.h"
 
 #include "ncsi-pkt.h"
diff --git a/slirp/ndp_table.c b/slirp/ndp_table.c
index b7b73722f7..34ea4fdf1f 100644
--- a/slirp/ndp_table.c
+++ b/slirp/ndp_table.c
@@ -3,8 +3,6 @@
  * Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne.
  */
 
-#include "qemu/osdep.h"
-#include "qemu-common.h"
 #include "slirp.h"
 
 void ndp_table_add(Slirp *slirp, struct in6_addr ip_addr,
diff --git a/slirp/sbuf.c b/slirp/sbuf.c
index c83e4dd8ed..51a9f0cc7d 100644
--- a/slirp/sbuf.c
+++ b/slirp/sbuf.c
@@ -5,7 +5,6 @@
  * terms and conditions of the copyright.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 
 static void sbappendsb(struct sbuf *sb, struct mbuf *m);
diff --git a/slirp/slirp.c b/slirp/slirp.c
index ec1f606d72..730b78255c 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -21,8 +21,6 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-#include "qemu/osdep.h"
-#include "qemu-common.h"
 #include "slirp.h"
 
 #ifdef WITH_QEMU
diff --git a/slirp/socket.c b/slirp/socket.c
index 2e8dc22fb6..dea201f5ce 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -5,8 +5,6 @@
  * terms and conditions of the copyright.
  */
 
-#include "qemu/osdep.h"
-#include "qemu-common.h"
 #include "slirp.h"
 #include "ip_icmp.h"
 #ifdef __sun__
diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
index 7c1fe18fec..864da7d857 100644
--- a/slirp/tcp_input.c
+++ b/slirp/tcp_input.c
@@ -38,7 +38,6 @@
  * terms and conditions of the copyright.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 #include "ip_icmp.h"
 
diff --git a/slirp/tcp_output.c b/slirp/tcp_output.c
index 6dd1ecf5d9..2b4335eb34 100644
--- a/slirp/tcp_output.c
+++ b/slirp/tcp_output.c
@@ -38,7 +38,6 @@
  * terms and conditions of the copyright.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 
 static const u_char  tcp_outflags[TCP_NSTATES] = {
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index d8846a33b0..879a7dcd29 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -38,7 +38,6 @@
  * terms and conditions of the copyright.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 
 /* patchable/settable parameters for tcp */
diff --git a/slirp/tcp_timer.c b/slirp/tcp_timer.c
index a843e57a2b..703907eb37 100644
--- a/slirp/tcp_timer.c
+++ b/slirp/tcp_timer.c
@@ -30,7 +30,6 @@
  * tcp_timer.c,v 1.2 1994/08/02 07:49:10 davidg Exp
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 
 static struct tcpcb *tcp_timers(register struct tcpcb *tp, int timer);
diff --git a/slirp/tftp.c b/slirp/tftp.c
index 5c31886190..2d8f978786 100644
--- a/slirp/tftp.c
+++ b/slirp/tftp.c
@@ -22,9 +22,11 @@
  * THE SOFTWARE.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
-#include "qemu-common.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
 
 static inline int tftp_session_in_use(struct tftp_session *spt)
 {
diff --git a/slirp/udp.c b/slirp/udp.c
index 3915971b50..ac42be0d8e 100644
--- a/slirp/udp.c
+++ b/slirp/udp.c
@@ -38,7 +38,6 @@
  * terms and conditions of the copyright.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 #include "ip_icmp.h"
 
diff --git a/slirp/udp6.c b/slirp/udp6.c
index fa531e03c4..be5cba1f54 100644
--- a/slirp/udp6.c
+++ b/slirp/udp6.c
@@ -3,8 +3,6 @@
  * Guillaume Subiron
  */
 
-#include "qemu/osdep.h"
-#include "qemu-common.h"
 #include "slirp.h"
 #include "udp.h"
 #include "dhcpv6.h"
diff --git a/slirp/util.h b/slirp/util.h
index ef75804560..4963747aef 100644
--- a/slirp/util.h
+++ b/slirp/util.h
@@ -48,6 +48,27 @@
 # define SLIRP_PACKED __attribute__((packed))
 #endif
 
+#ifndef DIV_ROUND_UP
+#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
+#endif
+
+#ifndef container_of
+#define container_of(ptr, type, member) __extension__ ({    \
+    void *__mptr = (void *)(ptr);               \
+    ((type *)(__mptr - offsetof(type, member))); })
+#endif
+
+#if defined(_WIN32) /* CONFIG_IOVEC */
+# if !defined(IOV_MAX) /* XXX: to avoid duplicate with QEMU osdep.h */
+struct iovec {
+    void *iov_base;
+    size_t iov_len;
+};
+# endif
+#else
+#include <sys/uio.h>
+#endif
+
 #define SCALE_MS 1000000
 
 #define ETH_ALEN    6
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 26/32] slirp: prefer c99 types over BSD kind
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
                   ` (24 preceding siblings ...)
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 25/32] slirp: replace remaining qemu headers dependency Samuel Thibault
@ 2019-02-07 14:03 ` Samuel Thibault
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 27/32] slirp: improve send_packet() callback Samuel Thibault
                   ` (7 subsequent siblings)
  33 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Marc-André Lureau, stefanha, jan.kiszka, Samuel Thibault

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Replace:
- u_char -> uint8_t
- u_short -> uint16_t
- u_long -> uint32_t
- u_int -> unsigned
- caddr_t -> char *

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 slirp/ip_icmp.c    |  6 +++---
 slirp/ip_icmp.h    | 18 +++++++++---------
 slirp/ip_input.c   |  4 ++--
 slirp/main.h       |  2 +-
 slirp/mbuf.h       |  2 +-
 slirp/slirp.c      | 12 ++++++------
 slirp/slirp.h      |  8 +++-----
 slirp/socket.c     |  6 +++---
 slirp/socket.h     |  4 ++--
 slirp/tcp_input.c  | 22 +++++++++++-----------
 slirp/tcp_output.c | 12 ++++++------
 slirp/tcp_subr.c   | 18 +++++++++---------
 slirp/tcp_timer.c  |  2 +-
 slirp/tcp_var.h    | 14 +++++++-------
 slirp/udp.c        |  6 +++---
 slirp/udp.h        |  2 +-
 util/osdep.c       |  2 +-
 17 files changed, 69 insertions(+), 71 deletions(-)

diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
index 6b6344b776..7c5cb75ae5 100644
--- a/slirp/ip_icmp.c
+++ b/slirp/ip_icmp.c
@@ -240,7 +240,7 @@ end_error:
 
 #define ICMP_MAXDATALEN (IP_MSS-28)
 void
-icmp_send_error(struct mbuf *msrc, u_char type, u_char code, int minsize,
+icmp_send_error(struct mbuf *msrc, uint8_t type, uint8_t code, int minsize,
            const char *message)
 {
   unsigned hlen, shlen, s_ip_len;
@@ -388,7 +388,7 @@ icmp_reflect(struct mbuf *m)
      * Strip out original options by copying rest of first
      * mbuf's data back, and adjust the IP length.
      */
-    memmove((caddr_t)(ip + 1), (caddr_t)ip + hlen,
+    memmove((char *)(ip + 1), (char *)ip + hlen,
 	    (unsigned )(m->m_len - hlen));
     hlen -= optlen;
     ip->ip_hl = hlen >> 2;
@@ -412,7 +412,7 @@ void icmp_receive(struct socket *so)
     struct mbuf *m = so->so_m;
     struct ip *ip = mtod(m, struct ip *);
     int hlen = ip->ip_hl << 2;
-    u_char error_code;
+    uint8_t error_code;
     struct icmp *icp;
     int id, len;
 
diff --git a/slirp/ip_icmp.h b/slirp/ip_icmp.h
index d88ab34c1b..a4e5b8b265 100644
--- a/slirp/ip_icmp.h
+++ b/slirp/ip_icmp.h
@@ -44,22 +44,22 @@ typedef uint32_t n_time;
  * Structure of an icmp header.
  */
 struct icmp {
-	u_char	icmp_type;		/* type of message, see below */
-	u_char	icmp_code;		/* type sub code */
-	u_short	icmp_cksum;		/* ones complement cksum of struct */
+	uint8_t	icmp_type;		/* type of message, see below */
+	uint8_t	icmp_code;		/* type sub code */
+	uint16_t	icmp_cksum;		/* ones complement cksum of struct */
 	union {
-		u_char ih_pptr;			/* ICMP_PARAMPROB */
+		uint8_t ih_pptr;			/* ICMP_PARAMPROB */
 		struct in_addr ih_gwaddr;	/* ICMP_REDIRECT */
 		struct ih_idseq {
-			u_short	icd_id;
-			u_short	icd_seq;
+			uint16_t	icd_id;
+			uint16_t	icd_seq;
 		} ih_idseq;
 		int ih_void;
 
 		/* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */
 		struct ih_pmtu {
-			u_short ipm_void;
-			u_short ipm_nextmtu;
+			uint16_t ipm_void;
+			uint16_t ipm_nextmtu;
 		} ih_pmtu;
 	} icmp_hun;
 #define	icmp_pptr	icmp_hun.ih_pptr
@@ -156,7 +156,7 @@ struct icmp {
 void icmp_init(Slirp *slirp);
 void icmp_cleanup(Slirp *slirp);
 void icmp_input(struct mbuf *, int);
-void icmp_send_error(struct mbuf *msrc, u_char type, u_char code, int minsize,
+void icmp_send_error(struct mbuf *msrc, uint8_t type, uint8_t code, int minsize,
                      const char *message);
 void icmp_reflect(struct mbuf *);
 void icmp_receive(struct socket *so);
diff --git a/slirp/ip_input.c b/slirp/ip_input.c
index 774ce662e6..e0b94b0e42 100644
--- a/slirp/ip_input.c
+++ b/slirp/ip_input.c
@@ -458,11 +458,11 @@ ip_stripoptions(register struct mbuf *m, struct mbuf *mopt)
 {
 	register int i;
 	struct ip *ip = mtod(m, struct ip *);
-	register caddr_t opts;
+	register char *opts;
 	int olen;
 
 	olen = (ip->ip_hl<<2) - sizeof (struct ip);
-	opts = (caddr_t)(ip + 1);
+	opts = (char *)(ip + 1);
 	i = m->m_len - (sizeof (struct ip) + olen);
 	memcpy(opts, opts  + olen, (unsigned)i);
 	m->m_len -= olen;
diff --git a/slirp/main.h b/slirp/main.h
index 4bc05fb904..f11d4572b7 100644
--- a/slirp/main.h
+++ b/slirp/main.h
@@ -8,7 +8,7 @@
 #ifndef SLIRP_MAIN_H
 #define SLIRP_MAIN_H
 
-extern u_int curtime;
+extern unsigned curtime;
 extern struct in_addr loopback_addr;
 extern unsigned long loopback_mask;
 
diff --git a/slirp/mbuf.h b/slirp/mbuf.h
index cbf17e136b..e2d443418a 100644
--- a/slirp/mbuf.h
+++ b/slirp/mbuf.h
@@ -85,7 +85,7 @@ struct mbuf {
 	int	m_size;			/* Size of mbuf, from m_dat or m_ext */
 	struct	socket *m_so;
 
-	caddr_t	m_data;			/* Current location of data */
+	char *m_data;			/* Current location of data */
 	int	m_len;			/* Amount of data in this mbuf, from m_data */
 
 	Slirp *slirp;
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 730b78255c..3304c83001 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -46,7 +46,7 @@ static const uint8_t special_ethaddr[ETH_ALEN] = {
     0x52, 0x55, 0x00, 0x00, 0x00, 0x00
 };
 
-u_int curtime;
+unsigned curtime;
 
 static QTAILQ_HEAD(, Slirp) slirp_instances =
     QTAILQ_HEAD_INITIALIZER(slirp_instances);
@@ -55,9 +55,9 @@ static struct in_addr dns_addr;
 #ifndef _WIN32
 static struct in6_addr dns6_addr;
 #endif
-static u_int dns_addr_time;
+static unsigned dns_addr_time;
 #ifndef _WIN32
-static u_int dns6_addr_time;
+static unsigned dns6_addr_time;
 #endif
 
 #define TIMEOUT_FAST 2  /* milliseconds */
@@ -92,7 +92,7 @@ int get_dns_addr(struct in_addr *pdns_addr)
     }
 
     if ((ret = GetNetworkParams(FixedInfo, &BufLen)) != ERROR_SUCCESS) {
-        printf("GetNetworkParams failed. ret = %08x\n", (u_int)ret );
+        printf("GetNetworkParams failed. ret = %08x\n", (unsigned)ret );
         if (FixedInfo) {
             GlobalFree(FixedInfo);
             FixedInfo = NULL;
@@ -126,7 +126,7 @@ static void winsock_cleanup(void)
 
 static int get_dns_addr_cached(void *pdns_addr, void *cached_addr,
                                socklen_t addrlen,
-                               struct stat *cached_stat, u_int *cached_time)
+                               struct stat *cached_stat, unsigned *cached_time)
 {
     struct stat old_stat;
     if (curtime - *cached_time < TIMEOUT_DEFAULT) {
@@ -149,7 +149,7 @@ static int get_dns_addr_cached(void *pdns_addr, void *cached_addr,
 
 static int get_dns_addr_resolv_conf(int af, void *pdns_addr, void *cached_addr,
                                     socklen_t addrlen, uint32_t *scope_id,
-                                    u_int *cached_time)
+                                    unsigned *cached_time)
 {
     char buff[512];
     char buff2[257];
diff --git a/slirp/slirp.h b/slirp/slirp.h
index 0e4d973c2a..05b8364c07 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -12,8 +12,6 @@
 #define WIN32_LEAN_AND_MEAN
 #endif
 
-typedef char *caddr_t;
-
 # include <winsock2.h>
 # include <windows.h>
 # include <ws2tcpip.h>
@@ -124,8 +122,8 @@ bool ndp_table_search(Slirp *slirp, struct in6_addr ip_addr,
 
 struct Slirp {
     QTAILQ_ENTRY(Slirp) entry;
-    u_int time_fasttimo;
-    u_int last_slowtimo;
+    unsigned time_fasttimo;
+    unsigned last_slowtimo;
     bool do_slowtimo;
 
     bool in_enabled, in6_enabled;
@@ -245,7 +243,7 @@ int ip6_output(struct socket *, struct mbuf *, int fast);
 
 /* tcp_input.c */
 void tcp_input(register struct mbuf *, int, struct socket *, unsigned short af);
-int tcp_mss(register struct tcpcb *, u_int);
+int tcp_mss(register struct tcpcb *, unsigned);
 
 /* tcp_output.c */
 int tcp_output(register struct tcpcb *);
diff --git a/slirp/socket.c b/slirp/socket.c
index dea201f5ce..c896fa6da3 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -506,7 +506,7 @@ sorecvfrom(struct socket *so)
 	  /* XXX Check if reply is "correct"? */
 
 	  if(len == -1 || len == 0) {
-	    u_char code=ICMP_UNREACH_PORT;
+	    uint8_t code=ICMP_UNREACH_PORT;
 
 	    if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
 	    else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET;
@@ -676,8 +676,8 @@ sosendto(struct socket *so, struct mbuf *m)
  * Listen for incoming TCP connections
  */
 struct socket *
-tcp_listen(Slirp *slirp, uint32_t haddr, u_int hport, uint32_t laddr,
-           u_int lport, int flags)
+tcp_listen(Slirp *slirp, uint32_t haddr, unsigned hport, uint32_t laddr,
+           unsigned lport, int flags)
 {
 	struct sockaddr_in addr;
 	struct socket *so;
diff --git a/slirp/socket.h b/slirp/socket.h
index 1c1c8b5871..e4d12cd591 100644
--- a/slirp/socket.h
+++ b/slirp/socket.h
@@ -61,7 +61,7 @@ struct socket {
   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 */
+  unsigned	so_expire;		/* When the socket will expire */
 
   int	so_queued;		/* Number of packets queued from this socket */
   int	so_nqueued;		/* Number of packets queued in a row
@@ -144,7 +144,7 @@ int sosendoob(struct socket *);
 int sowrite(struct socket *);
 void sorecvfrom(struct socket *);
 int sosendto(struct socket *, struct mbuf *);
-struct socket * tcp_listen(Slirp *, uint32_t, u_int, uint32_t, u_int,
+struct socket * tcp_listen(Slirp *, uint32_t, unsigned, uint32_t, unsigned,
                                int);
 void soisfconnecting(register struct socket *);
 void soisfconnected(register struct socket *);
diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
index 864da7d857..6749b32f5d 100644
--- a/slirp/tcp_input.c
+++ b/slirp/tcp_input.c
@@ -76,7 +76,7 @@
 	} \
 }
 
-static void tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt,
+static void tcp_dooptions(struct tcpcb *tp, uint8_t *cp, int cnt,
                           struct tcpiphdr *ti);
 static void tcp_xmit_timer(register struct tcpcb *tp, int rtt);
 
@@ -197,7 +197,7 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso, unsigned short af)
 	struct ip save_ip, *ip;
 	struct ip6 save_ip6, *ip6;
 	register struct tcpiphdr *ti;
-	caddr_t optp = NULL;
+	char *optp = NULL;
 	int optlen = 0;
 	int len, tlen, off;
         register struct tcpcb *tp = NULL;
@@ -205,7 +205,7 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso, unsigned short af)
         struct socket *so = NULL;
 	int todrop, acked, ourfinisacked, needoutput = 0;
 	int iss = 0;
-	u_long tiwin;
+	uint32_t tiwin;
 	int ret;
 	struct sockaddr_storage lhost, fhost;
 	struct sockaddr_in *lhost4, *fhost4;
@@ -327,7 +327,7 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso, unsigned short af)
 	ti->ti_len = tlen;
 	if (off > sizeof (struct tcphdr)) {
 	  optlen = off - sizeof (struct tcphdr);
-	  optp = mtod(m, caddr_t) + sizeof (struct tcpiphdr);
+	  optp = mtod(m, char *) + sizeof (struct tcpiphdr);
 	}
 	tiflags = ti->ti_flags;
 
@@ -469,7 +469,7 @@ findso:
 	 * else do it below (after getting remote address).
 	 */
 	if (optp && tp->t_state != TCPS_LISTEN)
-		tcp_dooptions(tp, (u_char *)optp, optlen, ti);
+		tcp_dooptions(tp, (uint8_t *)optp, optlen, ti);
 
 	/*
 	 * Header prediction: check for the two common cases
@@ -724,7 +724,7 @@ findso:
 	  tcp_template(tp);
 
 	  if (optp)
-	    tcp_dooptions(tp, (u_char *)optp, optlen, ti);
+	    tcp_dooptions(tp, (uint8_t *)optp, optlen, ti);
 
 	  if (iss)
 	    tp->iss = iss;
@@ -1039,7 +1039,7 @@ trimthenstep6:
 					tp->t_dupacks = 0;
 				else if (++tp->t_dupacks == TCPREXMTTHRESH) {
 					tcp_seq onxt = tp->snd_nxt;
-					u_int win =
+					unsigned win =
                                                 MIN(tp->snd_wnd, tp->snd_cwnd) /
                                                 2 / tp->t_maxseg;
 
@@ -1108,8 +1108,8 @@ trimthenstep6:
 		 * (maxseg^2 / cwnd per packet).
 		 */
 		{
-		  register u_int cw = tp->snd_cwnd;
-		  register u_int incr = tp->t_maxseg;
+		  register unsigned cw = tp->snd_cwnd;
+		  register unsigned incr = tp->t_maxseg;
 
 		  if (cw > tp->snd_ssthresh)
 		    incr = incr * incr / cw;
@@ -1381,7 +1381,7 @@ drop:
 }
 
 static void
-tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt, struct tcpiphdr *ti)
+tcp_dooptions(struct tcpcb *tp, uint8_t *cp, int cnt, struct tcpiphdr *ti)
 {
 	uint16_t mss;
 	int opt, optlen;
@@ -1511,7 +1511,7 @@ tcp_xmit_timer(register struct tcpcb *tp, int rtt)
  */
 
 int
-tcp_mss(struct tcpcb *tp, u_int offer)
+tcp_mss(struct tcpcb *tp, unsigned offer)
 {
 	struct socket *so = tp->t_socket;
 	int mss;
diff --git a/slirp/tcp_output.c b/slirp/tcp_output.c
index 2b4335eb34..e9674df121 100644
--- a/slirp/tcp_output.c
+++ b/slirp/tcp_output.c
@@ -40,7 +40,7 @@
 
 #include "slirp.h"
 
-static const u_char  tcp_outflags[TCP_NSTATES] = {
+static const uint8_t  tcp_outflags[TCP_NSTATES] = {
 	TH_RST|TH_ACK, 0,      TH_SYN,        TH_SYN|TH_ACK,
 	TH_ACK,        TH_ACK, TH_FIN|TH_ACK, TH_FIN|TH_ACK,
 	TH_FIN|TH_ACK, TH_ACK, TH_ACK,
@@ -63,7 +63,7 @@ tcp_output(struct tcpcb *tp)
 	register struct tcpiphdr *ti, tcpiph_save;
 	struct ip *ip;
 	struct ip6 *ip6;
-	u_char opt[MAX_TCPOPTLEN];
+	uint8_t opt[MAX_TCPOPTLEN];
 	unsigned optlen, hdrlen;
 	int idle, sendalot;
 
@@ -271,7 +271,7 @@ send:
 			opt[0] = TCPOPT_MAXSEG;
 			opt[1] = 4;
 			mss = htons((uint16_t) tcp_mss(tp, 0));
-			memcpy((caddr_t)(opt + 2), (caddr_t)&mss, sizeof(mss));
+			memcpy((char *)(opt + 2), (char *)&mss, sizeof(mss));
 			optlen = 4;
 		}
 	}
@@ -301,7 +301,7 @@ send:
 		m->m_data += IF_MAXLINKHDR;
 		m->m_len = hdrlen;
 
-		sbcopy(&so->so_snd, off, (int) len, mtod(m, caddr_t) + hdrlen);
+		sbcopy(&so->so_snd, off, (int) len, mtod(m, char *) + hdrlen);
 		m->m_len += len;
 
 		/*
@@ -324,7 +324,7 @@ send:
 
 	ti = mtod(m, struct tcpiphdr *);
 
-	memcpy((caddr_t)ti, &tp->t_template, sizeof (struct tcpiphdr));
+	memcpy((char *)ti, &tp->t_template, sizeof (struct tcpiphdr));
 
 	/*
 	 * Fill in fields, remembering maximum advertised
@@ -353,7 +353,7 @@ send:
 		ti->ti_seq = htonl(tp->snd_max);
 	ti->ti_ack = htonl(tp->rcv_nxt);
 	if (optlen) {
-		memcpy((caddr_t)(ti + 1), (caddr_t)opt, optlen);
+		memcpy((char *)(ti + 1), (char *)opt, optlen);
 		ti->ti_off = (sizeof (struct tcphdr) + optlen) >> 2;
 	}
 	ti->ti_flags = flags;
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index 879a7dcd29..e35628a892 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -163,7 +163,7 @@ tcp_respond(struct tcpcb *tp, struct tcpiphdr *ti, struct mbuf *m,
 		 * ti points into m so the next line is just making
 		 * the mbuf point to ti
 		 */
-		m->m_data = (caddr_t)ti;
+		m->m_data = (char *)ti;
 
 		m->m_len = sizeof (struct tcpiphdr);
 		tlen = 0;
@@ -182,7 +182,7 @@ tcp_respond(struct tcpcb *tp, struct tcpiphdr *ti, struct mbuf *m,
 		}
 #undef xchg
 	}
-	ti->ti_len = htons((u_short)(sizeof (struct tcphdr) + tlen));
+	ti->ti_len = htons((uint16_t)(sizeof (struct tcphdr) + tlen));
 	tlen += sizeof (struct tcpiphdr);
 	m->m_len = tlen;
 
@@ -613,10 +613,10 @@ int
 tcp_emu(struct socket *so, struct mbuf *m)
 {
 	Slirp *slirp = so->slirp;
-	u_int n1, n2, n3, n4, n5, n6;
+	unsigned n1, n2, n3, n4, n5, n6;
         char buff[257];
 	uint32_t laddr;
-	u_int lport;
+	unsigned lport;
 	char *bptr;
 
 	DEBUG_CALL("tcp_emu");
@@ -853,7 +853,7 @@ tcp_emu(struct socket *so, struct mbuf *m)
 
 		bptr = m->m_data;
 		while (bptr < m->m_data + m->m_len) {
-			u_short p;
+			uint16_t p;
 			static int ra = 0;
 			char ra_tbl[4];
 
@@ -909,8 +909,8 @@ tcp_emu(struct socket *so, struct mbuf *m)
 				/* This is the field containing the port
 				 * number that RA-player is listening to.
 				 */
-				lport = (((u_char*)bptr)[0] << 8)
-				+ ((u_char *)bptr)[1];
+				lport = (((uint8_t*)bptr)[0] << 8)
+				+ ((uint8_t *)bptr)[1];
 				if (lport < 6970)
 				   lport += 256;   /* don't know why */
 				if (lport < 6970 || lport > 7170)
@@ -928,8 +928,8 @@ tcp_emu(struct socket *so, struct mbuf *m)
 				}
 				if (p == 7071)
 				   p = 0;
-				*(u_char *)bptr++ = (p >> 8) & 0xff;
-                                *(u_char *)bptr = p & 0xff;
+				*(uint8_t *)bptr++ = (p >> 8) & 0xff;
+                                *(uint8_t *)bptr = p & 0xff;
 				ra = 0;
 				return 1;   /* port redirected, we're done */
 				break;
diff --git a/slirp/tcp_timer.c b/slirp/tcp_timer.c
index 703907eb37..7be54570af 100644
--- a/slirp/tcp_timer.c
+++ b/slirp/tcp_timer.c
@@ -232,7 +232,7 @@ tcp_timers(register struct tcpcb *tp, int timer)
 		 * to go below this.)
 		 */
 		{
-                u_int win = MIN(tp->snd_wnd, tp->snd_cwnd) / 2 / tp->t_maxseg;
+                unsigned win = MIN(tp->snd_wnd, tp->snd_cwnd) / 2 / tp->t_maxseg;
 		if (win < 2)
 			win = 2;
 		tp->snd_cwnd = tp->t_maxseg;
diff --git a/slirp/tcp_var.h b/slirp/tcp_var.h
index 895ef6df1e..27ef1a51cb 100644
--- a/slirp/tcp_var.h
+++ b/slirp/tcp_var.h
@@ -47,9 +47,9 @@ struct tcpcb {
 	short	t_rxtshift;		/* log(2) of rexmt exp. backoff */
 	short	t_rxtcur;		/* current retransmit value */
 	short	t_dupacks;		/* consecutive dup acks recd */
-	u_short	t_maxseg;		/* maximum segment size */
+	uint16_t	t_maxseg;		/* maximum segment size */
 	uint8_t t_force;		/* 1 if forcing out a byte */
-	u_short	t_flags;
+	uint16_t	t_flags;
 #define	TF_ACKNOW	0x0001		/* ack peer immediately */
 #define	TF_DELACK	0x0002		/* ack, but try to delay it */
 #define	TF_NODELAY	0x0004		/* don't delay packets to coalesce */
@@ -105,7 +105,7 @@ struct tcpcb {
 	tcp_seq	t_rtseq;		/* sequence number being timed */
 	short	t_srtt;			/* smoothed round-trip time */
 	short	t_rttvar;		/* variance in round-trip time */
-	u_short	t_rttmin;		/* minimum rtt allowed */
+	uint16_t	t_rttmin;		/* minimum rtt allowed */
 	uint32_t max_sndwnd;		/* largest window peer has offered */
 
 /* out-of-band data */
@@ -116,10 +116,10 @@ struct tcpcb {
 	short	t_softerror;		/* possible error not yet reported */
 
 /* RFC 1323 variables */
-	u_char	snd_scale;		/* window scaling for send window */
-	u_char	rcv_scale;		/* window scaling for recv window */
-	u_char	request_r_scale;	/* pending window scaling */
-	u_char	requested_s_scale;
+	uint8_t	snd_scale;		/* window scaling for send window */
+	uint8_t	rcv_scale;		/* window scaling for recv window */
+	uint8_t	request_r_scale;	/* pending window scaling */
+	uint8_t	requested_s_scale;
 	uint32_t	ts_recent;		/* timestamp echo data */
 	uint32_t	ts_recent_age;		/* when last updated */
 	tcp_seq	last_ack_sent;
diff --git a/slirp/udp.c b/slirp/udp.c
index ac42be0d8e..5baa604b33 100644
--- a/slirp/udp.c
+++ b/slirp/udp.c
@@ -92,7 +92,7 @@ udp_input(register struct mbuf *m, int iphlen)
 	 * Get IP and UDP header together in first mbuf.
 	 */
 	ip = mtod(m, struct ip *);
-	uh = (struct udphdr *)((caddr_t)ip + iphlen);
+	uh = (struct udphdr *)((char *)ip + iphlen);
 
 	/*
 	 * Make mbuf data length reflect UDP length.
@@ -319,8 +319,8 @@ udp_tos(struct socket *so)
 }
 
 struct socket *
-udp_listen(Slirp *slirp, uint32_t haddr, u_int hport, uint32_t laddr,
-           u_int lport, int flags)
+udp_listen(Slirp *slirp, uint32_t haddr, unsigned hport, uint32_t laddr,
+           unsigned lport, int flags)
 {
 	struct sockaddr_in addr;
 	struct socket *so;
diff --git a/slirp/udp.h b/slirp/udp.h
index be657cf922..3d29504caa 100644
--- a/slirp/udp.h
+++ b/slirp/udp.h
@@ -78,7 +78,7 @@ void udp_cleanup(Slirp *);
 void udp_input(register struct mbuf *, int);
 int udp_attach(struct socket *, unsigned short af);
 void udp_detach(struct socket *);
-struct socket * udp_listen(Slirp *, uint32_t, u_int, uint32_t, u_int,
+struct socket * udp_listen(Slirp *, uint32_t, unsigned, uint32_t, unsigned,
                            int);
 int udp_output(struct socket *so, struct mbuf *m,
                 struct sockaddr_in *saddr, struct sockaddr_in *daddr,
diff --git a/util/osdep.c b/util/osdep.c
index 4b5dc7287d..3f04326040 100644
--- a/util/osdep.c
+++ b/util/osdep.c
@@ -29,7 +29,7 @@
 #include <sys/statvfs.h>
 /* See MySQL bug #7156 (http://bugs.mysql.com/bug.php?id=7156) for
    discussion about Solaris header problems */
-extern int madvise(caddr_t, size_t, int);
+extern int madvise(char *, size_t, int);
 #endif
 
 #include "qemu-common.h"
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 27/32] slirp: improve send_packet() callback
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
                   ` (25 preceding siblings ...)
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 26/32] slirp: prefer c99 types over BSD kind Samuel Thibault
@ 2019-02-07 14:03 ` Samuel Thibault
  2019-02-07 18:31   ` Philippe Mathieu-Daudé
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 28/32] slirp: replace global polling with per-instance & notifier Samuel Thibault
                   ` (6 subsequent siblings)
  33 siblings, 1 reply; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Marc-André Lureau, stefanha, jan.kiszka, Samuel Thibault

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Use a more descriptive name for the callback.

Reuse the SlirpWriteCb type. Wrap it to check that all data has been written.

Return a ssize_t for potential error handling and data-loss reporting.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 include/net/net.h |  2 +-
 net/net.c         |  4 ++--
 net/slirp.c       |  9 +++++----
 slirp/libslirp.h  | 11 +++++++----
 slirp/ncsi.c      |  2 +-
 slirp/slirp.c     | 18 +++++++++++++++---
 slirp/slirp.h     |  2 ++
 7 files changed, 33 insertions(+), 15 deletions(-)

diff --git a/include/net/net.h b/include/net/net.h
index 643295d163..075cc01267 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -146,7 +146,7 @@ ssize_t qemu_sendv_packet(NetClientState *nc, const struct iovec *iov,
                           int iovcnt);
 ssize_t qemu_sendv_packet_async(NetClientState *nc, const struct iovec *iov,
                                 int iovcnt, NetPacketSent *sent_cb);
-void qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size);
+ssize_t qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size);
 ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int size);
 ssize_t qemu_send_packet_async(NetClientState *nc, const uint8_t *buf,
                                int size, NetPacketSent *sent_cb);
diff --git a/net/net.c b/net/net.c
index 3acbdccd61..5dcff7fe2a 100644
--- a/net/net.c
+++ b/net/net.c
@@ -668,9 +668,9 @@ ssize_t qemu_send_packet_async(NetClientState *sender,
                                              buf, size, sent_cb);
 }
 
-void qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size)
+ssize_t qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size)
 {
-    qemu_send_packet_async(nc, buf, size, NULL);
+    return qemu_send_packet_async(nc, buf, size, NULL);
 }
 
 ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int size)
diff --git a/net/slirp.c b/net/slirp.c
index 7b4f9f5c5e..664ff1c002 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -108,11 +108,12 @@ static void slirp_smb_cleanup(SlirpState *s);
 static inline void slirp_smb_cleanup(SlirpState *s) { }
 #endif
 
-static void net_slirp_output(void *opaque, const uint8_t *pkt, int pkt_len)
+static ssize_t net_slirp_send_packet(const void *pkt, size_t pkt_len,
+                                     void *opaque)
 {
     SlirpState *s = opaque;
 
-    qemu_send_packet(&s->nc, pkt, pkt_len);
+    return qemu_send_packet(&s->nc, pkt, pkt_len);
 }
 
 static ssize_t net_slirp_receive(NetClientState *nc, const uint8_t *buf, size_t size)
@@ -197,7 +198,7 @@ static void net_slirp_unregister_poll_fd(int fd)
 }
 
 static const SlirpCb slirp_cb = {
-    .output = net_slirp_output,
+    .send_packet = net_slirp_send_packet,
     .guest_error = net_slirp_guest_error,
     .clock_get_ns = net_slirp_clock_get_ns,
     .timer_new = net_slirp_timer_new,
@@ -780,7 +781,7 @@ static void guestfwd_read(void *opaque, const uint8_t *buf, int size)
     slirp_socket_recv(fwd->slirp, fwd->server, fwd->port, buf, size);
 }
 
-static int guestfwd_write(const void *buf, size_t len, void *chr)
+static ssize_t guestfwd_write(const void *buf, size_t len, void *chr)
 {
     return qemu_chr_fe_write_all(chr, buf, len);
 }
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 02cbec9f8b..8e5d4ed11b 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -15,7 +15,7 @@
 
 typedef struct Slirp Slirp;
 
-typedef int (*SlirpWriteCb)(const void *buf, size_t len, void *opaque);
+typedef ssize_t (*SlirpWriteCb)(const void *buf, size_t len, void *opaque);
 typedef void (*SlirpTimerCb)(void *opaque);
 
 /*
@@ -23,10 +23,13 @@ typedef void (*SlirpTimerCb)(void *opaque);
  */
 typedef struct SlirpCb {
     /*
-     * Send an ethernet frame to the guest network. The opaque parameter
-     * is the one given to slirp_init().
+     * Send an ethernet frame to the guest network. The opaque
+     * parameter is the one given to slirp_init(). The function
+     * doesn't need to send all the data and may return <len (no
+     * buffering is done on libslirp side, so the data will be dropped
+     * in this case). <0 reports an IO error.
      */
-    void (*output)(void *opaque, const uint8_t *pkt, int pkt_len);
+    SlirpWriteCb send_packet;
     /* Print a message for an error due to guest misbehavior.  */
     void (*guest_error)(const char *msg);
     /* Return the virtual clock value in nanoseconds */
diff --git a/slirp/ncsi.c b/slirp/ncsi.c
index 327f17543c..359f52c284 100644
--- a/slirp/ncsi.c
+++ b/slirp/ncsi.c
@@ -162,5 +162,5 @@ void ncsi_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
     *pchecksum = htonl(checksum);
     ncsi_rsp_len += 4;
 
-    slirp->cb->output(slirp->opaque, ncsi_reply, ETH_HLEN + ncsi_rsp_len);
+    slirp_send_packet_all(slirp, ncsi_reply, ETH_HLEN + ncsi_rsp_len);
 }
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 3304c83001..2bc53e3e12 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -800,7 +800,7 @@ static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
             rah->ar_sip = ah->ar_tip;
             memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
             rah->ar_tip = ah->ar_sip;
-            slirp->cb->output(slirp->opaque, arp_reply, sizeof(arp_reply));
+            slirp_send_packet_all(slirp, arp_reply, sizeof(arp_reply));
         }
         break;
     case ARPOP_REPLY:
@@ -900,7 +900,7 @@ static int if_encap4(Slirp *slirp, struct mbuf *ifm, struct ethhdr *eh,
             /* target IP */
             rah->ar_tip = iph->ip_dst.s_addr;
             slirp->client_ipaddr = iph->ip_dst;
-            slirp->cb->output(slirp->opaque, arp_req, sizeof(arp_req));
+            slirp_send_packet_all(slirp, arp_req, sizeof(arp_req));
             ifm->resolution_requested = true;
 
             /* Expire request and drop outgoing packet after 1 second */
@@ -985,7 +985,7 @@ int if_encap(Slirp *slirp, struct mbuf *ifm)
               eh->h_dest[0], eh->h_dest[1], eh->h_dest[2],
               eh->h_dest[3], eh->h_dest[4], eh->h_dest[5]);
     memcpy(buf + sizeof(struct ethhdr), ifm->m_data, ifm->m_len);
-    slirp->cb->output(slirp->opaque, buf, ifm->m_len + ETH_HLEN);
+    slirp_send_packet_all(slirp, buf, ifm->m_len + ETH_HLEN);
     return 1;
 }
 
@@ -1152,3 +1152,15 @@ void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr, int guest_port,
     if (ret > 0)
         tcp_output(sototcpcb(so));
 }
+
+void slirp_send_packet_all(Slirp *slirp, const void *buf, size_t len)
+{
+    ssize_t ret = slirp->cb->send_packet(buf, len, slirp->opaque);
+
+    if (ret < 0) {
+        g_critical("Failed to send packet, ret: %ld", (long) ret);
+    } else if (ret < len) {
+        DEBUG_ERROR("send_packet() didn't send all data: %ld < %lu",
+                (long) ret, (unsigned long) len);
+    }
+}
diff --git a/slirp/slirp.h b/slirp/slirp.h
index 05b8364c07..752a4cd8c8 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -269,4 +269,6 @@ struct tcpcb *tcp_drop(struct tcpcb *tp, int err);
 struct socket *
 slirp_find_ctl_socket(Slirp *slirp, struct in_addr guest_addr, int guest_port);
 
+void slirp_send_packet_all(Slirp *slirp, const void *buf, size_t len);
+
 #endif
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 28/32] slirp: replace global polling with per-instance & notifier
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
                   ` (26 preceding siblings ...)
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 27/32] slirp: improve send_packet() callback Samuel Thibault
@ 2019-02-07 14:03 ` Samuel Thibault
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 29/32] slirp: remove slirp_instances list Samuel Thibault
                   ` (5 subsequent siblings)
  33 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Marc-André Lureau, stefanha, jan.kiszka, Samuel Thibault

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Remove hard-coded dependency on slirp in main-loop, and use a "poll"
notifier instead. The notifier is registered per slirp instance.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 include/qemu/main-loop.h |  15 ++
 net/slirp.c              |  24 ++
 slirp/libslirp.h         |   4 +-
 slirp/slirp.c            | 555 +++++++++++++++++++--------------------
 stubs/Makefile.objs      |   1 -
 stubs/slirp.c            |  13 -
 util/main-loop.c         |  30 ++-
 7 files changed, 333 insertions(+), 309 deletions(-)
 delete mode 100644 stubs/slirp.c

diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h
index e59f9ae1e9..f6ba78ea73 100644
--- a/include/qemu/main-loop.h
+++ b/include/qemu/main-loop.h
@@ -302,4 +302,19 @@ void qemu_fd_register(int fd);
 QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque);
 void qemu_bh_schedule_idle(QEMUBH *bh);
 
+enum {
+    MAIN_LOOP_POLL_FILL,
+    MAIN_LOOP_POLL_ERR,
+    MAIN_LOOP_POLL_OK,
+};
+
+typedef struct MainLoopPoll {
+    int state;
+    uint32_t timeout;
+    GArray *pollfds;
+} MainLoopPoll;
+
+void main_loop_poll_add_notifier(Notifier *notify);
+void main_loop_poll_remove_notifier(Notifier *notify);
+
 #endif
diff --git a/net/slirp.c b/net/slirp.c
index 664ff1c002..4d55f64168 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -86,6 +86,7 @@ typedef struct SlirpState {
     NetClientState nc;
     QTAILQ_ENTRY(SlirpState) entry;
     Slirp *slirp;
+    Notifier poll_notifier;
     Notifier exit_notifier;
 #ifndef _WIN32
     gchar *smb_dir;
@@ -144,6 +145,7 @@ static void net_slirp_cleanup(NetClientState *nc)
     SlirpState *s = DO_UPCAST(SlirpState, nc, nc);
 
     g_slist_free_full(s->fwd, slirp_free_fwd);
+    main_loop_poll_remove_notifier(&s->poll_notifier);
     slirp_cleanup(s->slirp);
     if (s->exit_notifier.notify) {
         qemu_remove_exit_notifier(&s->exit_notifier);
@@ -209,6 +211,25 @@ static const SlirpCb slirp_cb = {
     .notify = qemu_notify_event,
 };
 
+static void net_slirp_poll_notify(Notifier *notifier, void *data)
+{
+    MainLoopPoll *poll = data;
+    SlirpState *s = container_of(notifier, SlirpState, poll_notifier);
+
+    switch (poll->state) {
+    case MAIN_LOOP_POLL_FILL:
+        slirp_pollfds_fill(s->slirp, poll->pollfds, &poll->timeout);
+        break;
+    case MAIN_LOOP_POLL_OK:
+    case MAIN_LOOP_POLL_ERR:
+        slirp_pollfds_poll(s->slirp, poll->pollfds,
+                           poll->state == MAIN_LOOP_POLL_ERR);
+        break;
+    default:
+        g_assert_not_reached();
+    }
+}
+
 static int net_slirp_init(NetClientState *peer, const char *model,
                           const char *name, int restricted,
                           bool ipv4, const char *vnetwork, const char *vhost,
@@ -429,6 +450,9 @@ static int net_slirp_init(NetClientState *peer, const char *model,
                           &slirp_cb, s);
     QTAILQ_INSERT_TAIL(&slirp_stacks, s, entry);
 
+    s->poll_notifier.notify = net_slirp_poll_notify;
+    main_loop_poll_add_notifier(&s->poll_notifier);
+
     for (config = slirp_configs; config; config = config->next) {
         if (config->flags & SLIRP_CFG_HOSTFWD) {
             if (slirp_hostfwd(s, config->str, errp) < 0) {
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 8e5d4ed11b..18d5fb0133 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -63,9 +63,9 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
                   void *opaque);
 void slirp_cleanup(Slirp *slirp);
 
-void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout);
+void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout);
 
-void slirp_pollfds_poll(GArray *pollfds, int select_error);
+void slirp_pollfds_poll(Slirp *slirp, GArray *pollfds, int select_error);
 
 void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len);
 
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 2bc53e3e12..3a8d1bc459 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -368,9 +368,8 @@ void slirp_cleanup(Slirp *slirp)
 #define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
 #define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
 
-static void slirp_update_timeout(uint32_t *timeout)
+static void slirp_update_timeout(Slirp *slirp, uint32_t *timeout)
 {
-    Slirp *slirp;
     uint32_t t;
 
     if (*timeout <= TIMEOUT_FAST) {
@@ -382,370 +381,352 @@ static void slirp_update_timeout(uint32_t *timeout)
     /* If we have tcp timeout with slirp, then we will fill @timeout with
      * more precise value.
      */
-    QTAILQ_FOREACH(slirp, &slirp_instances, entry) {
-        if (slirp->time_fasttimo) {
-            *timeout = TIMEOUT_FAST;
-            return;
-        }
-        if (slirp->do_slowtimo) {
-            t = MIN(TIMEOUT_SLOW, t);
-        }
+    if (slirp->time_fasttimo) {
+        *timeout = TIMEOUT_FAST;
+        return;
+    }
+    if (slirp->do_slowtimo) {
+        t = MIN(TIMEOUT_SLOW, t);
     }
     *timeout = t;
 }
 
-void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout)
+void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout)
 {
-    Slirp *slirp;
     struct socket *so, *so_next;
 
-    if (QTAILQ_EMPTY(&slirp_instances)) {
-        return;
-    }
-
     /*
      * First, TCP sockets
      */
 
-    QTAILQ_FOREACH(slirp, &slirp_instances, entry) {
-        /*
-         * *_slowtimo needs calling if there are IP fragments
-         * in the fragment queue, or there are TCP connections active
-         */
-        slirp->do_slowtimo = ((slirp->tcb.so_next != &slirp->tcb) ||
-                (&slirp->ipq.ip_link != slirp->ipq.ip_link.next));
-
-        for (so = slirp->tcb.so_next; so != &slirp->tcb;
-                so = so_next) {
-            int events = 0;
-
-            so_next = so->so_next;
+    /*
+     * *_slowtimo needs calling if there are IP fragments
+     * in the fragment queue, or there are TCP connections active
+     */
+    slirp->do_slowtimo = ((slirp->tcb.so_next != &slirp->tcb) ||
+                          (&slirp->ipq.ip_link != slirp->ipq.ip_link.next));
 
-            so->pollfds_idx = -1;
+    for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so_next) {
+        int events = 0;
 
-            /*
-             * See if we need a tcp_fasttimo
-             */
-            if (slirp->time_fasttimo == 0 &&
-                so->so_tcpcb->t_flags & TF_DELACK) {
-                slirp->time_fasttimo = curtime; /* Flag when want a fasttimo */
-            }
+        so_next = so->so_next;
 
-            /*
-             * NOFDREF can include still connecting to local-host,
-             * newly socreated() sockets etc. Don't want to select these.
-             */
-            if (so->so_state & SS_NOFDREF || so->s == -1) {
-                continue;
-            }
+        so->pollfds_idx = -1;
 
-            /*
-             * Set for reading sockets which are accepting
-             */
-            if (so->so_state & SS_FACCEPTCONN) {
-                GPollFD pfd = {
-                    .fd = so->s,
-                    .events = G_IO_IN | G_IO_HUP | G_IO_ERR,
-                };
-                so->pollfds_idx = pollfds->len;
-                g_array_append_val(pollfds, pfd);
-                continue;
-            }
+        /*
+         * See if we need a tcp_fasttimo
+         */
+        if (slirp->time_fasttimo == 0 &&
+            so->so_tcpcb->t_flags & TF_DELACK) {
+            slirp->time_fasttimo = curtime; /* Flag when want a fasttimo */
+        }
 
-            /*
-             * Set for writing sockets which are connecting
-             */
-            if (so->so_state & SS_ISFCONNECTING) {
-                GPollFD pfd = {
-                    .fd = so->s,
-                    .events = G_IO_OUT | G_IO_ERR,
-                };
-                so->pollfds_idx = pollfds->len;
-                g_array_append_val(pollfds, pfd);
-                continue;
-            }
+        /*
+         * NOFDREF can include still connecting to local-host,
+         * newly socreated() sockets etc. Don't want to select these.
+         */
+        if (so->so_state & SS_NOFDREF || so->s == -1) {
+            continue;
+        }
 
-            /*
-             * Set for writing if we are connected, can send more, and
-             * we have something to send
-             */
-            if (CONN_CANFSEND(so) && so->so_rcv.sb_cc) {
-                events |= G_IO_OUT | G_IO_ERR;
-            }
+        /*
+         * Set for reading sockets which are accepting
+         */
+        if (so->so_state & SS_FACCEPTCONN) {
+            GPollFD pfd = {
+                .fd = so->s,
+                .events = G_IO_IN | G_IO_HUP | G_IO_ERR,
+            };
+            so->pollfds_idx = pollfds->len;
+            g_array_append_val(pollfds, pfd);
+            continue;
+        }
 
-            /*
-             * Set for reading (and urgent data) if we are connected, can
-             * receive more, and we have room for it XXX /2 ?
-             */
-            if (CONN_CANFRCV(so) &&
-                (so->so_snd.sb_cc < (so->so_snd.sb_datalen/2))) {
-                events |= G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_PRI;
-            }
+        /*
+         * Set for writing sockets which are connecting
+         */
+        if (so->so_state & SS_ISFCONNECTING) {
+            GPollFD pfd = {
+                .fd = so->s,
+                .events = G_IO_OUT | G_IO_ERR,
+            };
+            so->pollfds_idx = pollfds->len;
+            g_array_append_val(pollfds, pfd);
+            continue;
+        }
 
-            if (events) {
-                GPollFD pfd = {
-                    .fd = so->s,
-                    .events = events,
-                };
-                so->pollfds_idx = pollfds->len;
-                g_array_append_val(pollfds, pfd);
-            }
+        /*
+         * Set for writing if we are connected, can send more, and
+         * we have something to send
+         */
+        if (CONN_CANFSEND(so) && so->so_rcv.sb_cc) {
+            events |= G_IO_OUT | G_IO_ERR;
         }
 
         /*
-         * UDP sockets
+         * Set for reading (and urgent data) if we are connected, can
+         * receive more, and we have room for it XXX /2 ?
          */
-        for (so = slirp->udb.so_next; so != &slirp->udb;
-                so = so_next) {
-            so_next = so->so_next;
+        if (CONN_CANFRCV(so) &&
+            (so->so_snd.sb_cc < (so->so_snd.sb_datalen/2))) {
+            events |= G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_PRI;
+        }
 
-            so->pollfds_idx = -1;
+        if (events) {
+            GPollFD pfd = {
+                .fd = so->s,
+                .events = events,
+            };
+            so->pollfds_idx = pollfds->len;
+            g_array_append_val(pollfds, pfd);
+        }
+    }
 
-            /*
-             * See if it's timed out
-             */
-            if (so->so_expire) {
-                if (so->so_expire <= curtime) {
-                    udp_detach(so);
-                    continue;
-                } else {
-                    slirp->do_slowtimo = true; /* Let socket expire */
-                }
-            }
+    /*
+     * UDP sockets
+     */
+    for (so = slirp->udb.so_next; so != &slirp->udb; so = so_next) {
+        so_next = so->so_next;
 
-            /*
-             * When UDP packets are received from over the
-             * link, they're sendto()'d straight away, so
-             * no need for setting for writing
-             * Limit the number of packets queued by this session
-             * to 4.  Note that even though we try and limit this
-             * to 4 packets, the session could have more queued
-             * if the packets needed to be fragmented
-             * (XXX <= 4 ?)
-             */
-            if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) {
-                GPollFD pfd = {
-                    .fd = so->s,
-                    .events = G_IO_IN | G_IO_HUP | G_IO_ERR,
-                };
-                so->pollfds_idx = pollfds->len;
-                g_array_append_val(pollfds, pfd);
+        so->pollfds_idx = -1;
+
+        /*
+         * See if it's timed out
+         */
+        if (so->so_expire) {
+            if (so->so_expire <= curtime) {
+                udp_detach(so);
+                continue;
+            } else {
+                slirp->do_slowtimo = true; /* Let socket expire */
             }
         }
 
         /*
-         * ICMP sockets
+         * When UDP packets are received from over the
+         * link, they're sendto()'d straight away, so
+         * no need for setting for writing
+         * Limit the number of packets queued by this session
+         * to 4.  Note that even though we try and limit this
+         * to 4 packets, the session could have more queued
+         * if the packets needed to be fragmented
+         * (XXX <= 4 ?)
          */
-        for (so = slirp->icmp.so_next; so != &slirp->icmp;
-                so = so_next) {
-            so_next = so->so_next;
+        if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) {
+            GPollFD pfd = {
+                .fd = so->s,
+                .events = G_IO_IN | G_IO_HUP | G_IO_ERR,
+            };
+            so->pollfds_idx = pollfds->len;
+            g_array_append_val(pollfds, pfd);
+        }
+    }
 
-            so->pollfds_idx = -1;
+    /*
+     * ICMP sockets
+     */
+    for (so = slirp->icmp.so_next; so != &slirp->icmp; so = so_next) {
+        so_next = so->so_next;
 
-            /*
-             * See if it's timed out
-             */
-            if (so->so_expire) {
-                if (so->so_expire <= curtime) {
-                    icmp_detach(so);
-                    continue;
-                } else {
-                    slirp->do_slowtimo = true; /* Let socket expire */
-                }
-            }
+        so->pollfds_idx = -1;
 
-            if (so->so_state & SS_ISFCONNECTED) {
-                GPollFD pfd = {
-                    .fd = so->s,
-                    .events = G_IO_IN | G_IO_HUP | G_IO_ERR,
-                };
-                so->pollfds_idx = pollfds->len;
-                g_array_append_val(pollfds, pfd);
+        /*
+         * See if it's timed out
+         */
+        if (so->so_expire) {
+            if (so->so_expire <= curtime) {
+                icmp_detach(so);
+                continue;
+            } else {
+                slirp->do_slowtimo = true; /* Let socket expire */
             }
         }
+
+        if (so->so_state & SS_ISFCONNECTED) {
+            GPollFD pfd = {
+                .fd = so->s,
+                .events = G_IO_IN | G_IO_HUP | G_IO_ERR,
+            };
+            so->pollfds_idx = pollfds->len;
+            g_array_append_val(pollfds, pfd);
+        }
     }
-    slirp_update_timeout(timeout);
+
+    slirp_update_timeout(slirp, timeout);
 }
 
-void slirp_pollfds_poll(GArray *pollfds, int select_error)
+void slirp_pollfds_poll(Slirp *slirp, GArray *pollfds, int select_error)
 {
-    Slirp *slirp = QTAILQ_FIRST(&slirp_instances);
     struct socket *so, *so_next;
     int ret;
 
-    if (!slirp) {
-        return;
-    }
-
     curtime = slirp->cb->clock_get_ns() / SCALE_MS;
 
-    QTAILQ_FOREACH(slirp, &slirp_instances, entry) {
-        /*
-         * See if anything has timed out
-         */
-        if (slirp->time_fasttimo &&
-            ((curtime - slirp->time_fasttimo) >= TIMEOUT_FAST)) {
-            tcp_fasttimo(slirp);
-            slirp->time_fasttimo = 0;
-        }
-        if (slirp->do_slowtimo &&
-            ((curtime - slirp->last_slowtimo) >= TIMEOUT_SLOW)) {
-            ip_slowtimo(slirp);
-            tcp_slowtimo(slirp);
-            slirp->last_slowtimo = curtime;
-        }
+    /*
+     * See if anything has timed out
+     */
+    if (slirp->time_fasttimo &&
+        ((curtime - slirp->time_fasttimo) >= TIMEOUT_FAST)) {
+        tcp_fasttimo(slirp);
+        slirp->time_fasttimo = 0;
+    }
+    if (slirp->do_slowtimo &&
+        ((curtime - slirp->last_slowtimo) >= TIMEOUT_SLOW)) {
+        ip_slowtimo(slirp);
+        tcp_slowtimo(slirp);
+        slirp->last_slowtimo = curtime;
+    }
 
+    /*
+     * Check sockets
+     */
+    if (!select_error) {
         /*
-         * Check sockets
+         * Check TCP sockets
          */
-        if (!select_error) {
-            /*
-             * Check TCP sockets
-             */
-            for (so = slirp->tcb.so_next; so != &slirp->tcb;
-                    so = so_next) {
-                int revents;
+        for (so = slirp->tcb.so_next; so != &slirp->tcb;
+             so = so_next) {
+            int revents;
 
-                so_next = so->so_next;
+            so_next = so->so_next;
 
-                revents = 0;
-                if (so->pollfds_idx != -1) {
-                    revents = g_array_index(pollfds, GPollFD,
-                                            so->pollfds_idx).revents;
-                }
+            revents = 0;
+            if (so->pollfds_idx != -1) {
+                revents = g_array_index(pollfds, GPollFD,
+                                        so->pollfds_idx).revents;
+            }
 
-                if (so->so_state & SS_NOFDREF || so->s == -1) {
+            if (so->so_state & SS_NOFDREF || so->s == -1) {
+                continue;
+            }
+
+            /*
+             * Check for URG data
+             * This will soread as well, so no need to
+             * test for G_IO_IN below if this succeeds
+             */
+            if (revents & G_IO_PRI) {
+                ret = sorecvoob(so);
+                if (ret < 0) {
+                    /* Socket error might have resulted in the socket being
+                     * removed, do not try to do anything more with it. */
                     continue;
                 }
-
+            }
+            /*
+             * Check sockets for reading
+             */
+            else if (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR)) {
                 /*
-                 * Check for URG data
-                 * This will soread as well, so no need to
-                 * test for G_IO_IN below if this succeeds
+                 * Check for incoming connections
                  */
-                if (revents & G_IO_PRI) {
-                    ret = sorecvoob(so);
-                    if (ret < 0) {
-                        /* Socket error might have resulted in the socket being
-                         * removed, do not try to do anything more with it. */
-                        continue;
-                    }
+                if (so->so_state & SS_FACCEPTCONN) {
+                    tcp_connect(so);
+                    continue;
+                } /* else */
+                ret = soread(so);
+
+                /* Output it if we read something */
+                if (ret > 0) {
+                    tcp_output(sototcpcb(so));
+                }
+                if (ret < 0) {
+                    /* Socket error might have resulted in the socket being
+                     * removed, do not try to do anything more with it. */
+                    continue;
                 }
+            }
+
+            /*
+             * Check sockets for writing
+             */
+            if (!(so->so_state & SS_NOFDREF) &&
+                (revents & (G_IO_OUT | G_IO_ERR))) {
                 /*
-                 * Check sockets for reading
+                 * Check for non-blocking, still-connecting sockets
                  */
-                else if (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR)) {
-                    /*
-                     * Check for incoming connections
-                     */
-                    if (so->so_state & SS_FACCEPTCONN) {
-                        tcp_connect(so);
-                        continue;
-                    } /* else */
-                    ret = soread(so);
+                if (so->so_state & SS_ISFCONNECTING) {
+                    /* Connected */
+                    so->so_state &= ~SS_ISFCONNECTING;
 
-                    /* Output it if we read something */
-                    if (ret > 0) {
-                        tcp_output(sototcpcb(so));
-                    }
+                    ret = send(so->s, (const void *) &ret, 0, 0);
                     if (ret < 0) {
-                        /* Socket error might have resulted in the socket being
-                         * removed, do not try to do anything more with it. */
-                        continue;
+                        /* XXXXX Must fix, zero bytes is a NOP */
+                        if (errno == EAGAIN || errno == EWOULDBLOCK ||
+                            errno == EINPROGRESS || errno == ENOTCONN) {
+                            continue;
+                        }
+
+                        /* else failed */
+                        so->so_state &= SS_PERSISTENT_MASK;
+                        so->so_state |= SS_NOFDREF;
                     }
-                }
+                    /* else so->so_state &= ~SS_ISFCONNECTING; */
 
-                /*
-                 * Check sockets for writing
-                 */
-                if (!(so->so_state & SS_NOFDREF) &&
-                        (revents & (G_IO_OUT | G_IO_ERR))) {
                     /*
-                     * Check for non-blocking, still-connecting sockets
+                     * Continue tcp_input
                      */
-                    if (so->so_state & SS_ISFCONNECTING) {
-                        /* Connected */
-                        so->so_state &= ~SS_ISFCONNECTING;
-
-                        ret = send(so->s, (const void *) &ret, 0, 0);
-                        if (ret < 0) {
-                            /* XXXXX Must fix, zero bytes is a NOP */
-                            if (errno == EAGAIN || errno == EWOULDBLOCK ||
-                                errno == EINPROGRESS || errno == ENOTCONN) {
-                                continue;
-                            }
-
-                            /* else failed */
-                            so->so_state &= SS_PERSISTENT_MASK;
-                            so->so_state |= SS_NOFDREF;
-                        }
-                        /* else so->so_state &= ~SS_ISFCONNECTING; */
-
-                        /*
-                         * Continue tcp_input
-                         */
-                        tcp_input((struct mbuf *)NULL, sizeof(struct ip), so,
-                                  so->so_ffamily);
-                        /* continue; */
-                    } else {
-                        ret = sowrite(so);
-                        if (ret > 0) {
-                            /* Call tcp_output in case we need to send a window
-                             * update to the guest, otherwise it will be stuck
-                             * until it sends a window probe. */
-                            tcp_output(sototcpcb(so));
-                        }
+                    tcp_input((struct mbuf *)NULL, sizeof(struct ip), so,
+                              so->so_ffamily);
+                    /* continue; */
+                } else {
+                    ret = sowrite(so);
+                    if (ret > 0) {
+                        /* Call tcp_output in case we need to send a window
+                         * update to the guest, otherwise it will be stuck
+                         * until it sends a window probe. */
+                        tcp_output(sototcpcb(so));
                     }
                 }
             }
+        }
 
-            /*
-             * Now UDP sockets.
-             * Incoming packets are sent straight away, they're not buffered.
-             * Incoming UDP data isn't buffered either.
-             */
-            for (so = slirp->udb.so_next; so != &slirp->udb;
-                    so = so_next) {
-                int revents;
+        /*
+         * Now UDP sockets.
+         * Incoming packets are sent straight away, they're not buffered.
+         * Incoming UDP data isn't buffered either.
+         */
+        for (so = slirp->udb.so_next; so != &slirp->udb;
+             so = so_next) {
+            int revents;
 
-                so_next = so->so_next;
+            so_next = so->so_next;
 
-                revents = 0;
-                if (so->pollfds_idx != -1) {
-                    revents = g_array_index(pollfds, GPollFD,
-                            so->pollfds_idx).revents;
-                }
+            revents = 0;
+            if (so->pollfds_idx != -1) {
+                revents = g_array_index(pollfds, GPollFD,
+                                        so->pollfds_idx).revents;
+            }
 
-                if (so->s != -1 &&
-                    (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR))) {
-                    sorecvfrom(so);
-                }
+            if (so->s != -1 &&
+                (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR))) {
+                sorecvfrom(so);
             }
+        }
 
-            /*
-             * Check incoming ICMP relies.
-             */
-            for (so = slirp->icmp.so_next; so != &slirp->icmp;
-                    so = so_next) {
-                    int revents;
+        /*
+         * Check incoming ICMP relies.
+         */
+        for (so = slirp->icmp.so_next; so != &slirp->icmp;
+             so = so_next) {
+            int revents;
 
-                    so_next = so->so_next;
+            so_next = so->so_next;
 
-                    revents = 0;
-                    if (so->pollfds_idx != -1) {
-                        revents = g_array_index(pollfds, GPollFD,
-                                                so->pollfds_idx).revents;
-                    }
+            revents = 0;
+            if (so->pollfds_idx != -1) {
+                revents = g_array_index(pollfds, GPollFD,
+                                        so->pollfds_idx).revents;
+            }
 
-                    if (so->s != -1 &&
-                        (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR))) {
-                    icmp_receive(so);
-                }
+            if (so->s != -1 &&
+                (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR))) {
+                icmp_receive(so);
             }
         }
-
-        if_start(slirp);
     }
+
+    if_start(slirp);
 }
 
 static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index cda0efa4e8..1558ff1fe7 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -26,7 +26,6 @@ stub-obj-y += qtest.o
 stub-obj-y += replay.o
 stub-obj-y += runstate-check.o
 stub-obj-y += set-fd-handler.o
-stub-obj-y += slirp.o
 stub-obj-y += sysbus.o
 stub-obj-y += tpm.o
 stub-obj-y += trace-control.o
diff --git a/stubs/slirp.c b/stubs/slirp.c
deleted file mode 100644
index 70704346fd..0000000000
--- a/stubs/slirp.c
+++ /dev/null
@@ -1,13 +0,0 @@
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "qemu/host-utils.h"
-#include "slirp/libslirp.h"
-
-void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout)
-{
-}
-
-void slirp_pollfds_poll(GArray *pollfds, int select_error)
-{
-}
-
diff --git a/util/main-loop.c b/util/main-loop.c
index 443cb4cfe8..d4a521caeb 100644
--- a/util/main-loop.c
+++ b/util/main-loop.c
@@ -469,25 +469,42 @@ static int os_host_main_loop_wait(int64_t timeout)
 }
 #endif
 
+static NotifierList main_loop_poll_notifiers =
+    NOTIFIER_LIST_INITIALIZER(main_loop_poll_notifiers);
+
+void main_loop_poll_add_notifier(Notifier *notify)
+{
+    notifier_list_add(&main_loop_poll_notifiers, notify);
+}
+
+void main_loop_poll_remove_notifier(Notifier *notify)
+{
+    notifier_remove(notify);
+}
+
 void main_loop_wait(int nonblocking)
 {
+    MainLoopPoll mlpoll = {
+        .state = MAIN_LOOP_POLL_FILL,
+        .timeout = UINT32_MAX,
+        .pollfds = gpollfds,
+    };
     int ret;
-    uint32_t timeout = UINT32_MAX;
     int64_t timeout_ns;
 
     if (nonblocking) {
-        timeout = 0;
+        mlpoll.timeout = 0;
     }
 
     /* poll any events */
     g_array_set_size(gpollfds, 0); /* reset for new iteration */
     /* XXX: separate device handlers from system ones */
-    slirp_pollfds_fill(gpollfds, &timeout);
+    notifier_list_notify(&main_loop_poll_notifiers, &mlpoll);
 
-    if (timeout == UINT32_MAX) {
+    if (mlpoll.timeout == UINT32_MAX) {
         timeout_ns = -1;
     } else {
-        timeout_ns = (uint64_t)timeout * (int64_t)(SCALE_MS);
+        timeout_ns = (uint64_t)mlpoll.timeout * (int64_t)(SCALE_MS);
     }
 
     timeout_ns = qemu_soonest_timeout(timeout_ns,
@@ -495,7 +512,8 @@ void main_loop_wait(int nonblocking)
                                           &main_loop_tlg));
 
     ret = os_host_main_loop_wait(timeout_ns);
-    slirp_pollfds_poll(gpollfds, (ret < 0));
+    mlpoll.state = ret < 0 ? MAIN_LOOP_POLL_ERR : MAIN_LOOP_POLL_OK;
+    notifier_list_notify(&main_loop_poll_notifiers, &mlpoll);
 
     /* CPU thread can infinitely wait for event after
        missing the warp */
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 29/32] slirp: remove slirp_instances list
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
                   ` (27 preceding siblings ...)
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 28/32] slirp: replace global polling with per-instance & notifier Samuel Thibault
@ 2019-02-07 14:03 ` Samuel Thibault
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 30/32] slirp: use polling callbacks, drop glib requirement Samuel Thibault
                   ` (4 subsequent siblings)
  33 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Marc-André Lureau, stefanha, jan.kiszka, Samuel Thibault

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Now that polling is done per-instance, we don't need a global list of
slirp instances.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 slirp/slirp.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/slirp/slirp.c b/slirp/slirp.c
index 3a8d1bc459..b37dd34382 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -48,9 +48,6 @@ static const uint8_t special_ethaddr[ETH_ALEN] = {
 
 unsigned curtime;
 
-static QTAILQ_HEAD(, Slirp) slirp_instances =
-    QTAILQ_HEAD_INITIALIZER(slirp_instances);
-
 static struct in_addr dns_addr;
 #ifndef _WIN32
 static struct in6_addr dns6_addr;
@@ -333,7 +330,6 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
 #ifdef WITH_QEMU
     slirp_state_register(slirp);
 #endif
-    QTAILQ_INSERT_TAIL(&slirp_instances, slirp, entry);
 
     return slirp;
 }
@@ -348,7 +344,6 @@ void slirp_cleanup(Slirp *slirp)
         g_free(e);
     }
 
-    QTAILQ_REMOVE(&slirp_instances, slirp, entry);
 #ifdef WITH_QEMU
     slirp_state_unregister(slirp);
 #endif
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 30/32] slirp: use polling callbacks, drop glib requirement
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
                   ` (28 preceding siblings ...)
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 29/32] slirp: remove slirp_instances list Samuel Thibault
@ 2019-02-07 14:03 ` Samuel Thibault
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 31/32] slirp: pass opaque to all callbacks Samuel Thibault
                   ` (3 subsequent siblings)
  33 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Marc-André Lureau, stefanha, jan.kiszka, Samuel Thibault

From: Marc-André Lureau <marcandre.lureau@redhat.com>

It would be legitimate to use libslirp without glib. Let's
add_poll/get_revents pair of callbacks to provide the same
functionality.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 net/slirp.c      | 72 ++++++++++++++++++++++++++++++++++++++++++++++--
 slirp/libslirp.h | 17 ++++++++++--
 slirp/slirp.c    | 72 +++++++++++++++++-------------------------------
 3 files changed, 109 insertions(+), 52 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index 4d55f64168..a85e42ff43 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -211,6 +211,71 @@ static const SlirpCb slirp_cb = {
     .notify = qemu_notify_event,
 };
 
+static int slirp_poll_to_gio(int events)
+{
+    int ret = 0;
+
+    if (events & SLIRP_POLL_IN) {
+        ret |= G_IO_IN;
+    }
+    if (events & SLIRP_POLL_OUT) {
+        ret |= G_IO_OUT;
+    }
+    if (events & SLIRP_POLL_PRI) {
+        ret |= G_IO_PRI;
+    }
+    if (events & SLIRP_POLL_ERR) {
+        ret |= G_IO_ERR;
+    }
+    if (events & SLIRP_POLL_HUP) {
+        ret |= G_IO_HUP;
+    }
+
+    return ret;
+}
+
+static int net_slirp_add_poll(int fd, int events, void *opaque)
+{
+    GArray *pollfds = opaque;
+    GPollFD pfd = {
+        .fd = fd,
+        .events = slirp_poll_to_gio(events),
+    };
+    int idx = pollfds->len;
+    g_array_append_val(pollfds, pfd);
+    return idx;
+}
+
+static int slirp_gio_to_poll(int events)
+{
+    int ret = 0;
+
+    if (events & G_IO_IN) {
+        ret |= SLIRP_POLL_IN;
+    }
+    if (events & G_IO_OUT) {
+        ret |= SLIRP_POLL_OUT;
+    }
+    if (events & G_IO_PRI) {
+        ret |= SLIRP_POLL_PRI;
+    }
+    if (events & G_IO_ERR) {
+        ret |= SLIRP_POLL_ERR;
+    }
+    if (events & G_IO_HUP) {
+        ret |= SLIRP_POLL_HUP;
+    }
+
+    return ret;
+}
+
+static int net_slirp_get_revents(int idx, void *opaque)
+{
+    GArray *pollfds = opaque;
+
+    return slirp_gio_to_poll(g_array_index(pollfds, GPollFD, idx).revents);
+}
+
 static void net_slirp_poll_notify(Notifier *notifier, void *data)
 {
     MainLoopPoll *poll = data;
@@ -218,12 +283,13 @@ static void net_slirp_poll_notify(Notifier *notifier, void *data)
 
     switch (poll->state) {
     case MAIN_LOOP_POLL_FILL:
-        slirp_pollfds_fill(s->slirp, poll->pollfds, &poll->timeout);
+        slirp_pollfds_fill(s->slirp, &poll->timeout,
+                           net_slirp_add_poll, poll->pollfds);
         break;
     case MAIN_LOOP_POLL_OK:
     case MAIN_LOOP_POLL_ERR:
-        slirp_pollfds_poll(s->slirp, poll->pollfds,
-                           poll->state == MAIN_LOOP_POLL_ERR);
+        slirp_pollfds_poll(s->slirp, poll->state == MAIN_LOOP_POLL_ERR,
+                           net_slirp_get_revents, poll->pollfds);
         break;
     default:
         g_assert_not_reached();
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 18d5fb0133..b5c1b2122b 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -1,7 +1,6 @@
 #ifndef LIBSLIRP_H
 #define LIBSLIRP_H
 
-#include <glib.h>
 #include <stdint.h>
 #include <stdbool.h>
 
@@ -15,8 +14,18 @@
 
 typedef struct Slirp Slirp;
 
+enum {
+    SLIRP_POLL_IN  = 1 << 0,
+    SLIRP_POLL_OUT = 1 << 1,
+    SLIRP_POLL_PRI = 1 << 2,
+    SLIRP_POLL_ERR = 1 << 3,
+    SLIRP_POLL_HUP = 1 << 4,
+};
+
 typedef ssize_t (*SlirpWriteCb)(const void *buf, size_t len, void *opaque);
 typedef void (*SlirpTimerCb)(void *opaque);
+typedef int (*SlirpAddPollCb)(int fd, int events, void *opaque);
+typedef int (*SlirpGetREventsCb)(int idx, void *opaque);
 
 /*
  * Callbacks from slirp
@@ -63,9 +72,11 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
                   void *opaque);
 void slirp_cleanup(Slirp *slirp);
 
-void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout);
+void slirp_pollfds_fill(Slirp *slirp, uint32_t *timeout,
+                        SlirpAddPollCb add_poll, void *opaque);
 
-void slirp_pollfds_poll(Slirp *slirp, GArray *pollfds, int select_error);
+void slirp_pollfds_poll(Slirp *slirp, int select_error,
+                        SlirpGetREventsCb get_revents, void *opaque);
 
 void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len);
 
diff --git a/slirp/slirp.c b/slirp/slirp.c
index b37dd34382..eedbce23dc 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -386,7 +386,8 @@ static void slirp_update_timeout(Slirp *slirp, uint32_t *timeout)
     *timeout = t;
 }
 
-void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout)
+void slirp_pollfds_fill(Slirp *slirp, uint32_t *timeout,
+                        SlirpAddPollCb add_poll, void *opaque)
 {
     struct socket *so, *so_next;
 
@@ -428,12 +429,8 @@ void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout)
          * Set for reading sockets which are accepting
          */
         if (so->so_state & SS_FACCEPTCONN) {
-            GPollFD pfd = {
-                .fd = so->s,
-                .events = G_IO_IN | G_IO_HUP | G_IO_ERR,
-            };
-            so->pollfds_idx = pollfds->len;
-            g_array_append_val(pollfds, pfd);
+            so->pollfds_idx = add_poll(so->s,
+                SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR, opaque);
             continue;
         }
 
@@ -441,12 +438,8 @@ void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout)
          * Set for writing sockets which are connecting
          */
         if (so->so_state & SS_ISFCONNECTING) {
-            GPollFD pfd = {
-                .fd = so->s,
-                .events = G_IO_OUT | G_IO_ERR,
-            };
-            so->pollfds_idx = pollfds->len;
-            g_array_append_val(pollfds, pfd);
+            so->pollfds_idx = add_poll(so->s,
+                SLIRP_POLL_OUT | SLIRP_POLL_ERR, opaque);
             continue;
         }
 
@@ -455,7 +448,7 @@ void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout)
          * we have something to send
          */
         if (CONN_CANFSEND(so) && so->so_rcv.sb_cc) {
-            events |= G_IO_OUT | G_IO_ERR;
+            events |= SLIRP_POLL_OUT | SLIRP_POLL_ERR;
         }
 
         /*
@@ -464,16 +457,12 @@ void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout)
          */
         if (CONN_CANFRCV(so) &&
             (so->so_snd.sb_cc < (so->so_snd.sb_datalen/2))) {
-            events |= G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_PRI;
+            events |= SLIRP_POLL_IN | SLIRP_POLL_HUP |
+                      SLIRP_POLL_ERR | SLIRP_POLL_PRI;
         }
 
         if (events) {
-            GPollFD pfd = {
-                .fd = so->s,
-                .events = events,
-            };
-            so->pollfds_idx = pollfds->len;
-            g_array_append_val(pollfds, pfd);
+            so->pollfds_idx = add_poll(so->s, events, opaque);
         }
     }
 
@@ -508,12 +497,8 @@ void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout)
          * (XXX <= 4 ?)
          */
         if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) {
-            GPollFD pfd = {
-                .fd = so->s,
-                .events = G_IO_IN | G_IO_HUP | G_IO_ERR,
-            };
-            so->pollfds_idx = pollfds->len;
-            g_array_append_val(pollfds, pfd);
+            so->pollfds_idx = add_poll(so->s,
+                SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR, opaque);
         }
     }
 
@@ -538,19 +523,16 @@ void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout)
         }
 
         if (so->so_state & SS_ISFCONNECTED) {
-            GPollFD pfd = {
-                .fd = so->s,
-                .events = G_IO_IN | G_IO_HUP | G_IO_ERR,
-            };
-            so->pollfds_idx = pollfds->len;
-            g_array_append_val(pollfds, pfd);
+            so->pollfds_idx = add_poll(so->s,
+                SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR, opaque);
         }
     }
 
     slirp_update_timeout(slirp, timeout);
 }
 
-void slirp_pollfds_poll(Slirp *slirp, GArray *pollfds, int select_error)
+void slirp_pollfds_poll(Slirp *slirp, int select_error,
+                        SlirpGetREventsCb get_revents, void *opaque)
 {
     struct socket *so, *so_next;
     int ret;
@@ -587,8 +569,7 @@ void slirp_pollfds_poll(Slirp *slirp, GArray *pollfds, int select_error)
 
             revents = 0;
             if (so->pollfds_idx != -1) {
-                revents = g_array_index(pollfds, GPollFD,
-                                        so->pollfds_idx).revents;
+                revents = get_revents(so->pollfds_idx, opaque);
             }
 
             if (so->so_state & SS_NOFDREF || so->s == -1) {
@@ -598,9 +579,9 @@ void slirp_pollfds_poll(Slirp *slirp, GArray *pollfds, int select_error)
             /*
              * Check for URG data
              * This will soread as well, so no need to
-             * test for G_IO_IN below if this succeeds
+             * test for SLIRP_POLL_IN below if this succeeds
              */
-            if (revents & G_IO_PRI) {
+            if (revents & SLIRP_POLL_PRI) {
                 ret = sorecvoob(so);
                 if (ret < 0) {
                     /* Socket error might have resulted in the socket being
@@ -611,7 +592,8 @@ void slirp_pollfds_poll(Slirp *slirp, GArray *pollfds, int select_error)
             /*
              * Check sockets for reading
              */
-            else if (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR)) {
+            else if (revents &
+                     (SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR)) {
                 /*
                  * Check for incoming connections
                  */
@@ -636,7 +618,7 @@ void slirp_pollfds_poll(Slirp *slirp, GArray *pollfds, int select_error)
              * Check sockets for writing
              */
             if (!(so->so_state & SS_NOFDREF) &&
-                (revents & (G_IO_OUT | G_IO_ERR))) {
+                (revents & (SLIRP_POLL_OUT | SLIRP_POLL_ERR))) {
                 /*
                  * Check for non-blocking, still-connecting sockets
                  */
@@ -689,12 +671,11 @@ void slirp_pollfds_poll(Slirp *slirp, GArray *pollfds, int select_error)
 
             revents = 0;
             if (so->pollfds_idx != -1) {
-                revents = g_array_index(pollfds, GPollFD,
-                                        so->pollfds_idx).revents;
+                revents = get_revents(so->pollfds_idx, opaque);
             }
 
             if (so->s != -1 &&
-                (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR))) {
+                (revents & (SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR))) {
                 sorecvfrom(so);
             }
         }
@@ -710,12 +691,11 @@ void slirp_pollfds_poll(Slirp *slirp, GArray *pollfds, int select_error)
 
             revents = 0;
             if (so->pollfds_idx != -1) {
-                revents = g_array_index(pollfds, GPollFD,
-                                        so->pollfds_idx).revents;
+                revents = get_revents(so->pollfds_idx, opaque);
             }
 
             if (so->s != -1 &&
-                (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR))) {
+                (revents & (SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR))) {
                 icmp_receive(so);
             }
         }
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 31/32] slirp: pass opaque to all callbacks
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
                   ` (29 preceding siblings ...)
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 30/32] slirp: use polling callbacks, drop glib requirement Samuel Thibault
@ 2019-02-07 14:03 ` Samuel Thibault
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 32/32] slirp: API is extern C Samuel Thibault
                   ` (2 subsequent siblings)
  33 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Marc-André Lureau, stefanha, jan.kiszka, Samuel Thibault

From: Marc-André Lureau <marcandre.lureau@redhat.com>

This is friendlier for FFI bindings.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 net/slirp.c      | 25 ++++++++++++++++---------
 slirp/dhcpv6.c   |  2 +-
 slirp/if.c       |  2 +-
 slirp/ip6_icmp.c | 15 +++++++++------
 slirp/ip_icmp.c  |  2 +-
 slirp/libslirp.h | 16 ++++++++--------
 slirp/misc.c     |  2 +-
 slirp/slirp.c    | 13 ++++++-------
 slirp/socket.c   |  2 +-
 slirp/tcp_subr.c |  8 ++++----
 slirp/udp.c      |  2 +-
 11 files changed, 49 insertions(+), 40 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index a85e42ff43..7a16d8d615 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -161,44 +161,51 @@ static NetClientInfo net_slirp_info = {
     .cleanup = net_slirp_cleanup,
 };
 
-static void net_slirp_guest_error(const char *msg)
+static void net_slirp_guest_error(const char *msg, void *opaque)
 {
     qemu_log_mask(LOG_GUEST_ERROR, "%s", msg);
 }
 
-static int64_t net_slirp_clock_get_ns(void)
+static int64_t net_slirp_clock_get_ns(void *opaque)
 {
     return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 }
 
-static void *net_slirp_timer_new(SlirpTimerCb cb, void *opaque)
+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, opaque);
+                          cb, cb_opaque);
 }
 
-static void net_slirp_timer_free(void *timer)
+static void net_slirp_timer_free(void *timer, void *opaque)
 {
     timer_del(timer);
     timer_free(timer);
 }
 
-static void net_slirp_timer_mod(void *timer, int64_t expire_timer)
+static void net_slirp_timer_mod(void *timer, int64_t expire_timer,
+                                void *opaque)
 {
     timer_mod(timer, expire_timer);
 }
 
-static void net_slirp_register_poll_fd(int fd)
+static void net_slirp_register_poll_fd(int fd, void *opaque)
 {
     qemu_fd_register(fd);
 }
 
-static void net_slirp_unregister_poll_fd(int fd)
+static void net_slirp_unregister_poll_fd(int fd, void *opaque)
 {
     /* no qemu_fd_unregister */
 }
 
+static void net_slirp_notify(void *opaque)
+{
+    qemu_notify_event();
+}
+
 static const SlirpCb slirp_cb = {
     .send_packet = net_slirp_send_packet,
     .guest_error = net_slirp_guest_error,
@@ -208,7 +215,7 @@ static const SlirpCb slirp_cb = {
     .timer_mod = net_slirp_timer_mod,
     .register_poll_fd = net_slirp_register_poll_fd,
     .unregister_poll_fd = net_slirp_unregister_poll_fd,
-    .notify = qemu_notify_event,
+    .notify = net_slirp_notify,
 };
 
 static int slirp_poll_to_gio(int events)
diff --git a/slirp/dhcpv6.c b/slirp/dhcpv6.c
index 9ffba38e8f..e655c7d5b1 100644
--- a/slirp/dhcpv6.c
+++ b/slirp/dhcpv6.c
@@ -59,7 +59,7 @@ static int dhcpv6_parse_info_request(Slirp *slirp, uint8_t *odata, int olen,
         int len = odata[2] << 8 | odata[3];
 
         if (len + 4 > olen) {
-            slirp->cb->guest_error("Guest sent bad DHCPv6 packet!");
+            slirp->cb->guest_error("Guest sent bad DHCPv6 packet!", slirp->opaque);
             return -E2BIG;
         }
 
diff --git a/slirp/if.c b/slirp/if.c
index 2ad03b8a79..1830cc396c 100644
--- a/slirp/if.c
+++ b/slirp/if.c
@@ -146,7 +146,7 @@ diddit:
  */
 void if_start(Slirp *slirp)
 {
-    uint64_t now = slirp->cb->clock_get_ns();
+    uint64_t now = slirp->cb->clock_get_ns(slirp->opaque);
     bool from_batchq = false;
     struct mbuf *ifm, *ifm_next, *ifqt;
 
diff --git a/slirp/ip6_icmp.c b/slirp/ip6_icmp.c
index 2a432ebbd4..c1e3d30470 100644
--- a/slirp/ip6_icmp.c
+++ b/slirp/ip6_icmp.c
@@ -14,7 +14,8 @@ static void ra_timer_handler(void *opaque)
     Slirp *slirp = opaque;
 
     slirp->cb->timer_mod(slirp->ra_timer,
-                         slirp->cb->clock_get_ns() / SCALE_MS + NDP_Interval);
+        slirp->cb->clock_get_ns(slirp->opaque) / SCALE_MS + NDP_Interval,
+        slirp->opaque);
     ndp_send_ra(slirp);
 }
 
@@ -24,9 +25,10 @@ void icmp6_init(Slirp *slirp)
         return;
     }
 
-    slirp->ra_timer = slirp->cb->timer_new(ra_timer_handler, slirp);
+    slirp->ra_timer = slirp->cb->timer_new(ra_timer_handler, slirp, slirp->opaque);
     slirp->cb->timer_mod(slirp->ra_timer,
-                         slirp->cb->clock_get_ns() / SCALE_MS + NDP_Interval);
+        slirp->cb->clock_get_ns(slirp->opaque) / SCALE_MS + NDP_Interval,
+        slirp->opaque);
 }
 
 void icmp6_cleanup(Slirp *slirp)
@@ -35,7 +37,7 @@ void icmp6_cleanup(Slirp *slirp)
         return;
     }
 
-    slirp->cb->timer_free(slirp->ra_timer);
+    slirp->cb->timer_free(slirp->ra_timer, slirp->opaque);
 }
 
 static void icmp6_send_echoreply(struct mbuf *m, Slirp *slirp, struct ip6 *ip,
@@ -334,7 +336,8 @@ static void ndp_input(struct mbuf *m, Slirp *slirp, struct ip6 *ip,
 
     case ICMP6_NDP_RA:
         DEBUG_CALL(" type = Router Advertisement");
-        slirp->cb->guest_error("Warning: guest sent NDP RA, but shouldn't");
+        slirp->cb->guest_error("Warning: guest sent NDP RA, but shouldn't",
+                               slirp->opaque);
         break;
 
     case ICMP6_NDP_NS:
@@ -368,7 +371,7 @@ static void ndp_input(struct mbuf *m, Slirp *slirp, struct ip6 *ip,
     case ICMP6_NDP_REDIRECT:
         DEBUG_CALL(" type = Redirect");
         slirp->cb->guest_error(
-            "Warning: guest sent NDP REDIRECT, but shouldn't");
+            "Warning: guest sent NDP REDIRECT, but shouldn't", slirp->opaque);
         break;
     }
 }
diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
index 7c5cb75ae5..ce79c0b051 100644
--- a/slirp/ip_icmp.c
+++ b/slirp/ip_icmp.c
@@ -113,7 +113,7 @@ static int icmp_send(struct socket *so, struct mbuf *m, int hlen)
 
 void icmp_detach(struct socket *so)
 {
-    so->slirp->cb->unregister_poll_fd(so->s);
+    so->slirp->cb->unregister_poll_fd(so->s, so->slirp->opaque);
     slirp_closesocket(so->s);
     sofree(so);
 }
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index b5c1b2122b..9b13d8250c 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -40,21 +40,21 @@ typedef struct SlirpCb {
      */
     SlirpWriteCb send_packet;
     /* Print a message for an error due to guest misbehavior.  */
-    void (*guest_error)(const char *msg);
+    void (*guest_error)(const char *msg, void *opaque);
     /* Return the virtual clock value in nanoseconds */
-    int64_t (*clock_get_ns)(void);
+    int64_t (*clock_get_ns)(void *opaque);
     /* Create a new timer with the given callback and opaque data */
-    void *(*timer_new)(SlirpTimerCb cb, void *opaque);
+    void *(*timer_new)(SlirpTimerCb cb, void *cb_opaque, void *opaque);
     /* Remove and free a timer */
-    void (*timer_free)(void *timer);
+    void (*timer_free)(void *timer, void *opaque);
     /* Modify a timer to expire at @expire_time */
-    void (*timer_mod)(void *timer, int64_t expire_time);
+    void (*timer_mod)(void *timer, int64_t expire_time, void *opaque);
     /* Register a fd for future polling */
-    void (*register_poll_fd)(int fd);
+    void (*register_poll_fd)(int fd, void *opaque);
     /* Unregister a fd */
-    void (*unregister_poll_fd)(int fd);
+    void (*unregister_poll_fd)(int fd, void *opaque);
     /* Kick the io-thread, to signal that new events may be processed */
-    void (*notify)(void);
+    void (*notify)(void *opaque);
 } SlirpCb;
 
 
diff --git a/slirp/misc.c b/slirp/misc.c
index 3c02510101..3f4cd852f8 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -222,7 +222,7 @@ fork_exec(struct socket *so, const char *ex)
     opt = 1;
     slirp_setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
     slirp_set_nonblock(so->s);
-    so->slirp->cb->register_poll_fd(so->s);
+    so->slirp->cb->register_poll_fd(so->s, so->slirp->opaque);
     return 1;
 }
 
diff --git a/slirp/slirp.c b/slirp/slirp.c
index eedbce23dc..a746c6fd86 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -289,6 +289,7 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
 
     slirp_init_once();
 
+    slirp->opaque = opaque;
     slirp->cb = callbacks;
     slirp->grand = g_rand_new();
     slirp->restricted = restricted;
@@ -325,12 +326,9 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
         translate_dnssearch(slirp, vdnssearch);
     }
 
-    slirp->opaque = opaque;
-
 #ifdef WITH_QEMU
     slirp_state_register(slirp);
 #endif
-
     return slirp;
 }
 
@@ -537,7 +535,7 @@ void slirp_pollfds_poll(Slirp *slirp, int select_error,
     struct socket *so, *so_next;
     int ret;
 
-    curtime = slirp->cb->clock_get_ns() / SCALE_MS;
+    curtime = slirp->cb->clock_get_ns(slirp->opaque) / SCALE_MS;
 
     /*
      * See if anything has timed out
@@ -860,7 +858,8 @@ static int if_encap4(Slirp *slirp, struct mbuf *ifm, struct ethhdr *eh,
             ifm->resolution_requested = true;
 
             /* Expire request and drop outgoing packet after 1 second */
-            ifm->expiration_date = slirp->cb->clock_get_ns() + 1000000000ULL;
+            ifm->expiration_date =
+                slirp->cb->clock_get_ns(slirp->opaque) + 1000000000ULL;
         }
         return 0;
     } else {
@@ -886,7 +885,7 @@ static int if_encap6(Slirp *slirp, struct mbuf *ifm, struct ethhdr *eh,
         if (!ifm->resolution_requested) {
             ndp_send_ns(slirp, ip6h->ip_dst);
             ifm->resolution_requested = true;
-            ifm->expiration_date = slirp->cb->clock_get_ns() + 1000000000ULL;
+            ifm->expiration_date = slirp->cb->clock_get_ns(slirp->opaque) + 1000000000ULL;
         }
         return 0;
     } else {
@@ -961,7 +960,7 @@ int slirp_remove_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr,
             getsockname(so->s, (struct sockaddr *)&addr, &addr_len) == 0 &&
             addr.sin_addr.s_addr == host_addr.s_addr &&
             addr.sin_port == port) {
-            so->slirp->cb->unregister_poll_fd(so->s);
+            so->slirp->cb->unregister_poll_fd(so->s, so->slirp->opaque);
             slirp_closesocket(so->s);
             sofree(so);
             return 0;
diff --git a/slirp/socket.c b/slirp/socket.c
index c896fa6da3..ce1d6ffa1d 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -930,6 +930,6 @@ void sotranslate_accept(struct socket *so)
 void sodrop(struct socket *s, int num)
 {
     if (sbdrop(&s->so_snd, num)) {
-        s->slirp->cb->notify();
+        s->slirp->cb->notify(s->slirp->opaque);
     }
 }
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index e35628a892..cda94815f6 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -336,7 +336,7 @@ tcp_close(struct tcpcb *tp)
 	/* clobber input socket cache if we're closing the cached connection */
 	if (so == slirp->tcp_last_so)
 		slirp->tcp_last_so = &slirp->tcb;
-	so->slirp->cb->unregister_poll_fd(so->s);
+	so->slirp->cb->unregister_poll_fd(so->s, so->slirp->opaque);
 	slirp_closesocket(so->s);
 	sbfree(&so->so_rcv);
 	sbfree(&so->so_snd);
@@ -413,7 +413,7 @@ int tcp_fconnect(struct socket *so, unsigned short af)
     struct sockaddr_storage addr;
 
     slirp_set_nonblock(s);
-    so->slirp->cb->register_poll_fd(so->s);
+    so->slirp->cb->register_poll_fd(so->s, so->slirp->opaque);
     slirp_socket_set_fast_reuse(s);
     opt = 1;
     slirp_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(opt));
@@ -486,7 +486,7 @@ void tcp_connect(struct socket *inso)
         return;
     }
     slirp_set_nonblock(s);
-    so->slirp->cb->register_poll_fd(so->s);
+    so->slirp->cb->register_poll_fd(so->s, so->slirp->opaque);
     slirp_socket_set_fast_reuse(s);
     opt = 1;
     slirp_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
@@ -498,7 +498,7 @@ void tcp_connect(struct socket *inso)
     /* Close the accept() socket, set right state */
     if (inso->so_state & SS_FACCEPTONCE) {
         /* If we only accept once, close the accept() socket */
-        so->slirp->cb->unregister_poll_fd(so->s);
+        so->slirp->cb->unregister_poll_fd(so->s, so->slirp->opaque);
         slirp_closesocket(so->s);
 
         /* Don't select it yet, even though we have an FD */
diff --git a/slirp/udp.c b/slirp/udp.c
index 5baa604b33..29a31e9400 100644
--- a/slirp/udp.c
+++ b/slirp/udp.c
@@ -291,7 +291,7 @@ udp_attach(struct socket *so, unsigned short af)
 void
 udp_detach(struct socket *so)
 {
-	so->slirp->cb->unregister_poll_fd(so->s);
+	so->slirp->cb->unregister_poll_fd(so->s, so->slirp->opaque);
 	slirp_closesocket(so->s);
 	sofree(so);
 }
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PULLv4 32/32] slirp: API is extern C
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
                   ` (30 preceding siblings ...)
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 31/32] slirp: pass opaque to all callbacks Samuel Thibault
@ 2019-02-07 14:03 ` Samuel Thibault
  2019-02-07 14:59 ` [Qemu-devel] [PULLv4 00/32] More work towards libslirp no-reply
  2019-02-08 10:58 ` Peter Maydell
  33 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 14:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Marc-André Lureau, stefanha, jan.kiszka, Samuel Thibault

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Make it possible to use headers easily with C++ projects.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 slirp/libslirp.h | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 9b13d8250c..fccab42518 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -12,6 +12,10 @@
 #include <arpa/inet.h>
 #endif
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 typedef struct Slirp Slirp;
 
 enum {
@@ -96,5 +100,8 @@ void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr,
                        int guest_port, const uint8_t *buf, int size);
 size_t slirp_socket_can_recv(Slirp *slirp, struct in_addr guest_addr,
                              int guest_port);
-
+#ifdef __cplusplus
+} /* extern "C" */
 #endif
+
+#endif /* LIBSLIRP_H */
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PULLv4 00/32] More work towards libslirp
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
                   ` (31 preceding siblings ...)
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 32/32] slirp: API is extern C Samuel Thibault
@ 2019-02-07 14:59 ` no-reply
  2019-02-08 10:58 ` Peter Maydell
  33 siblings, 0 replies; 37+ messages in thread
From: no-reply @ 2019-02-07 14:59 UTC (permalink / raw)
  To: samuel.thibault; +Cc: fam, qemu-devel, peter.maydell, stefanha, jan.kiszka

Patchew URL: https://patchew.org/QEMU/20190207140316.16103-1-samuel.thibault@ens-lyon.org/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Subject: [Qemu-devel] [PULLv4 00/32] More work towards libslirp
Type: series
Message-id: 20190207140316.16103-1-samuel.thibault@ens-lyon.org

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
   713acc316d..1dca054955  master     -> master
 * [new tag]               patchew/20190207140316.16103-1-samuel.thibault@ens-lyon.org -> patchew/20190207140316.16103-1-samuel.thibault@ens-lyon.org
 t [tag update]            patchew/cover.1549545591.git.berto@igalia.com -> patchew/cover.1549545591.git.berto@igalia.com
Switched to a new branch 'test'
33314ca993 slirp: API is extern C
def44b9e1f slirp: pass opaque to all callbacks
619e3c22a9 slirp: use polling callbacks, drop glib requirement
25ed9a94b9 slirp: remove slirp_instances list
766080e20c slirp: replace global polling with per-instance & notifier
19f0fbff0b slirp: improve send_packet() callback
0767ffe68b slirp: prefer c99 types over BSD kind
c862dcd06b slirp: replace remaining qemu headers dependency
ba4a673af8 slirp: Move g_spawn_async_with_fds_qemu compatibility to slirp/
114294c71e slirp: replace QEMU_BUILD_BUG_ON with G_STATIC_ASSERT
57ae54dfbb slirp: replace qemu qtailq with slirp own copy
f854704da1 slirp: replace net/eth.h inclusion with own defines
3e22f44481 slirp: remove now useless QEMU headers inclusions
626c91b06d slirp: remove qemu timer.h dependency
31ff9b5865 slirp: add slirp own version of pstrcpy
5de0bf1688 slirp: improve windows headers inclusion
0a644d3622 slirp: do not include qemu headers in libslirp.h public API header
3b5081836c slirp: move QEMU state saving to a separate unit
0714ba3864 slirp: replace qemu_notify_event() with a callback
7cb0bee111 slirp: add unregister_poll_fd() callback
bd2e721ae7 slirp: replace qemu_set_nonblock()
a014aaa497 slirp: replace most qemu socket utilities with slirp own version
4762ebf715 slirp: replace QEMU_PACKED with SLIRP_PACKED
98685cf72f slirp: replace trace functions with DEBUG calls
40df17f75a slirp: add callbacks for timer
f0223b5273 net/slirp: fix leaks on forwarding rule registration error
f4f2eb80b0 net/slirp: free forwarding rules on cleanup
73cf8f5d37 net/slirp: simplify checking for cmd: prefix
227239db78 slirp: generalize guestfwd with a callback based approach
96e2f65d10 slirp: Don't mark struct ipq or struct ipasfrag as packed
0185e3b3b9 slirp: Avoid marking naturally packed structs as QEMU_PACKED
52f09e0c1c slirp: Avoid unaligned 16bit memory access

=== OUTPUT BEGIN ===
1/32 Checking commit 52f09e0c1ccb (slirp: Avoid unaligned 16bit memory access)
2/32 Checking commit 0185e3b3b9ff (slirp: Avoid marking naturally packed structs as QEMU_PACKED)
3/32 Checking commit 96e2f65d109d (slirp: Don't mark struct ipq or struct ipasfrag as packed)
4/32 Checking commit 227239db78d4 (slirp: generalize guestfwd with a callback based approach)
ERROR: code indent should never use tabs
#148: FILE: slirp/misc.h:14:
+^ISlirpWriteCb write_cb;$

ERROR: code indent should never use tabs
#149: FILE: slirp/misc.h:15:
+^Ivoid *opaque;$

total: 2 errors, 0 warnings, 226 lines checked

Patch 4/32 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

5/32 Checking commit 73cf8f5d3774 (net/slirp: simplify checking for cmd: prefix)
6/32 Checking commit f4f2eb80b072 (net/slirp: free forwarding rules on cleanup)
7/32 Checking commit f0223b527316 (net/slirp: fix leaks on forwarding rule registration error)
8/32 Checking commit 40df17f75a79 (slirp: add callbacks for timer)
9/32 Checking commit 98685cf72fd0 (slirp: replace trace functions with DEBUG calls)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#100: 
deleted file mode 100644

total: 0 errors, 1 warnings, 62 lines checked

Patch 9/32 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
10/32 Checking commit 4762ebf7159d (slirp: replace QEMU_PACKED with SLIRP_PACKED)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#111: 
new file mode 100644

total: 0 errors, 1 warnings, 111 lines checked

Patch 10/32 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
11/32 Checking commit a014aaa49710 (slirp: replace most qemu socket utilities with slirp own version)
ERROR: code indent should never use tabs
#130: FILE: slirp/socket.c:190:
+^Inn = slirp_recv(so->s, iov[0].iov_base, iov[0].iov_len,0);$

ERROR: space required after that ',' (ctx:VxV)
#130: FILE: slirp/socket.c:190:
+       nn = slirp_recv(so->s, iov[0].iov_base, iov[0].iov_len,0);
                                                              ^

WARNING: line over 80 characters
#139: FILE: slirp/socket.c:206:
+                                       slirp_getsockopt(so->s, SOL_SOCKET, SO_ERROR,

ERROR: code indent should never use tabs
#139: FILE: slirp/socket.c:206:
+^I^I^I^I^Islirp_getsockopt(so->s, SOL_SOCKET, SO_ERROR,$

ERROR: space required after that ',' (ctx:VxV)
#148: FILE: slirp/socket.c:236:
+            ret = slirp_recv(so->s, iov[1].iov_base, iov[1].iov_len,0);
                                                                    ^

ERROR: code indent should never use tabs
#157: FILE: slirp/socket.c:557:
+^I  slirp_ioctlsocket(so->s, FIONREAD, &n);$

ERROR: code indent should never use tabs
#167: FILE: slirp/socket.c:722:
+^Iif (((s = slirp_socket(AF_INET,SOCK_STREAM,0)) < 0) ||$

ERROR: space required after that ',' (ctx:VxV)
#167: FILE: slirp/socket.c:722:
+       if (((s = slirp_socket(AF_INET,SOCK_STREAM,0)) < 0) ||
                                      ^

ERROR: space required after that ',' (ctx:VxV)
#167: FILE: slirp/socket.c:722:
+       if (((s = slirp_socket(AF_INET,SOCK_STREAM,0)) < 0) ||
                                                  ^

ERROR: do not use assignment in if condition
#167: FILE: slirp/socket.c:722:
+       if (((s = slirp_socket(AF_INET,SOCK_STREAM,0)) < 0) ||

ERROR: code indent should never use tabs
#168: FILE: slirp/socket.c:723:
+^I    (slirp_socket_set_fast_reuse(s) < 0) ||$

ERROR: code indent should never use tabs
#184: FILE: slirp/socket.c:740:
+^Islirp_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));$

ERROR: code indent should never use tabs
#187: FILE: slirp/socket.c:742:
+^Islirp_setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(int));$

ERROR: code indent should never use tabs
#200: FILE: slirp/tcp_subr.c:340:
+^Islirp_closesocket(so->s);$

ERROR: code indent should never use tabs
#267: FILE: slirp/udp.c:295:
+^Islirp_closesocket(so->s);$

ERROR: code indent should never use tabs
#276: FILE: slirp/udp.c:330:
+^Iso->s = slirp_socket(AF_INET,SOCK_DGRAM,0);$

ERROR: space required after that ',' (ctx:VxV)
#276: FILE: slirp/udp.c:330:
+       so->s = slirp_socket(AF_INET,SOCK_DGRAM,0);
                                    ^

ERROR: space required after that ',' (ctx:VxV)
#276: FILE: slirp/udp.c:330:
+       so->s = slirp_socket(AF_INET,SOCK_DGRAM,0);
                                               ^

ERROR: code indent should never use tabs
#285: FILE: slirp/udp.c:346:
+^Islirp_socket_set_fast_reuse(so->s);$

WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#290: 
new file mode 100644

ERROR: return of an errno should typically be -ve (return -EINTR)
#379: FILE: slirp/util.c:85:
+        return EINTR;

ERROR: return of an errno should typically be -ve (return -EINVAL)
#381: FILE: slirp/util.c:87:
+        return EINVAL;

ERROR: return of an errno should typically be -ve (return -EBADF)
#383: FILE: slirp/util.c:89:
+        return EBADF;

ERROR: return of an errno should typically be -ve (return -ENOMEM)
#385: FILE: slirp/util.c:91:
+        return ENOMEM;

ERROR: return of an errno should typically be -ve (return -EINVAL)
#387: FILE: slirp/util.c:93:
+        return EINVAL;

ERROR: return of an errno should typically be -ve (return -ENAMETOOLONG)
#389: FILE: slirp/util.c:95:
+        return ENAMETOOLONG;

ERROR: return of an errno should typically be -ve (return -ENOTEMPTY)
#391: FILE: slirp/util.c:97:
+        return ENOTEMPTY;

WARNING: Block comments use a leading /* on a separate line
#393: FILE: slirp/util.c:99:
+         /* not using EWOULDBLOCK as we don't want code to have

WARNING: Block comments use a trailing */ on a separate line
#394: FILE: slirp/util.c:100:
+          * to check both EWOULDBLOCK and EAGAIN */

ERROR: return of an errno should typically be -ve (return -EAGAIN)
#395: FILE: slirp/util.c:101:
+        return EAGAIN;

ERROR: return of an errno should typically be -ve (return -EINPROGRESS)
#397: FILE: slirp/util.c:103:
+        return EINPROGRESS;

ERROR: return of an errno should typically be -ve (return -EALREADY)
#399: FILE: slirp/util.c:105:
+        return EALREADY;

ERROR: return of an errno should typically be -ve (return -ENOTSOCK)
#401: FILE: slirp/util.c:107:
+        return ENOTSOCK;

ERROR: return of an errno should typically be -ve (return -EDESTADDRREQ)
#403: FILE: slirp/util.c:109:
+        return EDESTADDRREQ;

ERROR: return of an errno should typically be -ve (return -EMSGSIZE)
#405: FILE: slirp/util.c:111:
+        return EMSGSIZE;

ERROR: return of an errno should typically be -ve (return -EPROTOTYPE)
#407: FILE: slirp/util.c:113:
+        return EPROTOTYPE;

ERROR: return of an errno should typically be -ve (return -ENOPROTOOPT)
#409: FILE: slirp/util.c:115:
+        return ENOPROTOOPT;

ERROR: return of an errno should typically be -ve (return -EPROTONOSUPPORT)
#411: FILE: slirp/util.c:117:
+        return EPROTONOSUPPORT;

ERROR: return of an errno should typically be -ve (return -EOPNOTSUPP)
#413: FILE: slirp/util.c:119:
+        return EOPNOTSUPP;

ERROR: return of an errno should typically be -ve (return -EAFNOSUPPORT)
#415: FILE: slirp/util.c:121:
+        return EAFNOSUPPORT;

ERROR: return of an errno should typically be -ve (return -EADDRINUSE)
#417: FILE: slirp/util.c:123:
+        return EADDRINUSE;

ERROR: return of an errno should typically be -ve (return -EADDRNOTAVAIL)
#419: FILE: slirp/util.c:125:
+        return EADDRNOTAVAIL;

ERROR: return of an errno should typically be -ve (return -ENETDOWN)
#421: FILE: slirp/util.c:127:
+        return ENETDOWN;

ERROR: return of an errno should typically be -ve (return -ENETUNREACH)
#423: FILE: slirp/util.c:129:
+        return ENETUNREACH;

ERROR: return of an errno should typically be -ve (return -ENETRESET)
#425: FILE: slirp/util.c:131:
+        return ENETRESET;

ERROR: return of an errno should typically be -ve (return -ECONNABORTED)
#427: FILE: slirp/util.c:133:
+        return ECONNABORTED;

ERROR: return of an errno should typically be -ve (return -ECONNRESET)
#429: FILE: slirp/util.c:135:
+        return ECONNRESET;

ERROR: return of an errno should typically be -ve (return -ENOBUFS)
#431: FILE: slirp/util.c:137:
+        return ENOBUFS;

ERROR: return of an errno should typically be -ve (return -EISCONN)
#433: FILE: slirp/util.c:139:
+        return EISCONN;

ERROR: return of an errno should typically be -ve (return -ENOTCONN)
#435: FILE: slirp/util.c:141:
+        return ENOTCONN;

ERROR: return of an errno should typically be -ve (return -ETIMEDOUT)
#437: FILE: slirp/util.c:143:
+        return ETIMEDOUT;

ERROR: return of an errno should typically be -ve (return -ECONNREFUSED)
#439: FILE: slirp/util.c:145:
+        return ECONNREFUSED;

ERROR: return of an errno should typically be -ve (return -ELOOP)
#441: FILE: slirp/util.c:147:
+        return ELOOP;

ERROR: return of an errno should typically be -ve (return -EHOSTUNREACH)
#443: FILE: slirp/util.c:149:
+        return EHOSTUNREACH;

ERROR: return of an errno should typically be -ve (return -EIO)
#445: FILE: slirp/util.c:151:
+        return EIO;

WARNING: line over 80 characters
#514: FILE: slirp/util.h:61:
+#define slirp_recv(sockfd, buf, len, flags) recv(sockfd, (void *)buf, len, flags)

WARNING: Block comments use a leading /* on a separate line
#537: FILE: slirp/util.h:84:
+    /* Enabling the reuse of an endpoint that was used by a socket still in

WARNING: Block comments use a trailing */ on a separate line
#541: FILE: slirp/util.h:88:
+     * http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621.aspx */

total: 51 errors, 7 warnings, 477 lines checked

Patch 11/32 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

12/32 Checking commit bd2e721ae757 (slirp: replace qemu_set_nonblock())
13/32 Checking commit 7cb0bee1113c (slirp: add unregister_poll_fd() callback)
ERROR: code indent should never use tabs
#87: FILE: slirp/tcp_subr.c:340:
+^Iso->slirp->cb->unregister_poll_fd(so->s);$

ERROR: code indent should never use tabs
#107: FILE: slirp/udp.c:295:
+^Iso->slirp->cb->unregister_poll_fd(so->s);$

total: 2 errors, 0 warnings, 63 lines checked

Patch 13/32 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

14/32 Checking commit 0714ba3864d3 (slirp: replace qemu_notify_event() with a callback)
ERROR: code indent should never use tabs
#115: FILE: slirp/tcp_input.c:509:
+^I^I^I^Isodrop(so, acked);$

ERROR: code indent should never use tabs
#124: FILE: slirp/tcp_input.c:1121:
+^I^I^Isodrop(so, (int)so->so_snd.sb_cc);$

ERROR: code indent should never use tabs
#128: FILE: slirp/tcp_input.c:1124:
+^I^I^Isodrop(so, acked);$

total: 3 errors, 0 warnings, 79 lines checked

Patch 14/32 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

15/32 Checking commit 3b5081836c51 (slirp: move QEMU state saving to a separate unit)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#455: 
new file mode 100644

WARNING: Block comments use a leading /* on a separate line
#547: FILE: slirp/state.c:88:
+/* The sbuf has a pair of pointers that are migrated as offsets;

WARNING: Block comments use a leading /* on a separate line
#645: FILE: slirp/state.c:186:
+/* The OS provided ss_family field isn't that portable; it's size

ERROR: if this code is redundant consider removing it
#715: FILE: slirp/state.c:256:
+#if 0

total: 1 errors, 3 warnings, 475 lines checked

Patch 15/32 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

16/32 Checking commit 0a644d36220d (slirp: do not include qemu headers in libslirp.h public API header)
17/32 Checking commit 5de0bf168845 (slirp: improve windows headers inclusion)
18/32 Checking commit 31ff9b5865a3 (slirp: add slirp own version of pstrcpy)
WARNING: line over 80 characters
#37: FILE: slirp/tftp.c:219:
+  slirp_pstrcpy((char *)tp->x.tp_error.tp_msg, sizeof(tp->x.tp_error.tp_msg), msg);

ERROR: braces {} are necessary for all arms of this statement
#55: FILE: slirp/util.c:197:
+    if (buf_size <= 0)
[...]

ERROR: space required before the open parenthesis '('
#58: FILE: slirp/util.c:200:
+    for(;;) {

ERROR: braces {} are necessary for all arms of this statement
#60: FILE: slirp/util.c:202:
+        if (c == 0 || q >= buf + buf_size - 1)
[...]

total: 3 errors, 1 warnings, 44 lines checked

Patch 18/32 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

19/32 Checking commit 626c91b06dba (slirp: remove qemu timer.h dependency)
20/32 Checking commit 3e22f44481de (slirp: remove now useless QEMU headers inclusions)
21/32 Checking commit f854704da1d5 (slirp: replace net/eth.h inclusion with own defines)
22/32 Checking commit 57ae54dfbb62 (slirp: replace qemu qtailq with slirp own copy)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#12: 
new file mode 100644

WARNING: Block comments use a leading /* on a separate line
#76: FILE: slirp/qtailq.h:60:
+        struct type *tqh_first;       /* first element */               \

WARNING: Block comments use a leading /* on a separate line
#77: FILE: slirp/qtailq.h:61:
+        QTailQLink tqh_circ;          /* link for circular backwards list */ \

WARNING: Block comments use a leading /* on a separate line
#85: FILE: slirp/qtailq.h:69:
+        struct type *tqe_next;        /* next element */                \

WARNING: Block comments use a leading /* on a separate line
#86: FILE: slirp/qtailq.h:70:
+        QTailQLink tqe_circ;          /* link for circular backwards list */ \

WARNING: Block comments use a leading /* on a separate line
#92: FILE: slirp/qtailq.h:76:
+} while (/*CONSTCOND*/0)

ERROR: do not use assignment in if condition
#95: FILE: slirp/qtailq.h:79:
+        if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)        \

WARNING: Block comments use a leading /* on a separate line
#102: FILE: slirp/qtailq.h:86:
+} while (/*CONSTCOND*/0)

WARNING: Block comments use a leading /* on a separate line
#109: FILE: slirp/qtailq.h:93:
+} while (/*CONSTCOND*/0)

ERROR: do not use assignment in if condition
#112: FILE: slirp/qtailq.h:96:
+        if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\

WARNING: Block comments use a leading /* on a separate line
#119: FILE: slirp/qtailq.h:103:
+} while (/*CONSTCOND*/0)

WARNING: Block comments use a leading /* on a separate line
#126: FILE: slirp/qtailq.h:110:
+} while (/*CONSTCOND*/0)

WARNING: Block comments use a leading /* on a separate line
#136: FILE: slirp/qtailq.h:120:
+} while (/*CONSTCOND*/0)

WARNING: line over 80 characters
#164: FILE: slirp/qtailq.h:148:
+#define QTAILQ_IN_USE(elm, field)        ((elm)->field.tqe_circ.tql_prev != NULL)

WARNING: line over 80 characters
#171: FILE: slirp/qtailq.h:155:
+        ((typeof((elm)->field.tqe_next)) QTAILQ_LINK_PREV((elm)->field.tqe_circ))

WARNING: line over 80 characters
#202: FILE: slirp/qtailq.h:186:
+#define QTAILQ_RAW_INSERT_TAIL(head, elm, entry) do {                           \

WARNING: line over 80 characters
#203: FILE: slirp/qtailq.h:187:
+        *QTAILQ_RAW_NEXT(elm, entry) = NULL;                                    \

WARNING: line over 80 characters
#204: FILE: slirp/qtailq.h:188:
+        QTAILQ_RAW_TQE_CIRC(elm, entry)->tql_prev = QTAILQ_RAW_TQH_CIRC(head)->tql_prev; \

WARNING: line over 80 characters
#205: FILE: slirp/qtailq.h:189:
+        QTAILQ_RAW_TQH_CIRC(head)->tql_prev->tql_next = (elm);                  \

WARNING: line over 80 characters
#206: FILE: slirp/qtailq.h:190:
+        QTAILQ_RAW_TQH_CIRC(head)->tql_prev = QTAILQ_RAW_TQE_CIRC(elm, entry);  \

WARNING: Block comments use a leading /* on a separate line
#207: FILE: slirp/qtailq.h:191:
+} while (/*CONSTCOND*/0)

total: 2 errors, 19 warnings, 202 lines checked

Patch 22/32 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

23/32 Checking commit 114294c71eca (slirp: replace QEMU_BUILD_BUG_ON with G_STATIC_ASSERT)
24/32 Checking commit ba4a673af8ae (slirp: Move g_spawn_async_with_fds_qemu compatibility to slirp/)
25/32 Checking commit c862dcd06b2f (slirp: replace remaining qemu headers dependency)
26/32 Checking commit 0767ffe68b02 (slirp: prefer c99 types over BSD kind)
ERROR: code indent should never use tabs
#60: FILE: slirp/ip_icmp.h:47:
+^Iuint8_t^Iicmp_type;^I^I/* type of message, see below */$

ERROR: code indent should never use tabs
#61: FILE: slirp/ip_icmp.h:48:
+^Iuint8_t^Iicmp_code;^I^I/* type sub code */$

WARNING: line over 80 characters
#62: FILE: slirp/ip_icmp.h:49:
+       uint16_t        icmp_cksum;             /* ones complement cksum of struct */

ERROR: code indent should never use tabs
#62: FILE: slirp/ip_icmp.h:49:
+^Iuint16_t^Iicmp_cksum;^I^I/* ones complement cksum of struct */$

ERROR: code indent should never use tabs
#65: FILE: slirp/ip_icmp.h:51:
+^I^Iuint8_t ih_pptr;^I^I^I/* ICMP_PARAMPROB */$

ERROR: code indent should never use tabs
#70: FILE: slirp/ip_icmp.h:54:
+^I^I^Iuint16_t^Iicd_id;$

ERROR: code indent should never use tabs
#71: FILE: slirp/ip_icmp.h:55:
+^I^I^Iuint16_t^Iicd_seq;$

ERROR: code indent should never use tabs
#79: FILE: slirp/ip_icmp.h:61:
+^I^I^Iuint16_t ipm_void;$

ERROR: code indent should never use tabs
#80: FILE: slirp/ip_icmp.h:62:
+^I^I^Iuint16_t ipm_nextmtu;$

ERROR: code indent should never use tabs
#102: FILE: slirp/ip_input.c:461:
+^Iregister char *opts;$

ERROR: code indent should never use tabs
#107: FILE: slirp/ip_input.c:465:
+^Iopts = (char *)(ip + 1);$

ERROR: code indent should never use tabs
#133: FILE: slirp/mbuf.h:88:
+^Ichar *m_data;^I^I^I/* Current location of data */$

ERROR: space prohibited before that close parenthesis ')'
#167: FILE: slirp/slirp.c:95:
+        printf("GetNetworkParams failed. ret = %08x\n", (unsigned)ret );

ERROR: code indent should never use tabs
#231: FILE: slirp/socket.c:509:
+^I    uint8_t code=ICMP_UNREACH_PORT;$

ERROR: spaces required around that '=' (ctx:VxV)
#231: FILE: slirp/socket.c:509:
+           uint8_t code=ICMP_UNREACH_PORT;
                        ^

ERROR: code indent should never use tabs
#255: FILE: slirp/socket.h:64:
+  unsigned^Iso_expire;^I^I/* When the socket will expire */$

ERROR: "foo * bar" should be "foo *bar"
#264: FILE: slirp/socket.h:147:
+struct socket * tcp_listen(Slirp *, uint32_t, unsigned, uint32_t, unsigned,

ERROR: code indent should never use tabs
#286: FILE: slirp/tcp_input.c:200:
+^Ichar *optp = NULL;$

ERROR: code indent should never use tabs
#295: FILE: slirp/tcp_input.c:208:
+^Iuint32_t tiwin;$

ERROR: code indent should never use tabs
#304: FILE: slirp/tcp_input.c:330:
+^I  optp = mtod(m, char *) + sizeof (struct tcpiphdr);$

ERROR: space prohibited between function name and open parenthesis '('
#304: FILE: slirp/tcp_input.c:330:
+         optp = mtod(m, char *) + sizeof (struct tcpiphdr);

ERROR: code indent should never use tabs
#313: FILE: slirp/tcp_input.c:472:
+^I^Itcp_dooptions(tp, (uint8_t *)optp, optlen, ti);$

ERROR: code indent should never use tabs
#322: FILE: slirp/tcp_input.c:727:
+^I    tcp_dooptions(tp, (uint8_t *)optp, optlen, ti);$

ERROR: code indent should never use tabs
#331: FILE: slirp/tcp_input.c:1042:
+^I^I^I^I^Iunsigned win =$

ERROR: code indent should never use tabs
#341: FILE: slirp/tcp_input.c:1111:
+^I^I  register unsigned cw = tp->snd_cwnd;$

ERROR: code indent should never use tabs
#342: FILE: slirp/tcp_input.c:1112:
+^I^I  register unsigned incr = tp->t_maxseg;$

ERROR: code indent should never use tabs
#382: FILE: slirp/tcp_output.c:66:
+^Iuint8_t opt[MAX_TCPOPTLEN];$

ERROR: code indent should never use tabs
#391: FILE: slirp/tcp_output.c:274:
+^I^I^Imemcpy((char *)(opt + 2), (char *)&mss, sizeof(mss));$

ERROR: code indent should never use tabs
#400: FILE: slirp/tcp_output.c:304:
+^I^Isbcopy(&so->so_snd, off, (int) len, mtod(m, char *) + hdrlen);$

ERROR: code indent should never use tabs
#409: FILE: slirp/tcp_output.c:327:
+^Imemcpy((char *)ti, &tp->t_template, sizeof (struct tcpiphdr));$

ERROR: space prohibited between function name and open parenthesis '('
#409: FILE: slirp/tcp_output.c:327:
+       memcpy((char *)ti, &tp->t_template, sizeof (struct tcpiphdr));

ERROR: code indent should never use tabs
#418: FILE: slirp/tcp_output.c:356:
+^I^Imemcpy((char *)(ti + 1), (char *)opt, optlen);$

ERROR: code indent should never use tabs
#431: FILE: slirp/tcp_subr.c:166:
+^I^Im->m_data = (char *)ti;$

ERROR: code indent should never use tabs
#440: FILE: slirp/tcp_subr.c:185:
+^Iti->ti_len = htons((uint16_t)(sizeof (struct tcphdr) + tlen));$

ERROR: space prohibited between function name and open parenthesis '('
#440: FILE: slirp/tcp_subr.c:185:
+       ti->ti_len = htons((uint16_t)(sizeof (struct tcphdr) + tlen));

ERROR: code indent should never use tabs
#449: FILE: slirp/tcp_subr.c:616:
+^Iunsigned n1, n2, n3, n4, n5, n6;$

ERROR: code indent should never use tabs
#453: FILE: slirp/tcp_subr.c:619:
+^Iunsigned lport;$

ERROR: code indent should never use tabs
#462: FILE: slirp/tcp_subr.c:856:
+^I^I^Iuint16_t p;$

ERROR: code indent should never use tabs
#472: FILE: slirp/tcp_subr.c:912:
+^I^I^I^Ilport = (((uint8_t*)bptr)[0] << 8)$

ERROR: "(foo*)" should be "(foo *)"
#472: FILE: slirp/tcp_subr.c:912:
+                               lport = (((uint8_t*)bptr)[0] << 8)

ERROR: code indent should never use tabs
#473: FILE: slirp/tcp_subr.c:913:
+^I^I^I^I+ ((uint8_t *)bptr)[1];$

ERROR: code indent should never use tabs
#483: FILE: slirp/tcp_subr.c:931:
+^I^I^I^I*(uint8_t *)bptr++ = (p >> 8) & 0xff;$

WARNING: line over 80 characters
#497: FILE: slirp/tcp_timer.c:235:
+                unsigned win = MIN(tp->snd_wnd, tp->snd_cwnd) / 2 / tp->t_maxseg;

ERROR: code indent should never use tabs
#510: FILE: slirp/tcp_var.h:50:
+^Iuint16_t^It_maxseg;^I^I/* maximum segment size */$

ERROR: code indent should never use tabs
#513: FILE: slirp/tcp_var.h:52:
+^Iuint16_t^It_flags;$

ERROR: code indent should never use tabs
#522: FILE: slirp/tcp_var.h:108:
+^Iuint16_t^It_rttmin;^I^I/* minimum rtt allowed */$

ERROR: code indent should never use tabs
#534: FILE: slirp/tcp_var.h:119:
+^Iuint8_t^Isnd_scale;^I^I/* window scaling for send window */$

ERROR: code indent should never use tabs
#535: FILE: slirp/tcp_var.h:120:
+^Iuint8_t^Ircv_scale;^I^I/* window scaling for recv window */$

ERROR: code indent should never use tabs
#536: FILE: slirp/tcp_var.h:121:
+^Iuint8_t^Irequest_r_scale;^I/* pending window scaling */$

ERROR: code indent should never use tabs
#537: FILE: slirp/tcp_var.h:122:
+^Iuint8_t^Irequested_s_scale;$

ERROR: code indent should never use tabs
#550: FILE: slirp/udp.c:95:
+^Iuh = (struct udphdr *)((char *)ip + iphlen);$

ERROR: "foo * bar" should be "foo *bar"
#574: FILE: slirp/udp.h:81:
+struct socket * udp_listen(Slirp *, uint32_t, unsigned, uint32_t, unsigned,

ERROR: externs should be avoided in .c files
#587: FILE: util/osdep.c:32:
+extern int madvise(char *, size_t, int);

total: 51 errors, 2 warnings, 455 lines checked

Patch 26/32 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

27/32 Checking commit 19f0fbff0be6 (slirp: improve send_packet() callback)
28/32 Checking commit 766080e20c1f (slirp: replace global polling with per-instance & notifier)
ERROR: spaces required around that '/' (ctx:VxV)
#237: FILE: slirp/slirp.c:471:
+            (so->so_snd.sb_cc < (so->so_snd.sb_datalen/2))) {
                                                       ^

WARNING: Block comments use a leading /* on a separate line
#565: FILE: slirp/slirp.c:611:
+                    /* Socket error might have resulted in the socket being

WARNING: Block comments use a trailing */ on a separate line
#566: FILE: slirp/slirp.c:612:
+                     * removed, do not try to do anything more with it. */

WARNING: Block comments use a leading /* on a separate line
#594: FILE: slirp/slirp.c:634:
+                    /* Socket error might have resulted in the socket being

WARNING: Block comments use a trailing */ on a separate line
#595: FILE: slirp/slirp.c:635:
+                     * removed, do not try to do anything more with it. */

WARNING: Block comments use a leading /* on a separate line
#653: FILE: slirp/slirp.c:675:
+                        /* Call tcp_output in case we need to send a window

WARNING: Block comments use a trailing */ on a separate line
#655: FILE: slirp/slirp.c:677:
+                         * until it sends a window probe. */

WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#817: 
deleted file mode 100644

total: 1 errors, 7 warnings, 829 lines checked

Patch 28/32 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

29/32 Checking commit 25ed9a94b9c2 (slirp: remove slirp_instances list)
30/32 Checking commit 619e3c22a900 (slirp: use polling callbacks, drop glib requirement)
31/32 Checking commit def44b9e1f42 (slirp: pass opaque to all callbacks)
WARNING: line over 80 characters
#95: FILE: slirp/dhcpv6.c:62:
+            slirp->cb->guest_error("Guest sent bad DHCPv6 packet!", slirp->opaque);

WARNING: line over 80 characters
#131: FILE: slirp/ip6_icmp.c:28:
+    slirp->ra_timer = slirp->cb->timer_new(ra_timer_handler, slirp, slirp->opaque);

WARNING: line over 80 characters
#276: FILE: slirp/slirp.c:888:
+            ifm->expiration_date = slirp->cb->clock_get_ns(slirp->opaque) + 1000000000ULL;

ERROR: code indent should never use tabs
#310: FILE: slirp/tcp_subr.c:339:
+^Iso->slirp->cb->unregister_poll_fd(so->s, so->slirp->opaque);$

ERROR: code indent should never use tabs
#350: FILE: slirp/udp.c:294:
+^Iso->slirp->cb->unregister_poll_fd(so->s, so->slirp->opaque);$

total: 2 errors, 3 warnings, 273 lines checked

Patch 31/32 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

32/32 Checking commit 33314ca9936c (slirp: API is extern C)
WARNING: architecture specific defines should be avoided
#21: FILE: slirp/libslirp.h:15:
+#ifdef __cplusplus

WARNING: architecture specific defines should be avoided
#33: FILE: slirp/libslirp.h:103:
+#ifdef __cplusplus

total: 0 errors, 2 warnings, 19 lines checked

Patch 32/32 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/20190207140316.16103-1-samuel.thibault@ens-lyon.org/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@redhat.com

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PULLv4 27/32] slirp: improve send_packet() callback
  2019-02-07 14:03 ` [Qemu-devel] [PULLv4 27/32] slirp: improve send_packet() callback Samuel Thibault
@ 2019-02-07 18:31   ` Philippe Mathieu-Daudé
  2019-02-07 19:04     ` Samuel Thibault
  0 siblings, 1 reply; 37+ messages in thread
From: Philippe Mathieu-Daudé @ 2019-02-07 18:31 UTC (permalink / raw)
  To: Samuel Thibault, Marc-André Lureau, Daniel P. Berrange
  Cc: qemu-devel, peter.maydell, stefanha, jan.kiszka

Hi Samuel,

On 2/7/19 3:03 PM, Samuel Thibault wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
> 
> Use a more descriptive name for the callback.
> 
> Reuse the SlirpWriteCb type. Wrap it to check that all data has been written.
> 
> Return a ssize_t for potential error handling and data-loss reporting.
> 
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
> ---
>  include/net/net.h |  2 +-
>  net/net.c         |  4 ++--
>  net/slirp.c       |  9 +++++----
>  slirp/libslirp.h  | 11 +++++++----
>  slirp/ncsi.c      |  2 +-
>  slirp/slirp.c     | 18 +++++++++++++++---
>  slirp/slirp.h     |  2 ++
>  7 files changed, 33 insertions(+), 15 deletions(-)
> 
> diff --git a/include/net/net.h b/include/net/net.h
> index 643295d163..075cc01267 100644
> --- a/include/net/net.h
> +++ b/include/net/net.h
> @@ -146,7 +146,7 @@ ssize_t qemu_sendv_packet(NetClientState *nc, const struct iovec *iov,
>                            int iovcnt);
>  ssize_t qemu_sendv_packet_async(NetClientState *nc, const struct iovec *iov,
>                                  int iovcnt, NetPacketSent *sent_cb);
> -void qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size);
> +ssize_t qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size);
>  ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int size);
>  ssize_t qemu_send_packet_async(NetClientState *nc, const uint8_t *buf,
>                                 int size, NetPacketSent *sent_cb);
> diff --git a/net/net.c b/net/net.c
> index 3acbdccd61..5dcff7fe2a 100644
> --- a/net/net.c
> +++ b/net/net.c
> @@ -668,9 +668,9 @@ ssize_t qemu_send_packet_async(NetClientState *sender,
>                                               buf, size, sent_cb);
>  }
>  
> -void qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size)
> +ssize_t qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size)
>  {
> -    qemu_send_packet_async(nc, buf, size, NULL);
> +    return qemu_send_packet_async(nc, buf, size, NULL);
>  }
>  
>  ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int size)
> diff --git a/net/slirp.c b/net/slirp.c
> index 7b4f9f5c5e..664ff1c002 100644
> --- a/net/slirp.c
> +++ b/net/slirp.c
> @@ -108,11 +108,12 @@ static void slirp_smb_cleanup(SlirpState *s);
>  static inline void slirp_smb_cleanup(SlirpState *s) { }
>  #endif
>  
> -static void net_slirp_output(void *opaque, const uint8_t *pkt, int pkt_len)
> +static ssize_t net_slirp_send_packet(const void *pkt, size_t pkt_len,
> +                                     void *opaque)
>  {
>      SlirpState *s = opaque;
>  
> -    qemu_send_packet(&s->nc, pkt, pkt_len);
> +    return qemu_send_packet(&s->nc, pkt, pkt_len);
>  }
>  
>  static ssize_t net_slirp_receive(NetClientState *nc, const uint8_t *buf, size_t size)
> @@ -197,7 +198,7 @@ static void net_slirp_unregister_poll_fd(int fd)
>  }
>  
>  static const SlirpCb slirp_cb = {
> -    .output = net_slirp_output,
> +    .send_packet = net_slirp_send_packet,
>      .guest_error = net_slirp_guest_error,
>      .clock_get_ns = net_slirp_clock_get_ns,
>      .timer_new = net_slirp_timer_new,
> @@ -780,7 +781,7 @@ static void guestfwd_read(void *opaque, const uint8_t *buf, int size)
>      slirp_socket_recv(fwd->slirp, fwd->server, fwd->port, buf, size);
>  }
>  
> -static int guestfwd_write(const void *buf, size_t len, void *chr)
> +static ssize_t guestfwd_write(const void *buf, size_t len, void *chr)
>  {
>      return qemu_chr_fe_write_all(chr, buf, len);
>  }
> diff --git a/slirp/libslirp.h b/slirp/libslirp.h
> index 02cbec9f8b..8e5d4ed11b 100644
> --- a/slirp/libslirp.h
> +++ b/slirp/libslirp.h
> @@ -15,7 +15,7 @@
>  
>  typedef struct Slirp Slirp;
>  
> -typedef int (*SlirpWriteCb)(const void *buf, size_t len, void *opaque);
> +typedef ssize_t (*SlirpWriteCb)(const void *buf, size_t len, void *opaque);
>  typedef void (*SlirpTimerCb)(void *opaque);
>  
>  /*
> @@ -23,10 +23,13 @@ typedef void (*SlirpTimerCb)(void *opaque);
>   */
>  typedef struct SlirpCb {
>      /*
> -     * Send an ethernet frame to the guest network. The opaque parameter
> -     * is the one given to slirp_init().
> +     * Send an ethernet frame to the guest network. The opaque
> +     * parameter is the one given to slirp_init(). The function
> +     * doesn't need to send all the data and may return <len (no
> +     * buffering is done on libslirp side, so the data will be dropped
> +     * in this case). <0 reports an IO error.
>       */
> -    void (*output)(void *opaque, const uint8_t *pkt, int pkt_len);
> +    SlirpWriteCb send_packet;
>      /* Print a message for an error due to guest misbehavior.  */
>      void (*guest_error)(const char *msg);
>      /* Return the virtual clock value in nanoseconds */
> diff --git a/slirp/ncsi.c b/slirp/ncsi.c
> index 327f17543c..359f52c284 100644
> --- a/slirp/ncsi.c
> +++ b/slirp/ncsi.c
> @@ -162,5 +162,5 @@ void ncsi_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
>      *pchecksum = htonl(checksum);
>      ncsi_rsp_len += 4;
>  
> -    slirp->cb->output(slirp->opaque, ncsi_reply, ETH_HLEN + ncsi_rsp_len);
> +    slirp_send_packet_all(slirp, ncsi_reply, ETH_HLEN + ncsi_rsp_len);
>  }
> diff --git a/slirp/slirp.c b/slirp/slirp.c
> index 3304c83001..2bc53e3e12 100644
> --- a/slirp/slirp.c
> +++ b/slirp/slirp.c
> @@ -800,7 +800,7 @@ static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
>              rah->ar_sip = ah->ar_tip;
>              memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
>              rah->ar_tip = ah->ar_sip;
> -            slirp->cb->output(slirp->opaque, arp_reply, sizeof(arp_reply));
> +            slirp_send_packet_all(slirp, arp_reply, sizeof(arp_reply));
>          }
>          break;
>      case ARPOP_REPLY:
> @@ -900,7 +900,7 @@ static int if_encap4(Slirp *slirp, struct mbuf *ifm, struct ethhdr *eh,
>              /* target IP */
>              rah->ar_tip = iph->ip_dst.s_addr;
>              slirp->client_ipaddr = iph->ip_dst;
> -            slirp->cb->output(slirp->opaque, arp_req, sizeof(arp_req));
> +            slirp_send_packet_all(slirp, arp_req, sizeof(arp_req));
>              ifm->resolution_requested = true;
>  
>              /* Expire request and drop outgoing packet after 1 second */
> @@ -985,7 +985,7 @@ int if_encap(Slirp *slirp, struct mbuf *ifm)
>                eh->h_dest[0], eh->h_dest[1], eh->h_dest[2],
>                eh->h_dest[3], eh->h_dest[4], eh->h_dest[5]);
>      memcpy(buf + sizeof(struct ethhdr), ifm->m_data, ifm->m_len);
> -    slirp->cb->output(slirp->opaque, buf, ifm->m_len + ETH_HLEN);
> +    slirp_send_packet_all(slirp, buf, ifm->m_len + ETH_HLEN);
>      return 1;
>  }
>  
> @@ -1152,3 +1152,15 @@ void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr, int guest_port,
>      if (ret > 0)
>          tcp_output(sototcpcb(so));
>  }
> +
> +void slirp_send_packet_all(Slirp *slirp, const void *buf, size_t len)
> +{
> +    ssize_t ret = slirp->cb->send_packet(buf, len, slirp->opaque);
> +
> +    if (ret < 0) {
> +        g_critical("Failed to send packet, ret: %ld", (long) ret);

>From the v3 discussion [*] I thought send_packet() would return a
gssize, then we'd use G_GSSIZE_FORMAT here (and similarly use gssize
instead ssize_t in this series).
Anyway your fix is simpler. And we can still do this on top of this PR.

[*] https://lists.gnu.org/archive/html/qemu-devel/2019-02/msg01841.html

> +    } else if (ret < len) {
> +        DEBUG_ERROR("send_packet() didn't send all data: %ld < %lu",
> +                (long) ret, (unsigned long) len);
> +    }
> +}
> diff --git a/slirp/slirp.h b/slirp/slirp.h
> index 05b8364c07..752a4cd8c8 100644
> --- a/slirp/slirp.h
> +++ b/slirp/slirp.h
> @@ -269,4 +269,6 @@ struct tcpcb *tcp_drop(struct tcpcb *tp, int err);
>  struct socket *
>  slirp_find_ctl_socket(Slirp *slirp, struct in_addr guest_addr, int guest_port);
>  
> +void slirp_send_packet_all(Slirp *slirp, const void *buf, size_t len);
> +
>  #endif
> 

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PULLv4 27/32] slirp: improve send_packet() callback
  2019-02-07 18:31   ` Philippe Mathieu-Daudé
@ 2019-02-07 19:04     ` Samuel Thibault
  0 siblings, 0 replies; 37+ messages in thread
From: Samuel Thibault @ 2019-02-07 19:04 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé
  Cc: Marc-André Lureau, Daniel P. Berrange, qemu-devel,
	peter.maydell, stefanha, jan.kiszka

Philippe Mathieu-Daudé, le jeu. 07 févr. 2019 19:31:49 +0100, a ecrit:
> > +    if (ret < 0) {
> > +        g_critical("Failed to send packet, ret: %ld", (long) ret);
> 
> From the v3 discussion [*] I thought send_packet() would return a
> gssize, then we'd use G_GSSIZE_FORMAT here (and similarly use gssize
> instead ssize_t in this series).
> Anyway your fix is simpler.

That was the idea of my fix, yes :)

Samuel

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PULLv4 00/32] More work towards libslirp
  2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
                   ` (32 preceding siblings ...)
  2019-02-07 14:59 ` [Qemu-devel] [PULLv4 00/32] More work towards libslirp no-reply
@ 2019-02-08 10:58 ` Peter Maydell
  33 siblings, 0 replies; 37+ messages in thread
From: Peter Maydell @ 2019-02-08 10:58 UTC (permalink / raw)
  To: Samuel Thibault; +Cc: QEMU Developers, Stefan Hajnoczi, Jan Kiszka

On Thu, 7 Feb 2019 at 14:03, Samuel Thibault
<samuel.thibault@ens-lyon.org> wrote:
>
> The following changes since commit 713acc316ddca119fe168e72846f1d2dd0548430:
>
>   Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20190206' into staging (2019-02-07 11:46:40 +0000)
>
> are available in the Git repository at:
>
>   https://people.debian.org/~sthibault/qemu.git tags/samuel-thibault
>
> for you to fetch changes up to ee261c02332ea856352f250b295a8ecd1eeb748e:
>
>   slirp: API is extern C (2019-02-07 15:49:08 +0200)
>
> ----------------------------------------------------------------
> More work towards libslirp
>

Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/4.0
for any user-visible changes.

-- PMM

^ permalink raw reply	[flat|nested] 37+ messages in thread

end of thread, other threads:[~2019-02-08 10:58 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-07 14:02 [Qemu-devel] [PULLv4 00/32] More work towards libslirp Samuel Thibault
2019-02-07 14:02 ` [Qemu-devel] [PULLv4 01/32] slirp: Avoid unaligned 16bit memory access Samuel Thibault
2019-02-07 14:02 ` [Qemu-devel] [PULLv4 02/32] slirp: Avoid marking naturally packed structs as QEMU_PACKED Samuel Thibault
2019-02-07 14:02 ` [Qemu-devel] [PULLv4 03/32] slirp: Don't mark struct ipq or struct ipasfrag as packed Samuel Thibault
2019-02-07 14:02 ` [Qemu-devel] [PULLv4 04/32] slirp: generalize guestfwd with a callback based approach Samuel Thibault
2019-02-07 14:02 ` [Qemu-devel] [PULLv4 05/32] net/slirp: simplify checking for cmd: prefix Samuel Thibault
2019-02-07 14:02 ` [Qemu-devel] [PULLv4 06/32] net/slirp: free forwarding rules on cleanup Samuel Thibault
2019-02-07 14:02 ` [Qemu-devel] [PULLv4 07/32] net/slirp: fix leaks on forwarding rule registration error Samuel Thibault
2019-02-07 14:02 ` [Qemu-devel] [PULLv4 08/32] slirp: add callbacks for timer Samuel Thibault
2019-02-07 14:02 ` [Qemu-devel] [PULLv4 09/32] slirp: replace trace functions with DEBUG calls Samuel Thibault
2019-02-07 14:02 ` [Qemu-devel] [PULLv4 10/32] slirp: replace QEMU_PACKED with SLIRP_PACKED Samuel Thibault
2019-02-07 14:02 ` [Qemu-devel] [PULLv4 11/32] slirp: replace most qemu socket utilities with slirp own version Samuel Thibault
2019-02-07 14:02 ` [Qemu-devel] [PULLv4 12/32] slirp: replace qemu_set_nonblock() Samuel Thibault
2019-02-07 14:02 ` [Qemu-devel] [PULLv4 13/32] slirp: add unregister_poll_fd() callback Samuel Thibault
2019-02-07 14:02 ` [Qemu-devel] [PULLv4 14/32] slirp: replace qemu_notify_event() with a callback Samuel Thibault
2019-02-07 14:02 ` [Qemu-devel] [PULLv4 15/32] slirp: move QEMU state saving to a separate unit Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 16/32] slirp: do not include qemu headers in libslirp.h public API header Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 17/32] slirp: improve windows headers inclusion Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 18/32] slirp: add slirp own version of pstrcpy Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 19/32] slirp: remove qemu timer.h dependency Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 20/32] slirp: remove now useless QEMU headers inclusions Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 21/32] slirp: replace net/eth.h inclusion with own defines Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 22/32] slirp: replace qemu qtailq with slirp own copy Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 23/32] slirp: replace QEMU_BUILD_BUG_ON with G_STATIC_ASSERT Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 24/32] slirp: Move g_spawn_async_with_fds_qemu compatibility to slirp/ Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 25/32] slirp: replace remaining qemu headers dependency Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 26/32] slirp: prefer c99 types over BSD kind Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 27/32] slirp: improve send_packet() callback Samuel Thibault
2019-02-07 18:31   ` Philippe Mathieu-Daudé
2019-02-07 19:04     ` Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 28/32] slirp: replace global polling with per-instance & notifier Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 29/32] slirp: remove slirp_instances list Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 30/32] slirp: use polling callbacks, drop glib requirement Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 31/32] slirp: pass opaque to all callbacks Samuel Thibault
2019-02-07 14:03 ` [Qemu-devel] [PULLv4 32/32] slirp: API is extern C Samuel Thibault
2019-02-07 14:59 ` [Qemu-devel] [PULLv4 00/32] More work towards libslirp no-reply
2019-02-08 10:58 ` Peter Maydell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.