All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2)
@ 2019-01-17 11:43 Marc-André Lureau
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 01/27] slirp: generalize guestfwd with a callback based approach Marc-André Lureau
                   ` (28 more replies)
  0 siblings, 29 replies; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-17 11:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Samuel Thibault,
	Jason Wang

Hi,

The goal is to allow building libslirp as an independent library.

After this series is applied, it is possible to build an independent
libslirp.  However, QEMU still requires internals of libslirp to
handle migration. I will be posting the remaining part to handle
migration and link with the external libslirp in a 3rd part.

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 forwaring 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

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

-- 
2.20.1.98.gecbdaf0899

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

* [Qemu-devel] [PATCH 01/27] slirp: generalize guestfwd with a callback based approach
  2019-01-17 11:43 [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Marc-André Lureau
@ 2019-01-17 11:43 ` Marc-André Lureau
  2019-01-17 23:04   ` Samuel Thibault
  2019-01-26 23:47   ` Samuel Thibault
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 02/27] net/slirp: simplify checking for cmd: prefix Marc-André Lureau
                   ` (27 subsequent siblings)
  28 siblings, 2 replies; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-17 11:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Samuel Thibault,
	Jason Wang

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>
---
 slirp/libslirp.h |  6 +++++-
 slirp/misc.h     | 15 +++++++++++++--
 slirp/socket.h   |  4 +++-
 net/slirp.c      | 14 ++++++++++----
 slirp/misc.c     | 37 +++++++++++++++++++++++--------------
 slirp/slirp.c    | 27 +++++++++++++++++++--------
 slirp/tcp_subr.c |  4 ++--
 7 files changed, 75 insertions(+), 32 deletions(-)

diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 4611a7447b5..ea019828e8d 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.h b/slirp/misc.h
index 1df707c052d..c2ceadb591b 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/socket.h b/slirp/socket.h
index 930ed95972f..fc35ca5f72a 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/net/slirp.c b/net/slirp.c
index f98425ee9f4..ec07f662c00 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/misc.c b/slirp/misc.c
index eae9596a55d..b8a2bf971af 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/slirp.c b/slirp/slirp.c
index a9674ab0909..7b23722d5db 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/tcp_subr.c b/slirp/tcp_subr.c
index 23a841f26e4..4e81736d6fd 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.98.gecbdaf0899

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

* [Qemu-devel] [PATCH 02/27] net/slirp: simplify checking for cmd: prefix
  2019-01-17 11:43 [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Marc-André Lureau
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 01/27] slirp: generalize guestfwd with a callback based approach Marc-André Lureau
@ 2019-01-17 11:43 ` Marc-André Lureau
  2019-01-26 23:49   ` Samuel Thibault
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 03/27] net/slirp: free forwarding rules on cleanup Marc-André Lureau
                   ` (26 subsequent siblings)
  28 siblings, 1 reply; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-17 11:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Samuel Thibault,
	Jason Wang

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

diff --git a/net/slirp.c b/net/slirp.c
index ec07f662c00..b91741b8fc1 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.98.gecbdaf0899

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

* [Qemu-devel] [PATCH 03/27] net/slirp: free forwarding rules on cleanup
  2019-01-17 11:43 [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Marc-André Lureau
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 01/27] slirp: generalize guestfwd with a callback based approach Marc-André Lureau
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 02/27] net/slirp: simplify checking for cmd: prefix Marc-André Lureau
@ 2019-01-17 11:43 ` Marc-André Lureau
  2019-01-26 23:52   ` Samuel Thibault
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 04/27] net/slirp: fix leaks on forwaring rule registration error Marc-André Lureau
                   ` (25 subsequent siblings)
  28 siblings, 1 reply; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-17 11:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Samuel Thibault,
	Jason Wang

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

diff --git a/net/slirp.c b/net/slirp.c
index b91741b8fc1..750105a466e 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.98.gecbdaf0899

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

* [Qemu-devel] [PATCH 04/27] net/slirp: fix leaks on forwaring rule registration error
  2019-01-17 11:43 [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Marc-André Lureau
                   ` (2 preceding siblings ...)
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 03/27] net/slirp: free forwarding rules on cleanup Marc-André Lureau
@ 2019-01-17 11:43 ` Marc-André Lureau
  2019-01-17 17:50   ` Eric Blake
  2019-01-26 23:57   ` Samuel Thibault
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 05/27] slirp: add callbacks for timer Marc-André Lureau
                   ` (24 subsequent siblings)
  28 siblings, 2 replies; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-17 11:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Samuel Thibault,
	Jason Wang

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

diff --git a/net/slirp.c b/net/slirp.c
index 750105a466e..0b15f427f5c 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.98.gecbdaf0899

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

* [Qemu-devel] [PATCH 05/27] slirp: add callbacks for timer
  2019-01-17 11:43 [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Marc-André Lureau
                   ` (3 preceding siblings ...)
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 04/27] net/slirp: fix leaks on forwaring rule registration error Marc-André Lureau
@ 2019-01-17 11:43 ` Marc-André Lureau
  2019-01-27  0:01   ` Samuel Thibault
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 06/27] slirp: replace trace functions with DEBUG calls Marc-André Lureau
                   ` (23 subsequent siblings)
  28 siblings, 1 reply; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-17 11:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Samuel Thibault,
	Jason Wang

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

diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index ea019828e8d..3e75dadfa31 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 9aa245715dd..17056f4b836 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;
diff --git a/net/slirp.c b/net/slirp.c
index 0b15f427f5c..c24a779425b 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 5261baae271..e72c57a81dc 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,
-- 
2.20.1.98.gecbdaf0899

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

* [Qemu-devel] [PATCH 06/27] slirp: replace trace functions with DEBUG calls
  2019-01-17 11:43 [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Marc-André Lureau
                   ` (4 preceding siblings ...)
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 05/27] slirp: add callbacks for timer Marc-André Lureau
@ 2019-01-17 11:43 ` Marc-André Lureau
  2019-01-27  0:03   ` Samuel Thibault
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 07/27] slirp: replace QEMU_PACKED with SLIRP_PACKED Marc-André Lureau
                   ` (22 subsequent siblings)
  28 siblings, 1 reply; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-17 11:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Samuel Thibault,
	Jason Wang

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>
---
 slirp/debug.h      | 13 ++++++++++---
 slirp/slirp.c      |  1 +
 slirp/tftp.c       |  7 ++++---
 Makefile.objs      |  1 -
 slirp/trace-events |  5 -----
 5 files changed, 15 insertions(+), 12 deletions(-)
 delete mode 100644 slirp/trace-events

diff --git a/slirp/debug.h b/slirp/debug.h
index 269d97d8073..f6a048450dd 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 (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 7b23722d5db..dd72829017f 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 a9ba1480db4..6fb381ef337 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/Makefile.objs b/Makefile.objs
index 67a054b08af..b7aae33367f 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/trace-events b/slirp/trace-events
deleted file mode 100644
index ff8f656e8c5..00000000000
--- 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.98.gecbdaf0899

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

* [Qemu-devel] [PATCH 07/27] slirp: replace QEMU_PACKED with SLIRP_PACKED
  2019-01-17 11:43 [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Marc-André Lureau
                   ` (5 preceding siblings ...)
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 06/27] slirp: replace trace functions with DEBUG calls Marc-André Lureau
@ 2019-01-17 11:43 ` Marc-André Lureau
  2019-01-27  0:07   ` Samuel Thibault
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 08/27] slirp: replace most qemu socket utilities with slirp own version Marc-André Lureau
                   ` (21 subsequent siblings)
  28 siblings, 1 reply; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-17 11:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Samuel Thibault,
	Jason Wang

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 slirp/ip.h       | 14 +++++++-------
 slirp/ip6.h      |  4 ++--
 slirp/ip6_icmp.h | 16 ++++++++--------
 slirp/slirp.h    |  5 +++--
 slirp/util.h     | 32 ++++++++++++++++++++++++++++++++
 5 files changed, 52 insertions(+), 19 deletions(-)
 create mode 100644 slirp/util.h

diff --git a/slirp/ip.h b/slirp/ip.h
index 243b6c8b249..cd6ddf2bb7a 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
@@ -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;
+} SLIRP_PACKED;
 
 /*
  * Ip header, when holding a fragment.
@@ -227,7 +227,7 @@ struct ipq {
 struct	ipasfrag {
 	struct qlink ipf_link;
 	struct ip ipf_ip;
-} QEMU_PACKED;
+} SLIRP_PACKED;
 
 #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 14e9c787357..b6ba0a63927 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;
+} SLIRP_PACKED;
 
 /*
  * IPv6 pseudo-header used by upper-layer protocols
@@ -145,7 +145,7 @@ struct ip6_pseudohdr {
     uint16_t    ih_zero_hi;       /* zero */
     uint8_t     ih_zero_lo;       /* zero */
     uint8_t     ih_nh;            /* next header */
-} QEMU_PACKED;
+} SLIRP_PACKED;
 
 
 #endif
diff --git a/slirp/ip6_icmp.h b/slirp/ip6_icmp.h
index 32b0914055a..1f09b485e32 100644
--- a/slirp/ip6_icmp.h
+++ b/slirp/ip6_icmp.h
@@ -48,12 +48,12 @@ 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;
+} SLIRP_PACKED;
 
 struct ndp_ns {     /* Neighbor Solicitation Message */
     uint32_t reserved;
     struct in6_addr target; /* Target Address */
-} QEMU_PACKED;
+} SLIRP_PACKED;
 
 struct ndp_na {     /* Neighbor Advertisement Message */
 #if G_BYTE_ORDER == G_BIG_ENDIAN
@@ -72,13 +72,13 @@ struct ndp_na {     /* Neighbor Advertisement Message */
         reserved_lo:24;
 #endif
     struct in6_addr target; /* Target Address */
-} QEMU_PACKED;
+} SLIRP_PACKED;
 
 struct ndp_redirect {
     uint32_t reserved;
     struct in6_addr target; /* Target Address */
     struct in6_addr dest;   /* Destination Address */
-} QEMU_PACKED;
+} SLIRP_PACKED;
 
 /*
  * Structure of an icmpv6 header.
@@ -103,7 +103,7 @@ 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;
+} SLIRP_PACKED;
 
 #define ICMP6_MINLEN    4
 #define ICMP6_ERROR_MINLEN  8
@@ -134,16 +134,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 17056f4b836..67ff4d610c4 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 00000000000..00291c30a67
--- /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.98.gecbdaf0899

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

* [Qemu-devel] [PATCH 08/27] slirp: replace most qemu socket utilities with slirp own version
  2019-01-17 11:43 [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Marc-André Lureau
                   ` (6 preceding siblings ...)
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 07/27] slirp: replace QEMU_PACKED with SLIRP_PACKED Marc-André Lureau
@ 2019-01-17 11:43 ` Marc-André Lureau
  2019-01-27  0:18   ` Samuel Thibault
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 09/27] slirp: replace qemu_set_nonblock() Marc-André Lureau
                   ` (20 subsequent siblings)
  28 siblings, 1 reply; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-17 11:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Samuel Thibault,
	Jason Wang

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>
---
 slirp/util.h        |  59 +++++++++++++++
 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/Makefile.objs |   1 +
 8 files changed, 271 insertions(+), 35 deletions(-)
 create mode 100644 slirp/util.c

diff --git a/slirp/util.h b/slirp/util.h
index 00291c30a67..050ca7f1a3f 100644
--- a/slirp/util.h
+++ b/slirp/util.h
@@ -23,10 +23,69 @@
 #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);
+int inet_aton(const char *cp, struct in_addr *ia);
+#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
diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
index 7c7e042049d..b59daa801d1 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 b8a2bf971af..32ec02a5251 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 5ffbaa064a5..5805d30f3d8 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 4e81736d6fd..3567f320ff0 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 309feb9aaef..6c3fb9a29ff 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 00000000000..b1a36b27bc5
--- /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/Makefile.objs b/slirp/Makefile.objs
index 959558c7328..38ebdb416e3 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\"
-- 
2.20.1.98.gecbdaf0899

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

* [Qemu-devel] [PATCH 09/27] slirp: replace qemu_set_nonblock()
  2019-01-17 11:43 [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Marc-André Lureau
                   ` (7 preceding siblings ...)
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 08/27] slirp: replace most qemu socket utilities with slirp own version Marc-André Lureau
@ 2019-01-17 11:43 ` Marc-André Lureau
  2019-01-17 17:55   ` Eric Blake
  2019-01-27  0:21   ` Samuel Thibault
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 10/27] slirp: add unregister_poll_fd() callback Marc-André Lureau
                   ` (19 subsequent siblings)
  28 siblings, 2 replies; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-17 11:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Samuel Thibault,
	Jason Wang

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>
---
 slirp/libslirp.h    |  2 ++
 slirp/util.h        |  1 +
 net/slirp.c         |  6 ++++++
 slirp/misc.c        |  3 ++-
 slirp/tcp_subr.c    |  6 ++++--
 slirp/util.c        | 12 ++++++++++++
 stubs/Makefile.objs |  2 +-
 7 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 3e75dadfa31..70e99139bf6 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/util.h b/slirp/util.h
index 050ca7f1a3f..782ae8ef0ee 100644
--- a/slirp/util.h
+++ b/slirp/util.h
@@ -66,6 +66,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/net/slirp.c b/net/slirp.c
index c24a779425b..6f756a4dccc 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/misc.c b/slirp/misc.c
index 32ec02a5251..4ee20a10e44 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 3567f320ff0..8087ffc047f 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 b1a36b27bc5..499c5cea46f 100644
--- a/slirp/util.c
+++ b/slirp/util.c
@@ -43,6 +43,18 @@ 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);
+    fcntl(fd, F_SETFL, f | O_NONBLOCK);
+#else
+    unsigned long opt = 1;
+    ioctlsocket(fd, FIONBIO, &opt);
+#endif
+}
+
 static void slirp_set_cloexec(int fd)
 {
 #ifndef _WIN32
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index 5dd0aeeec69..cda0efa4e86 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.98.gecbdaf0899

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

* [Qemu-devel] [PATCH 10/27] slirp: add unregister_poll_fd() callback
  2019-01-17 11:43 [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Marc-André Lureau
                   ` (8 preceding siblings ...)
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 09/27] slirp: replace qemu_set_nonblock() Marc-André Lureau
@ 2019-01-17 11:43 ` Marc-André Lureau
  2019-01-27  0:28   ` Samuel Thibault
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 11/27] slirp: replace qemu_notify_event() with a callback Marc-André Lureau
                   ` (18 subsequent siblings)
  28 siblings, 1 reply; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-17 11:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Samuel Thibault,
	Jason Wang

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>
---
 slirp/libslirp.h | 2 ++
 net/slirp.c      | 6 ++++++
 slirp/ip_icmp.c  | 1 +
 slirp/slirp.c    | 3 ++-
 slirp/tcp_subr.c | 2 ++
 slirp/udp.c      | 1 +
 6 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 70e99139bf6..8ce69f0be39 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/net/slirp.c b/net/slirp.c
index 6f756a4dccc..78ba96b63f7 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 b59daa801d1..19e247f773e 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/slirp.c b/slirp/slirp.c
index dd72829017f..fdf26d5e626 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 8087ffc047f..d8846a33b0c 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 6c3fb9a29ff..3915971b506 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.98.gecbdaf0899

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

* [Qemu-devel] [PATCH 11/27] slirp: replace qemu_notify_event() with a callback
  2019-01-17 11:43 [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Marc-André Lureau
                   ` (9 preceding siblings ...)
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 10/27] slirp: add unregister_poll_fd() callback Marc-André Lureau
@ 2019-01-17 11:43 ` Marc-André Lureau
  2019-01-27  0:30   ` Samuel Thibault
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 12/27] slirp: move QEMU state saving to a separate unit Marc-André Lureau
                   ` (17 subsequent siblings)
  28 siblings, 1 reply; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-17 11:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Samuel Thibault,
	Jason Wang

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>
---
 slirp/libslirp.h  | 2 ++
 slirp/sbuf.h      | 2 +-
 slirp/socket.h    | 1 +
 net/slirp.c       | 1 +
 slirp/sbuf.c      | 6 ++++--
 slirp/socket.c    | 7 +++++++
 slirp/tcp_input.c | 6 +++---
 7 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 8ce69f0be39..679a25422b9 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.h b/slirp/sbuf.h
index 644c2013413..1cb9a428341 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.h b/slirp/socket.h
index fc35ca5f72a..1c1c8b5871c 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/net/slirp.c b/net/slirp.c
index 78ba96b63f7..7b4f9f5c5ee 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/sbuf.c b/slirp/sbuf.c
index 912f235f652..17f28e97a63 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/socket.c b/slirp/socket.c
index 5805d30f3d8..2e8dc22fb62 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/tcp_input.c b/slirp/tcp_input.c
index de5b74a52b1..7c1fe18fec1 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.98.gecbdaf0899

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

* [Qemu-devel] [PATCH 12/27] slirp: move QEMU state saving to a separate unit
  2019-01-17 11:43 [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Marc-André Lureau
                   ` (10 preceding siblings ...)
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 11/27] slirp: replace qemu_notify_event() with a callback Marc-André Lureau
@ 2019-01-17 11:43 ` Marc-André Lureau
  2019-01-27  0:34   ` Samuel Thibault
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 13/27] slirp: do not include qemu headers in libslirp.h public API header Marc-André Lureau
                   ` (16 subsequent siblings)
  28 siblings, 1 reply; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-17 11:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Samuel Thibault,
	Jason Wang

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>
---
 slirp/slirp.h       |   3 +
 slirp/state.h       |   9 +
 slirp/slirp.c       | 372 ++---------------------------------------
 slirp/state.c       | 394 ++++++++++++++++++++++++++++++++++++++++++++
 slirp/Makefile.objs |   3 +-
 5 files changed, 419 insertions(+), 362 deletions(-)
 create mode 100644 slirp/state.h
 create mode 100644 slirp/state.c

diff --git a/slirp/slirp.h b/slirp/slirp.h
index 67ff4d610c4..8d9d72ca9d0 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.h b/slirp/state.h
new file mode 100644
index 00000000000..154866898f5
--- /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_ */
diff --git a/slirp/slirp.c b/slirp/slirp.c
index fdf26d5e626..5450b52dbf4 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/state.c b/slirp/state.c
new file mode 100644
index 00000000000..0e5a706e877
--- /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/Makefile.objs b/slirp/Makefile.objs
index 38ebdb416e3..61cdcc6877f 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 \
@@ -30,4 +31,4 @@ slirp.mo-objs = \
 	util.o \
 	$(NULL)
 
-slirp.mo-cflags = -DG_LOG_DOMAIN=\"Slirp\"
+slirp.mo-cflags = -DG_LOG_DOMAIN=\"Slirp\" -DWITH_QEMU=1
-- 
2.20.1.98.gecbdaf0899

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

* [Qemu-devel] [PATCH 13/27] slirp: do not include qemu headers in libslirp.h public API header
  2019-01-17 11:43 [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Marc-André Lureau
                   ` (11 preceding siblings ...)
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 12/27] slirp: move QEMU state saving to a separate unit Marc-André Lureau
@ 2019-01-17 11:43 ` Marc-André Lureau
  2019-01-27  0:35   ` Samuel Thibault
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 14/27] slirp: improve windows headers inclusion Marc-André Lureau
                   ` (15 subsequent siblings)
  28 siblings, 1 reply; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-17 11:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Samuel Thibault,
	Jason Wang

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

diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 679a25422b9..02cbec9f8be 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.98.gecbdaf0899

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

* [Qemu-devel] [PATCH 14/27] slirp: improve windows headers inclusion
  2019-01-17 11:43 [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Marc-André Lureau
                   ` (12 preceding siblings ...)
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 13/27] slirp: do not include qemu headers in libslirp.h public API header Marc-André Lureau
@ 2019-01-17 11:43 ` Marc-André Lureau
  2019-01-27  0:41   ` Samuel Thibault
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 15/27] slirp: add slirp own version of pstrcpy Marc-André Lureau
                   ` (14 subsequent siblings)
  28 siblings, 1 reply; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-17 11:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Samuel Thibault,
	Jason Wang

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>
---
 slirp/slirp.h | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/slirp/slirp.h b/slirp/slirp.h
index 8d9d72ca9d0..5a830ddcb86 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.98.gecbdaf0899

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

* [Qemu-devel] [PATCH 15/27] slirp: add slirp own version of pstrcpy
  2019-01-17 11:43 [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Marc-André Lureau
                   ` (13 preceding siblings ...)
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 14/27] slirp: improve windows headers inclusion Marc-André Lureau
@ 2019-01-17 11:43 ` Marc-André Lureau
  2019-01-27  0:42   ` Samuel Thibault
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 16/27] slirp: remove qemu timer.h dependency Marc-André Lureau
                   ` (13 subsequent siblings)
  28 siblings, 1 reply; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-17 11:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Samuel Thibault,
	Jason Wang

Remove a dependency on qemu util.

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

diff --git a/slirp/util.h b/slirp/util.h
index 782ae8ef0ee..e3332cdcd60 100644
--- a/slirp/util.h
+++ b/slirp/util.h
@@ -89,4 +89,6 @@ static inline int slirp_socket_set_fast_reuse(int fd)
 #endif
 }
 
+void slirp_pstrcpy(char *buf, int buf_size, const char *str);
+
 #endif
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 5450b52dbf4..9e38d3f8cb3 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 6fb381ef337..f0bcc72c925 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 499c5cea46f..60f474f0aab 100644
--- a/slirp/util.c
+++ b/slirp/util.c
@@ -186,3 +186,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';
+}
-- 
2.20.1.98.gecbdaf0899

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

* [Qemu-devel] [PATCH 16/27] slirp: remove qemu timer.h dependency
  2019-01-17 11:43 [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Marc-André Lureau
                   ` (14 preceding siblings ...)
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 15/27] slirp: add slirp own version of pstrcpy Marc-André Lureau
@ 2019-01-17 11:43 ` Marc-André Lureau
  2019-01-27  0:43   ` Samuel Thibault
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 17/27] slirp: remove now useless QEMU headers inclusions Marc-André Lureau
                   ` (12 subsequent siblings)
  28 siblings, 1 reply; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-17 11:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Samuel Thibault,
	Jason Wang

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

diff --git a/slirp/util.h b/slirp/util.h
index e3332cdcd60..4664e8159ba 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);
diff --git a/slirp/if.c b/slirp/if.c
index 73e3705740f..90b9078687f 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 e72c57a81dc..682597e6762 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 9e38d3f8cb3..8067b624eaf 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"
-- 
2.20.1.98.gecbdaf0899

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

* [Qemu-devel] [PATCH 17/27] slirp: remove now useless QEMU headers inclusions
  2019-01-17 11:43 [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Marc-André Lureau
                   ` (15 preceding siblings ...)
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 16/27] slirp: remove qemu timer.h dependency Marc-André Lureau
@ 2019-01-17 11:43 ` Marc-André Lureau
  2019-01-27  0:44   ` Samuel Thibault
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 18/27] slirp: replace net/eth.h inclusion with own defines Marc-André Lureau
                   ` (11 subsequent siblings)
  28 siblings, 1 reply; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-17 11:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Samuel Thibault,
	Jason Wang

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>
---
 slirp/slirp.h    | 1 -
 slirp/dhcpv6.c   | 1 -
 slirp/ip6_icmp.c | 2 --
 slirp/misc.c     | 2 --
 slirp/sbuf.c     | 1 -
 slirp/slirp.c    | 4 ----
 slirp/tftp.c     | 1 -
 7 files changed, 12 deletions(-)

diff --git a/slirp/slirp.h b/slirp/slirp.h
index 5a830ddcb86..5707805be22 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/dhcpv6.c b/slirp/dhcpv6.c
index 752df405361..e27d9a46f84 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 682597e6762..b3b7e50a311 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 4ee20a10e44..a77cc34b305 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 17f28e97a63..c83e4dd8ed1 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 8067b624eaf..cfce82bbb5b 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/tftp.c b/slirp/tftp.c
index f0bcc72c925..5c31886190f 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)
 {
-- 
2.20.1.98.gecbdaf0899

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

* [Qemu-devel] [PATCH 18/27] slirp: replace net/eth.h inclusion with own defines
  2019-01-17 11:43 [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Marc-André Lureau
                   ` (16 preceding siblings ...)
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 17/27] slirp: remove now useless QEMU headers inclusions Marc-André Lureau
@ 2019-01-17 11:43 ` Marc-André Lureau
  2019-01-27  0:45   ` Samuel Thibault
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 19/27] slirp: replace qemu qtailq with slirp own copy Marc-André Lureau
                   ` (10 subsequent siblings)
  28 siblings, 1 reply; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-17 11:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Samuel Thibault,
	Jason Wang

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 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 b6ba0a63927..e0a13dec1cc 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 5707805be22..c9f91438016 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 4664e8159ba..ef758045602 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.98.gecbdaf0899

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

* [Qemu-devel] [PATCH 19/27] slirp: replace qemu qtailq with slirp own copy
  2019-01-17 11:43 [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Marc-André Lureau
                   ` (17 preceding siblings ...)
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 18/27] slirp: replace net/eth.h inclusion with own defines Marc-André Lureau
@ 2019-01-17 11:43 ` Marc-André Lureau
  2019-01-27  0:46   ` Samuel Thibault
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 20/27] slirp: replace remaining qemu headers dependency Marc-André Lureau
                   ` (9 subsequent siblings)
  28 siblings, 1 reply; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-17 11:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Samuel Thibault,
	Jason Wang

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 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 00000000000..a89b0c439a9
--- /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 c9f91438016..0e4d973c2ab 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.98.gecbdaf0899

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

* [Qemu-devel] [PATCH 20/27] slirp: replace remaining qemu headers dependency
  2019-01-17 11:43 [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Marc-André Lureau
                   ` (18 preceding siblings ...)
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 19/27] slirp: replace qemu qtailq with slirp own copy Marc-André Lureau
@ 2019-01-17 11:43 ` Marc-André Lureau
  2019-01-27  0:49   ` Samuel Thibault
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 21/27] slirp: prefer c99 types over BSD kind Marc-André Lureau
                   ` (8 subsequent siblings)
  28 siblings, 1 reply; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-17 11:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Samuel Thibault,
	Jason Wang

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>
---
 slirp/util.h       | 22 ++++++++++++++++++++++
 slirp/arp_table.c  |  1 -
 slirp/bootp.c      |  1 -
 slirp/cksum.c      |  1 -
 slirp/dhcpv6.c     |  1 -
 slirp/dnssearch.c  |  1 -
 slirp/if.c         |  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 --
 27 files changed, 26 insertions(+), 33 deletions(-)

diff --git a/slirp/util.h b/slirp/util.h
index ef758045602..1937ffaacc0 100644
--- a/slirp/util.h
+++ b/slirp/util.h
@@ -48,6 +48,28 @@
 # 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
diff --git a/slirp/arp_table.c b/slirp/arp_table.c
index bf71b984ad7..8ea655f79d2 100644
--- a/slirp/arp_table.c
+++ b/slirp/arp_table.c
@@ -22,7 +22,6 @@
  * THE SOFTWARE.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 
 void arp_table_add(Slirp *slirp, uint32_t ip_addr, uint8_t ethaddr[ETH_ALEN])
diff --git a/slirp/bootp.c b/slirp/bootp.c
index 4c9a77eb98f..d396849a05e 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 84c858fafb1..25bfa67348e 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 e27d9a46f84..9ffba38e8f4 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 8fb563321bc..c459cece8d6 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 90b9078687f..2ad03b8a79b 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_icmp.c b/slirp/ip6_icmp.c
index b3b7e50a311..2a432ebbd48 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 ab656a0a9de..1b8c003c660 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 52c88ad6911..19d1ae77489 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 19e247f773e..6b6344b7769 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 d3606208383..774ce662e60 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 db403f04c1e..f6ec141df59 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 d8d275e0e7b..521c02c9673 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 a77cc34b305..4662071be0a 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 85943822708..327f17543ce 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 b7b73722f79..34ea4fdf1fc 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 c83e4dd8ed1..51a9f0cc7d4 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 cfce82bbb5b..2c0ccc621b4 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 2e8dc22fb62..dea201f5ce9 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 7c1fe18fec1..864da7d857d 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 6dd1ecf5d9e..2b4335eb34a 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 d8846a33b0c..879a7dcd296 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 a843e57a2b9..703907eb37a 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 5c31886190f..2d8f9787862 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 3915971b506..ac42be0d8e9 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 fa531e03c4b..be5cba1f54d 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"
-- 
2.20.1.98.gecbdaf0899

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

* [Qemu-devel] [PATCH 21/27] slirp: prefer c99 types over BSD kind
  2019-01-17 11:43 [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Marc-André Lureau
                   ` (19 preceding siblings ...)
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 20/27] slirp: replace remaining qemu headers dependency Marc-André Lureau
@ 2019-01-17 11:43 ` Marc-André Lureau
  2019-01-17 22:52   ` Samuel Thibault
  2019-01-27  0:52   ` Samuel Thibault
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 22/27] slirp: improve send_packet() callback Marc-André Lureau
                   ` (7 subsequent siblings)
  28 siblings, 2 replies; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-17 11:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Samuel Thibault,
	Jason Wang

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

(indentation mess is hopefully going to be fixed when slirp is made a
separate project and clang-format is applied over the history)

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

diff --git a/slirp/ip_icmp.h b/slirp/ip_icmp.h
index d88ab34c1ba..a4e5b8b2657 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/main.h b/slirp/main.h
index 4bc05fb904b..f11d4572b76 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 cbf17e136b1..e2d443418ab 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.h b/slirp/slirp.h
index 0e4d973c2ab..05b8364c07c 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.h b/slirp/socket.h
index 1c1c8b5871c..e4d12cd5911 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_var.h b/slirp/tcp_var.h
index 895ef6df1e4..27ef1a51cb4 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.h b/slirp/udp.h
index be657cf9229..3d29504caa6 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/slirp/ip_icmp.c b/slirp/ip_icmp.c
index 6b6344b7769..7c5cb75ae51 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_input.c b/slirp/ip_input.c
index 774ce662e60..e0b94b0e426 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/slirp.c b/slirp/slirp.c
index 2c0ccc621b4..c7e15e88c0c 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/socket.c b/slirp/socket.c
index dea201f5ce9..c896fa6da33 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/tcp_input.c b/slirp/tcp_input.c
index 864da7d857d..6749b32f5d9 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 2b4335eb34a..e9674df1216 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 879a7dcd296..e35628a892a 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 703907eb37a..7be54570af0 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/udp.c b/slirp/udp.c
index ac42be0d8e9..5baa604b33a 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/util/osdep.c b/util/osdep.c
index 4b5dc7287db..3f04326040d 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.98.gecbdaf0899

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

* [Qemu-devel] [PATCH 22/27] slirp: improve send_packet() callback
  2019-01-17 11:43 [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Marc-André Lureau
                   ` (20 preceding siblings ...)
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 21/27] slirp: prefer c99 types over BSD kind Marc-André Lureau
@ 2019-01-17 11:43 ` Marc-André Lureau
  2019-01-27  0:54   ` Samuel Thibault
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 23/27] slirp: replace global polling with per-instance & notifier Marc-André Lureau
                   ` (6 subsequent siblings)
  28 siblings, 1 reply; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-17 11:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Samuel Thibault,
	Jason Wang

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>
---
 include/net/net.h |  2 +-
 slirp/libslirp.h  | 11 +++++++----
 slirp/slirp.h     |  2 ++
 net/net.c         |  4 ++--
 net/slirp.c       |  9 +++++----
 slirp/ncsi.c      |  2 +-
 slirp/slirp.c     | 17 ++++++++++++++---
 7 files changed, 32 insertions(+), 15 deletions(-)

diff --git a/include/net/net.h b/include/net/net.h
index 643295d1637..075cc012671 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/slirp/libslirp.h b/slirp/libslirp.h
index 02cbec9f8be..8e5d4ed11b5 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/slirp.h b/slirp/slirp.h
index 05b8364c07c..752a4cd8c81 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
diff --git a/net/net.c b/net/net.c
index 3acbdccd61b..5dcff7fe2ab 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 7b4f9f5c5ee..664ff1c0022 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/ncsi.c b/slirp/ncsi.c
index 327f17543ce..359f52c2840 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 c7e15e88c0c..f42d31fb632 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,14 @@ 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: %zd", ret);
+    } else if (ret < len) {
+        DEBUG_ERROR("send_packet() didn't send all data: %zd < %zu", ret, len);
+    }
+}
-- 
2.20.1.98.gecbdaf0899

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

* [Qemu-devel] [PATCH 23/27] slirp: replace global polling with per-instance & notifier
  2019-01-17 11:43 [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Marc-André Lureau
                   ` (21 preceding siblings ...)
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 22/27] slirp: improve send_packet() callback Marc-André Lureau
@ 2019-01-17 11:43 ` Marc-André Lureau
  2019-01-27  0:59   ` Samuel Thibault
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 24/27] slirp: remove slirp_instances list Marc-André Lureau
                   ` (5 subsequent siblings)
  28 siblings, 1 reply; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-17 11:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Samuel Thibault,
	Jason Wang

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>
---
 include/qemu/main-loop.h |  15 ++
 slirp/libslirp.h         |   4 +-
 net/slirp.c              |  24 ++
 slirp/slirp.c            | 555 +++++++++++++++++++--------------------
 stubs/slirp.c            |  13 -
 util/main-loop.c         |  30 ++-
 stubs/Makefile.objs      |   1 -
 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 e59f9ae1e9d..f6ba78ea739 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/slirp/libslirp.h b/slirp/libslirp.h
index 8e5d4ed11b5..18d5fb01335 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/net/slirp.c b/net/slirp.c
index 664ff1c0022..4d55f641684 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/slirp.c b/slirp/slirp.c
index f42d31fb632..35630efe5db 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/slirp.c b/stubs/slirp.c
deleted file mode 100644
index 70704346fdf..00000000000
--- 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 affe0403c58..5f15cdf88d1 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 */
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index cda0efa4e86..1558ff1fe72 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
-- 
2.20.1.98.gecbdaf0899

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

* [Qemu-devel] [PATCH 24/27] slirp: remove slirp_instances list
  2019-01-17 11:43 [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Marc-André Lureau
                   ` (22 preceding siblings ...)
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 23/27] slirp: replace global polling with per-instance & notifier Marc-André Lureau
@ 2019-01-17 11:43 ` Marc-André Lureau
  2019-01-27  1:00   ` Samuel Thibault
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 25/27] slirp: use polling callbacks, drop glib requirement Marc-André Lureau
                   ` (4 subsequent siblings)
  28 siblings, 1 reply; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-17 11:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Samuel Thibault,
	Jason Wang

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>
---
 slirp/slirp.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/slirp/slirp.c b/slirp/slirp.c
index 35630efe5db..98ff23723d9 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.98.gecbdaf0899

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

* [Qemu-devel] [PATCH 25/27] slirp: use polling callbacks, drop glib requirement
  2019-01-17 11:43 [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Marc-André Lureau
                   ` (23 preceding siblings ...)
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 24/27] slirp: remove slirp_instances list Marc-André Lureau
@ 2019-01-17 11:43 ` Marc-André Lureau
  2019-01-27  1:05   ` Samuel Thibault
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 26/27] slirp: pass opaque to all callbacks Marc-André Lureau
                   ` (3 subsequent siblings)
  28 siblings, 1 reply; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-17 11:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Samuel Thibault,
	Jason Wang

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>
---
 slirp/libslirp.h | 17 ++++++++++--
 net/slirp.c      | 72 ++++++++++++++++++++++++++++++++++++++++++++++--
 slirp/slirp.c    | 72 +++++++++++++++++-------------------------------
 3 files changed, 109 insertions(+), 52 deletions(-)

diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 18d5fb01335..b5c1b2122bc 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/net/slirp.c b/net/slirp.c
index 4d55f641684..a85e42ff432 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/slirp.c b/slirp/slirp.c
index 98ff23723d9..8fb3ae06c41 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.98.gecbdaf0899

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

* [Qemu-devel] [PATCH 26/27] slirp: pass opaque to all callbacks
  2019-01-17 11:43 [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Marc-André Lureau
                   ` (24 preceding siblings ...)
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 25/27] slirp: use polling callbacks, drop glib requirement Marc-André Lureau
@ 2019-01-17 11:43 ` Marc-André Lureau
  2019-01-27  1:06   ` Samuel Thibault
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 27/27] slirp: API is extern C Marc-André Lureau
                   ` (2 subsequent siblings)
  28 siblings, 1 reply; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-17 11:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Samuel Thibault,
	Jason Wang

This is friendlier for FFI bindings.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 slirp/libslirp.h | 16 ++++++++--------
 net/slirp.c      | 25 ++++++++++++++++---------
 slirp/dhcpv6.c   |  2 +-
 slirp/if.c       |  2 +-
 slirp/ip6_icmp.c | 15 +++++++++------
 slirp/ip_icmp.c  |  2 +-
 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/slirp/libslirp.h b/slirp/libslirp.h
index b5c1b2122bc..9b13d8250c6 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/net/slirp.c b/net/slirp.c
index a85e42ff432..7a16d8d6150 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 9ffba38e8f4..e655c7d5b10 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 2ad03b8a79b..1830cc396c5 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 2a432ebbd48..c1e3d30470a 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 7c5cb75ae51..ce79c0b051c 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/misc.c b/slirp/misc.c
index 4662071be0a..edb0d187d7d 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -160,7 +160,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 8fb3ae06c41..b50fba95853 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 c896fa6da33..ce1d6ffa1d2 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 e35628a892a..cda94815f62 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 5baa604b33a..29a31e9400d 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.98.gecbdaf0899

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

* [Qemu-devel] [PATCH 27/27] slirp: API is extern C
  2019-01-17 11:43 [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Marc-André Lureau
                   ` (25 preceding siblings ...)
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 26/27] slirp: pass opaque to all callbacks Marc-André Lureau
@ 2019-01-17 11:43 ` Marc-André Lureau
  2019-01-27  1:07   ` Samuel Thibault
  2019-01-17 23:08 ` [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Samuel Thibault
  2019-01-31 17:47 ` no-reply
  28 siblings, 1 reply; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-17 11:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Samuel Thibault,
	Jason Wang

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

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

diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 9b13d8250c6..fccab425187 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.98.gecbdaf0899

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

* Re: [Qemu-devel] [PATCH 04/27] net/slirp: fix leaks on forwaring rule registration error
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 04/27] net/slirp: fix leaks on forwaring rule registration error Marc-André Lureau
@ 2019-01-17 17:50   ` Eric Blake
  2019-01-26 23:57   ` Samuel Thibault
  1 sibling, 0 replies; 67+ messages in thread
From: Eric Blake @ 2019-01-17 17:50 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel
  Cc: Li Zhijian, Jan Kiszka, Jason Wang, Zhang Chen, Samuel Thibault,
	pbonzini

[-- Attachment #1: Type: text/plain, Size: 1246 bytes --]

On 1/17/19 5:43 AM, Marc-André Lureau wrote:

In the subject: s/forwaring/forwarding/

> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>  net/slirp.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/net/slirp.c b/net/slirp.c
> index 750105a466e..0b15f427f5c 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;
>          }
> 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3226
Virtualization:  qemu.org | libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [Qemu-devel] [PATCH 09/27] slirp: replace qemu_set_nonblock()
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 09/27] slirp: replace qemu_set_nonblock() Marc-André Lureau
@ 2019-01-17 17:55   ` Eric Blake
  2019-01-17 22:39     ` Marc-André Lureau
  2019-01-27  0:21   ` Samuel Thibault
  1 sibling, 1 reply; 67+ messages in thread
From: Eric Blake @ 2019-01-17 17:55 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel
  Cc: Li Zhijian, Jan Kiszka, Jason Wang, Zhang Chen, Samuel Thibault,
	pbonzini

[-- Attachment #1: Type: text/plain, Size: 817 bytes --]

On 1/17/19 5:43 AM, Marc-André Lureau wrote:
> 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>
> ---

> +++ b/slirp/util.c
> @@ -43,6 +43,18 @@ 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);
> +    fcntl(fd, F_SETFL, f | O_NONBLOCK);

No error checking?  Is that wise?

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3226
Virtualization:  qemu.org | libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [Qemu-devel] [PATCH 09/27] slirp: replace qemu_set_nonblock()
  2019-01-17 17:55   ` Eric Blake
@ 2019-01-17 22:39     ` Marc-André Lureau
  0 siblings, 0 replies; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-17 22:39 UTC (permalink / raw)
  To: Eric Blake
  Cc: qemu-devel, Li Zhijian, Jan Kiszka, Jason Wang, Zhang Chen,
	Samuel Thibault, Bonzini, Paolo

Hi

On Thu, Jan 17, 2019 at 9:55 PM Eric Blake <eblake@redhat.com> wrote:
>
> On 1/17/19 5:43 AM, Marc-André Lureau wrote:
> > 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>
> > ---
>
> > +++ b/slirp/util.c
> > @@ -43,6 +43,18 @@ 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);
> > +    fcntl(fd, F_SETFL, f | O_NONBLOCK);
>
> No error checking?  Is that wise?

I did a simple c&p from util/oslib-win32.c & util/oslib-posix.c.

Should I add some g_critical() ?

>
> --
> Eric Blake, Principal Software Engineer
> Red Hat, Inc.           +1-919-301-3226
> Virtualization:  qemu.org | libvirt.org
>

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

* Re: [Qemu-devel] [PATCH 21/27] slirp: prefer c99 types over BSD kind
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 21/27] slirp: prefer c99 types over BSD kind Marc-André Lureau
@ 2019-01-17 22:52   ` Samuel Thibault
  2019-01-27  0:52   ` Samuel Thibault
  1 sibling, 0 replies; 67+ messages in thread
From: Samuel Thibault @ 2019-01-17 22:52 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Jason Wang

Marc-André Lureau, le jeu. 17 janv. 2019 15:43:53 +0400, a ecrit:
> (indentation mess is hopefully going to be fixed when slirp is made a
> separate project and clang-format is applied over the history)

Yes, let's do it :)

Samuel

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

* Re: [Qemu-devel] [PATCH 01/27] slirp: generalize guestfwd with a callback based approach
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 01/27] slirp: generalize guestfwd with a callback based approach Marc-André Lureau
@ 2019-01-17 23:04   ` Samuel Thibault
  2019-01-18 11:04     ` Marc-André Lureau
  2019-01-26 23:47   ` Samuel Thibault
  1 sibling, 1 reply; 67+ messages in thread
From: Samuel Thibault @ 2019-01-17 23:04 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Jason Wang

Marc-André Lureau, le jeu. 17 janv. 2019 15:43:33 +0400, a ecrit:
>          /* XXX this blocks entire thread. Rewrite to use
>           * qemu_chr_fe_write and background I/O callbacks */

Seeing this, I guess a whole pass will be useful to turn these qemu
comment references into something that does not require knowledge of
qemu internals :)

Samuel

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

* Re: [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2)
  2019-01-17 11:43 [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Marc-André Lureau
                   ` (26 preceding siblings ...)
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 27/27] slirp: API is extern C Marc-André Lureau
@ 2019-01-17 23:08 ` Samuel Thibault
  2019-01-18 11:02   ` Marc-André Lureau
  2019-01-31 17:47 ` no-reply
  28 siblings, 1 reply; 67+ messages in thread
From: Samuel Thibault @ 2019-01-17 23:08 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Jason Wang

Also thinking about it: I guess we'd want to make the usage of libslirp
optional, at least because (I guess) at some points the future libslirp
may want to change the API (nobody can do something perfect at first
try), and when that breaks qemu build it would nasty if people couldn't
just disable libslirp usage to get qemu built for needs which don't
require slirp.

Also some people would really like to see the dreaded slirp stack off
their qemu binaries :)

Samuel

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

* Re: [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2)
  2019-01-17 23:08 ` [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Samuel Thibault
@ 2019-01-18 11:02   ` Marc-André Lureau
  2019-01-27  1:09     ` Samuel Thibault
  0 siblings, 1 reply; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-18 11:02 UTC (permalink / raw)
  To: Samuel Thibault
  Cc: Li Zhijian, Jan Kiszka, Jason Wang, QEMU, Zhang Chen, Paolo Bonzini

Hi

On Fri, Jan 18, 2019 at 3:09 AM Samuel Thibault <samuel.thibault@gnu.org> wrote:
>
> Also thinking about it: I guess we'd want to make the usage of libslirp
> optional, at least because (I guess) at some points the future libslirp

There is already --disable-slirp. My upcoming patches for external
libslirp honor that too.

> may want to change the API (nobody can do something perfect at first
> try), and when that breaks qemu build it would nasty if people couldn't
> just disable libslirp usage to get qemu built for needs which don't
> require slirp.

Certainly, however we will be careful to keep a stable API/ABI and
have library deprecation policies.

Major API/ABI break / rewrite could also use a different soname.

>
> Also some people would really like to see the dreaded slirp stack off
> their qemu binaries :)
>

Fortunately, that's already possible with --disable-slirp.

-- 
Marc-André Lureau

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

* Re: [Qemu-devel] [PATCH 01/27] slirp: generalize guestfwd with a callback based approach
  2019-01-17 23:04   ` Samuel Thibault
@ 2019-01-18 11:04     ` Marc-André Lureau
  0 siblings, 0 replies; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-18 11:04 UTC (permalink / raw)
  To: Samuel Thibault
  Cc: Li Zhijian, Jan Kiszka, Jason Wang, QEMU, Zhang Chen, Paolo Bonzini

Hi

On Fri, Jan 18, 2019 at 3:07 AM Samuel Thibault <samuel.thibault@gnu.org> wrote:
>
> Marc-André Lureau, le jeu. 17 janv. 2019 15:43:33 +0400, a ecrit:
> >          /* XXX this blocks entire thread. Rewrite to use
> >           * qemu_chr_fe_write and background I/O callbacks */
>
> Seeing this, I guess a whole pass will be useful to turn these qemu
> comment references into something that does not require knowledge of
> qemu internals :)

Sure, we will have to do some doc/comments update. I can look at it.
That's not a blocker imho.

thanks


-- 
Marc-André Lureau

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

* Re: [Qemu-devel] [PATCH 01/27] slirp: generalize guestfwd with a callback based approach
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 01/27] slirp: generalize guestfwd with a callback based approach Marc-André Lureau
  2019-01-17 23:04   ` Samuel Thibault
@ 2019-01-26 23:47   ` Samuel Thibault
  1 sibling, 0 replies; 67+ messages in thread
From: Samuel Thibault @ 2019-01-26 23:47 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Jason Wang

Marc-André Lureau, le jeu. 17 janv. 2019 15:43:33 +0400, a ecrit:
> 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>

applied, thanks!

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

* Re: [Qemu-devel] [PATCH 02/27] net/slirp: simplify checking for cmd: prefix
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 02/27] net/slirp: simplify checking for cmd: prefix Marc-André Lureau
@ 2019-01-26 23:49   ` Samuel Thibault
  0 siblings, 0 replies; 67+ messages in thread
From: Samuel Thibault @ 2019-01-26 23:49 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Jason Wang

Marc-André Lureau, le jeu. 17 janv. 2019 15:43:34 +0400, a ecrit:
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

It's not strictly the same (g_str_has_prefix doesn't test that there are
characters after the prefix), but that should be fine, applied, thanks!

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

* Re: [Qemu-devel] [PATCH 03/27] net/slirp: free forwarding rules on cleanup
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 03/27] net/slirp: free forwarding rules on cleanup Marc-André Lureau
@ 2019-01-26 23:52   ` Samuel Thibault
  0 siblings, 0 replies; 67+ messages in thread
From: Samuel Thibault @ 2019-01-26 23:52 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Jason Wang

Marc-André Lureau, le jeu. 17 janv. 2019 15:43:35 +0400, a ecrit:
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Applied, thanks!

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

* Re: [Qemu-devel] [PATCH 04/27] net/slirp: fix leaks on forwaring rule registration error
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 04/27] net/slirp: fix leaks on forwaring rule registration error Marc-André Lureau
  2019-01-17 17:50   ` Eric Blake
@ 2019-01-26 23:57   ` Samuel Thibault
  1 sibling, 0 replies; 67+ messages in thread
From: Samuel Thibault @ 2019-01-26 23:57 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Jason Wang

Marc-André Lureau, le jeu. 17 janv. 2019 15:43:36 +0400, a ecrit:
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Applied, thanks!

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

* Re: [Qemu-devel] [PATCH 05/27] slirp: add callbacks for timer
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 05/27] slirp: add callbacks for timer Marc-André Lureau
@ 2019-01-27  0:01   ` Samuel Thibault
  2019-01-27 11:42     ` Marc-André Lureau
  0 siblings, 1 reply; 67+ messages in thread
From: Samuel Thibault @ 2019-01-27  0:01 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Jason Wang

Applied too, but

Marc-André Lureau, le jeu. 17 janv. 2019 15:43:37 +0400, a ecrit:
> +    /* 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);

I'd say we will want to make the API use an opaque type for timers, for
typechecking.

Samuel

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

* Re: [Qemu-devel] [PATCH 06/27] slirp: replace trace functions with DEBUG calls
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 06/27] slirp: replace trace functions with DEBUG calls Marc-André Lureau
@ 2019-01-27  0:03   ` Samuel Thibault
  0 siblings, 0 replies; 67+ messages in thread
From: Samuel Thibault @ 2019-01-27  0:03 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Jason Wang

Marc-André Lureau, le jeu. 17 janv. 2019 15:43:38 +0400, a ecrit:
> 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>

Applied with just an additional G_UNLIKELY, thanks!

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

* Re: [Qemu-devel] [PATCH 07/27] slirp: replace QEMU_PACKED with SLIRP_PACKED
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 07/27] slirp: replace QEMU_PACKED with SLIRP_PACKED Marc-André Lureau
@ 2019-01-27  0:07   ` Samuel Thibault
  0 siblings, 0 replies; 67+ messages in thread
From: Samuel Thibault @ 2019-01-27  0:07 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Jason Wang

Marc-André Lureau, le jeu. 17 janv. 2019 15:43:39 +0400, a ecrit:
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Applied except the ones which are removed in the other thread, thanks!

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

* Re: [Qemu-devel] [PATCH 08/27] slirp: replace most qemu socket utilities with slirp own version
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 08/27] slirp: replace most qemu socket utilities with slirp own version Marc-André Lureau
@ 2019-01-27  0:18   ` Samuel Thibault
  0 siblings, 0 replies; 67+ messages in thread
From: Samuel Thibault @ 2019-01-27  0:18 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Jason Wang

Marc-André Lureau, le jeu. 17 janv. 2019 15:43:40 +0400, a ecrit:
> 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>

Applied, I just added a -DWITH_QEMU in the Makefile, for inet_aton,
thanks!

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

* Re: [Qemu-devel] [PATCH 09/27] slirp: replace qemu_set_nonblock()
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 09/27] slirp: replace qemu_set_nonblock() Marc-André Lureau
  2019-01-17 17:55   ` Eric Blake
@ 2019-01-27  0:21   ` Samuel Thibault
  1 sibling, 0 replies; 67+ messages in thread
From: Samuel Thibault @ 2019-01-27  0:21 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Jason Wang

Marc-André Lureau, le jeu. 17 janv. 2019 15:43:41 +0400, a ecrit:
> 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>

Applied, with the additional assert(), thanks!

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

* Re: [Qemu-devel] [PATCH 10/27] slirp: add unregister_poll_fd() callback
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 10/27] slirp: add unregister_poll_fd() callback Marc-André Lureau
@ 2019-01-27  0:28   ` Samuel Thibault
  0 siblings, 0 replies; 67+ messages in thread
From: Samuel Thibault @ 2019-01-27  0:28 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Jason Wang

Marc-André Lureau, le jeu. 17 janv. 2019 15:43:42 +0400, a ecrit:
> 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>

Applied, thanks!

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

* Re: [Qemu-devel] [PATCH 11/27] slirp: replace qemu_notify_event() with a callback
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 11/27] slirp: replace qemu_notify_event() with a callback Marc-André Lureau
@ 2019-01-27  0:30   ` Samuel Thibault
  0 siblings, 0 replies; 67+ messages in thread
From: Samuel Thibault @ 2019-01-27  0:30 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Jason Wang

Marc-André Lureau, le jeu. 17 janv. 2019 15:43:43 +0400, a ecrit:
> 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>

Applied, thanks!

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

* Re: [Qemu-devel] [PATCH 12/27] slirp: move QEMU state saving to a separate unit
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 12/27] slirp: move QEMU state saving to a separate unit Marc-André Lureau
@ 2019-01-27  0:34   ` Samuel Thibault
  0 siblings, 0 replies; 67+ messages in thread
From: Samuel Thibault @ 2019-01-27  0:34 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Jason Wang

Marc-André Lureau, le jeu. 17 janv. 2019 15:43:44 +0400, a ecrit:
> 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>

Applied, thanks!

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

* Re: [Qemu-devel] [PATCH 13/27] slirp: do not include qemu headers in libslirp.h public API header
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 13/27] slirp: do not include qemu headers in libslirp.h public API header Marc-André Lureau
@ 2019-01-27  0:35   ` Samuel Thibault
  0 siblings, 0 replies; 67+ messages in thread
From: Samuel Thibault @ 2019-01-27  0:35 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Jason Wang

Marc-André Lureau, le jeu. 17 janv. 2019 15:43:45 +0400, a ecrit:
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Applied, thanks!

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

* Re: [Qemu-devel] [PATCH 14/27] slirp: improve windows headers inclusion
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 14/27] slirp: improve windows headers inclusion Marc-André Lureau
@ 2019-01-27  0:41   ` Samuel Thibault
  0 siblings, 0 replies; 67+ messages in thread
From: Samuel Thibault @ 2019-01-27  0:41 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Jason Wang

Marc-André Lureau, le jeu. 17 janv. 2019 15:43:46 +0400, a ecrit:
> 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>

Applied, thanks!

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

* Re: [Qemu-devel] [PATCH 15/27] slirp: add slirp own version of pstrcpy
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 15/27] slirp: add slirp own version of pstrcpy Marc-André Lureau
@ 2019-01-27  0:42   ` Samuel Thibault
  0 siblings, 0 replies; 67+ messages in thread
From: Samuel Thibault @ 2019-01-27  0:42 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Jason Wang

Marc-André Lureau, le jeu. 17 janv. 2019 15:43:47 +0400, a ecrit:
> Remove a dependency on qemu util.
> 
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Applied, thanks!

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

* Re: [Qemu-devel] [PATCH 16/27] slirp: remove qemu timer.h dependency
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 16/27] slirp: remove qemu timer.h dependency Marc-André Lureau
@ 2019-01-27  0:43   ` Samuel Thibault
  0 siblings, 0 replies; 67+ messages in thread
From: Samuel Thibault @ 2019-01-27  0:43 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Jason Wang

Marc-André Lureau, le jeu. 17 janv. 2019 15:43:48 +0400, a ecrit:
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Applied, thanks!

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

* Re: [Qemu-devel] [PATCH 17/27] slirp: remove now useless QEMU headers inclusions
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 17/27] slirp: remove now useless QEMU headers inclusions Marc-André Lureau
@ 2019-01-27  0:44   ` Samuel Thibault
  0 siblings, 0 replies; 67+ messages in thread
From: Samuel Thibault @ 2019-01-27  0:44 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Jason Wang

Marc-André Lureau, le jeu. 17 janv. 2019 15:43:49 +0400, a ecrit:
> 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>

Applied, thanks!

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

* Re: [Qemu-devel] [PATCH 18/27] slirp: replace net/eth.h inclusion with own defines
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 18/27] slirp: replace net/eth.h inclusion with own defines Marc-André Lureau
@ 2019-01-27  0:45   ` Samuel Thibault
  0 siblings, 0 replies; 67+ messages in thread
From: Samuel Thibault @ 2019-01-27  0:45 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Jason Wang

Marc-André Lureau, le jeu. 17 janv. 2019 15:43:50 +0400, a ecrit:
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Applied, thanks!

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

* Re: [Qemu-devel] [PATCH 19/27] slirp: replace qemu qtailq with slirp own copy
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 19/27] slirp: replace qemu qtailq with slirp own copy Marc-André Lureau
@ 2019-01-27  0:46   ` Samuel Thibault
  0 siblings, 0 replies; 67+ messages in thread
From: Samuel Thibault @ 2019-01-27  0:46 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Jason Wang

Marc-André Lureau, le jeu. 17 janv. 2019 15:43:51 +0400, a ecrit:
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Applied, thanks!

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

* Re: [Qemu-devel] [PATCH 20/27] slirp: replace remaining qemu headers dependency
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 20/27] slirp: replace remaining qemu headers dependency Marc-André Lureau
@ 2019-01-27  0:49   ` Samuel Thibault
  0 siblings, 0 replies; 67+ messages in thread
From: Samuel Thibault @ 2019-01-27  0:49 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Jason Wang

Marc-André Lureau, le jeu. 17 janv. 2019 15:43:52 +0400, a ecrit:
> 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>

Applied, thanks!

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

* Re: [Qemu-devel] [PATCH 21/27] slirp: prefer c99 types over BSD kind
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 21/27] slirp: prefer c99 types over BSD kind Marc-André Lureau
  2019-01-17 22:52   ` Samuel Thibault
@ 2019-01-27  0:52   ` Samuel Thibault
  1 sibling, 0 replies; 67+ messages in thread
From: Samuel Thibault @ 2019-01-27  0:52 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Jason Wang

Marc-André Lureau, le jeu. 17 janv. 2019 15:43:53 +0400, a ecrit:
> 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>

Applied, thanks!

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

* Re: [Qemu-devel] [PATCH 22/27] slirp: improve send_packet() callback
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 22/27] slirp: improve send_packet() callback Marc-André Lureau
@ 2019-01-27  0:54   ` Samuel Thibault
  0 siblings, 0 replies; 67+ messages in thread
From: Samuel Thibault @ 2019-01-27  0:54 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Jason Wang

Marc-André Lureau, le jeu. 17 janv. 2019 15:43:54 +0400, a ecrit:
> 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>

Applied, thanks!

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

* Re: [Qemu-devel] [PATCH 23/27] slirp: replace global polling with per-instance & notifier
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 23/27] slirp: replace global polling with per-instance & notifier Marc-André Lureau
@ 2019-01-27  0:59   ` Samuel Thibault
  0 siblings, 0 replies; 67+ messages in thread
From: Samuel Thibault @ 2019-01-27  0:59 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Jason Wang

Marc-André Lureau, le jeu. 17 janv. 2019 15:43:55 +0400, a ecrit:
> 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>

Applied, thanks!

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

* Re: [Qemu-devel] [PATCH 24/27] slirp: remove slirp_instances list
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 24/27] slirp: remove slirp_instances list Marc-André Lureau
@ 2019-01-27  1:00   ` Samuel Thibault
  0 siblings, 0 replies; 67+ messages in thread
From: Samuel Thibault @ 2019-01-27  1:00 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Jason Wang

Marc-André Lureau, le jeu. 17 janv. 2019 15:43:56 +0400, a ecrit:
> 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>

Applied, thanks!

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

* Re: [Qemu-devel] [PATCH 25/27] slirp: use polling callbacks, drop glib requirement
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 25/27] slirp: use polling callbacks, drop glib requirement Marc-André Lureau
@ 2019-01-27  1:05   ` Samuel Thibault
  0 siblings, 0 replies; 67+ messages in thread
From: Samuel Thibault @ 2019-01-27  1:05 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Jason Wang

Marc-André Lureau, le jeu. 17 janv. 2019 15:43:57 +0400, a ecrit:
> 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>

Applied, thanks!

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

* Re: [Qemu-devel] [PATCH 26/27] slirp: pass opaque to all callbacks
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 26/27] slirp: pass opaque to all callbacks Marc-André Lureau
@ 2019-01-27  1:06   ` Samuel Thibault
  0 siblings, 0 replies; 67+ messages in thread
From: Samuel Thibault @ 2019-01-27  1:06 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Jason Wang

Marc-André Lureau, le jeu. 17 janv. 2019 15:43:58 +0400, a ecrit:
> This is friendlier for FFI bindings.
> 
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Applied, thanks!

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

* Re: [Qemu-devel] [PATCH 27/27] slirp: API is extern C
  2019-01-17 11:43 ` [Qemu-devel] [PATCH 27/27] slirp: API is extern C Marc-André Lureau
@ 2019-01-27  1:07   ` Samuel Thibault
  0 siblings, 0 replies; 67+ messages in thread
From: Samuel Thibault @ 2019-01-27  1:07 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Zhang Chen, Li Zhijian, pbonzini, Jan Kiszka, Jason Wang

Marc-André Lureau, le jeu. 17 janv. 2019 15:43:59 +0400, a ecrit:
> Make it possible to use headers easily with C++ projects.
> 
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Applied, thanks!

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

* Re: [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2)
  2019-01-18 11:02   ` Marc-André Lureau
@ 2019-01-27  1:09     ` Samuel Thibault
  0 siblings, 0 replies; 67+ messages in thread
From: Samuel Thibault @ 2019-01-27  1:09 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: Li Zhijian, Jan Kiszka, Jason Wang, QEMU, Zhang Chen, Paolo Bonzini

Marc-André Lureau, le ven. 18 janv. 2019 15:02:46 +0400, a ecrit:
> > may want to change the API (nobody can do something perfect at first
> > try), and when that breaks qemu build it would nasty if people couldn't
> > just disable libslirp usage to get qemu built for needs which don't
> > require slirp.
> 
> Certainly, however we will be careful to keep a stable API/ABI and
> have library deprecation policies.
> 
> Major API/ABI break / rewrite could also use a different soname.

Sure, but at least the first release of libslirp needs to be usable by
qemu with the same API as what qemu had last :)

> > Also some people would really like to see the dreaded slirp stack off
> > their qemu binaries :)
> 
> Fortunately, that's already possible with --disable-slirp.

Alright :)

Samuel

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

* Re: [Qemu-devel] [PATCH 05/27] slirp: add callbacks for timer
  2019-01-27  0:01   ` Samuel Thibault
@ 2019-01-27 11:42     ` Marc-André Lureau
  2019-01-27 11:48       ` Samuel Thibault
  0 siblings, 1 reply; 67+ messages in thread
From: Marc-André Lureau @ 2019-01-27 11:42 UTC (permalink / raw)
  To: Samuel Thibault
  Cc: Li Zhijian, Jan Kiszka, Jason Wang, QEMU, Zhang Chen, Paolo Bonzini

Hi

On Sun, Jan 27, 2019 at 4:17 AM Samuel Thibault <samuel.thibault@gnu.org> wrote:
>
> Applied too, but
>
> Marc-André Lureau, le jeu. 17 janv. 2019 15:43:37 +0400, a ecrit:
> > +    /* 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);
>
> I'd say we will want to make the API use an opaque type for timers, for
> typechecking.

You mean declaring a typedef struct SlirpTimer in libslirp.h?

I am not sure it's a good idea, since the type is defined by the API
client, it's an opaque type for the library.

thanks

>
> Samuel
>


-- 
Marc-André Lureau

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

* Re: [Qemu-devel] [PATCH 05/27] slirp: add callbacks for timer
  2019-01-27 11:42     ` Marc-André Lureau
@ 2019-01-27 11:48       ` Samuel Thibault
  0 siblings, 0 replies; 67+ messages in thread
From: Samuel Thibault @ 2019-01-27 11:48 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: Li Zhijian, Jan Kiszka, Jason Wang, QEMU, Zhang Chen, Paolo Bonzini

Marc-André Lureau, le dim. 27 janv. 2019 15:42:41 +0400, a ecrit:
> On Sun, Jan 27, 2019 at 4:17 AM Samuel Thibault <samuel.thibault@gnu.org> wrote:
> > Marc-André Lureau, le jeu. 17 janv. 2019 15:43:37 +0400, a ecrit:
> > > +    /* 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);
> >
> > I'd say we will want to make the API use an opaque type for timers, for
> > typechecking.
> 
> You mean declaring a typedef struct SlirpTimer in libslirp.h?
> 
> I am not sure it's a good idea, since the type is defined by the API
> client, it's an opaque type for the library.

Ah, right, C doesn't permit to declare a type without defining it.
Too bad, then.

Samuel

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

* Re: [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2)
  2019-01-17 11:43 [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Marc-André Lureau
                   ` (27 preceding siblings ...)
  2019-01-17 23:08 ` [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Samuel Thibault
@ 2019-01-31 17:47 ` no-reply
  28 siblings, 0 replies; 67+ messages in thread
From: no-reply @ 2019-01-31 17:47 UTC (permalink / raw)
  To: marcandre.lureau
  Cc: fam, qemu-devel, lizhijian, jan.kiszka, jasowang, zhangckid,
	samuel.thibault, pbonzini

Patchew URL: https://patchew.org/QEMU/20190117114359.5164-1-marcandre.lureau@redhat.com/



Hi,

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

Subject: [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2)
Type: series
Message-id: 20190117114359.5164-1-marcandre.lureau@redhat.com

=== 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
Switched to a new branch 'test'
2cf761b5c1 slirp: API is extern C
bc95af56e1 slirp: pass opaque to all callbacks
657ff52f2c slirp: use polling callbacks, drop glib requirement
9a4ae85643 slirp: remove slirp_instances list
d553802b2c slirp: replace global polling with per-instance & notifier
52b7c50d1b slirp: improve send_packet() callback
351b772a02 slirp: prefer c99 types over BSD kind
ddeb208a22 slirp: replace remaining qemu headers dependency
d2bad6f3a1 slirp: replace qemu qtailq with slirp own copy
848302e24d slirp: replace net/eth.h inclusion with own defines
deb2e7b8ad slirp: remove now useless QEMU headers inclusions
cfead77e82 slirp: remove qemu timer.h dependency
8261250276 slirp: add slirp own version of pstrcpy
53843ba7f1 slirp: improve windows headers inclusion
842e6e37a9 slirp: do not include qemu headers in libslirp.h public API header
af5f9f0da6 slirp: move QEMU state saving to a separate unit
9539c9254f slirp: replace qemu_notify_event() with a callback
54bfafb18a slirp: add unregister_poll_fd() callback
86bf6c954f slirp: replace qemu_set_nonblock()
e7e9665c70 slirp: replace most qemu socket utilities with slirp own version
a3688a158d slirp: replace QEMU_PACKED with SLIRP_PACKED
9a067d1b28 slirp: replace trace functions with DEBUG calls
eb6a11a0c4 slirp: add callbacks for timer
36bf852e39 net/slirp: fix leaks on forwaring rule registration error
15bd318ea2 net/slirp: free forwarding rules on cleanup
b3ee7a6d08 net/slirp: simplify checking for cmd: prefix
d13d4d7734 slirp: generalize guestfwd with a callback based approach

=== OUTPUT BEGIN ===
1/27 Checking commit d13d4d77341f (slirp: generalize guestfwd with a callback based approach)
ERROR: code indent should never use tabs
#147: FILE: slirp/misc.h:14:
+^ISlirpWriteCb write_cb;$

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

total: 2 errors, 0 warnings, 226 lines checked

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

2/27 Checking commit b3ee7a6d081b (net/slirp: simplify checking for cmd: prefix)
3/27 Checking commit 15bd318ea20c (net/slirp: free forwarding rules on cleanup)
4/27 Checking commit 36bf852e3922 (net/slirp: fix leaks on forwaring rule registration error)
5/27 Checking commit eb6a11a0c41a (slirp: add callbacks for timer)
6/27 Checking commit 9a067d1b28a9 (slirp: replace trace functions with DEBUG calls)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#99: 
deleted file mode 100644

total: 0 errors, 1 warnings, 62 lines checked

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

total: 0 errors, 1 warnings, 180 lines checked

Patch 7/27 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
8/27 Checking commit e7e9665c706f (slirp: replace most qemu socket utilities with slirp own version)
ERROR: code indent should never use tabs
#128: 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)
#128: FILE: slirp/socket.c:190:
+       nn = slirp_recv(so->s, iov[0].iov_base, iov[0].iov_len,0);
                                                              ^

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

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

ERROR: space required after that ',' (ctx:VxV)
#146: 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
#155: FILE: slirp/socket.c:557:
+^I  slirp_ioctlsocket(so->s, FIONREAD, &n);$

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

WARNING: Block comments use a leading /* on a separate line
#391: 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
#392: FILE: slirp/util.c:100:
+          * to check both EWOULDBLOCK and EAGAIN */

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

total: 51 errors, 7 warnings, 474 lines checked

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

9/27 Checking commit 86bf6c954f1a (slirp: replace qemu_set_nonblock())
10/27 Checking commit 54bfafb18a21 (slirp: add unregister_poll_fd() callback)
ERROR: code indent should never use tabs
#86: FILE: slirp/tcp_subr.c:340:
+^Iso->slirp->cb->unregister_poll_fd(so->s);$

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

total: 2 errors, 0 warnings, 63 lines checked

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

11/27 Checking commit 9539c9254f16 (slirp: replace qemu_notify_event() with a callback)
ERROR: code indent should never use tabs
#114: FILE: slirp/tcp_input.c:509:
+^I^I^I^Isodrop(so, acked);$

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

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

total: 3 errors, 0 warnings, 79 lines checked

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

12/27 Checking commit af5f9f0da68d (slirp: move QEMU state saving to a separate unit)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#460: 
new file mode 100644

WARNING: Block comments use a leading /* on a separate line
#552: 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
#650: 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
#720: FILE: slirp/state.c:256:
+#if 0

total: 1 errors, 3 warnings, 480 lines checked

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

13/27 Checking commit 842e6e37a981 (slirp: do not include qemu headers in libslirp.h public API header)
14/27 Checking commit 53843ba7f165 (slirp: improve windows headers inclusion)
15/27 Checking commit 8261250276ba (slirp: add slirp own version of pstrcpy)
WARNING: line over 80 characters
#36: 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
#54: FILE: slirp/util.c:195:
+    if (buf_size <= 0)
[...]

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

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

total: 3 errors, 1 warnings, 44 lines checked

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

16/27 Checking commit cfead77e8226 (slirp: remove qemu timer.h dependency)
17/27 Checking commit deb2e7b8ade7 (slirp: remove now useless QEMU headers inclusions)
18/27 Checking commit 848302e24dee (slirp: replace net/eth.h inclusion with own defines)
19/27 Checking commit d2bad6f3a1f5 (slirp: replace qemu qtailq with slirp own copy)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#11: 
new file mode 100644

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

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

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

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

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

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

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

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

ERROR: do not use assignment in if condition
#111: 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
#118: FILE: slirp/qtailq.h:103:
+} while (/*CONSTCOND*/0)

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

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

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

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

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

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

WARNING: line over 80 characters
#203: 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
#204: FILE: slirp/qtailq.h:189:
+        QTAILQ_RAW_TQH_CIRC(head)->tql_prev->tql_next = (elm);                  \

WARNING: line over 80 characters
#205: 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
#206: FILE: slirp/qtailq.h:191:
+} while (/*CONSTCOND*/0)

total: 2 errors, 19 warnings, 202 lines checked

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

20/27 Checking commit ddeb208a2296 (slirp: replace remaining qemu headers dependency)
21/27 Checking commit 351b772a0287 (slirp: prefer c99 types over BSD kind)
ERROR: code indent should never use tabs
#62: FILE: slirp/ip_icmp.h:47:
+^Iuint8_t^Iicmp_type;^I^I/* type of message, see below */$

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ERROR: code indent should never use tabs
#402: 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
#411: FILE: slirp/tcp_output.c:327:
+^Imemcpy((char *)ti, &tp->t_template, sizeof (struct tcpiphdr));$

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

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

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

ERROR: code indent should never use tabs
#442: 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 '('
#442: FILE: slirp/tcp_subr.c:185:
+       ti->ti_len = htons((uint16_t)(sizeof (struct tcphdr) + tlen));

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

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

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

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

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

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

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

WARNING: line over 80 characters
#499: 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
#512: FILE: slirp/tcp_var.h:50:
+^Iuint16_t^It_maxseg;^I^I/* maximum segment size */$

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

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

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

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

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

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

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

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

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

total: 51 errors, 2 warnings, 455 lines checked

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

22/27 Checking commit 52b7c50d1b6f (slirp: improve send_packet() callback)
23/27 Checking commit d553802b2c05 (slirp: replace global polling with per-instance & notifier)
ERROR: spaces required around that '/' (ctx:VxV)
#236: 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
#564: FILE: slirp/slirp.c:611:
+                    /* Socket error might have resulted in the socket being

WARNING: Block comments use a trailing */ on a separate line
#565: 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
#593: FILE: slirp/slirp.c:634:
+                    /* Socket error might have resulted in the socket being

WARNING: Block comments use a trailing */ on a separate line
#594: 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
#652: 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
#654: FILE: slirp/slirp.c:677:
+                         * until it sends a window probe. */

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

total: 1 errors, 7 warnings, 829 lines checked

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

24/27 Checking commit 9a4ae85643ca (slirp: remove slirp_instances list)
25/27 Checking commit 657ff52f2c65 (slirp: use polling callbacks, drop glib requirement)
26/27 Checking commit bc95af56e11f (slirp: pass opaque to all callbacks)
WARNING: line over 80 characters
#94: FILE: slirp/dhcpv6.c:62:
+            slirp->cb->guest_error("Guest sent bad DHCPv6 packet!", slirp->opaque);

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

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

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

ERROR: code indent should never use tabs
#349: 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 26/27 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

27/27 Checking commit 2cf761b5c1da (slirp: API is extern C)
WARNING: architecture specific defines should be avoided
#20: FILE: slirp/libslirp.h:15:
+#ifdef __cplusplus

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

total: 0 errors, 2 warnings, 19 lines checked

Patch 27/27 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/20190117114359.5164-1-marcandre.lureau@redhat.com/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] 67+ messages in thread

end of thread, other threads:[~2019-01-31 17:49 UTC | newest]

Thread overview: 67+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-17 11:43 [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Marc-André Lureau
2019-01-17 11:43 ` [Qemu-devel] [PATCH 01/27] slirp: generalize guestfwd with a callback based approach Marc-André Lureau
2019-01-17 23:04   ` Samuel Thibault
2019-01-18 11:04     ` Marc-André Lureau
2019-01-26 23:47   ` Samuel Thibault
2019-01-17 11:43 ` [Qemu-devel] [PATCH 02/27] net/slirp: simplify checking for cmd: prefix Marc-André Lureau
2019-01-26 23:49   ` Samuel Thibault
2019-01-17 11:43 ` [Qemu-devel] [PATCH 03/27] net/slirp: free forwarding rules on cleanup Marc-André Lureau
2019-01-26 23:52   ` Samuel Thibault
2019-01-17 11:43 ` [Qemu-devel] [PATCH 04/27] net/slirp: fix leaks on forwaring rule registration error Marc-André Lureau
2019-01-17 17:50   ` Eric Blake
2019-01-26 23:57   ` Samuel Thibault
2019-01-17 11:43 ` [Qemu-devel] [PATCH 05/27] slirp: add callbacks for timer Marc-André Lureau
2019-01-27  0:01   ` Samuel Thibault
2019-01-27 11:42     ` Marc-André Lureau
2019-01-27 11:48       ` Samuel Thibault
2019-01-17 11:43 ` [Qemu-devel] [PATCH 06/27] slirp: replace trace functions with DEBUG calls Marc-André Lureau
2019-01-27  0:03   ` Samuel Thibault
2019-01-17 11:43 ` [Qemu-devel] [PATCH 07/27] slirp: replace QEMU_PACKED with SLIRP_PACKED Marc-André Lureau
2019-01-27  0:07   ` Samuel Thibault
2019-01-17 11:43 ` [Qemu-devel] [PATCH 08/27] slirp: replace most qemu socket utilities with slirp own version Marc-André Lureau
2019-01-27  0:18   ` Samuel Thibault
2019-01-17 11:43 ` [Qemu-devel] [PATCH 09/27] slirp: replace qemu_set_nonblock() Marc-André Lureau
2019-01-17 17:55   ` Eric Blake
2019-01-17 22:39     ` Marc-André Lureau
2019-01-27  0:21   ` Samuel Thibault
2019-01-17 11:43 ` [Qemu-devel] [PATCH 10/27] slirp: add unregister_poll_fd() callback Marc-André Lureau
2019-01-27  0:28   ` Samuel Thibault
2019-01-17 11:43 ` [Qemu-devel] [PATCH 11/27] slirp: replace qemu_notify_event() with a callback Marc-André Lureau
2019-01-27  0:30   ` Samuel Thibault
2019-01-17 11:43 ` [Qemu-devel] [PATCH 12/27] slirp: move QEMU state saving to a separate unit Marc-André Lureau
2019-01-27  0:34   ` Samuel Thibault
2019-01-17 11:43 ` [Qemu-devel] [PATCH 13/27] slirp: do not include qemu headers in libslirp.h public API header Marc-André Lureau
2019-01-27  0:35   ` Samuel Thibault
2019-01-17 11:43 ` [Qemu-devel] [PATCH 14/27] slirp: improve windows headers inclusion Marc-André Lureau
2019-01-27  0:41   ` Samuel Thibault
2019-01-17 11:43 ` [Qemu-devel] [PATCH 15/27] slirp: add slirp own version of pstrcpy Marc-André Lureau
2019-01-27  0:42   ` Samuel Thibault
2019-01-17 11:43 ` [Qemu-devel] [PATCH 16/27] slirp: remove qemu timer.h dependency Marc-André Lureau
2019-01-27  0:43   ` Samuel Thibault
2019-01-17 11:43 ` [Qemu-devel] [PATCH 17/27] slirp: remove now useless QEMU headers inclusions Marc-André Lureau
2019-01-27  0:44   ` Samuel Thibault
2019-01-17 11:43 ` [Qemu-devel] [PATCH 18/27] slirp: replace net/eth.h inclusion with own defines Marc-André Lureau
2019-01-27  0:45   ` Samuel Thibault
2019-01-17 11:43 ` [Qemu-devel] [PATCH 19/27] slirp: replace qemu qtailq with slirp own copy Marc-André Lureau
2019-01-27  0:46   ` Samuel Thibault
2019-01-17 11:43 ` [Qemu-devel] [PATCH 20/27] slirp: replace remaining qemu headers dependency Marc-André Lureau
2019-01-27  0:49   ` Samuel Thibault
2019-01-17 11:43 ` [Qemu-devel] [PATCH 21/27] slirp: prefer c99 types over BSD kind Marc-André Lureau
2019-01-17 22:52   ` Samuel Thibault
2019-01-27  0:52   ` Samuel Thibault
2019-01-17 11:43 ` [Qemu-devel] [PATCH 22/27] slirp: improve send_packet() callback Marc-André Lureau
2019-01-27  0:54   ` Samuel Thibault
2019-01-17 11:43 ` [Qemu-devel] [PATCH 23/27] slirp: replace global polling with per-instance & notifier Marc-André Lureau
2019-01-27  0:59   ` Samuel Thibault
2019-01-17 11:43 ` [Qemu-devel] [PATCH 24/27] slirp: remove slirp_instances list Marc-André Lureau
2019-01-27  1:00   ` Samuel Thibault
2019-01-17 11:43 ` [Qemu-devel] [PATCH 25/27] slirp: use polling callbacks, drop glib requirement Marc-André Lureau
2019-01-27  1:05   ` Samuel Thibault
2019-01-17 11:43 ` [Qemu-devel] [PATCH 26/27] slirp: pass opaque to all callbacks Marc-André Lureau
2019-01-27  1:06   ` Samuel Thibault
2019-01-17 11:43 ` [Qemu-devel] [PATCH 27/27] slirp: API is extern C Marc-André Lureau
2019-01-27  1:07   ` Samuel Thibault
2019-01-17 23:08 ` [Qemu-devel] [PATCH 00/27] slirp: make it again a standalone project (part 2) Samuel Thibault
2019-01-18 11:02   ` Marc-André Lureau
2019-01-27  1:09     ` Samuel Thibault
2019-01-31 17:47 ` no-reply

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.