Re: [Qemu-devel] [PATCH 2/2] curses: add option to specify VGA font encoding

2019-03-03 Thread Samuel Thibault
Markus Armbruster, le lun. 04 mars 2019 07:44:34 +0100, a ecrit:
> Samuel Thibault  writes:
> > --- a/qapi/ui.json
> > +++ b/qapi/ui.json
> > @@ -1131,6 +1131,7 @@
> >  # @full-screen:   Start user interface in fullscreen mode (default: off).
> >  # @window-close:  Allow to quit qemu with window close button (default: 
> > on).
> >  # @gl:Enable OpenGL support (default: off).
> > +# @charset:   Font charset used by guest (default: CP437).
> 
> Can you give brief rationale for defaulting to CP437?

I have added to the commit message:

“
The default charset is made CP437 since that is the charset of the
hardware default VGA font.
”

> > @@ -492,6 +709,10 @@ static void curses_display_init(DisplayState *ds, 
> > DisplayOptions *opts)
> >  }
> >  #endif
> >  
> > +setlocale(LC_CTYPE, "");
> 
> General principles: any change to locale deserves prominent mention in
> the commit message.

I have added to the commit message:

“
This also makes the curses backend set the LC_CTYPE locale to "" to
allow curses to emit wide characters.
”

Samuel



[Qemu-devel] [PULLv2] Reduce curses escdelay from 1s to 25ms

2019-03-03 Thread Samuel Thibault
By default, curses will only report single ESC key event after 1s delay,
since ESC is also used for keypad escape sequences. This however makes
users believe that ESC is not working. Reducing to 25ms provides good user
experience, while still allowing 25ms for keypad sequences to get in, which
should be enough.

Signed-off-by: Samuel Thibault 
---
 ui/curses.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/ui/curses.c b/ui/curses.c
index 6e0091c3b2..870273de51 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -231,7 +231,7 @@ static void curses_refresh(DisplayChangeListener *dcl)
 keycode = curses2keycode[chr];
 keycode_alt = 0;
 
-/* alt key */
+/* alt or esc key */
 if (keycode == 1) {
 int nextchr = getch();
 
@@ -361,6 +361,7 @@ static void curses_setup(void)
 initscr(); noecho(); intrflush(stdscr, FALSE);
 nodelay(stdscr, TRUE); nonl(); keypad(stdscr, TRUE);
 start_color(); raw(); scrollok(stdscr, FALSE);
+set_escdelay(25);
 
 /* Make color pair to match color format (3bits bg:3bits fg) */
 for (i = 0; i < 64; i++) {
-- 
2.20.1




Re: [Qemu-devel] [PATCH] Reduce curses escdelay from 1s to 0.2s

2019-03-03 Thread Samuel Thibault
Warner Losh, le dim. 03 mars 2019 10:11:52 -0700, a ecrit:
> On Sun, Mar 3, 2019, 12:45 AM Samuel Thibault 
> <[1]samuel.thiba...@ens-lyon.org>
> wrote:
> 
> By default, curses will only report single ESC key event after 1s delay,
> since ESC is also used for keypad escape sequences. This however makes
> users
> believe that ESC is not working. Reducing to 0.2s provides good enough 
> user
> experience, while still allowing 200ms for keypad sequences to get in,
> which
> should be more than enough.
> 
> How did you come up with this number?

Since the default was very long, I chose a value that felt fast enough
for the user.

> Still seems a bit long for the ESC ESC case where the user hits ESC
> twice in quick succession.

Right, there might be such double-press.

> Even back in the day, terminals would send the characters back to back
> at 1200 baud, which is 8ms per character. 32ms is 4x that, 32x 9600
> baud rates. 25 or 50ms is suggested from these figures.

Alright, let's try 25 then.

Samuel



[Qemu-devel] [PATCH 0/2] curses: Add support for wide output

2019-03-03 Thread Samuel Thibault
Hello,

This adds support for wide output in the curses frontend

Samuel Thibault (2):
  iconv: detect and make curses depend on it
  curses: add option to specify VGA font encoding

 configure   |  45 ++-
 qapi/ui.json|   4 +-
 qemu-options.hx |   5 +-
 ui/curses.c | 315 
 vl.c|   2 +-
 5 files changed, 320 insertions(+), 51 deletions(-)

-- 
2.20.1




[Qemu-devel] [PATCH 2/2] curses: add option to specify VGA font encoding

2019-03-03 Thread Samuel Thibault
This uses iconv to convert glyphs from the specified VGA font encoding to
unicode, and makes use of cchar_t instead of chtype when using ncursesw,
which allows to store all wide char as well as the WACS values.

Signed-off-by: Samuel Thibault 
Cc: Eddie Kohler 
---
 configure   |   5 +-
 qapi/ui.json|   4 +-
 qemu-options.hx |   5 +-
 ui/curses.c | 315 
 4 files changed, 279 insertions(+), 50 deletions(-)

diff --git a/configure b/configure
index 9979ca708d..1270dc8dc0 100755
--- a/configure
+++ b/configure
@@ -3449,14 +3449,17 @@ if test "$curses" != "no" ; then
 #include 
 #include 
 #include 
+#include 
 int main(void) {
+  const char *codeset;
   wchar_t wch = L'w';
   setlocale(LC_ALL, "");
   resize_term(0, 0);
   addwstr(L"wide chars\n");
   addnwstr(, 1);
   add_wch(WACS_DEGREE);
-  return 0;
+  codeset = nl_langinfo(CODESET);
+  return codeset != 0;
 }
 EOF
   IFS=:
diff --git a/qapi/ui.json b/qapi/ui.json
index c5d1d7f099..12d3a2c751 100644
--- a/qapi/ui.json
+++ b/qapi/ui.json
@@ -1131,6 +1131,7 @@
 # @full-screen:   Start user interface in fullscreen mode (default: off).
 # @window-close:  Allow to quit qemu with window close button (default: on).
 # @gl:Enable OpenGL support (default: off).
+# @charset:   Font charset used by guest (default: CP437).
 #
 # Since: 2.12
 #
@@ -1139,7 +1140,8 @@
   'base': { 'type'   : 'DisplayType',
 '*full-screen'   : 'bool',
 '*window-close'  : 'bool',
-'*gl': 'DisplayGLMode' },
+'*gl': 'DisplayGLMode',
+'*charset'   : 'str' },
   'discriminator' : 'type',
   'data': { 'gtk': 'DisplayGTK',
 'egl-headless'   : 'DisplayEGLHeadless'} }
diff --git a/qemu-options.hx b/qemu-options.hx
index 1cf9aac1fe..4bc4e736bb 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1216,7 +1216,7 @@ DEF("display", HAS_ARG, QEMU_OPTION_display,
 "[,window_close=on|off][,gl=on|core|es|off]\n"
 "-display gtk[,grab_on_hover=on|off][,gl=on|off]|\n"
 "-display vnc=[,]\n"
-"-display curses\n"
+"-display curses[,charset=]\n"
 "-display none\n"
 "-display egl-headless[,rendernode=]"
 "select display type\n"
@@ -1248,6 +1248,9 @@ support a text mode, QEMU can display this output using a
 curses/ncurses interface. Nothing is displayed when the graphics
 device is in graphical mode or if the graphics device does not support
 a text mode. Generally only the VGA device models support text mode.
+The font charset used by the guest can be specified with the
+@code{charset} option, for example @code{charset=CP850} for IBM CP850
+encoding. The default is @code{CP437}.
 @item none
 Do not display video output. The guest will still see an emulated
 graphics card, but its output will not be displayed to the QEMU
diff --git a/ui/curses.c b/ui/curses.c
index 1724dd57d4..203cc075d0 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -27,6 +27,10 @@
 #include 
 #include 
 #endif
+#include 
+#include 
+#include 
+#include 
 
 #include "qapi/error.h"
 #include "qemu-common.h"
@@ -54,7 +58,8 @@ static WINDOW *screenpad = NULL;
 static int width, height, gwidth, gheight, invalidate;
 static int px, py, sminx, sminy, smaxx, smaxy;
 
-static chtype vga_to_curses[256];
+static const char *font_charset = "CP437";
+static cchar_t vga_to_curses[256];
 
 static wint_t console_getch(enum maybe_keycode *maybe_keycode)
 {
@@ -77,19 +82,23 @@ static void curses_update(DisplayChangeListener *dcl,
   int x, int y, int w, int h)
 {
 console_ch_t *line;
-chtype curses_line[width];
+cchar_t curses_line[width];
 
 line = screen + y * width;
 for (h += y; y < h; y ++, line += width) {
 for (x = 0; x < width; x++) {
 chtype ch = line[x] & 0xff;
 chtype at = line[x] & ~0xff;
-if (vga_to_curses[ch]) {
-ch = vga_to_curses[ch];
+if (vga_to_curses[ch].chars[0]) {
+curses_line[x] = vga_to_curses[ch];
+} else {
+curses_line[x].chars[0] = ch;
+curses_line[x].chars[1] = 0;
+curses_line[x].attr = 0;
 }
-curses_line[x] = ch | at;
+curses_line[x].attr |=  at;
 }
-mvwaddchnstr(screenpad, y, 0, curses_line, width);
+mvwadd_wchnstr(screenpad, y, 0, curses_line, width);
 }
 
 pnoutrefresh(screenpad, py, px, sminy, sminx, smaxy - 1, smaxx - 1);
@@ -391,6 +400,254 @@ static void curses_atexit(void)
 endwin();
 }
 
+/* Setup wchar glyph for one UCS-2 char */
+static void convert_ucs(int glyph, uint16_t ch, iconv_t conv)
+{
+   

[Qemu-devel] [PATCH 1/2] iconv: detect and make curses depend on it

2019-03-03 Thread Samuel Thibault
curses will use it for proper wide output support.

Signed-off-by: Samuel Thibault 
---
 configure | 40 
 vl.c  |  2 +-
 2 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/configure b/configure
index 540bee19ba..9979ca708d 100755
--- a/configure
+++ b/configure
@@ -1217,6 +1217,10 @@ for opt do
   ;;
   --enable-curses) curses="yes"
   ;;
+  --disable-iconv) iconv="no"
+  ;;
+  --enable-iconv) iconv="yes"
+  ;;
   --disable-curl) curl="no"
   ;;
   --enable-curl) curl="yes"
@@ -1718,6 +1722,7 @@ disabled with --disable-FEATURE, default is enabled if 
available:
   gtk gtk UI
   vte vte support for the gtk UI
   curses  curses UI
+  iconv   font glyph conversion support
   vnc VNC UI support
   vnc-saslSASL encryption for VNC server
   vnc-jpegJPEG lossy compression for VNC server
@@ -3398,8 +3403,39 @@ EOF
   fi
 fi
 
+##
+# iconv probe
+if test "$iconv" != "no" ; then
+  cat > $TMPC << EOF
+#include 
+int main(void) {
+  iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
+  return conv != (iconv_t) -1;
+}
+EOF
+  for iconv_lib in '' -liconv; do
+if compile_prog "" "$iconv_lib" ; then
+  iconv_found=yes
+  libs_softmmu="$iconv_lib $libs_softmmu"
+  break
+fi
+  done
+  if test "$iconv_found" = "yes" ; then
+iconv=yes
+  else
+if test "$iconv" = "yes" ; then
+  feature_not_found "iconv" "Install iconv devel"
+fi
+iconv=no
+  fi
+fi
+
 ##
 # curses probe
+if test "$iconv" = "no" ; then
+  # curses will need iconv
+  curses=no
+fi
 if test "$curses" != "no" ; then
   if test "$mingw32" = "yes" ; then
 curses_inc_list="$($pkg_config --cflags ncurses 2>/dev/null):"
@@ -6111,6 +6147,7 @@ echo "libgcrypt $gcrypt"
 echo "nettle$nettle $(echo_version $nettle $nettle_version)"
 echo "libtasn1  $tasn1"
 echo "PAM   $auth_pam"
+echo "iconv support $iconv"
 echo "curses support$curses"
 echo "virgl support $virglrenderer $(echo_version $virglrenderer 
$virgl_version)"
 echo "curl support  $curl"
@@ -6435,6 +6472,9 @@ fi
 if test "$cocoa" = "yes" ; then
   echo "CONFIG_COCOA=y" >> $config_host_mak
 fi
+if test "$iconv" = "yes" ; then
+  echo "CONFIG_ICONV=y" >> $config_host_mak
+fi
 if test "$curses" = "yes" ; then
   echo "CONFIG_CURSES=m" >> $config_host_mak
   echo "CURSES_CFLAGS=$curses_inc" >> $config_host_mak
diff --git a/vl.c b/vl.c
index 502857a176..c8594fc6d5 100644
--- a/vl.c
+++ b/vl.c
@@ -3171,7 +3171,7 @@ int main(int argc, char **argv, char **envp)
 #ifdef CONFIG_CURSES
 dpy.type = DISPLAY_TYPE_CURSES;
 #else
-error_report("curses support is disabled");
+error_report("curses or iconv support is disabled");
 exit(1);
 #endif
 break;
-- 
2.20.1




[Qemu-devel] [PATCH] slirp: Mark pieces missing IPv6 support

2019-03-02 Thread Samuel Thibault
Signed-off-by: Samuel Thibault 
---
 net/slirp.c   | 1 +
 slirp/misc.c  | 3 +++
 slirp/slirp.c | 5 +
 slirp/socket.c| 1 +
 slirp/tcp_input.c | 2 ++
 slirp/tcp_subr.c  | 2 ++
 slirp/udp.c   | 1 +
 7 files changed, 15 insertions(+)

diff --git a/net/slirp.c b/net/slirp.c
index 4ec989b592..a8fd9e6364 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -885,6 +885,7 @@ static ssize_t guestfwd_write(const void *buf, size_t len, 
void *chr)
 
 static int slirp_guestfwd(SlirpState *s, const char *config_str, Error **errp)
 {
+/* TODO: IPv6 */
 struct in_addr server = { .s_addr = 0 };
 struct GuestFwd *fwd;
 const char *p;
diff --git a/slirp/misc.c b/slirp/misc.c
index d9fc586a24..937a418d4e 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -28,6 +28,7 @@ remque(void *a)
   element->qh_rlink = NULL;
 }
 
+/* TODO: IPv6 */
 struct gfwd_list *
 add_guestfwd(struct gfwd_list **ex_ptr,
  SlirpWriteCb write_cb, void *opaque,
@@ -254,6 +255,8 @@ char *slirp_connection_info(Slirp *slirp)
 "  Protocol[State]FD  Source Address  Port   "
 "Dest. Address  Port RecvQ SendQ\n");
 
+/* TODO: IPv6 */
+
 for (so = slirp->tcb.so_next; so != >tcb; so = so->so_next) {
 if (so->so_state & SS_HOSTFWD) {
 state = "HOST_FORWARD";
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 55591430dc..cbdf9f778d 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -729,6 +729,7 @@ static void arp_input(Slirp *slirp, const uint8_t *pkt, int 
pkt_len)
 if (ah->ar_tip == slirp->vnameserver_addr.s_addr ||
 ah->ar_tip == slirp->vhost_addr.s_addr)
 goto arp_ok;
+/* TODO: IPv6 */
 for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = 
ex_ptr->ex_next) {
 if (ex_ptr->ex_addr.s_addr == ah->ar_tip)
 goto arp_ok;
@@ -945,6 +946,7 @@ int if_encap(Slirp *slirp, struct mbuf *ifm)
 }
 
 /* Drop host forwarding rule, return 0 if found. */
+/* TODO: IPv6 */
 int slirp_remove_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr,
  int host_port)
 {
@@ -970,6 +972,7 @@ int slirp_remove_hostfwd(Slirp *slirp, int is_udp, struct 
in_addr host_addr,
 return -1;
 }
 
+/* TODO: IPv6 */
 int slirp_add_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr,
   int host_port, struct in_addr guest_addr, int guest_port)
 {
@@ -988,6 +991,7 @@ int slirp_add_hostfwd(Slirp *slirp, int is_udp, struct 
in_addr host_addr,
 return 0;
 }
 
+/* TODO: IPv6 */
 static bool
 check_guestfwd(Slirp *slirp, struct in_addr *guest_addr, int guest_port)
 {
@@ -1065,6 +1069,7 @@ slirp_find_ctl_socket(Slirp *slirp, struct in_addr 
guest_addr, int guest_port)
 {
 struct socket *so;
 
+/* TODO: IPv6 */
 for (so = slirp->tcb.so_next; so != >tcb; so = so->so_next) {
 if (so->so_faddr.s_addr == guest_addr.s_addr &&
 htons(so->so_fport) == guest_port) {
diff --git a/slirp/socket.c b/slirp/socket.c
index 03266128b1..76ef0774f4 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -687,6 +687,7 @@ struct socket *
 tcp_listen(Slirp *slirp, uint32_t haddr, unsigned hport, uint32_t laddr,
unsigned lport, int flags)
 {
+/* TODO: IPv6 */
struct sockaddr_in addr;
struct socket *so;
int s, opt = 1;
diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
index 6749b32f5d..b10477fc57 100644
--- a/slirp/tcp_input.c
+++ b/slirp/tcp_input.c
@@ -388,6 +388,7 @@ findso:
 * as if it was LISTENING, and continue...
 */
 if (so == NULL) {
+  /* TODO: IPv6 */
   if (slirp->restricted) {
 /* Any hostfwds will have an existing socket, so we only get here
  * for non-hostfwd connections. These should be dropped, unless it
@@ -609,6 +610,7 @@ findso:
   * If this is destined for the control address, then flag to
   * tcp_ctl once connected, otherwise connect
   */
+  /* TODO: IPv6 */
  if (af == AF_INET &&
 (so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
 slirp->vnetwork_addr.s_addr) {
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index 1d7e72dca7..1db59caa89 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -626,6 +626,7 @@ tcp_emu(struct socket *so, struct mbuf *m)
switch(so->so_emu) {
int x, i;
 
+/* TODO: IPv6 */
 case EMU_IDENT:
/*
 * Identification protocol as per rfc-1413
@@ -964,6 +965,7 @@ int tcp_ctl(struct socket *so)
 DEBUG_CALL("tcp_ctl");
 DEBUG_ARG("so = %p", so);
 
+/* TODO: IPv6 */
 if (so->so_faddr.s_addr != slirp->vhost_addr.s_addr) {
 /* Check if it's pty_exec */
 for (ex_ptr = slirp->gue

[Qemu-devel] [PATCH] Reduce curses escdelay from 1s to 0.2s

2019-03-02 Thread Samuel Thibault
By default, curses will only report single ESC key event after 1s delay,
since ESC is also used for keypad escape sequences. This however makes users
believe that ESC is not working. Reducing to 0.2s provides good enough user
experience, while still allowing 200ms for keypad sequences to get in, which
should be more than enough.

Signed-off-by: Samuel Thibault 
---
 ui/curses.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/ui/curses.c b/ui/curses.c
index 6e0091c3b2..700315bc09 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -231,7 +231,7 @@ static void curses_refresh(DisplayChangeListener *dcl)
 keycode = curses2keycode[chr];
 keycode_alt = 0;
 
-/* alt key */
+/* alt or esc key */
 if (keycode == 1) {
 int nextchr = getch();
 
@@ -361,6 +361,7 @@ static void curses_setup(void)
 initscr(); noecho(); intrflush(stdscr, FALSE);
 nodelay(stdscr, TRUE); nonl(); keypad(stdscr, TRUE);
 start_color(); raw(); scrollok(stdscr, FALSE);
+set_escdelay(200);
 
 /* Make color pair to match color format (3bits bg:3bits fg) */
 for (i = 0; i < 64; i++) {
-- 
2.20.1




Re: [Qemu-devel] [PATCH] slirp: check sscanf result when emulating ident

2019-03-02 Thread Samuel Thibault
Hello,

Philippe Mathieu-Daudé, le sam. 02 mars 2019 18:42:42 +0100, a ecrit:
> Samuel: since this diff is not obvious without looking at the context
> (also due to the code re-indent),

I dropped the code re-indent to make the change obvious. I still added
the commit description, always better goes with saying it :)

Thanks!

Samuel



Re: [Qemu-devel] [PATCH] slirp: fix big/little endian conversion in ident protocol

2019-03-02 Thread Samuel Thibault
Philippe Mathieu-Daudé, le sam. 02 mars 2019 18:31:56 +0100, a ecrit:
> On 3/2/19 3:25 AM, Samuel Thibault wrote:
> > Signed-off-by: Samuel Thibault 
> > ---
> 
> I got:
> 
> Applying: slirp: fix big/little endian conversion in ident protocol
> error: patch failed: slirp/tcp_subr.c:660
> error: slirp/tcp_subr.c: patch does not apply
> 
> Then noticed another slirp patch, applied first then this one succeed,
> so you missed:
> 
> Based-on: <1551476756-25749-1-git-send-email-w...@wbowling.info>

Oh, I didn't know about that one.

> Reviewed-by: Philippe Mathieu-Daudé 

Thanks!

Samuel



[Qemu-devel] [PATCH] slirp: fix big/little endian conversion in ident protocol

2019-03-01 Thread Samuel Thibault
Signed-off-by: Samuel Thibault 
---
 slirp/tcp_subr.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index ef9d99c154..1d7e72dca7 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -660,10 +660,12 @@ tcp_emu(struct socket *so, struct mbuf *m)
tmpso->so_fport == n1) {
if 
(getsockname(tmpso->s,
(struct 
sockaddr *), ) == 0)
-  n2 = 
ntohs(addr.sin_port);
+  n2 = addr.sin_port;
break;
}
}
+   NTOHS(n1);
+   NTOHS(n2);
so_rcv->sb_cc = 
snprintf(so_rcv->sb_data,
 
so_rcv->sb_datalen,
 "%d,%d\r\n", 
n1, n2);
-- 
2.20.1




Re: [Qemu-devel] [PATCH] slirp: check sscanf result when emulating ident

2019-03-01 Thread Samuel Thibault
William Bowling, le ven. 01 mars 2019 21:45:56 +, a ecrit:
> When emulating ident in tcp_emu, if the strchr checks passed but the
> sscanf check failed, two uninitialized variables would be copied and
> sent in the reply.
> 
> Signed-off-by: William Bowling 

Applied to my tree, thanks!

> ---
>  slirp/tcp_subr.c | 12 ++--
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
> index 262a42d6c8..73a160ba16 100644
> --- a/slirp/tcp_subr.c
> +++ b/slirp/tcp_subr.c
> @@ -664,12 +664,12 @@ tcp_emu(struct socket *so, struct mbuf *m)
>   break;
>   }
>   }
> - }
> -so_rcv->sb_cc = snprintf(so_rcv->sb_data,
> - so_rcv->sb_datalen,
> - "%d,%d\r\n", n1, 
> n2);
> - so_rcv->sb_rptr = so_rcv->sb_data;
> - so_rcv->sb_wptr = so_rcv->sb_data + 
> so_rcv->sb_cc;
> +so_rcv->sb_cc = snprintf(so_rcv->sb_data,
> + so_rcv->sb_datalen,
> + "%d,%d\r\n", n1, n2);
> +so_rcv->sb_rptr = so_rcv->sb_data;
> +so_rcv->sb_wptr = so_rcv->sb_data + so_rcv->sb_cc;
> +}
>   }
>   m_free(m);
>   return 0;
> -- 
> 2.15.1
> 
> 

-- 
Samuel
What's this script do?
unzip ; touch ; finger ; mount ; gasp ; yes ; umount ; sleep
Hint for the answer: not everything is computer-oriented. Sometimes you're
in a sleeping bag, camping out.
(Contributed by Frans van der Zande.)



Re: [Qemu-devel] [PATCH v2] slirp: check for ioctlsocket error and 0-length udp payload.

2019-03-01 Thread Samuel Thibault
Vic Lee, le ven. 01 mars 2019 14:48:09 +0800, a ecrit:
> Sometimes sorecvfrom() is called from slirp.c because revents == G_IO_IN,
> but there is 0 bytes available and recvfrom could be blocking indefinitely.
> This is likely due to 0-length udp payload. This also adds an error
> checking for ioctlsocket.
> 
> Signed-off-by: Vic Lee 

Applied to my tree, thanks!

Samuel



Re: [Qemu-devel] [PATCH v2] slirp: Fix build with gcc 9

2019-03-01 Thread Samuel Thibault
Peter Maydell, le ven. 01 mars 2019 09:49:26 +, a ecrit:
> On Fri, 1 Mar 2019 at 09:39, Greg Kurz  wrote:
> >
> > Build fails with gcc 9:
> >
> >   CC  slirp/ndp_table.o
> > slirp/ndp_table.c: In function ‘ndp_table_add’:
> > slirp/ndp_table.c:31:23: error: taking address of packed member of ‘struct 
> > ndpentry’ may result in an unaligned pointer value 
> > [-Werror=address-of-packed-member]
> >31 | if (in6_equal(_table->table[i].ip_addr, _addr)) {
> >   |   ^~~~
> > slirp/ndp_table.c: In function ‘ndp_table_search’:
> > slirp/ndp_table.c:75:23: error: taking address of packed member of ‘struct 
> > ndpentry’ may result in an unaligned pointer value 
> > [-Werror=address-of-packed-member]
> >75 | if (in6_equal(_table->table[i].ip_addr, _addr)) {
> >   |   ^~~~
> > cc1: all warnings being treated as errors
> >
> > The ndpentry structure isn't used to model on-the-wire data or anything
> > else that would care for the struct layout. It doesn't need to be packed
> > actually. Just drop SLIRP_PACKED.
> >
> > Signed-off-by: Greg Kurz 
> > ---
> > v2: - don't check the struct size at compile time
> > ---
> >  slirp/slirp.h |2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/slirp/slirp.h b/slirp/slirp.h
> > index 752a4cd8c81c..8068ba1d1e9e 100644
> > --- a/slirp/slirp.h
> > +++ b/slirp/slirp.h
> > @@ -106,7 +106,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   */
> > -} SLIRP_PACKED;
> > +};
> >
> >  #define NDP_TABLE_SIZE 16
> 
> Reviewed-by: Peter Maydell 

Applied to my tree, thanks!

Samuel



Re: [Qemu-devel] [PATCH v2 3/5] contrib: gitdm: add more individual contributors

2019-03-01 Thread Samuel Thibault
Alex Bennée, le ven. 01 mars 2019 10:03:08 +, a ecrit:
> I know Richard's is right because I asked him in the pub. I'm guessing
> Fredrik's based on the fact I vaguely remember an Atari demo. The
> others I attributed to academic institutions last time I posted so
> have moved them to individuals as requested.
> 
> Cc: Richard Henderson 
> Cc: Fredrik Noring 
> Cc: Samuel Thibault 
> Cc: Aurelien Jarno 
> Cc: BALATON Zoltan 
> Signed-off-by: Alex Bennée 

Acked-by: Samuel Thibault 

> ---
>  contrib/gitdm/group-map-individuals | 5 +
>  1 file changed, 5 insertions(+)
> 
> diff --git a/contrib/gitdm/group-map-individuals 
> b/contrib/gitdm/group-map-individuals
> index afdbe7d460..05e355d30e 100644
> --- a/contrib/gitdm/group-map-individuals
> +++ b/contrib/gitdm/group-map-individuals
> @@ -8,3 +8,8 @@
>  f4...@amsat.org
>  m...@tls.msk.ru
>  mark.cave-ayl...@ilande.co.uk
> +r...@twiddle.net
> +nor...@nocrew.org
> +samuel.thiba...@ens-lyon.org
> +aurel...@aurel32.net
> +bala...@eik.bme.hu
> -- 
> 2.20.1
> 

-- 
Samuel
/* Amuse the user in a SPARC fashion */
if (err) printk(
KERN_CRIT "  ___ \n"
KERN_CRIT " < Your System ate a SPARC! Gah! >\n"
KERN_CRIT "  --- \n"
KERN_CRIT " \\   ^__^\n"
KERN_CRIT "  \\  (xx)\\___\n"
KERN_CRIT " (__)\\   )\\/\\\n"
KERN_CRIT "  U  ||w |\n"
KERN_CRIT " || ||\n");
(From linux/arch/parisc/kernel/traps.c:die_if_kernel())



Re: [Qemu-devel] [PATCH] socket: fix blocking udp recvfrom.

2019-02-28 Thread Samuel Thibault
llyzs, le ven. 01 mars 2019 12:27:31 +0800, a ecrit:
> I believe this is because UDP packet can have 0 length payload.

Ah, right, that one makes sense indeed.

> I also found out that sometimes ioctlsocket() call can return error
> (probably caused by my unstable wifi linux driver), in which case we
> can also return immediately.

We should check for the value returned by ioctlsocket() then, otherwise
the value of n is undefined.

Samuel



Re: [Qemu-devel] [PATCH] socket: fix blocking udp recvfrom.

2019-02-28 Thread Samuel Thibault
Hello,

llyzs, le jeu. 28 févr. 2019 19:59:12 +0800, a ecrit:
> Sometimes sorecvfrom() is called from slirp.c because revents == G_IO_IN,
> however inside sorecvfrom() function, ioctlsocket() returns 0 bytes available
> and recvfrom could be blocking indefinitely. This adds a non-blocking flag to
> recvfrom and checks data availability.

When ioctlsocket() returns 0 bytes available, we could as well just
immediately return, without even calling recvfrom. We could just move
that ioctlsocket call above the m_get() call, so we can just return
without having to clean up anything.

This however still looks weird. AFAIK, G_IO_IN means that we can make
one recv call and be sure that it won't block. Do you have an idea why
it wouldn't necessarily be the case?

Samuel



Re: [Qemu-devel] [PATCH] slirp: Fix build with gcc 9

2019-02-28 Thread Samuel Thibault
Hello,

Peter Maydell, le jeu. 28 févr. 2019 18:14:40 +, a ecrit:
> My guess is that this got a packed attribute mistakenly
> by analogy with the struct slirp_arphdr which is used in
> the ArpTable struct -- but that struct really is used to
> match on-the-wire data, and this one is not.

This looks like cargo-culted indeed. Greg, please repost with the size
constraint, we do not need it.

Samuel



Re: [Qemu-devel] [PATCH v1 3/6] contrib: gitdm: add some more people academic group

2019-02-26 Thread Samuel Thibault
Alex Bennée, le mar. 26 févr. 2019 17:11:25 +, a ecrit:
> Samuel Thibault  writes:
> 
> > Hello,
> >
> > Alex Bennée, le mar. 26 févr. 2019 16:44:57 +, a ecrit:
> >> I'm basing this on email addresses or published employment. Please
> >> confirm if this is correct or you want to be under (None).
> >>
> >> Cc: Samuel Thibault 
> >
> > @ens-lyon.org means "None".
> > (it's just my alumni address, which I use for all my personal
> > projects)
> 
> Fair enough, I shall move you to the individual contributors section
> then?

Yes, please.

Samuel



Re: [Qemu-devel] [PATCH v1 3/6] contrib: gitdm: add some more people academic group

2019-02-26 Thread Samuel Thibault
Hello,

Alex Bennée, le mar. 26 févr. 2019 16:44:57 +, a ecrit:
> I'm basing this on email addresses or published employment. Please
> confirm if this is correct or you want to be under (None).
> 
> Cc: Samuel Thibault 

@ens-lyon.org means "None".
(it's just my alumni address, which I use for all my personal projects)

Only @ens-lyon.fr would mean under ENS employment.

Samuel



[Qemu-devel] [PULL 0/2] Fix slirp on windows

2019-02-13 Thread Samuel Thibault
The following changes since commit 0b5e750bea635b167eb03d86c3d9a09bbd43bc06:

  Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into 
staging (2019-02-12 10:53:37 +)

are available in the Git repository at:

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

for you to fetch changes up to adf1add2927c7bb652a168f5be627102921cf35f:

  slirp: wrap the remaining socket functions (2019-02-12 20:49:13 +0100)


Fix slirp on windows

Marc-André Lureau (2):
  slirp: remove slirp_ prefix for socket wrappers
  slirp: wrap the remaining socket functions


Marc-André Lureau (2):
  slirp: remove slirp_ prefix for socket wrappers
  slirp: wrap the remaining socket functions

 slirp/ip_icmp.c  |   4 +-
 slirp/misc.c |  14 ++---
 slirp/slirp.c|   2 +-
 slirp/socket.c   |  14 ++---
 slirp/tcp_subr.c |  10 ++--
 slirp/udp.c  |   2 +-
 slirp/util.c | 164 ++-
 slirp/util.h |  75 -
 8 files changed, 246 insertions(+), 39 deletions(-)



[Qemu-devel] [PULL 2/2] slirp: wrap the remaining socket functions

2019-02-13 Thread Samuel Thibault
From: Marc-André Lureau 

QEMU wraps the socket functions in os-win32.h, but in commit
a9d8b3ec4385793815d71217857304, the header inclusion was dropped,
breaking libslirp on Windows.

Wrap the missing functions.

Rename the wrapped function with "slirp_" prefix and "_wrap" suffix,
for consistency and to avoid a clash with existing function (such as
"slirp_socket").

Fixes: a9d8b3ec ("slirp: replace remaining qemu headers dependency")
Signed-off-by: Marc-André Lureau 
Message-Id: <20190212160953.29051-3-marcandre.lur...@redhat.com>
Signed-off-by: Samuel Thibault 
Tested-by: Howard Spoelstra
---
 slirp/util.c | 164 ++-
 slirp/util.h |  56 +++---
 2 files changed, 209 insertions(+), 11 deletions(-)

diff --git a/slirp/util.c b/slirp/util.c
index 84f5afdbc3..1cbaa26b60 100644
--- a/slirp/util.c
+++ b/slirp/util.c
@@ -167,7 +167,7 @@ static int socket_error(void)
 }
 
 #undef ioctlsocket
-int slirp_ioctlsocket(int fd, int req, void *val)
+int slirp_ioctlsocket_wrap(int fd, int req, void *val)
 {
 int ret;
 ret = ioctlsocket(fd, req, val);
@@ -178,7 +178,7 @@ int slirp_ioctlsocket(int fd, int req, void *val)
 }
 
 #undef closesocket
-int slirp_closesocket(int fd)
+int slirp_closesocket_wrap(int fd)
 {
 int ret;
 ret = closesocket(fd);
@@ -187,6 +187,166 @@ int slirp_closesocket(int fd)
 }
 return ret;
 }
+
+#undef connect
+int slirp_connect_wrap(int sockfd, const struct sockaddr *addr, int addrlen)
+{
+int ret;
+ret = connect(sockfd, addr, addrlen);
+if (ret < 0) {
+errno = socket_error();
+}
+return ret;
+}
+
+#undef listen
+int slirp_listen_wrap(int sockfd, int backlog)
+{
+int ret;
+ret = listen(sockfd, backlog);
+if (ret < 0) {
+errno = socket_error();
+}
+return ret;
+}
+
+#undef bind
+int slirp_bind_wrap(int sockfd, const struct sockaddr *addr, int addrlen)
+{
+int ret;
+ret = bind(sockfd, addr, addrlen);
+if (ret < 0) {
+errno = socket_error();
+}
+return ret;
+}
+
+#undef socket
+int slirp_socket_wrap(int domain, int type, int protocol)
+{
+int ret;
+ret = socket(domain, type, protocol);
+if (ret < 0) {
+errno = socket_error();
+}
+return ret;
+}
+
+#undef accept
+int slirp_accept_wrap(int sockfd, struct sockaddr *addr, int *addrlen)
+{
+int ret;
+ret = accept(sockfd, addr, addrlen);
+if (ret < 0) {
+errno = socket_error();
+}
+return ret;
+}
+
+#undef shutdown
+int slirp_shutdown_wrap(int sockfd, int how)
+{
+int ret;
+ret = shutdown(sockfd, how);
+if (ret < 0) {
+errno = socket_error();
+}
+return ret;
+}
+
+#undef getsockopt
+int slirp_getsockopt_wrap(int sockfd, int level, int optname,
+  void *optval, int *optlen)
+{
+int ret;
+ret = getsockopt(sockfd, level, optname, optval, optlen);
+if (ret < 0) {
+errno = socket_error();
+}
+return ret;
+}
+
+#undef setsockopt
+int slirp_setsockopt_wrap(int sockfd, int level, int optname,
+  const void *optval, int optlen)
+{
+int ret;
+ret = setsockopt(sockfd, level, optname, optval, optlen);
+if (ret < 0) {
+errno = socket_error();
+}
+return ret;
+}
+
+#undef getpeername
+int slirp_getpeername_wrap(int sockfd, struct sockaddr *addr,
+   int *addrlen)
+{
+int ret;
+ret = getpeername(sockfd, addr, addrlen);
+if (ret < 0) {
+errno = socket_error();
+}
+return ret;
+}
+
+#undef getsockname
+int slirp_getsockname_wrap(int sockfd, struct sockaddr *addr,
+   int *addrlen)
+{
+int ret;
+ret = getsockname(sockfd, addr, addrlen);
+if (ret < 0) {
+errno = socket_error();
+}
+return ret;
+}
+
+#undef send
+ssize_t slirp_send_wrap(int sockfd, const void *buf, size_t len, int flags)
+{
+int ret;
+ret = send(sockfd, buf, len, flags);
+if (ret < 0) {
+errno = socket_error();
+}
+return ret;
+}
+
+#undef sendto
+ssize_t slirp_sendto_wrap(int sockfd, const void *buf, size_t len, int flags,
+ const struct sockaddr *addr, int addrlen)
+{
+int ret;
+ret = sendto(sockfd, buf, len, flags, addr, addrlen);
+if (ret < 0) {
+errno = socket_error();
+}
+return ret;
+}
+
+#undef recv
+ssize_t slirp_recv_wrap(int sockfd, void *buf, size_t len, int flags)
+{
+int ret;
+ret = recv(sockfd, buf, len, flags);
+if (ret < 0) {
+errno = socket_error();
+}
+return ret;
+}
+
+#undef recvfrom
+ssize_t slirp_recvfrom_wrap(int sockfd, void *buf, size_t len, int flags,
+struct sockaddr *addr, int *addrlen)
+{
+int ret;
+ret = recvfrom(sockfd, buf, len, flags, addr, addrlen);
+if (ret < 0) {
+errno = socket_erro

[Qemu-devel] [PULL 1/2] slirp: remove slirp_ prefix for socket wrappers

2019-02-13 Thread Samuel Thibault
From: Marc-André Lureau 

QEMU wraps the socket functions in os-win32.h, but in commit
a9d8b3ec4385793815d71217857304, the header inclusion was dropped,
breaking libslirp on Windows.

There are already a few socket functions that are wrapped in libslirp,
with "slirp_" prefix, but many of them are missing, and we are going
to wrap the missing functions in a second patch.

Using "slirp_" prefix avoids the conflict with socket function #define
wrappers in QEMU os-win32.h, but they are quite intrusive. In the end,
the functions should behave the same as original one, but with errno
being set. To avoid the churn, and potential confusion, remove the
"slirp_" prefix. A series of #undef is necessary until libslirp is
made standalone to prevent the #define conflict with QEMU.

Signed-off-by: Marc-André Lureau 
Message-Id: <20190212160953.29051-2-marcandre.lur...@redhat.com>
Signed-off-by: Samuel Thibault 
---
 slirp/ip_icmp.c  |  4 ++--
 slirp/misc.c | 14 +++---
 slirp/slirp.c|  2 +-
 slirp/socket.c   | 14 +++---
 slirp/tcp_subr.c | 10 +-
 slirp/udp.c  |  2 +-
 slirp/util.h | 31 ---
 7 files changed, 43 insertions(+), 34 deletions(-)

diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
index ce79c0b051..120108f582 100644
--- a/slirp/ip_icmp.c
+++ b/slirp/ip_icmp.c
@@ -114,7 +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, so->slirp->opaque);
-slirp_closesocket(so->s);
+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 = slirp_recv(so->s, icp, M_ROOM(m), 0);
+len = 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 3f4cd852f8..d9fc586a24 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -98,16 +98,16 @@ slirp_socketpair_with_oob(int sv[2])
 goto err;
 }
 
-slirp_closesocket(s);
+closesocket(s);
 return 0;
 
 err:
 g_critical("slirp_socketpair(): %s", strerror(errno));
 if (s >= 0) {
-slirp_closesocket(s);
+closesocket(s);
 }
 if (sv[1] >= 0) {
-slirp_closesocket(sv[1]);
+closesocket(sv[1]);
 }
 return -1;
 }
@@ -211,16 +211,16 @@ fork_exec(struct socket *so, const char *ex)
 if (err) {
 g_critical("fork_exec: %s", err->message);
 g_error_free(err);
-slirp_closesocket(sp[0]);
-slirp_closesocket(sp[1]);
+closesocket(sp[0]);
+closesocket(sp[1]);
 return 0;
 }
 
 so->s = sp[0];
-slirp_closesocket(sp[1]);
+closesocket(sp[1]);
 slirp_socket_set_fast_reuse(so->s);
 opt = 1;
-slirp_setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, , sizeof(int));
+setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, , sizeof(int));
 slirp_set_nonblock(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 a746c6fd86..55591430dc 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -961,7 +961,7 @@ int slirp_remove_hostfwd(Slirp *slirp, int is_udp, struct 
in_addr host_addr,
 addr.sin_addr.s_addr == host_addr.s_addr &&
 addr.sin_port == port) {
 so->slirp->cb->unregister_poll_fd(so->s, so->slirp->opaque);
-slirp_closesocket(so->s);
+closesocket(so->s);
 sofree(so);
 return 0;
 }
diff --git a/slirp/socket.c b/slirp/socket.c
index ce1d6ffa1d..4876ea3f31 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -185,7 +185,7 @@ soread(struct socket *so)
 */
sopreprbuf(so, iov, );
 
-   nn = slirp_recv(so->s, iov[0].iov_base, iov[0].iov_len,0);
+   nn = recv(so->s, iov[0].iov_base, iov[0].iov_len,0);
if (nn <= 0) {
if (nn < 0 && (errno == EINTR || errno == EAGAIN))
return 0;
@@ -201,7 +201,7 @@ soread(struct socket *so)
if (getpeername(so->s, paddr, ) < 0) {
err = errno;
} else {
-   slirp_getsockopt(so->s, SOL_SOCKET, 
SO_ERROR,
+   getsockopt(so->s, SOL_SOCKET, SO_ERROR,
, );
}
}
@@ -231,7 +231,7 @@ soread(struct socket *so)
 */
if (n == 2 && nn == iov[0].iov_len) {
   

Re: [Qemu-devel] [PATCH 0/2] Fix slirp regression on win32

2019-02-12 Thread Samuel Thibault
Marc-André Lureau, le mar. 12 févr. 2019 17:09:51 +0100, a ecrit:
> QEMU wraps the socket functions in os-win32.h, but in commit
> a9d8b3ec4385793815d71217857304, the header inclusion was dropped,
> breaking slirp on Windows. Fix the regression by wrapping all the
> socket functions.

Applied to my tree, thanks!

Samuel



Re: [Qemu-devel] [PATCH 1/1] RFC: net/slirp: link with libslirp

2019-02-11 Thread Samuel Thibault
Marc-André Lureau, le lun. 11 févr. 2019 12:34:47 +0100, a ecrit:
> On Mon, Feb 11, 2019 at 12:09 PM Daniel P. Berrangé  
> wrote:
> >
> > On Fri, Feb 08, 2019 at 07:12:26PM +0100, Marc-André Lureau wrote:
> > > Once libslirp has received its first release, we can link with the
> > > external libslirp library.
> > >
> > > The migration data should be compatible with current and older qemu
> > > versions (same compatibility as today). See "slirp: add state
> > > saving/loading" patch. However, the content should be treated as a
> > > blob, as the format may change eventually in the future.
> >
> > How are we going to manage live migration compat if libslirp changes
> > the blob content ?
> >
> > Bear in mind that we need to support all existing QEMU releases live
> > migrating to effectively all future QEMU releases, with all future
> > libslirp releases, in *both* directions. ie arbitrarily newer
> > libslirp needs to be able to emit a blob format that can be read
> > by arbitrarily older slirp inside QEMU.
> 
> Right, this is all supported currently with the proposed patch set,
> since it is effectively the same code.
> 
> So register_savevm_live() get passed slirp_state_version() (currently == 4)
> 
> & slirp_state_load() get the version_id from QEMU.

Mmm, but do we guarantee that the current version of slirp will be able
to read blobs produced by future versions of slirp?

Future extensions of the format would have to be so that the current
version could discard their content without issues.

Perhaps qemu should actually explicitly pass 4 to
register_savevm_live(), for that function to only record that format
(and thus get compatibility of course) and only bump to greater values
when qemu is modified to make use of a functionality which requires
extending the blob format, which then makes it unreadable by older qemu
releases, but that is fine for qemu.

Samuel



Re: [Qemu-devel] [PATCH slirp 0/5] Make it a standalone project

2019-02-10 Thread Samuel Thibault
Hello,

Peter Maydell, le dim. 10 févr. 2019 21:35:37 +, a ecrit:
> On Fri, 8 Feb 2019 at 20:58,  wrote:
> > As discussed earlier in "[PATCH for-3.2 00/41] RFC: slirp: make it
> > again a standalone project" and other threads, it would be useful to
> > make slirp a separate project (the submodule approach was discarded)
> > for various projects to share.
> 
> > The following patches add meson build system (if necessary for older
> > distros, autotools could be added - however I believe python & ninja
> > are generally available on the QEMU supported platforms)
> 
> Do you really need to make QEMU add an extra build dependency
> just to use a different build system?

AIUI, this patches series is meant for the slirp repository, not the
QEMU repository. I.e. just to show how it'll look like, until a project
it settled somewhere and the discussion can happen there.

Samuel



Re: [Qemu-devel] [PATCH slirp 4/5] slirp: add state saving/loading

2019-02-09 Thread Samuel Thibault
Marc-André Lureau, le sam. 09 févr. 2019 14:16:53 +0100, a ecrit:
> Hi
> 
> On Sat, Feb 9, 2019 at 2:13 PM Samuel Thibault  
> wrote:
> >
> > Marc-André Lureau, le sam. 09 févr. 2019 14:09:02 +0100, a ecrit:
> > > On Sat, Feb 9, 2019 at 12:40 PM Samuel Thibault  
> > > wrote:
> > > >
> > > > marcandre.lur...@redhat.com, le ven. 08 févr. 2019 19:11:21 +0100, a 
> > > > ecrit:
> > > > > From: Marc-André Lureau 
> > > > >
> > > > > Based on qemu vmstate serialization code. At this point it should
> > > > > produce the same result. However, with future state versions, slirp
> > > > > should be free to change its format, by bumping the reported state
> > > > > version.
> > > >
> > > > Mmm, then qemu needs to be taught to call slirp_state_save/load/version?
> > >
> > > Yes, see "[Qemu-devel] [PATCH 1/1] RFC: net/slirp: link with libslirp"
> >
> > Ah, I did have a look there but somehow missed it because burried within
> > file removals :)
> >
> 
> Indeed, the original patch series was splited in 2, but I thought as
> an RFC it was easier to send a single patch. Bad choice I suppose.

No, it's fine enough, it's just the file ordering in the patch which
posed problem :)

Samuel



Re: [Qemu-devel] [PATCH 1/1] RFC: net/slirp: link with libslirp

2019-02-09 Thread Samuel Thibault
Marc-André Lureau, le ven. 08 févr. 2019 19:12:26 +0100, a ecrit:
> Once libslirp has received its first release, we can link with the
> external libslirp library.
> 
> The migration data should be compatible with current and older qemu
> versions (same compatibility as today). See "slirp: add state
> saving/loading" patch. However, the content should be treated as a
> blob, as the format may change eventually in the future.
> 
> Signed-off-by: Marc-André Lureau 

Reviewed-by: Samuel Thibault 

Thanks so much for all this work :)



Re: [Qemu-devel] [PATCH slirp 4/5] slirp: add state saving/loading

2019-02-09 Thread Samuel Thibault
Marc-André Lureau, le sam. 09 févr. 2019 14:09:02 +0100, a ecrit:
> On Sat, Feb 9, 2019 at 12:40 PM Samuel Thibault  
> wrote:
> >
> > marcandre.lur...@redhat.com, le ven. 08 févr. 2019 19:11:21 +0100, a ecrit:
> > > From: Marc-André Lureau 
> > >
> > > Based on qemu vmstate serialization code. At this point it should
> > > produce the same result. However, with future state versions, slirp
> > > should be free to change its format, by bumping the reported state
> > > version.
> >
> > Mmm, then qemu needs to be taught to call slirp_state_save/load/version?
> 
> Yes, see "[Qemu-devel] [PATCH 1/1] RFC: net/slirp: link with libslirp"

Ah, I did have a look there but somehow missed it because burried within
file removals :)

Samuel



Re: [Qemu-devel] [PATCH slirp 4/5] slirp: add state saving/loading

2019-02-09 Thread Samuel Thibault
marcandre.lur...@redhat.com, le ven. 08 févr. 2019 19:11:21 +0100, a ecrit:
> From: Marc-André Lureau 
> 
> Based on qemu vmstate serialization code. At this point it should
> produce the same result. However, with future state versions, slirp
> should be free to change its format, by bumping the reported state
> version.

Mmm, then qemu needs to be taught to call slirp_state_save/load/version?

Samuel



Re: [Qemu-devel] [PATCH slirp 0/5] Make it a standalone project

2019-02-09 Thread Samuel Thibault
Hello,

marcandre.lur...@redhat.com, le ven. 08 févr. 2019 19:11:17 +0100, a ecrit:
> Where should this new project be hosted? (I suggest some gitlab
> instance, because of the nice ui/CI/issues/milestone...)

I'd say freedesktop's gitlab would make a lot of sense yes, I'd go for
it https://www.freedesktop.org/wiki/NewProject/

Samuel



Re: [Qemu-devel] [PULLv4 27/32] slirp: improve send_packet() callback

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

That was the idea of my fix, yes :)

Samuel



[Qemu-devel] [PULLv4 27/32] slirp: improve send_packet() callback

2019-02-07 Thread Samuel Thibault
From: Marc-André Lureau 

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 
Signed-off-by: Samuel Thibault 
---
 include/net/net.h |  2 +-
 net/net.c |  4 ++--
 net/slirp.c   |  9 +
 slirp/libslirp.h  | 11 +++
 slirp/ncsi.c  |  2 +-
 slirp/slirp.c | 18 +++---
 slirp/slirp.h |  2 ++
 7 files changed, 33 insertions(+), 15 deletions(-)

diff --git a/include/net/net.h b/include/net/net.h
index 643295d163..075cc01267 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -146,7 +146,7 @@ ssize_t qemu_sendv_packet(NetClientState *nc, const struct 
iovec *iov,
   int iovcnt);
 ssize_t qemu_sendv_packet_async(NetClientState *nc, const struct iovec *iov,
 int iovcnt, NetPacketSent *sent_cb);
-void qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size);
+ssize_t qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size);
 ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int size);
 ssize_t qemu_send_packet_async(NetClientState *nc, const uint8_t *buf,
int size, NetPacketSent *sent_cb);
diff --git a/net/net.c b/net/net.c
index 3acbdccd61..5dcff7fe2a 100644
--- a/net/net.c
+++ b/net/net.c
@@ -668,9 +668,9 @@ ssize_t qemu_send_packet_async(NetClientState *sender,
  buf, size, sent_cb);
 }
 
-void qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size)
+ssize_t qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size)
 {
-qemu_send_packet_async(nc, buf, size, NULL);
+return qemu_send_packet_async(nc, buf, size, NULL);
 }
 
 ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int size)
diff --git a/net/slirp.c b/net/slirp.c
index 7b4f9f5c5e..664ff1c002 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -108,11 +108,12 @@ static void slirp_smb_cleanup(SlirpState *s);
 static inline void slirp_smb_cleanup(SlirpState *s) { }
 #endif
 
-static void net_slirp_output(void *opaque, const uint8_t *pkt, int pkt_len)
+static ssize_t net_slirp_send_packet(const void *pkt, size_t pkt_len,
+ void *opaque)
 {
 SlirpState *s = opaque;
 
-qemu_send_packet(>nc, pkt, pkt_len);
+return qemu_send_packet(>nc, pkt, pkt_len);
 }
 
 static ssize_t net_slirp_receive(NetClientState *nc, const uint8_t *buf, 
size_t size)
@@ -197,7 +198,7 @@ static void net_slirp_unregister_poll_fd(int fd)
 }
 
 static const SlirpCb slirp_cb = {
-.output = net_slirp_output,
+.send_packet = net_slirp_send_packet,
 .guest_error = net_slirp_guest_error,
 .clock_get_ns = net_slirp_clock_get_ns,
 .timer_new = net_slirp_timer_new,
@@ -780,7 +781,7 @@ static void guestfwd_read(void *opaque, const uint8_t *buf, 
int size)
 slirp_socket_recv(fwd->slirp, fwd->server, fwd->port, buf, size);
 }
 
-static int guestfwd_write(const void *buf, size_t len, void *chr)
+static ssize_t guestfwd_write(const void *buf, size_t len, void *chr)
 {
 return qemu_chr_fe_write_all(chr, buf, len);
 }
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 02cbec9f8b..8e5d4ed11b 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -15,7 +15,7 @@
 
 typedef struct Slirp Slirp;
 
-typedef int (*SlirpWriteCb)(const void *buf, size_t len, void *opaque);
+typedef ssize_t (*SlirpWriteCb)(const void *buf, size_t len, void *opaque);
 typedef void (*SlirpTimerCb)(void *opaque);
 
 /*
@@ -23,10 +23,13 @@ typedef void (*SlirpTimerCb)(void *opaque);
  */
 typedef struct SlirpCb {
 /*
- * Send an ethernet frame to the guest network. The opaque parameter
- * is the one given to slirp_init().
+ * Send an ethernet frame to the guest network. The opaque
+ * parameter is the one given to slirp_init(). The function
+ * doesn't need to send all the data and may return cb->output(slirp->opaque, ncsi_reply, ETH_HLEN + ncsi_rsp_len);
+slirp_send_packet_all(slirp, ncsi_reply, ETH_HLEN + ncsi_rsp_len);
 }
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 3304c83001..2bc53e3e12 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -800,7 +800,7 @@ static void arp_input(Slirp *slirp, const uint8_t *pkt, int 
pkt_len)
 rah->ar_sip = ah->ar_tip;
 memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
 rah->ar_tip = ah->ar_sip;
-slirp->cb->output(slirp->opaque, arp_reply, sizeof(arp_reply));
+slirp_send_packet_all(slirp, arp_reply, sizeof(arp_reply));
 }
 break;
 case ARPOP_REPLY:
@@ -900,7 +900,7 @@ static int if_encap4(Slirp *slirp, struct mbuf *ifm, struct 
ethhdr *eh,
 /* target IP */
 rah->ar_tip = iph->ip_dst.s_addr;
 slir

[Qemu-devel] [PULLv4 28/32] slirp: replace global polling with per-instance & notifier

2019-02-07 Thread Samuel Thibault
From: Marc-André Lureau 

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 
Signed-off-by: Samuel Thibault 
---
 include/qemu/main-loop.h |  15 ++
 net/slirp.c  |  24 ++
 slirp/libslirp.h |   4 +-
 slirp/slirp.c| 555 +++
 stubs/Makefile.objs  |   1 -
 stubs/slirp.c|  13 -
 util/main-loop.c |  30 ++-
 7 files changed, 333 insertions(+), 309 deletions(-)
 delete mode 100644 stubs/slirp.c

diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h
index e59f9ae1e9..f6ba78ea73 100644
--- a/include/qemu/main-loop.h
+++ b/include/qemu/main-loop.h
@@ -302,4 +302,19 @@ void qemu_fd_register(int fd);
 QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque);
 void qemu_bh_schedule_idle(QEMUBH *bh);
 
+enum {
+MAIN_LOOP_POLL_FILL,
+MAIN_LOOP_POLL_ERR,
+MAIN_LOOP_POLL_OK,
+};
+
+typedef struct MainLoopPoll {
+int state;
+uint32_t timeout;
+GArray *pollfds;
+} MainLoopPoll;
+
+void main_loop_poll_add_notifier(Notifier *notify);
+void main_loop_poll_remove_notifier(Notifier *notify);
+
 #endif
diff --git a/net/slirp.c b/net/slirp.c
index 664ff1c002..4d55f64168 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -86,6 +86,7 @@ typedef struct SlirpState {
 NetClientState nc;
 QTAILQ_ENTRY(SlirpState) entry;
 Slirp *slirp;
+Notifier poll_notifier;
 Notifier exit_notifier;
 #ifndef _WIN32
 gchar *smb_dir;
@@ -144,6 +145,7 @@ static void net_slirp_cleanup(NetClientState *nc)
 SlirpState *s = DO_UPCAST(SlirpState, nc, nc);
 
 g_slist_free_full(s->fwd, slirp_free_fwd);
+main_loop_poll_remove_notifier(>poll_notifier);
 slirp_cleanup(s->slirp);
 if (s->exit_notifier.notify) {
 qemu_remove_exit_notifier(>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, >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,
   _cb, s);
 QTAILQ_INSERT_TAIL(_stacks, s, entry);
 
+s->poll_notifier.notify = net_slirp_poll_notify;
+main_loop_poll_add_notifier(>poll_notifier);
+
 for (config = slirp_configs; config; config = config->next) {
 if (config->flags & SLIRP_CFG_HOSTFWD) {
 if (slirp_hostfwd(s, config->str, errp) < 0) {
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 8e5d4ed11b..18d5fb0133 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -63,9 +63,9 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct 
in_addr vnetwork,
   void *opaque);
 void slirp_cleanup(Slirp *slirp);
 
-void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout);
+void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout);
 
-void slirp_pollfds_poll(GArray *pollfds, int select_error);
+void slirp_pollfds_poll(Slirp *slirp, GArray *pollfds, int select_error);
 
 void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len);
 
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 2bc53e3e12..3a8d1bc459 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -368,9 +368,8 @@ void slirp_cleanup(Slirp *slirp)
 #define CONN_CANFSEND(so) (((so)->so_state & 
(SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
 #define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) 
== SS_ISFCONNECTED)
 
-static void slirp_update_timeout(uint32_t *timeout)
+static void slirp_update_timeout(Slirp *slirp, uint32_t *timeout)
 {
-Slirp *slirp;
 uint32_t t;
 
 if (*timeout <= TIMEOUT_FAST) {
@@ -382,370 +381,352 @@ static void slirp_update_timeout(uint32_t *timeout)
 /* If we have tcp timeout with slirp, then we will fill @timeout with
  * more precise value.
  */
-QTAILQ_FOREACH(slirp, _instances, entry) {
-if (slirp->time_fasttimo) {
-*timeout = TIMEOUT_FAST;
-return;
-}
-if (slirp->do_slowtimo) {
-t = MIN(TIMEOUT_SLOW, t);
-}
+if (slirp->time_fas

[Qemu-devel] [PULLv4 32/32] slirp: API is extern C

2019-02-07 Thread Samuel Thibault
From: Marc-André Lureau 

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

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/libslirp.h | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 9b13d8250c..fccab42518 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -12,6 +12,10 @@
 #include 
 #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




[Qemu-devel] [PULLv4 26/32] slirp: prefer c99 types over BSD kind

2019-02-07 Thread Samuel Thibault
From: Marc-André Lureau 

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 
Signed-off-by: Samuel Thibault 
---
 slirp/ip_icmp.c|  6 +++---
 slirp/ip_icmp.h| 18 +-
 slirp/ip_input.c   |  4 ++--
 slirp/main.h   |  2 +-
 slirp/mbuf.h   |  2 +-
 slirp/slirp.c  | 12 ++--
 slirp/slirp.h  |  8 +++-
 slirp/socket.c |  6 +++---
 slirp/socket.h |  4 ++--
 slirp/tcp_input.c  | 22 +++---
 slirp/tcp_output.c | 12 ++--
 slirp/tcp_subr.c   | 18 +-
 slirp/tcp_timer.c  |  2 +-
 slirp/tcp_var.h| 14 +++---
 slirp/udp.c|  6 +++---
 slirp/udp.h|  2 +-
 util/osdep.c   |  2 +-
 17 files changed, 69 insertions(+), 71 deletions(-)

diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
index 6b6344b776..7c5cb75ae5 100644
--- a/slirp/ip_icmp.c
+++ b/slirp/ip_icmp.c
@@ -240,7 +240,7 @@ end_error:
 
 #define ICMP_MAXDATALEN (IP_MSS-28)
 void
-icmp_send_error(struct mbuf *msrc, u_char type, u_char code, int minsize,
+icmp_send_error(struct mbuf *msrc, uint8_t type, uint8_t code, int minsize,
const char *message)
 {
   unsigned hlen, shlen, s_ip_len;
@@ -388,7 +388,7 @@ icmp_reflect(struct mbuf *m)
  * Strip out original options by copying rest of first
  * mbuf's data back, and adjust the IP length.
  */
-memmove((caddr_t)(ip + 1), (caddr_t)ip + hlen,
+memmove((char *)(ip + 1), (char *)ip + hlen,
(unsigned )(m->m_len - hlen));
 hlen -= optlen;
 ip->ip_hl = hlen >> 2;
@@ -412,7 +412,7 @@ void icmp_receive(struct socket *so)
 struct mbuf *m = so->so_m;
 struct ip *ip = mtod(m, struct ip *);
 int hlen = ip->ip_hl << 2;
-u_char error_code;
+uint8_t error_code;
 struct icmp *icp;
 int id, len;
 
diff --git a/slirp/ip_icmp.h b/slirp/ip_icmp.h
index d88ab34c1b..a4e5b8b265 100644
--- a/slirp/ip_icmp.h
+++ b/slirp/ip_icmp.h
@@ -44,22 +44,22 @@ typedef uint32_t n_time;
  * Structure of an icmp header.
  */
 struct icmp {
-   u_char  icmp_type;  /* type of message, see below */
-   u_char  icmp_code;  /* type sub code */
-   u_short icmp_cksum; /* ones complement cksum of struct */
+   uint8_t icmp_type;  /* type of message, see below */
+   uint8_t icmp_code;  /* type sub code */
+   uint16_ticmp_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_ticd_id;
+   uint16_ticd_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;
 #defineicmp_pptr   icmp_hun.ih_pptr
@@ -156,7 +156,7 @@ struct icmp {
 void icmp_init(Slirp *slirp);
 void icmp_cleanup(Slirp *slirp);
 void icmp_input(struct mbuf *, int);
-void icmp_send_error(struct mbuf *msrc, u_char type, u_char code, int minsize,
+void icmp_send_error(struct mbuf *msrc, uint8_t type, uint8_t code, int 
minsize,
  const char *message);
 void icmp_reflect(struct mbuf *);
 void icmp_receive(struct socket *so);
diff --git a/slirp/ip_input.c b/slirp/ip_input.c
index 774ce662e6..e0b94b0e42 100644
--- a/slirp/ip_input.c
+++ b/slirp/ip_input.c
@@ -458,11 +458,11 @@ ip_stripoptions(register struct mbuf *m, struct mbuf 
*mopt)
 {
register int i;
struct ip *ip = mtod(m, struct ip *);
-   register caddr_t opts;
+   register char *opts;
int olen;
 
olen = (ip->ip_hl<<2) - sizeof (struct ip);
-   opts = (caddr_t)(ip + 1);
+   opts = (char *)(ip + 1);
i = m->m_len - (sizeof (struct ip) + olen);
memcpy(opts, opts  + olen, (unsigned)i);
m->m_len -= olen;
diff --git a/slirp/main.h b/slirp/main.h
index 4bc05fb904..f11d4572b7 100644
--- a/slirp/main.h
+++ b/slirp/main.h
@@ -8,7 +8,7 @@
 #ifndef SLIRP_MAIN_H
 #define SLIRP_MAIN_H
 
-extern u_int curtime;
+extern unsigned curtime;
 extern struct in_addr loopback_addr;
 extern unsigned long loopback_mask;
 
diff --git a/slirp/mbuf.h b/slirp/mbuf.h
index cbf17e136b..e2d443418a 100644
--- a/slirp/mbuf.h
+++ b/slirp/mbuf.h
@@ -85,7 +85,7 @@ struct mbuf {
int m_size

[Qemu-devel] [PULLv4 30/32] slirp: use polling callbacks, drop glib requirement

2019-02-07 Thread Samuel Thibault
From: Marc-André Lureau 

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

diff --git a/net/slirp.c b/net/slirp.c
index 4d55f64168..a85e42ff43 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -211,6 +211,71 @@ static const SlirpCb slirp_cb = {
 .notify = qemu_notify_event,
 };
 
+static int slirp_poll_to_gio(int events)
+{
+int ret = 0;
+
+if (events & SLIRP_POLL_IN) {
+ret |= G_IO_IN;
+}
+if (events & SLIRP_POLL_OUT) {
+ret |= G_IO_OUT;
+}
+if (events & SLIRP_POLL_PRI) {
+ret |= G_IO_PRI;
+}
+if (events & SLIRP_POLL_ERR) {
+ret |= G_IO_ERR;
+}
+if (events & SLIRP_POLL_HUP) {
+ret |= G_IO_HUP;
+}
+
+return ret;
+}
+
+static int net_slirp_add_poll(int fd, int events, void *opaque)
+{
+GArray *pollfds = opaque;
+GPollFD pfd = {
+.fd = fd,
+.events = slirp_poll_to_gio(events),
+};
+int idx = pollfds->len;
+g_array_append_val(pollfds, pfd);
+return idx;
+}
+
+static int slirp_gio_to_poll(int events)
+{
+int ret = 0;
+
+if (events & G_IO_IN) {
+ret |= SLIRP_POLL_IN;
+}
+if (events & G_IO_OUT) {
+ret |= SLIRP_POLL_OUT;
+}
+if (events & G_IO_PRI) {
+ret |= SLIRP_POLL_PRI;
+}
+if (events & G_IO_ERR) {
+ret |= SLIRP_POLL_ERR;
+}
+if (events & G_IO_HUP) {
+ret |= SLIRP_POLL_HUP;
+}
+
+return ret;
+}
+
+static int net_slirp_get_revents(int idx, void *opaque)
+{
+GArray *pollfds = opaque;
+
+return slirp_gio_to_poll(g_array_index(pollfds, GPollFD, idx).revents);
+}
+
 static void net_slirp_poll_notify(Notifier *notifier, void *data)
 {
 MainLoopPoll *poll = data;
@@ -218,12 +283,13 @@ static void net_slirp_poll_notify(Notifier *notifier, 
void *data)
 
 switch (poll->state) {
 case MAIN_LOOP_POLL_FILL:
-slirp_pollfds_fill(s->slirp, poll->pollfds, >timeout);
+slirp_pollfds_fill(s->slirp, >timeout,
+   net_slirp_add_poll, poll->pollfds);
 break;
 case MAIN_LOOP_POLL_OK:
 case MAIN_LOOP_POLL_ERR:
-slirp_pollfds_poll(s->slirp, poll->pollfds,
-   poll->state == MAIN_LOOP_POLL_ERR);
+slirp_pollfds_poll(s->slirp, poll->state == MAIN_LOOP_POLL_ERR,
+   net_slirp_get_revents, poll->pollfds);
 break;
 default:
 g_assert_not_reached();
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 18d5fb0133..b5c1b2122b 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -1,7 +1,6 @@
 #ifndef LIBSLIRP_H
 #define LIBSLIRP_H
 
-#include 
 #include 
 #include 
 
@@ -15,8 +14,18 @@
 
 typedef struct Slirp Slirp;
 
+enum {
+SLIRP_POLL_IN  = 1 << 0,
+SLIRP_POLL_OUT = 1 << 1,
+SLIRP_POLL_PRI = 1 << 2,
+SLIRP_POLL_ERR = 1 << 3,
+SLIRP_POLL_HUP = 1 << 4,
+};
+
 typedef ssize_t (*SlirpWriteCb)(const void *buf, size_t len, void *opaque);
 typedef void (*SlirpTimerCb)(void *opaque);
+typedef int (*SlirpAddPollCb)(int fd, int events, void *opaque);
+typedef int (*SlirpGetREventsCb)(int idx, void *opaque);
 
 /*
  * Callbacks from slirp
@@ -63,9 +72,11 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct 
in_addr vnetwork,
   void *opaque);
 void slirp_cleanup(Slirp *slirp);
 
-void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout);
+void slirp_pollfds_fill(Slirp *slirp, uint32_t *timeout,
+SlirpAddPollCb add_poll, void *opaque);
 
-void slirp_pollfds_poll(Slirp *slirp, GArray *pollfds, int select_error);
+void slirp_pollfds_poll(Slirp *slirp, int select_error,
+SlirpGetREventsCb get_revents, void *opaque);
 
 void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len);
 
diff --git a/slirp/slirp.c b/slirp/slirp.c
index b37dd34382..eedbce23dc 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -386,7 +386,8 @@ static void slirp_update_timeout(Slirp *slirp, uint32_t 
*timeout)
 *timeout = t;
 }
 
-void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout)
+void slirp_pollfds_fill(Slirp *slirp, uint32_t *timeout,
+SlirpAddPollCb add_poll, void *opaque)
 {
 struct socket *so, *so_next;
 
@@ -428,12 +429,8 @@ void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, 
uint32_t *timeout)
  * Set for reading sockets which are accepting
  */
 if (so->so_state & SS_FACCEPTCONN) {
-GPollFD pfd = {

[Qemu-devel] [PULLv4 29/32] slirp: remove slirp_instances list

2019-02-07 Thread Samuel Thibault
From: Marc-André Lureau 

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

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/slirp.c | 5 -
 1 file changed, 5 deletions(-)

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




[Qemu-devel] [PULLv4 04/32] slirp: generalize guestfwd with a callback based approach

2019-02-07 Thread Samuel Thibault
From: Marc-André Lureau 

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

diff --git a/net/slirp.c b/net/slirp.c
index f98425ee9f..ec07f662c0 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -704,8 +704,8 @@ static int slirp_smb(SlirpState* s, const char 
*exported_dir,
  CONFIG_SMBD_COMMAND, s->smb_dir, smb_conf);
 g_free(smb_conf);
 
-if (slirp_add_exec(s->slirp, NULL, smb_cmdline, _addr, 139) < 0 ||
-slirp_add_exec(s->slirp, NULL, smb_cmdline, _addr, 445) < 0) {
+if (slirp_add_exec(s->slirp, smb_cmdline, _addr, 139) < 0 ||
+slirp_add_exec(s->slirp, smb_cmdline, _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, [4], , port) < 0) {
+if (slirp_add_exec(s->slirp, [4], , 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, >hd, NULL, , port) < 0) {
+if (slirp_add_guestfwd(s->slirp, guestfwd_write, >hd,
+   , port) < 0) {
 error_setg(errp, "Conflicting/invalid host:port in guest "
"forwarding rule '%s'", config_str);
 g_free(fwd);
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 4611a7447b..ea019828e8 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -5,6 +5,8 @@
 
 typedef struct Slirp Slirp;
 
+typedef int (*SlirpWriteCb)(const void *buf, size_t len, void *opaque);
+
 /*
  * Callbacks from slirp
  *
@@ -45,7 +47,9 @@ int slirp_add_hostfwd(Slirp *slirp, int is_udp,
   struct in_addr guest_addr, int guest_port);
 int slirp_remove_hostfwd(Slirp *slirp, int is_udp,
  struct in_addr host_addr, int host_port);
-int slirp_add_exec(Slirp *slirp, void *chardev, const char *cmdline,
+int slirp_add_exec(Slirp *slirp, const char *cmdline,
+   struct in_addr *guest_addr, int guest_port);
+int slirp_add_guestfwd(Slirp *slirp, SlirpWriteCb write_cb, void *opaque,
struct in_addr *guest_addr, int guest_port);
 
 char *slirp_connection_info(Slirp *slirp);
diff --git a/slirp/misc.c b/slirp/misc.c
index eae9596a55..b8a2bf971a 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -32,24 +32,33 @@ remque(void *a)
   element->qh_rlink = NULL;
 }
 
-int add_exec(struct gfwd_list **ex_ptr, void *chardev, const char *cmdline,
+struct gfwd_list *
+add_guestfwd(struct gfwd_list **ex_ptr,
+ SlirpWriteCb write_cb, void *opaque,
  struct in_addr addr, int port)
 {
-   struct gfwd_list *tmp_ptr;
-
-   tmp_ptr = *ex_ptr;
-   *ex_ptr = g_new0(struct gfwd_list, 1);
-   (*ex_ptr)->ex_fport = port;
-   (*ex_ptr)->ex_addr = addr;
-   if (chardev) {
-   (*ex_ptr)->ex_chardev = chardev;
-   } else {
-   (*ex_ptr)->ex_exec = g_strdup(cmdline);
-   }
-   (*ex_ptr)->ex_next = tmp_ptr;
-   return 0;
+struct gfwd_list *f = g_new0(struct gfwd_list, 1);
+
+f->write_cb = write_cb;
+f->opaque = opaque;
+f->ex_fport = port;
+f->ex_addr = addr;
+f->ex_next = *ex_ptr;
+*ex_ptr = f;
+
+return f;
 }
 
+struct gfwd_list *
+add_exec(struct gfwd_list **ex_ptr, const char *cmdline,
+ struct in_addr addr, int port)
+{
+struct gfwd_list *f = add_guestfwd(ex_ptr, NULL, NULL, addr, port);
+
+

[Qemu-devel] [PULLv4 22/32] slirp: replace qemu qtailq with slirp own copy

2019-02-07 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 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 00..a89b0c439a
--- /dev/null
+++ b/slirp/qtailq.h
@@ -0,0 +1,193 @@
+/*  $NetBSD: queue.h,v 1.52 2009/04/20 09:56:08 mschuett Exp $ */
+
+/*
+ * slirp version: Copy from QEMU, removed all but tail queues.
+ */
+
+/*
+ * Copyright (c) 1991, 1993
+ *  The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *notice, this list of conditions and the following disclaimer in the
+ *documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *may be used to endorse or promote products derived from this software
+ *without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *  @(#)queue.h 8.5 (Berkeley) 8/20/94
+ */
+
+#ifndef QTAILQ_H
+#define QTAILQ_H
+
+/*
+ * A tail queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or
+ * after an existing element, at the head of the list, or at the end of
+ * the list. A tail queue may be traversed in either direction.
+ */
+typedef struct QTailQLink {
+void *tql_next;
+struct QTailQLink *tql_prev;
+} QTailQLink;
+
+/*
+ * Tail queue definitions.  The union acts as a poor man template, as if
+ * it were QTailQLink.
+ */
+#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; 

[Qemu-devel] [PULLv4 17/32] slirp: improve windows headers inclusion

2019-02-07 Thread Samuel Thibault
From: Marc-André Lureau 

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 
Signed-off-by: Samuel Thibault 
---
 slirp/slirp.h | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/slirp/slirp.h b/slirp/slirp.h
index 8d9d72ca9d..5a830ddcb8 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -3,10 +3,19 @@
 
 #ifdef _WIN32
 
+/* as defined in sdkddkver.h */
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0600 /* Vista */
+#endif
+/* reduces the number of implicitly included headers */
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+
 typedef char *caddr_t;
 
-# include 
 # include 
+# include 
 # include 
 # include 
 # include 
@@ -19,19 +28,10 @@ typedef char *caddr_t;
 
 #ifndef _WIN32
 #include 
-#endif
-
-#ifndef _WIN32
 #include 
 #include 
-#endif
-
-#ifndef _WIN32
 #include 
-#endif
-
-#ifndef _WIN32
-# include 
+#include 
 #endif
 
 #ifdef __APPLE__
-- 
2.20.1




[Qemu-devel] [PULLv4 05/32] net/slirp: simplify checking for cmd: prefix

2019-02-07 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 net/slirp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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




[Qemu-devel] [PULLv4 18/32] slirp: add slirp own version of pstrcpy

2019-02-07 Thread Samuel Thibault
From: Marc-André Lureau 

Remove a dependency on qemu util.

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/slirp.c |  4 ++--
 slirp/tftp.c  |  2 +-
 slirp/util.c  | 17 +
 slirp/util.h  |  2 ++
 4 files changed, 22 insertions(+), 3 deletions(-)

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




[Qemu-devel] [PULLv4 15/32] slirp: move QEMU state saving to a separate unit

2019-02-07 Thread Samuel Thibault
From: Marc-André Lureau 

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 
Signed-off-by: Samuel Thibault 
---
 slirp/Makefile.objs |   1 +
 slirp/slirp.c   | 372 ++---
 slirp/slirp.h   |   3 +
 slirp/state.c   | 394 
 slirp/state.h   |   9 +
 5 files changed, 418 insertions(+), 361 deletions(-)
 create mode 100644 slirp/state.c
 create mode 100644 slirp/state.h

diff --git a/slirp/Makefile.objs b/slirp/Makefile.objs
index d2ead94b3b..88340a583b 100644
--- a/slirp/Makefile.objs
+++ b/slirp/Makefile.objs
@@ -20,6 +20,7 @@ slirp.mo-objs = \
sbuf.o \
slirp.o \
socket.o \
+   state.o \
tcp_input.o \
tcp_output.o \
tcp_subr.o \
diff --git a/slirp/slirp.c b/slirp/slirp.c
index f0bd59fd6f..9ec1e4c62f 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -30,6 +30,10 @@
 #include "hw/hw.h"
 #include "qemu/cutils.h"
 
+#ifdef WITH_QEMU
+#include "state.h"
+#endif
+
 #ifndef _WIN32
 #include 
 #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, _slirp_state, slirp);
-
+#ifdef WITH_QEMU
+slirp_state_register(slirp);
+#endif
 QTAILQ_INSERT_TAIL(_instances, slirp, entry);
 
 return slirp;
@@ -359,9 +356,9 @@ void slirp_cleanup(Slirp *slirp)
 }
 
 QTAILQ_REMOVE(_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),

[Qemu-devel] [PULLv4 12/32] slirp: replace qemu_set_nonblock()

2019-02-07 Thread Samuel Thibault
From: Marc-André Lureau 

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 
Signed-off-by: Samuel Thibault 
---
 net/slirp.c |  6 ++
 slirp/libslirp.h|  2 ++
 slirp/misc.c|  3 ++-
 slirp/tcp_subr.c|  6 --
 slirp/util.c| 14 ++
 slirp/util.h|  1 +
 stubs/Makefile.objs |  2 +-
 7 files changed, 30 insertions(+), 4 deletions(-)

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




[Qemu-devel] [PULLv4 25/32] slirp: replace remaining qemu headers dependency

2019-02-07 Thread Samuel Thibault
From: Marc-André Lureau 

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 
Signed-off-by: Samuel Thibault 
---
 slirp/arp_table.c  |  3 ++-
 slirp/bootp.c  |  1 -
 slirp/cksum.c  |  1 -
 slirp/dhcpv6.c |  1 -
 slirp/dnssearch.c  |  1 -
 slirp/if.c |  1 -
 slirp/ip6.h|  1 +
 slirp/ip6_icmp.c   |  1 -
 slirp/ip6_input.c  |  1 -
 slirp/ip6_output.c |  2 --
 slirp/ip_icmp.c|  1 -
 slirp/ip_input.c   |  1 -
 slirp/ip_output.c  |  1 -
 slirp/mbuf.c   |  1 -
 slirp/misc.c   |  2 --
 slirp/ncsi.c   |  1 -
 slirp/ndp_table.c  |  2 --
 slirp/sbuf.c   |  1 -
 slirp/slirp.c  |  2 --
 slirp/socket.c |  2 --
 slirp/tcp_input.c  |  1 -
 slirp/tcp_output.c |  1 -
 slirp/tcp_subr.c   |  1 -
 slirp/tcp_timer.c  |  1 -
 slirp/tftp.c   |  6 --
 slirp/udp.c|  1 -
 slirp/udp6.c   |  2 --
 slirp/util.h   | 21 +
 28 files changed, 28 insertions(+), 33 deletions(-)

diff --git a/slirp/arp_table.c b/slirp/arp_table.c
index bf71b984ad..58eafdcfd8 100644
--- a/slirp/arp_table.c
+++ b/slirp/arp_table.c
@@ -22,9 +22,10 @@
  * THE SOFTWARE.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 
+#include 
+
 void arp_table_add(Slirp *slirp, uint32_t ip_addr, uint8_t ethaddr[ETH_ALEN])
 {
 const uint32_t broadcast_addr =
diff --git a/slirp/bootp.c b/slirp/bootp.c
index 4c9a77eb98..d396849a05 100644
--- a/slirp/bootp.c
+++ b/slirp/bootp.c
@@ -21,7 +21,6 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-#include "qemu/osdep.h"
 #include "slirp.h"
 
 #if defined(_WIN32)
diff --git a/slirp/cksum.c b/slirp/cksum.c
index 84c858fafb..25bfa67348 100644
--- a/slirp/cksum.c
+++ b/slirp/cksum.c
@@ -30,7 +30,6 @@
  * in_cksum.c,v 1.2 1994/08/02 07:48:16 davidg Exp
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 
 /*
diff --git a/slirp/dhcpv6.c b/slirp/dhcpv6.c
index e27d9a46f8..9ffba38e8f 100644
--- a/slirp/dhcpv6.c
+++ b/slirp/dhcpv6.c
@@ -20,7 +20,6 @@
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 #include "dhcpv6.h"
 
diff --git a/slirp/dnssearch.c b/slirp/dnssearch.c
index 8fb563321b..c459cece8d 100644
--- a/slirp/dnssearch.c
+++ b/slirp/dnssearch.c
@@ -22,7 +22,6 @@
  * THE SOFTWARE.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 
 static const uint8_t RFC3397_OPT_DOMAIN_SEARCH = 119;
diff --git a/slirp/if.c b/slirp/if.c
index 90b9078687..2ad03b8a79 100644
--- a/slirp/if.c
+++ b/slirp/if.c
@@ -5,7 +5,6 @@
  * terms and conditions of the copyright.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 
 static void
diff --git a/slirp/ip6.h b/slirp/ip6.h
index 5361bd7449..1b3364f960 100644
--- a/slirp/ip6.h
+++ b/slirp/ip6.h
@@ -7,6 +7,7 @@
 #define SLIRP_IP6_H
 
 #include 
+#include 
 
 #define ALLNODES_MULTICAST  { .s6_addr = \
 { 0xff, 0x02, 0x00, 0x00,\
diff --git a/slirp/ip6_icmp.c b/slirp/ip6_icmp.c
index b3b7e50a31..2a432ebbd4 100644
--- a/slirp/ip6_icmp.c
+++ b/slirp/ip6_icmp.c
@@ -3,7 +3,6 @@
  * Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 #include "ip6_icmp.h"
 
diff --git a/slirp/ip6_input.c b/slirp/ip6_input.c
index ab656a0a9d..1b8c003c66 100644
--- a/slirp/ip6_input.c
+++ b/slirp/ip6_input.c
@@ -3,7 +3,6 @@
  * Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 #include "ip6_icmp.h"
 
diff --git a/slirp/ip6_output.c b/slirp/ip6_output.c
index 52c88ad691..19d1ae7748 100644
--- a/slirp/ip6_output.c
+++ b/slirp/ip6_output.c
@@ -3,8 +3,6 @@
  * Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne.
  */
 
-#include "qemu/osdep.h"
-#include "qemu-common.h"
 #include "slirp.h"
 
 /* Number of packets queued before we start sending
diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
index 19e247f773..6b6344b776 100644
--- a/slirp/ip_icmp.c
+++ b/slirp/ip_icmp.c
@@ -30,7 +30,6 @@
  * ip_icmp.c,v 1.7 1995/05/30 08:09:42 rgrimes Exp
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 #include "ip_icmp.h"
 
diff --git a/slirp/ip_input.c b/slirp/ip_input.c
index d360620838..774ce662e6 100644
--- a/slirp/ip_input.c
+++ b/slirp/ip_input.c
@@ -38,7 +38,6 @@
  * terms and conditions of the copyright.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 #include "ip_icmp.h"
 
diff --git a/slirp/ip_output.c b/slirp/ip_output.c
index db403f04c1..f6ec141df5 100644
--- a/slirp/ip_output.c
+++ b/slirp/ip_output.c
@@ -38,7 +38,6 @@
  * terms and conditions of the copyright

[Qemu-devel] [PULLv4 19/32] slirp: remove qemu timer.h dependency

2019-02-07 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/if.c   | 1 -
 slirp/ip6_icmp.c | 1 -
 slirp/slirp.c| 1 -
 slirp/util.h | 2 ++
 4 files changed, 2 insertions(+), 3 deletions(-)

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




[Qemu-devel] [PULLv4 11/32] slirp: replace most qemu socket utilities with slirp own version

2019-02-07 Thread Samuel Thibault
From: Marc-André Lureau 

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

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/Makefile.objs |   3 +-
 slirp/ip_icmp.c |   6 +-
 slirp/misc.c|  20 ++---
 slirp/socket.c  |  18 ++---
 slirp/tcp_subr.c|  18 ++---
 slirp/udp.c |   8 +-
 slirp/util.c| 176 
 slirp/util.h|  61 +++
 8 files changed, 274 insertions(+), 36 deletions(-)
 create mode 100644 slirp/util.c

diff --git a/slirp/Makefile.objs b/slirp/Makefile.objs
index 959558c732..d2ead94b3b 100644
--- a/slirp/Makefile.objs
+++ b/slirp/Makefile.objs
@@ -27,6 +27,7 @@ slirp.mo-objs = \
tftp.o \
udp.o \
udp6.o \
+   util.o \
$(NULL)
 
-slirp.mo-cflags = -DG_LOG_DOMAIN=\"Slirp\"
+slirp.mo-cflags = -DG_LOG_DOMAIN=\"Slirp\" -DWITH_QEMU
diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
index 7c7e042049..b59daa801d 100644
--- a/slirp/ip_icmp.c
+++ b/slirp/ip_icmp.c
@@ -83,7 +83,7 @@ static int icmp_send(struct socket *so, struct mbuf *m, int 
hlen)
 struct ip *ip = mtod(m, struct ip *);
 struct sockaddr_in addr;
 
-so->s = qemu_socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
+so->s = slirp_socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
 if (so->s == -1) {
 return -1;
 }
@@ -114,7 +114,7 @@ static int icmp_send(struct socket *so, struct mbuf *m, int 
hlen)
 
 void icmp_detach(struct socket *so)
 {
-closesocket(so->s);
+slirp_closesocket(so->s);
 sofree(so);
 }
 
@@ -421,7 +421,7 @@ void icmp_receive(struct socket *so)
 icp = mtod(m, struct icmp *);
 
 id = icp->icmp_id;
-len = qemu_recv(so->s, icp, M_ROOM(m), 0);
+len = slirp_recv(so->s, icp, M_ROOM(m), 0);
 /*
  * The behavior of reading SOCK_DGRAM+IPPROTO_ICMP sockets is inconsistent
  * between host OSes.  On Linux, only the ICMP header and payload is
diff --git a/slirp/misc.c b/slirp/misc.c
index b8a2bf971a..32ec02a525 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -72,14 +72,14 @@ slirp_socketpair_with_oob(int sv[2])
 int ret, s;
 
 sv[1] = -1;
-s = qemu_socket(AF_INET, SOCK_STREAM, 0);
+s = slirp_socket(AF_INET, SOCK_STREAM, 0);
 if (s < 0 || bind(s, (struct sockaddr *), addrlen) < 0 ||
 listen(s, 1) < 0 ||
 getsockname(s, (struct sockaddr *), ) < 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, , sizeof(int));
+slirp_setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, , sizeof(int));
 qemu_set_nonblock(so->s);
 return 1;
 }
diff --git a/slirp/socket.c b/slirp/socket.c
index 5ffbaa064a..5805d30f3d 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -187,7 +187,7 @@ soread(struct socket *so)
 */
sopreprbuf(so, iov, );
 
-   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, ) < 0) {
err = errno;
} else {
-   getsockopt(so->s, SOL_SOCKET, SO_ERROR,
+   slirp_getsockopt(so->s, SOL_SOCKET, 
SO_ERROR,
, );
}
}
@@ -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_b

[Qemu-devel] [PULLv4 16/32] slirp: do not include qemu headers in libslirp.h public API header

2019-02-07 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/libslirp.h | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 679a25422b..02cbec9f8b 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -1,7 +1,17 @@
 #ifndef LIBSLIRP_H
 #define LIBSLIRP_H
 
-#include "qemu-common.h"
+#include 
+#include 
+#include 
+
+#ifdef _WIN32
+#include 
+#include 
+#else
+#include 
+#include 
+#endif
 
 typedef struct Slirp Slirp;
 
-- 
2.20.1




[Qemu-devel] [PULLv4 10/32] slirp: replace QEMU_PACKED with SLIRP_PACKED

2019-02-07 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/ip.h   | 10 +-
 slirp/ip6_icmp.h |  6 +++---
 slirp/slirp.h|  5 +++--
 slirp/util.h | 32 
 4 files changed, 43 insertions(+), 10 deletions(-)
 create mode 100644 slirp/util.h

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




[Qemu-devel] [PULLv4 06/32] net/slirp: free forwarding rules on cleanup

2019-02-07 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 net/slirp.c | 25 ++---
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index b91741b8fc..750105a466 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -75,6 +75,13 @@ struct slirp_config_str {
 char str[1024];
 };
 
+struct GuestFwd {
+CharBackend hd;
+struct in_addr server;
+int port;
+Slirp *slirp;
+};
+
 typedef struct SlirpState {
 NetClientState nc;
 QTAILQ_ENTRY(SlirpState) entry;
@@ -83,6 +90,7 @@ typedef struct SlirpState {
 #ifndef _WIN32
 gchar *smb_dir;
 #endif
+GSList *fwd;
 } SlirpState;
 
 static struct slirp_config_str *slirp_configs;
@@ -122,10 +130,19 @@ static void slirp_smb_exit(Notifier *n, void *data)
 slirp_smb_cleanup(s);
 }
 
+static void slirp_free_fwd(gpointer data)
+{
+struct GuestFwd *fwd = data;
+
+qemu_chr_fe_deinit(>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(>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(>hd, guestfwd_can_read, guestfwd_read,
  NULL, NULL, fwd, NULL, true);
+s->fwd = g_slist_append(s->fwd, fwd);
 }
 return 0;
 
-- 
2.20.1




[Qemu-devel] [PULLv4 31/32] slirp: pass opaque to all callbacks

2019-02-07 Thread Samuel Thibault
From: Marc-André Lureau 

This is friendlier for FFI bindings.

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 net/slirp.c  | 25 -
 slirp/dhcpv6.c   |  2 +-
 slirp/if.c   |  2 +-
 slirp/ip6_icmp.c | 15 +--
 slirp/ip_icmp.c  |  2 +-
 slirp/libslirp.h | 16 
 slirp/misc.c |  2 +-
 slirp/slirp.c| 13 ++---
 slirp/socket.c   |  2 +-
 slirp/tcp_subr.c |  8 
 slirp/udp.c  |  2 +-
 11 files changed, 49 insertions(+), 40 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index a85e42ff43..7a16d8d615 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -161,44 +161,51 @@ static NetClientInfo net_slirp_info = {
 .cleanup = net_slirp_cleanup,
 };
 
-static void net_slirp_guest_error(const char *msg)
+static void net_slirp_guest_error(const char *msg, void *opaque)
 {
 qemu_log_mask(LOG_GUEST_ERROR, "%s", msg);
 }
 
-static int64_t net_slirp_clock_get_ns(void)
+static int64_t net_slirp_clock_get_ns(void *opaque)
 {
 return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 }
 
-static void *net_slirp_timer_new(SlirpTimerCb cb, void *opaque)
+static void *net_slirp_timer_new(SlirpTimerCb cb,
+ void *cb_opaque, void *opaque)
 {
 return timer_new_full(NULL, QEMU_CLOCK_VIRTUAL,
   SCALE_MS, QEMU_TIMER_ATTR_EXTERNAL,
-  cb, opaque);
+  cb, cb_opaque);
 }
 
-static void net_slirp_timer_free(void *timer)
+static void net_slirp_timer_free(void *timer, void *opaque)
 {
 timer_del(timer);
 timer_free(timer);
 }
 
-static void net_slirp_timer_mod(void *timer, int64_t expire_timer)
+static void net_slirp_timer_mod(void *timer, int64_t expire_timer,
+void *opaque)
 {
 timer_mod(timer, expire_timer);
 }
 
-static void net_slirp_register_poll_fd(int fd)
+static void net_slirp_register_poll_fd(int fd, void *opaque)
 {
 qemu_fd_register(fd);
 }
 
-static void net_slirp_unregister_poll_fd(int fd)
+static void net_slirp_unregister_poll_fd(int fd, void *opaque)
 {
 /* no qemu_fd_unregister */
 }
 
+static void net_slirp_notify(void *opaque)
+{
+qemu_notify_event();
+}
+
 static const SlirpCb slirp_cb = {
 .send_packet = net_slirp_send_packet,
 .guest_error = net_slirp_guest_error,
@@ -208,7 +215,7 @@ static const SlirpCb slirp_cb = {
 .timer_mod = net_slirp_timer_mod,
 .register_poll_fd = net_slirp_register_poll_fd,
 .unregister_poll_fd = net_slirp_unregister_poll_fd,
-.notify = qemu_notify_event,
+.notify = net_slirp_notify,
 };
 
 static int slirp_poll_to_gio(int events)
diff --git a/slirp/dhcpv6.c b/slirp/dhcpv6.c
index 9ffba38e8f..e655c7d5b1 100644
--- a/slirp/dhcpv6.c
+++ b/slirp/dhcpv6.c
@@ -59,7 +59,7 @@ static int dhcpv6_parse_info_request(Slirp *slirp, uint8_t 
*odata, int olen,
 int len = odata[2] << 8 | odata[3];
 
 if (len + 4 > olen) {
-slirp->cb->guest_error("Guest sent bad DHCPv6 packet!");
+slirp->cb->guest_error("Guest sent bad DHCPv6 packet!", 
slirp->opaque);
 return -E2BIG;
 }
 
diff --git a/slirp/if.c b/slirp/if.c
index 2ad03b8a79..1830cc396c 100644
--- a/slirp/if.c
+++ b/slirp/if.c
@@ -146,7 +146,7 @@ diddit:
  */
 void if_start(Slirp *slirp)
 {
-uint64_t now = slirp->cb->clock_get_ns();
+uint64_t now = slirp->cb->clock_get_ns(slirp->opaque);
 bool from_batchq = false;
 struct mbuf *ifm, *ifm_next, *ifqt;
 
diff --git a/slirp/ip6_icmp.c b/slirp/ip6_icmp.c
index 2a432ebbd4..c1e3d30470 100644
--- a/slirp/ip6_icmp.c
+++ b/slirp/ip6_icmp.c
@@ -14,7 +14,8 @@ static void ra_timer_handler(void *opaque)
 Slirp *slirp = opaque;
 
 slirp->cb->timer_mod(slirp->ra_timer,
- slirp->cb->clock_get_ns() / SCALE_MS + NDP_Interval);
+slirp->cb->clock_get_ns(slirp->opaque) / SCALE_MS + NDP_Interval,
+slirp->opaque);
 ndp_send_ra(slirp);
 }
 
@@ -24,9 +25,10 @@ void icmp6_init(Slirp *slirp)
 return;
 }
 
-slirp->ra_timer = slirp->cb->timer_new(ra_timer_handler, slirp);
+slirp->ra_timer = slirp->cb->timer_new(ra_timer_handler, slirp, 
slirp->opaque);
 slirp->cb->timer_mod(slirp->ra_timer,
- slirp->cb->clock_get_ns() / SCALE_MS + NDP_Interval);
+slirp->cb->clock_get_ns(slirp->opaque) / SCALE_MS + NDP_Interval,
+slirp->opaque);
 }
 
 void icmp6_cleanup(Slirp *slirp)
@@ -35,7 +37,7 @@ void icmp6_cleanup(Slirp *slirp)
 return;
 }
 
-slirp->cb->timer_free(slirp->ra_timer);
+slirp->cb->timer_free(slirp->ra_timer, slirp->opaque);
 }
 
 static void icmp6_send_echoreply(struct mbuf *m, Slirp *slirp, struct ip6 *ip,
@@ -334,7 +336,8 @@ static void ndp_input(struct mbuf *m, Slir

[Qemu-devel] [PULLv4 07/32] net/slirp: fix leaks on forwarding rule registration error

2019-02-07 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 net/slirp.c | 2 ++
 1 file changed, 2 insertions(+)

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




[Qemu-devel] [PULLv4 24/32] slirp: Move g_spawn_async_with_fds_qemu compatibility to slirp/

2019-02-07 Thread Samuel Thibault
Only slirp actually needs it, and will need it along in libslirp.

Signed-off-by: Samuel Thibault 
Reviewed-by: Marc-André Lureau 
---
 include/glib-compat.h | 57 ---
 slirp/misc.c  | 62 +++
 2 files changed, 62 insertions(+), 57 deletions(-)

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




[Qemu-devel] [PULLv4 20/32] slirp: remove now useless QEMU headers inclusions

2019-02-07 Thread Samuel Thibault
From: Marc-André Lureau 

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

Signed-off-by: Marc-André Lureau 
Signed-off-by: samuel Thibault 
---
 slirp/dhcpv6.c   | 1 -
 slirp/ip6_icmp.c | 2 --
 slirp/misc.c | 2 --
 slirp/sbuf.c | 1 -
 slirp/slirp.c| 4 
 slirp/slirp.h| 1 -
 slirp/tftp.c | 1 -
 slirp/util.h | 2 --
 8 files changed, 14 deletions(-)

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




[Qemu-devel] [PULLv4 01/32] slirp: Avoid unaligned 16bit memory access

2019-02-07 Thread Samuel Thibault
pkt parameter may be unaligned, so we must access it byte-wise.

This fixes sparc64 host SIGBUS during pxe boot.

Signed-off-by: Samuel Thibault 
Reviewed-by: Richard Henderson 
---
 slirp/slirp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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




[Qemu-devel] [PULLv4 21/32] slirp: replace net/eth.h inclusion with own defines

2019-02-07 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/ip6.h   |  1 -
 slirp/slirp.h |  1 -
 slirp/util.h  | 10 ++
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/slirp/ip6.h b/slirp/ip6.h
index 1e3e329ce6..4e7c366505 100644
--- a/slirp/ip6.h
+++ b/slirp/ip6.h
@@ -7,7 +7,6 @@
 #define SLIRP_IP6_H
 
 #include 
-#include "net/eth.h"
 
 #define ALLNODES_MULTICAST  { .s6_addr = \
 { 0xff, 0x02, 0x00, 0x00,\
diff --git a/slirp/slirp.h b/slirp/slirp.h
index 5707805be2..c9f9143801 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -48,7 +48,6 @@ typedef char *caddr_t;
 #include "util.h"
 
 #include "qemu/queue.h"
-#include "net/eth.h"
 
 #include "libslirp.h"
 #include "ip.h"
diff --git a/slirp/util.h b/slirp/util.h
index 4664e8159b..ef75804560 100644
--- a/slirp/util.h
+++ b/slirp/util.h
@@ -50,6 +50,16 @@
 
 #define SCALE_MS 100
 
+#define ETH_ALEN6
+#define ETH_HLEN14
+#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 (0x)
+
 #ifdef _WIN32
 int slirp_closesocket(int fd);
 int slirp_ioctlsocket(int fd, int req, void *val);
-- 
2.20.1




[Qemu-devel] [PULLv4 03/32] slirp: Don't mark struct ipq or struct ipasfrag as packed

2019-02-07 Thread Samuel Thibault
From: Peter Maydell 

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

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

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

Signed-off-by: Peter Maydell 
Reviewed-by: Eric Blake 
Signed-off-by: Samuel Thibault 
---
 slirp/ip.h | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

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




[Qemu-devel] [PULLv4 14/32] slirp: replace qemu_notify_event() with a callback

2019-02-07 Thread Samuel Thibault
From: Marc-André Lureau 

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

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




[Qemu-devel] [PULLv4 13/32] slirp: add unregister_poll_fd() callback

2019-02-07 Thread Samuel Thibault
From: Marc-André Lureau 

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 
Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 net/slirp.c  | 6 ++
 slirp/ip_icmp.c  | 1 +
 slirp/libslirp.h | 2 ++
 slirp/slirp.c| 3 ++-
 slirp/tcp_subr.c | 2 ++
 slirp/udp.c  | 1 +
 6 files changed, 14 insertions(+), 1 deletion(-)

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




[Qemu-devel] [PULLv4 23/32] slirp: replace QEMU_BUILD_BUG_ON with G_STATIC_ASSERT

2019-02-07 Thread Samuel Thibault
to remove another dependency on qemu.

Signed-off-by: Samuel Thibault 
Reviewed-by: Marc-André Lureau 
Reviewed-by: Richard Henderson 
Reviewed-by: Stefano Garzarella 
Reviewed-by: Alex Bennée 
---
 slirp/ip.h   |  4 ++--
 slirp/ip6.h  |  4 ++--
 slirp/ip6_icmp.h | 10 +-
 3 files changed, 9 insertions(+), 9 deletions(-)

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




[Qemu-devel] [PULLv4 09/32] slirp: replace trace functions with DEBUG calls

2019-02-07 Thread Samuel Thibault
From: Marc-André Lureau 

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

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 Makefile.objs  |  1 -
 slirp/debug.h  | 13 ++---
 slirp/slirp.c  |  1 +
 slirp/tftp.c   |  7 ---
 slirp/trace-events |  5 -
 5 files changed, 15 insertions(+), 12 deletions(-)
 delete mode 100644 slirp/trace-events

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




[Qemu-devel] [PULLv4 08/32] slirp: add callbacks for timer

2019-02-07 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 net/slirp.c  | 21 +
 slirp/ip6_icmp.c | 16 +++-
 slirp/libslirp.h | 14 +++---
 slirp/slirp.h|  2 +-
 4 files changed, 40 insertions(+), 13 deletions(-)

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




[Qemu-devel] [PULLv4 02/32] slirp: Avoid marking naturally packed structs as QEMU_PACKED

2019-02-07 Thread Samuel Thibault
From: Peter Maydell 

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

Signed-off-by: Peter Maydell 
Reviewed-by: Eric Blake 
Signed-off-by: Samuel Thibault 
---
 slirp/ip6.h  | 12 ++--
 slirp/ip6_icmp.h | 20 +++-
 2 files changed, 25 insertions(+), 7 deletions(-)

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




[Qemu-devel] [PULLv4 00/32] More work towards libslirp

2019-02-07 Thread Samuel Thibault
The following changes since commit 713acc316ddca119fe168e72846f1d2dd0548430:

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

are available in the Git repository at:

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

for you to fetch changes up to ee261c02332ea856352f250b295a8ecd1eeb748e:

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


More work towards libslirp

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

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

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


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

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

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

 Makefile.objs|   1 -
 include/glib-compat.h|  57 ---
 include/net/net.h|   2 +-
 include/qemu/main-loop.h |  15 +
 net/net.c|   4 +-
 net/slirp.c  | 185 -
 slirp/Makefile.objs  |   4 +-
 slirp/arp_table.c|   3 +-
 slirp/bootp.c|   1 -
 slirp/cksum.c|   1 -
 slirp/debug.h|  13 +-
 slirp/dhcpv6.c   |   4 +-
 slirp/dnssearch.c|   1 -
 slirp/if.c   |   4 +-
 slirp/ip.h   |  17 +-
 slirp/ip6.h  |  14 +-
 slirp/ip6_icmp.c |  27 +-
 slirp/ip6_icmp.h |  26 +-
 slirp/ip6_input.c|   1 -
 slirp/ip6_output.c   |   2 -
 slirp/ip_icmp.c  |  14 +-
 slirp/ip_icmp.h  |  18 +-
 slirp/ip_input.c |   5 +-
 slirp/ip_output.c|   1 -
 slirp/libslirp.h |  71 +++-
 slirp/main.h |   2 +-
 slirp/mbuf.c |   1 -
 slirp/mbuf.h |   2 +

Re: [Qemu-devel] [PULLv3 00/32] More work towards libslirp

2019-02-07 Thread Samuel Thibault
Peter Maydell, le jeu. 07 févr. 2019 11:46:23 +, a ecrit:
> On Tue, 5 Feb 2019 at 18:28, Samuel Thibault
>  wrote:
> >
> > The following changes since commit 01a9a51ffaf4699827ea6425cb2b834a356e159d:
> >
> >   Merge remote-tracking branch 
> > 'remotes/kraxel/tags/ui-20190205-pull-request' into staging (2019-02-05 
> > 14:01:29 +)
> >
> > are available in the Git repository at:
> >
> >   https://people.debian.org/~sthibault/qemu.git tags/samuel-thibault
> >
> > for you to fetch changes up to 1e924479dce65a26a7432bf5920f89c1bf957d74:
> >
> >   slirp: API is extern C (2019-02-05 20:27:27 +0200)
> >
> > 
> > More work towards libslirp
> >
> 
> Format string issues for the Windows build:

Oh, I am not getting these errors with make docker-test-mingw@fedora,
perhaps something would need to be fixed there to test as much as you do?

> All the other builds went OK.

Good :) I'll have a look at these formatting issues.

Samuel



[Qemu-devel] [PULLv3 28/32] slirp: replace global polling with per-instance & notifier

2019-02-05 Thread Samuel Thibault
From: Marc-André Lureau 

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 
Signed-off-by: Samuel Thibault 
---
 include/qemu/main-loop.h |  15 ++
 net/slirp.c  |  24 ++
 slirp/libslirp.h |   4 +-
 slirp/slirp.c| 555 +++
 stubs/Makefile.objs  |   1 -
 stubs/slirp.c|  13 -
 util/main-loop.c |  30 ++-
 7 files changed, 333 insertions(+), 309 deletions(-)
 delete mode 100644 stubs/slirp.c

diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h
index e59f9ae1e9..f6ba78ea73 100644
--- a/include/qemu/main-loop.h
+++ b/include/qemu/main-loop.h
@@ -302,4 +302,19 @@ void qemu_fd_register(int fd);
 QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque);
 void qemu_bh_schedule_idle(QEMUBH *bh);
 
+enum {
+MAIN_LOOP_POLL_FILL,
+MAIN_LOOP_POLL_ERR,
+MAIN_LOOP_POLL_OK,
+};
+
+typedef struct MainLoopPoll {
+int state;
+uint32_t timeout;
+GArray *pollfds;
+} MainLoopPoll;
+
+void main_loop_poll_add_notifier(Notifier *notify);
+void main_loop_poll_remove_notifier(Notifier *notify);
+
 #endif
diff --git a/net/slirp.c b/net/slirp.c
index 664ff1c002..4d55f64168 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -86,6 +86,7 @@ typedef struct SlirpState {
 NetClientState nc;
 QTAILQ_ENTRY(SlirpState) entry;
 Slirp *slirp;
+Notifier poll_notifier;
 Notifier exit_notifier;
 #ifndef _WIN32
 gchar *smb_dir;
@@ -144,6 +145,7 @@ static void net_slirp_cleanup(NetClientState *nc)
 SlirpState *s = DO_UPCAST(SlirpState, nc, nc);
 
 g_slist_free_full(s->fwd, slirp_free_fwd);
+main_loop_poll_remove_notifier(>poll_notifier);
 slirp_cleanup(s->slirp);
 if (s->exit_notifier.notify) {
 qemu_remove_exit_notifier(>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, >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,
   _cb, s);
 QTAILQ_INSERT_TAIL(_stacks, s, entry);
 
+s->poll_notifier.notify = net_slirp_poll_notify;
+main_loop_poll_add_notifier(>poll_notifier);
+
 for (config = slirp_configs; config; config = config->next) {
 if (config->flags & SLIRP_CFG_HOSTFWD) {
 if (slirp_hostfwd(s, config->str, errp) < 0) {
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 8e5d4ed11b..18d5fb0133 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -63,9 +63,9 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct 
in_addr vnetwork,
   void *opaque);
 void slirp_cleanup(Slirp *slirp);
 
-void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout);
+void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout);
 
-void slirp_pollfds_poll(GArray *pollfds, int select_error);
+void slirp_pollfds_poll(Slirp *slirp, GArray *pollfds, int select_error);
 
 void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len);
 
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 60cd8249bf..a0de8b711c 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, _instances, entry) {
-if (slirp->time_fasttimo) {
-*timeout = TIMEOUT_FAST;
-return;
-}
-if (slirp->do_slowtimo) {
-t = MIN(TIMEOUT_SLOW, t);
-}
+if (slirp->time_fas

[Qemu-devel] [PULLv3 19/32] slirp: remove qemu timer.h dependency

2019-02-05 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/if.c   | 1 -
 slirp/ip6_icmp.c | 1 -
 slirp/slirp.c| 1 -
 slirp/util.h | 2 ++
 4 files changed, 2 insertions(+), 3 deletions(-)

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




Re: [Qemu-devel] [PULLv2 00/32] More work towards libslirp

2019-02-05 Thread Samuel Thibault
Peter Maydell, le mar. 05 févr. 2019 18:24:45 +, a ecrit:
> /home/pm215/qemu/slirp/misc.c:166:5: error: unknown type name ‘QemuGSpawnFds’

D'oh...

Fixed in v3.

Samuel



[Qemu-devel] [PULLv3 25/32] slirp: replace remaining qemu headers dependency

2019-02-05 Thread Samuel Thibault
From: Marc-André Lureau 

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 
Signed-off-by: Samuel Thibault 
---
 slirp/arp_table.c  |  3 ++-
 slirp/bootp.c  |  1 -
 slirp/cksum.c  |  1 -
 slirp/dhcpv6.c |  1 -
 slirp/dnssearch.c  |  1 -
 slirp/if.c |  1 -
 slirp/ip6.h|  1 +
 slirp/ip6_icmp.c   |  1 -
 slirp/ip6_input.c  |  1 -
 slirp/ip6_output.c |  2 --
 slirp/ip_icmp.c|  1 -
 slirp/ip_input.c   |  1 -
 slirp/ip_output.c  |  1 -
 slirp/mbuf.c   |  1 -
 slirp/misc.c   |  2 --
 slirp/ncsi.c   |  1 -
 slirp/ndp_table.c  |  2 --
 slirp/sbuf.c   |  1 -
 slirp/slirp.c  |  2 --
 slirp/socket.c |  2 --
 slirp/tcp_input.c  |  1 -
 slirp/tcp_output.c |  1 -
 slirp/tcp_subr.c   |  1 -
 slirp/tcp_timer.c  |  1 -
 slirp/tftp.c   |  6 --
 slirp/udp.c|  1 -
 slirp/udp6.c   |  2 --
 slirp/util.h   | 21 +
 28 files changed, 28 insertions(+), 33 deletions(-)

diff --git a/slirp/arp_table.c b/slirp/arp_table.c
index bf71b984ad..58eafdcfd8 100644
--- a/slirp/arp_table.c
+++ b/slirp/arp_table.c
@@ -22,9 +22,10 @@
  * THE SOFTWARE.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 
+#include 
+
 void arp_table_add(Slirp *slirp, uint32_t ip_addr, uint8_t ethaddr[ETH_ALEN])
 {
 const uint32_t broadcast_addr =
diff --git a/slirp/bootp.c b/slirp/bootp.c
index 4c9a77eb98..d396849a05 100644
--- a/slirp/bootp.c
+++ b/slirp/bootp.c
@@ -21,7 +21,6 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-#include "qemu/osdep.h"
 #include "slirp.h"
 
 #if defined(_WIN32)
diff --git a/slirp/cksum.c b/slirp/cksum.c
index 84c858fafb..25bfa67348 100644
--- a/slirp/cksum.c
+++ b/slirp/cksum.c
@@ -30,7 +30,6 @@
  * in_cksum.c,v 1.2 1994/08/02 07:48:16 davidg Exp
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 
 /*
diff --git a/slirp/dhcpv6.c b/slirp/dhcpv6.c
index e27d9a46f8..9ffba38e8f 100644
--- a/slirp/dhcpv6.c
+++ b/slirp/dhcpv6.c
@@ -20,7 +20,6 @@
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 #include "dhcpv6.h"
 
diff --git a/slirp/dnssearch.c b/slirp/dnssearch.c
index 8fb563321b..c459cece8d 100644
--- a/slirp/dnssearch.c
+++ b/slirp/dnssearch.c
@@ -22,7 +22,6 @@
  * THE SOFTWARE.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 
 static const uint8_t RFC3397_OPT_DOMAIN_SEARCH = 119;
diff --git a/slirp/if.c b/slirp/if.c
index 90b9078687..2ad03b8a79 100644
--- a/slirp/if.c
+++ b/slirp/if.c
@@ -5,7 +5,6 @@
  * terms and conditions of the copyright.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 
 static void
diff --git a/slirp/ip6.h b/slirp/ip6.h
index 5361bd7449..1b3364f960 100644
--- a/slirp/ip6.h
+++ b/slirp/ip6.h
@@ -7,6 +7,7 @@
 #define SLIRP_IP6_H
 
 #include 
+#include 
 
 #define ALLNODES_MULTICAST  { .s6_addr = \
 { 0xff, 0x02, 0x00, 0x00,\
diff --git a/slirp/ip6_icmp.c b/slirp/ip6_icmp.c
index b3b7e50a31..2a432ebbd4 100644
--- a/slirp/ip6_icmp.c
+++ b/slirp/ip6_icmp.c
@@ -3,7 +3,6 @@
  * Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 #include "ip6_icmp.h"
 
diff --git a/slirp/ip6_input.c b/slirp/ip6_input.c
index ab656a0a9d..1b8c003c66 100644
--- a/slirp/ip6_input.c
+++ b/slirp/ip6_input.c
@@ -3,7 +3,6 @@
  * Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 #include "ip6_icmp.h"
 
diff --git a/slirp/ip6_output.c b/slirp/ip6_output.c
index 52c88ad691..19d1ae7748 100644
--- a/slirp/ip6_output.c
+++ b/slirp/ip6_output.c
@@ -3,8 +3,6 @@
  * Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne.
  */
 
-#include "qemu/osdep.h"
-#include "qemu-common.h"
 #include "slirp.h"
 
 /* Number of packets queued before we start sending
diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
index 19e247f773..6b6344b776 100644
--- a/slirp/ip_icmp.c
+++ b/slirp/ip_icmp.c
@@ -30,7 +30,6 @@
  * ip_icmp.c,v 1.7 1995/05/30 08:09:42 rgrimes Exp
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 #include "ip_icmp.h"
 
diff --git a/slirp/ip_input.c b/slirp/ip_input.c
index d360620838..774ce662e6 100644
--- a/slirp/ip_input.c
+++ b/slirp/ip_input.c
@@ -38,7 +38,6 @@
  * terms and conditions of the copyright.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 #include "ip_icmp.h"
 
diff --git a/slirp/ip_output.c b/slirp/ip_output.c
index db403f04c1..f6ec141df5 100644
--- a/slirp/ip_output.c
+++ b/slirp/ip_output.c
@@ -38,7 +38,6 @@
  * terms and conditions of the copyright

[Qemu-devel] [PULLv3 26/32] slirp: prefer c99 types over BSD kind

2019-02-05 Thread Samuel Thibault
From: Marc-André Lureau 

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 
Signed-off-by: Samuel Thibault 
---
 slirp/ip_icmp.c|  6 +++---
 slirp/ip_icmp.h| 18 +-
 slirp/ip_input.c   |  4 ++--
 slirp/main.h   |  2 +-
 slirp/mbuf.h   |  2 +-
 slirp/slirp.c  | 12 ++--
 slirp/slirp.h  |  8 +++-
 slirp/socket.c |  6 +++---
 slirp/socket.h |  4 ++--
 slirp/tcp_input.c  | 22 +++---
 slirp/tcp_output.c | 12 ++--
 slirp/tcp_subr.c   | 18 +-
 slirp/tcp_timer.c  |  2 +-
 slirp/tcp_var.h| 14 +++---
 slirp/udp.c|  6 +++---
 slirp/udp.h|  2 +-
 util/osdep.c   |  2 +-
 17 files changed, 69 insertions(+), 71 deletions(-)

diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
index 6b6344b776..7c5cb75ae5 100644
--- a/slirp/ip_icmp.c
+++ b/slirp/ip_icmp.c
@@ -240,7 +240,7 @@ end_error:
 
 #define ICMP_MAXDATALEN (IP_MSS-28)
 void
-icmp_send_error(struct mbuf *msrc, u_char type, u_char code, int minsize,
+icmp_send_error(struct mbuf *msrc, uint8_t type, uint8_t code, int minsize,
const char *message)
 {
   unsigned hlen, shlen, s_ip_len;
@@ -388,7 +388,7 @@ icmp_reflect(struct mbuf *m)
  * Strip out original options by copying rest of first
  * mbuf's data back, and adjust the IP length.
  */
-memmove((caddr_t)(ip + 1), (caddr_t)ip + hlen,
+memmove((char *)(ip + 1), (char *)ip + hlen,
(unsigned )(m->m_len - hlen));
 hlen -= optlen;
 ip->ip_hl = hlen >> 2;
@@ -412,7 +412,7 @@ void icmp_receive(struct socket *so)
 struct mbuf *m = so->so_m;
 struct ip *ip = mtod(m, struct ip *);
 int hlen = ip->ip_hl << 2;
-u_char error_code;
+uint8_t error_code;
 struct icmp *icp;
 int id, len;
 
diff --git a/slirp/ip_icmp.h b/slirp/ip_icmp.h
index d88ab34c1b..a4e5b8b265 100644
--- a/slirp/ip_icmp.h
+++ b/slirp/ip_icmp.h
@@ -44,22 +44,22 @@ typedef uint32_t n_time;
  * Structure of an icmp header.
  */
 struct icmp {
-   u_char  icmp_type;  /* type of message, see below */
-   u_char  icmp_code;  /* type sub code */
-   u_short icmp_cksum; /* ones complement cksum of struct */
+   uint8_t icmp_type;  /* type of message, see below */
+   uint8_t icmp_code;  /* type sub code */
+   uint16_ticmp_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_ticd_id;
+   uint16_ticd_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;
 #defineicmp_pptr   icmp_hun.ih_pptr
@@ -156,7 +156,7 @@ struct icmp {
 void icmp_init(Slirp *slirp);
 void icmp_cleanup(Slirp *slirp);
 void icmp_input(struct mbuf *, int);
-void icmp_send_error(struct mbuf *msrc, u_char type, u_char code, int minsize,
+void icmp_send_error(struct mbuf *msrc, uint8_t type, uint8_t code, int 
minsize,
  const char *message);
 void icmp_reflect(struct mbuf *);
 void icmp_receive(struct socket *so);
diff --git a/slirp/ip_input.c b/slirp/ip_input.c
index 774ce662e6..e0b94b0e42 100644
--- a/slirp/ip_input.c
+++ b/slirp/ip_input.c
@@ -458,11 +458,11 @@ ip_stripoptions(register struct mbuf *m, struct mbuf 
*mopt)
 {
register int i;
struct ip *ip = mtod(m, struct ip *);
-   register caddr_t opts;
+   register char *opts;
int olen;
 
olen = (ip->ip_hl<<2) - sizeof (struct ip);
-   opts = (caddr_t)(ip + 1);
+   opts = (char *)(ip + 1);
i = m->m_len - (sizeof (struct ip) + olen);
memcpy(opts, opts  + olen, (unsigned)i);
m->m_len -= olen;
diff --git a/slirp/main.h b/slirp/main.h
index 4bc05fb904..f11d4572b7 100644
--- a/slirp/main.h
+++ b/slirp/main.h
@@ -8,7 +8,7 @@
 #ifndef SLIRP_MAIN_H
 #define SLIRP_MAIN_H
 
-extern u_int curtime;
+extern unsigned curtime;
 extern struct in_addr loopback_addr;
 extern unsigned long loopback_mask;
 
diff --git a/slirp/mbuf.h b/slirp/mbuf.h
index cbf17e136b..e2d443418a 100644
--- a/slirp/mbuf.h
+++ b/slirp/mbuf.h
@@ -85,7 +85,7 @@ struct mbuf {
int m_size

[Qemu-devel] [PULLv3 14/32] slirp: replace qemu_notify_event() with a callback

2019-02-05 Thread Samuel Thibault
From: Marc-André Lureau 

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

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




[Qemu-devel] [PULLv3 20/32] slirp: remove now useless QEMU headers inclusions

2019-02-05 Thread Samuel Thibault
From: Marc-André Lureau 

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

Signed-off-by: Marc-André Lureau 
Signed-off-by: samuel Thibault 
---
 slirp/dhcpv6.c   | 1 -
 slirp/ip6_icmp.c | 2 --
 slirp/misc.c | 2 --
 slirp/sbuf.c | 1 -
 slirp/slirp.c| 4 
 slirp/slirp.h| 1 -
 slirp/tftp.c | 1 -
 slirp/util.h | 2 --
 8 files changed, 14 deletions(-)

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




[Qemu-devel] [PULLv3 10/32] slirp: replace QEMU_PACKED with SLIRP_PACKED

2019-02-05 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/ip.h   | 10 +-
 slirp/ip6_icmp.h |  6 +++---
 slirp/slirp.h|  5 +++--
 slirp/util.h | 32 
 4 files changed, 43 insertions(+), 10 deletions(-)
 create mode 100644 slirp/util.h

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




[Qemu-devel] [PULLv3 18/32] slirp: add slirp own version of pstrcpy

2019-02-05 Thread Samuel Thibault
From: Marc-André Lureau 

Remove a dependency on qemu util.

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/slirp.c |  4 ++--
 slirp/tftp.c  |  2 +-
 slirp/util.c  | 17 +
 slirp/util.h  |  2 ++
 4 files changed, 22 insertions(+), 3 deletions(-)

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




[Qemu-devel] [PULLv3 04/32] slirp: generalize guestfwd with a callback based approach

2019-02-05 Thread Samuel Thibault
From: Marc-André Lureau 

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

diff --git a/net/slirp.c b/net/slirp.c
index f98425ee9f..ec07f662c0 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -704,8 +704,8 @@ static int slirp_smb(SlirpState* s, const char 
*exported_dir,
  CONFIG_SMBD_COMMAND, s->smb_dir, smb_conf);
 g_free(smb_conf);
 
-if (slirp_add_exec(s->slirp, NULL, smb_cmdline, _addr, 139) < 0 ||
-slirp_add_exec(s->slirp, NULL, smb_cmdline, _addr, 445) < 0) {
+if (slirp_add_exec(s->slirp, smb_cmdline, _addr, 139) < 0 ||
+slirp_add_exec(s->slirp, smb_cmdline, _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, [4], , port) < 0) {
+if (slirp_add_exec(s->slirp, [4], , 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, >hd, NULL, , port) < 0) {
+if (slirp_add_guestfwd(s->slirp, guestfwd_write, >hd,
+   , port) < 0) {
 error_setg(errp, "Conflicting/invalid host:port in guest "
"forwarding rule '%s'", config_str);
 g_free(fwd);
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 4611a7447b..ea019828e8 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -5,6 +5,8 @@
 
 typedef struct Slirp Slirp;
 
+typedef int (*SlirpWriteCb)(const void *buf, size_t len, void *opaque);
+
 /*
  * Callbacks from slirp
  *
@@ -45,7 +47,9 @@ int slirp_add_hostfwd(Slirp *slirp, int is_udp,
   struct in_addr guest_addr, int guest_port);
 int slirp_remove_hostfwd(Slirp *slirp, int is_udp,
  struct in_addr host_addr, int host_port);
-int slirp_add_exec(Slirp *slirp, void *chardev, const char *cmdline,
+int slirp_add_exec(Slirp *slirp, const char *cmdline,
+   struct in_addr *guest_addr, int guest_port);
+int slirp_add_guestfwd(Slirp *slirp, SlirpWriteCb write_cb, void *opaque,
struct in_addr *guest_addr, int guest_port);
 
 char *slirp_connection_info(Slirp *slirp);
diff --git a/slirp/misc.c b/slirp/misc.c
index eae9596a55..b8a2bf971a 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -32,24 +32,33 @@ remque(void *a)
   element->qh_rlink = NULL;
 }
 
-int add_exec(struct gfwd_list **ex_ptr, void *chardev, const char *cmdline,
+struct gfwd_list *
+add_guestfwd(struct gfwd_list **ex_ptr,
+ SlirpWriteCb write_cb, void *opaque,
  struct in_addr addr, int port)
 {
-   struct gfwd_list *tmp_ptr;
-
-   tmp_ptr = *ex_ptr;
-   *ex_ptr = g_new0(struct gfwd_list, 1);
-   (*ex_ptr)->ex_fport = port;
-   (*ex_ptr)->ex_addr = addr;
-   if (chardev) {
-   (*ex_ptr)->ex_chardev = chardev;
-   } else {
-   (*ex_ptr)->ex_exec = g_strdup(cmdline);
-   }
-   (*ex_ptr)->ex_next = tmp_ptr;
-   return 0;
+struct gfwd_list *f = g_new0(struct gfwd_list, 1);
+
+f->write_cb = write_cb;
+f->opaque = opaque;
+f->ex_fport = port;
+f->ex_addr = addr;
+f->ex_next = *ex_ptr;
+*ex_ptr = f;
+
+return f;
 }
 
+struct gfwd_list *
+add_exec(struct gfwd_list **ex_ptr, const char *cmdline,
+ struct in_addr addr, int port)
+{
+struct gfwd_list *f = add_guestfwd(ex_ptr, NULL, NULL, addr, port);
+
+

[Qemu-devel] [PULLv3 32/32] slirp: API is extern C

2019-02-05 Thread Samuel Thibault
From: Marc-André Lureau 

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

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/libslirp.h | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 9b13d8250c..fccab42518 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -12,6 +12,10 @@
 #include 
 #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




[Qemu-devel] [PULLv3 08/32] slirp: add callbacks for timer

2019-02-05 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 net/slirp.c  | 21 +
 slirp/ip6_icmp.c | 16 +++-
 slirp/libslirp.h | 14 +++---
 slirp/slirp.h|  2 +-
 4 files changed, 40 insertions(+), 13 deletions(-)

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




[Qemu-devel] [PULLv3 17/32] slirp: improve windows headers inclusion

2019-02-05 Thread Samuel Thibault
From: Marc-André Lureau 

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 
Signed-off-by: Samuel Thibault 
---
 slirp/slirp.h | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/slirp/slirp.h b/slirp/slirp.h
index 8d9d72ca9d..5a830ddcb8 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -3,10 +3,19 @@
 
 #ifdef _WIN32
 
+/* as defined in sdkddkver.h */
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0600 /* Vista */
+#endif
+/* reduces the number of implicitly included headers */
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+
 typedef char *caddr_t;
 
-# include 
 # include 
+# include 
 # include 
 # include 
 # include 
@@ -19,19 +28,10 @@ typedef char *caddr_t;
 
 #ifndef _WIN32
 #include 
-#endif
-
-#ifndef _WIN32
 #include 
 #include 
-#endif
-
-#ifndef _WIN32
 #include 
-#endif
-
-#ifndef _WIN32
-# include 
+#include 
 #endif
 
 #ifdef __APPLE__
-- 
2.20.1




[Qemu-devel] [PULLv3 01/32] slirp: Avoid unaligned 16bit memory access

2019-02-05 Thread Samuel Thibault
pkt parameter may be unaligned, so we must access it byte-wise.

This fixes sparc64 host SIGBUS during pxe boot.

Signed-off-by: Samuel Thibault 
Reviewed-by: Richard Henderson 
---
 slirp/slirp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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




[Qemu-devel] [PULLv3 27/32] slirp: improve send_packet() callback

2019-02-05 Thread Samuel Thibault
From: Marc-André Lureau 

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

diff --git a/include/net/net.h b/include/net/net.h
index 643295d163..075cc01267 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -146,7 +146,7 @@ ssize_t qemu_sendv_packet(NetClientState *nc, const struct 
iovec *iov,
   int iovcnt);
 ssize_t qemu_sendv_packet_async(NetClientState *nc, const struct iovec *iov,
 int iovcnt, NetPacketSent *sent_cb);
-void qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size);
+ssize_t qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size);
 ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int size);
 ssize_t qemu_send_packet_async(NetClientState *nc, const uint8_t *buf,
int size, NetPacketSent *sent_cb);
diff --git a/net/net.c b/net/net.c
index 3acbdccd61..5dcff7fe2a 100644
--- a/net/net.c
+++ b/net/net.c
@@ -668,9 +668,9 @@ ssize_t qemu_send_packet_async(NetClientState *sender,
  buf, size, sent_cb);
 }
 
-void qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size)
+ssize_t qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size)
 {
-qemu_send_packet_async(nc, buf, size, NULL);
+return qemu_send_packet_async(nc, buf, size, NULL);
 }
 
 ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int size)
diff --git a/net/slirp.c b/net/slirp.c
index 7b4f9f5c5e..664ff1c002 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -108,11 +108,12 @@ static void slirp_smb_cleanup(SlirpState *s);
 static inline void slirp_smb_cleanup(SlirpState *s) { }
 #endif
 
-static void net_slirp_output(void *opaque, const uint8_t *pkt, int pkt_len)
+static ssize_t net_slirp_send_packet(const void *pkt, size_t pkt_len,
+ void *opaque)
 {
 SlirpState *s = opaque;
 
-qemu_send_packet(>nc, pkt, pkt_len);
+return qemu_send_packet(>nc, pkt, pkt_len);
 }
 
 static ssize_t net_slirp_receive(NetClientState *nc, const uint8_t *buf, 
size_t size)
@@ -197,7 +198,7 @@ static void net_slirp_unregister_poll_fd(int fd)
 }
 
 static const SlirpCb slirp_cb = {
-.output = net_slirp_output,
+.send_packet = net_slirp_send_packet,
 .guest_error = net_slirp_guest_error,
 .clock_get_ns = net_slirp_clock_get_ns,
 .timer_new = net_slirp_timer_new,
@@ -780,7 +781,7 @@ static void guestfwd_read(void *opaque, const uint8_t *buf, 
int size)
 slirp_socket_recv(fwd->slirp, fwd->server, fwd->port, buf, size);
 }
 
-static int guestfwd_write(const void *buf, size_t len, void *chr)
+static ssize_t guestfwd_write(const void *buf, size_t len, void *chr)
 {
 return qemu_chr_fe_write_all(chr, buf, len);
 }
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 02cbec9f8b..8e5d4ed11b 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -15,7 +15,7 @@
 
 typedef struct Slirp Slirp;
 
-typedef int (*SlirpWriteCb)(const void *buf, size_t len, void *opaque);
+typedef ssize_t (*SlirpWriteCb)(const void *buf, size_t len, void *opaque);
 typedef void (*SlirpTimerCb)(void *opaque);
 
 /*
@@ -23,10 +23,13 @@ typedef void (*SlirpTimerCb)(void *opaque);
  */
 typedef struct SlirpCb {
 /*
- * Send an ethernet frame to the guest network. The opaque parameter
- * is the one given to slirp_init().
+ * Send an ethernet frame to the guest network. The opaque
+ * parameter is the one given to slirp_init(). The function
+ * doesn't need to send all the data and may return cb->output(slirp->opaque, ncsi_reply, ETH_HLEN + ncsi_rsp_len);
+slirp_send_packet_all(slirp, ncsi_reply, ETH_HLEN + ncsi_rsp_len);
 }
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 3304c83001..60cd8249bf 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;
 slir

[Qemu-devel] [PULLv3 30/32] slirp: use polling callbacks, drop glib requirement

2019-02-05 Thread Samuel Thibault
From: Marc-André Lureau 

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

diff --git a/net/slirp.c b/net/slirp.c
index 4d55f64168..a85e42ff43 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -211,6 +211,71 @@ static const SlirpCb slirp_cb = {
 .notify = qemu_notify_event,
 };
 
+static int slirp_poll_to_gio(int events)
+{
+int ret = 0;
+
+if (events & SLIRP_POLL_IN) {
+ret |= G_IO_IN;
+}
+if (events & SLIRP_POLL_OUT) {
+ret |= G_IO_OUT;
+}
+if (events & SLIRP_POLL_PRI) {
+ret |= G_IO_PRI;
+}
+if (events & SLIRP_POLL_ERR) {
+ret |= G_IO_ERR;
+}
+if (events & SLIRP_POLL_HUP) {
+ret |= G_IO_HUP;
+}
+
+return ret;
+}
+
+static int net_slirp_add_poll(int fd, int events, void *opaque)
+{
+GArray *pollfds = opaque;
+GPollFD pfd = {
+.fd = fd,
+.events = slirp_poll_to_gio(events),
+};
+int idx = pollfds->len;
+g_array_append_val(pollfds, pfd);
+return idx;
+}
+
+static int slirp_gio_to_poll(int events)
+{
+int ret = 0;
+
+if (events & G_IO_IN) {
+ret |= SLIRP_POLL_IN;
+}
+if (events & G_IO_OUT) {
+ret |= SLIRP_POLL_OUT;
+}
+if (events & G_IO_PRI) {
+ret |= SLIRP_POLL_PRI;
+}
+if (events & G_IO_ERR) {
+ret |= SLIRP_POLL_ERR;
+}
+if (events & G_IO_HUP) {
+ret |= SLIRP_POLL_HUP;
+}
+
+return ret;
+}
+
+static int net_slirp_get_revents(int idx, void *opaque)
+{
+GArray *pollfds = opaque;
+
+return slirp_gio_to_poll(g_array_index(pollfds, GPollFD, idx).revents);
+}
+
 static void net_slirp_poll_notify(Notifier *notifier, void *data)
 {
 MainLoopPoll *poll = data;
@@ -218,12 +283,13 @@ static void net_slirp_poll_notify(Notifier *notifier, 
void *data)
 
 switch (poll->state) {
 case MAIN_LOOP_POLL_FILL:
-slirp_pollfds_fill(s->slirp, poll->pollfds, >timeout);
+slirp_pollfds_fill(s->slirp, >timeout,
+   net_slirp_add_poll, poll->pollfds);
 break;
 case MAIN_LOOP_POLL_OK:
 case MAIN_LOOP_POLL_ERR:
-slirp_pollfds_poll(s->slirp, poll->pollfds,
-   poll->state == MAIN_LOOP_POLL_ERR);
+slirp_pollfds_poll(s->slirp, poll->state == MAIN_LOOP_POLL_ERR,
+   net_slirp_get_revents, poll->pollfds);
 break;
 default:
 g_assert_not_reached();
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 18d5fb0133..b5c1b2122b 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -1,7 +1,6 @@
 #ifndef LIBSLIRP_H
 #define LIBSLIRP_H
 
-#include 
 #include 
 #include 
 
@@ -15,8 +14,18 @@
 
 typedef struct Slirp Slirp;
 
+enum {
+SLIRP_POLL_IN  = 1 << 0,
+SLIRP_POLL_OUT = 1 << 1,
+SLIRP_POLL_PRI = 1 << 2,
+SLIRP_POLL_ERR = 1 << 3,
+SLIRP_POLL_HUP = 1 << 4,
+};
+
 typedef ssize_t (*SlirpWriteCb)(const void *buf, size_t len, void *opaque);
 typedef void (*SlirpTimerCb)(void *opaque);
+typedef int (*SlirpAddPollCb)(int fd, int events, void *opaque);
+typedef int (*SlirpGetREventsCb)(int idx, void *opaque);
 
 /*
  * Callbacks from slirp
@@ -63,9 +72,11 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct 
in_addr vnetwork,
   void *opaque);
 void slirp_cleanup(Slirp *slirp);
 
-void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout);
+void slirp_pollfds_fill(Slirp *slirp, uint32_t *timeout,
+SlirpAddPollCb add_poll, void *opaque);
 
-void slirp_pollfds_poll(Slirp *slirp, GArray *pollfds, int select_error);
+void slirp_pollfds_poll(Slirp *slirp, int select_error,
+SlirpGetREventsCb get_revents, void *opaque);
 
 void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len);
 
diff --git a/slirp/slirp.c b/slirp/slirp.c
index ecbb5c5b6c..04886d05fd 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 = {

[Qemu-devel] [PULLv3 02/32] slirp: Avoid marking naturally packed structs as QEMU_PACKED

2019-02-05 Thread Samuel Thibault
From: Peter Maydell 

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

Signed-off-by: Peter Maydell 
Reviewed-by: Eric Blake 
Signed-off-by: Samuel Thibault 
---
 slirp/ip6.h  | 12 ++--
 slirp/ip6_icmp.h | 20 +++-
 2 files changed, 25 insertions(+), 7 deletions(-)

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




[Qemu-devel] [PULLv3 21/32] slirp: replace net/eth.h inclusion with own defines

2019-02-05 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/ip6.h   |  1 -
 slirp/slirp.h |  1 -
 slirp/util.h  | 10 ++
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/slirp/ip6.h b/slirp/ip6.h
index 1e3e329ce6..4e7c366505 100644
--- a/slirp/ip6.h
+++ b/slirp/ip6.h
@@ -7,7 +7,6 @@
 #define SLIRP_IP6_H
 
 #include 
-#include "net/eth.h"
 
 #define ALLNODES_MULTICAST  { .s6_addr = \
 { 0xff, 0x02, 0x00, 0x00,\
diff --git a/slirp/slirp.h b/slirp/slirp.h
index 5707805be2..c9f9143801 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -48,7 +48,6 @@ typedef char *caddr_t;
 #include "util.h"
 
 #include "qemu/queue.h"
-#include "net/eth.h"
 
 #include "libslirp.h"
 #include "ip.h"
diff --git a/slirp/util.h b/slirp/util.h
index 4664e8159b..ef75804560 100644
--- a/slirp/util.h
+++ b/slirp/util.h
@@ -50,6 +50,16 @@
 
 #define SCALE_MS 100
 
+#define ETH_ALEN6
+#define ETH_HLEN14
+#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 (0x)
+
 #ifdef _WIN32
 int slirp_closesocket(int fd);
 int slirp_ioctlsocket(int fd, int req, void *val);
-- 
2.20.1




[Qemu-devel] [PULLv3 23/32] slirp: replace QEMU_BUILD_BUG_ON with G_STATIC_ASSERT

2019-02-05 Thread Samuel Thibault
to remove another dependency on qemu.

Signed-off-by: Samuel Thibault 
Reviewed-by: Marc-André Lureau 
Reviewed-by: Richard Henderson 
Reviewed-by: Stefano Garzarella 
Reviewed-by: Alex Bennée 
---
 slirp/ip.h   |  4 ++--
 slirp/ip6.h  |  4 ++--
 slirp/ip6_icmp.h | 10 +-
 3 files changed, 9 insertions(+), 9 deletions(-)

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




[Qemu-devel] [PULLv3 13/32] slirp: add unregister_poll_fd() callback

2019-02-05 Thread Samuel Thibault
From: Marc-André Lureau 

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 
Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 net/slirp.c  | 6 ++
 slirp/ip_icmp.c  | 1 +
 slirp/libslirp.h | 2 ++
 slirp/slirp.c| 3 ++-
 slirp/tcp_subr.c | 2 ++
 slirp/udp.c  | 1 +
 6 files changed, 14 insertions(+), 1 deletion(-)

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




[Qemu-devel] [PULLv3 29/32] slirp: remove slirp_instances list

2019-02-05 Thread Samuel Thibault
From: Marc-André Lureau 

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

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/slirp.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/slirp/slirp.c b/slirp/slirp.c
index a0de8b711c..ecbb5c5b6c 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(_instances, slirp, entry);
 
 return slirp;
 }
@@ -348,7 +344,6 @@ void slirp_cleanup(Slirp *slirp)
 g_free(e);
 }
 
-QTAILQ_REMOVE(_instances, slirp, entry);
 #ifdef WITH_QEMU
 slirp_state_unregister(slirp);
 #endif
-- 
2.20.1




[Qemu-devel] [PULLv3 00/32] More work towards libslirp

2019-02-05 Thread Samuel Thibault
The following changes since commit 01a9a51ffaf4699827ea6425cb2b834a356e159d:

  Merge remote-tracking branch 'remotes/kraxel/tags/ui-20190205-pull-request' 
into staging (2019-02-05 14:01:29 +)

are available in the Git repository at:

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

for you to fetch changes up to 1e924479dce65a26a7432bf5920f89c1bf957d74:

  slirp: API is extern C (2019-02-05 20:27:27 +0200)


More work towards libslirp

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

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

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


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

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

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

 Makefile.objs|   1 -
 include/glib-compat.h|  57 ---
 include/net/net.h|   2 +-
 include/qemu/main-loop.h |  15 +
 net/net.c|   4 +-
 net/slirp.c  | 185 -
 slirp/Makefile.objs  |   4 +-
 slirp/arp_table.c|   3 +-
 slirp/bootp.c|   1 -
 slirp/cksum.c|   1 -
 slirp/debug.h|  13 +-
 slirp/dhcpv6.c   |   4 +-
 slirp/dnssearch.c|   1 -
 slirp/if.c   |   4 +-
 slirp/ip.h   |  17 +-
 slirp/ip6.h  |  14 +-
 slirp/ip6_icmp.c |  27 +-
 slirp/ip6_icmp.h |  26 +-
 slirp/ip6_input.c|   1 -
 slirp/ip6_output.c   |   2 -
 slirp/ip_icmp.c  |  14 +-
 slirp/ip_icmp.h  |  18 +-
 slirp/ip_input.c |   5 +-
 slirp/ip_output.c|   1 -
 slirp/libslirp.h |  71 +++-
 slirp/main.h |   2 +-
 slirp/mbuf.c |   1 -
 slirp/mbuf.h  

[Qemu-devel] [PULLv3 22/32] slirp: replace qemu qtailq with slirp own copy

2019-02-05 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 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 00..a89b0c439a
--- /dev/null
+++ b/slirp/qtailq.h
@@ -0,0 +1,193 @@
+/*  $NetBSD: queue.h,v 1.52 2009/04/20 09:56:08 mschuett Exp $ */
+
+/*
+ * slirp version: Copy from QEMU, removed all but tail queues.
+ */
+
+/*
+ * Copyright (c) 1991, 1993
+ *  The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *notice, this list of conditions and the following disclaimer in the
+ *documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *may be used to endorse or promote products derived from this software
+ *without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *  @(#)queue.h 8.5 (Berkeley) 8/20/94
+ */
+
+#ifndef QTAILQ_H
+#define QTAILQ_H
+
+/*
+ * A tail queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or
+ * after an existing element, at the head of the list, or at the end of
+ * the list. A tail queue may be traversed in either direction.
+ */
+typedef struct QTailQLink {
+void *tql_next;
+struct QTailQLink *tql_prev;
+} QTailQLink;
+
+/*
+ * Tail queue definitions.  The union acts as a poor man template, as if
+ * it were QTailQLink.
+ */
+#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; 

[Qemu-devel] [PULLv3 15/32] slirp: move QEMU state saving to a separate unit

2019-02-05 Thread Samuel Thibault
From: Marc-André Lureau 

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 
Signed-off-by: Samuel Thibault 
---
 slirp/Makefile.objs |   1 +
 slirp/slirp.c   | 372 ++---
 slirp/slirp.h   |   3 +
 slirp/state.c   | 394 
 slirp/state.h   |   9 +
 5 files changed, 418 insertions(+), 361 deletions(-)
 create mode 100644 slirp/state.c
 create mode 100644 slirp/state.h

diff --git a/slirp/Makefile.objs b/slirp/Makefile.objs
index d2ead94b3b..88340a583b 100644
--- a/slirp/Makefile.objs
+++ b/slirp/Makefile.objs
@@ -20,6 +20,7 @@ slirp.mo-objs = \
sbuf.o \
slirp.o \
socket.o \
+   state.o \
tcp_input.o \
tcp_output.o \
tcp_subr.o \
diff --git a/slirp/slirp.c b/slirp/slirp.c
index f0bd59fd6f..9ec1e4c62f 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -30,6 +30,10 @@
 #include "hw/hw.h"
 #include "qemu/cutils.h"
 
+#ifdef WITH_QEMU
+#include "state.h"
+#endif
+
 #ifndef _WIN32
 #include 
 #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, _slirp_state, slirp);
-
+#ifdef WITH_QEMU
+slirp_state_register(slirp);
+#endif
 QTAILQ_INSERT_TAIL(_instances, slirp, entry);
 
 return slirp;
@@ -359,9 +356,9 @@ void slirp_cleanup(Slirp *slirp)
 }
 
 QTAILQ_REMOVE(_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),

[Qemu-devel] [PULLv3 05/32] net/slirp: simplify checking for cmd: prefix

2019-02-05 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 net/slirp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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




[Qemu-devel] [PULLv3 24/32] slirp: Move g_spawn_async_with_fds_qemu compatibility to slirp/

2019-02-05 Thread Samuel Thibault
Only slirp actually needs it, and will need it along in libslirp.

Signed-off-by: Samuel Thibault 
Reviewed-by: Marc-André Lureau 
---
 include/glib-compat.h | 57 ---
 slirp/misc.c  | 62 +++
 2 files changed, 62 insertions(+), 57 deletions(-)

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




[Qemu-devel] [PULLv3 07/32] net/slirp: fix leaks on forwarding rule registration error

2019-02-05 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 net/slirp.c | 2 ++
 1 file changed, 2 insertions(+)

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




[Qemu-devel] [PULLv3 31/32] slirp: pass opaque to all callbacks

2019-02-05 Thread Samuel Thibault
From: Marc-André Lureau 

This is friendlier for FFI bindings.

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 net/slirp.c  | 25 -
 slirp/dhcpv6.c   |  2 +-
 slirp/if.c   |  2 +-
 slirp/ip6_icmp.c | 15 +--
 slirp/ip_icmp.c  |  2 +-
 slirp/libslirp.h | 16 
 slirp/misc.c |  2 +-
 slirp/slirp.c| 13 ++---
 slirp/socket.c   |  2 +-
 slirp/tcp_subr.c |  8 
 slirp/udp.c  |  2 +-
 11 files changed, 49 insertions(+), 40 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index a85e42ff43..7a16d8d615 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -161,44 +161,51 @@ static NetClientInfo net_slirp_info = {
 .cleanup = net_slirp_cleanup,
 };
 
-static void net_slirp_guest_error(const char *msg)
+static void net_slirp_guest_error(const char *msg, void *opaque)
 {
 qemu_log_mask(LOG_GUEST_ERROR, "%s", msg);
 }
 
-static int64_t net_slirp_clock_get_ns(void)
+static int64_t net_slirp_clock_get_ns(void *opaque)
 {
 return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 }
 
-static void *net_slirp_timer_new(SlirpTimerCb cb, void *opaque)
+static void *net_slirp_timer_new(SlirpTimerCb cb,
+ void *cb_opaque, void *opaque)
 {
 return timer_new_full(NULL, QEMU_CLOCK_VIRTUAL,
   SCALE_MS, QEMU_TIMER_ATTR_EXTERNAL,
-  cb, opaque);
+  cb, cb_opaque);
 }
 
-static void net_slirp_timer_free(void *timer)
+static void net_slirp_timer_free(void *timer, void *opaque)
 {
 timer_del(timer);
 timer_free(timer);
 }
 
-static void net_slirp_timer_mod(void *timer, int64_t expire_timer)
+static void net_slirp_timer_mod(void *timer, int64_t expire_timer,
+void *opaque)
 {
 timer_mod(timer, expire_timer);
 }
 
-static void net_slirp_register_poll_fd(int fd)
+static void net_slirp_register_poll_fd(int fd, void *opaque)
 {
 qemu_fd_register(fd);
 }
 
-static void net_slirp_unregister_poll_fd(int fd)
+static void net_slirp_unregister_poll_fd(int fd, void *opaque)
 {
 /* no qemu_fd_unregister */
 }
 
+static void net_slirp_notify(void *opaque)
+{
+qemu_notify_event();
+}
+
 static const SlirpCb slirp_cb = {
 .send_packet = net_slirp_send_packet,
 .guest_error = net_slirp_guest_error,
@@ -208,7 +215,7 @@ static const SlirpCb slirp_cb = {
 .timer_mod = net_slirp_timer_mod,
 .register_poll_fd = net_slirp_register_poll_fd,
 .unregister_poll_fd = net_slirp_unregister_poll_fd,
-.notify = qemu_notify_event,
+.notify = net_slirp_notify,
 };
 
 static int slirp_poll_to_gio(int events)
diff --git a/slirp/dhcpv6.c b/slirp/dhcpv6.c
index 9ffba38e8f..e655c7d5b1 100644
--- a/slirp/dhcpv6.c
+++ b/slirp/dhcpv6.c
@@ -59,7 +59,7 @@ static int dhcpv6_parse_info_request(Slirp *slirp, uint8_t 
*odata, int olen,
 int len = odata[2] << 8 | odata[3];
 
 if (len + 4 > olen) {
-slirp->cb->guest_error("Guest sent bad DHCPv6 packet!");
+slirp->cb->guest_error("Guest sent bad DHCPv6 packet!", 
slirp->opaque);
 return -E2BIG;
 }
 
diff --git a/slirp/if.c b/slirp/if.c
index 2ad03b8a79..1830cc396c 100644
--- a/slirp/if.c
+++ b/slirp/if.c
@@ -146,7 +146,7 @@ diddit:
  */
 void if_start(Slirp *slirp)
 {
-uint64_t now = slirp->cb->clock_get_ns();
+uint64_t now = slirp->cb->clock_get_ns(slirp->opaque);
 bool from_batchq = false;
 struct mbuf *ifm, *ifm_next, *ifqt;
 
diff --git a/slirp/ip6_icmp.c b/slirp/ip6_icmp.c
index 2a432ebbd4..c1e3d30470 100644
--- a/slirp/ip6_icmp.c
+++ b/slirp/ip6_icmp.c
@@ -14,7 +14,8 @@ static void ra_timer_handler(void *opaque)
 Slirp *slirp = opaque;
 
 slirp->cb->timer_mod(slirp->ra_timer,
- slirp->cb->clock_get_ns() / SCALE_MS + NDP_Interval);
+slirp->cb->clock_get_ns(slirp->opaque) / SCALE_MS + NDP_Interval,
+slirp->opaque);
 ndp_send_ra(slirp);
 }
 
@@ -24,9 +25,10 @@ void icmp6_init(Slirp *slirp)
 return;
 }
 
-slirp->ra_timer = slirp->cb->timer_new(ra_timer_handler, slirp);
+slirp->ra_timer = slirp->cb->timer_new(ra_timer_handler, slirp, 
slirp->opaque);
 slirp->cb->timer_mod(slirp->ra_timer,
- slirp->cb->clock_get_ns() / SCALE_MS + NDP_Interval);
+slirp->cb->clock_get_ns(slirp->opaque) / SCALE_MS + NDP_Interval,
+slirp->opaque);
 }
 
 void icmp6_cleanup(Slirp *slirp)
@@ -35,7 +37,7 @@ void icmp6_cleanup(Slirp *slirp)
 return;
 }
 
-slirp->cb->timer_free(slirp->ra_timer);
+slirp->cb->timer_free(slirp->ra_timer, slirp->opaque);
 }
 
 static void icmp6_send_echoreply(struct mbuf *m, Slirp *slirp, struct ip6 *ip,
@@ -334,7 +336,8 @@ static void ndp_input(struct mbuf *m, Slir

[Qemu-devel] [PULLv3 16/32] slirp: do not include qemu headers in libslirp.h public API header

2019-02-05 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/libslirp.h | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 679a25422b..02cbec9f8b 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -1,7 +1,17 @@
 #ifndef LIBSLIRP_H
 #define LIBSLIRP_H
 
-#include "qemu-common.h"
+#include 
+#include 
+#include 
+
+#ifdef _WIN32
+#include 
+#include 
+#else
+#include 
+#include 
+#endif
 
 typedef struct Slirp Slirp;
 
-- 
2.20.1




[Qemu-devel] [PULLv3 03/32] slirp: Don't mark struct ipq or struct ipasfrag as packed

2019-02-05 Thread Samuel Thibault
From: Peter Maydell 

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

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

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

Signed-off-by: Peter Maydell 
Reviewed-by: Eric Blake 
Signed-off-by: Samuel Thibault 
---
 slirp/ip.h | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

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




[Qemu-devel] [PULLv3 11/32] slirp: replace most qemu socket utilities with slirp own version

2019-02-05 Thread Samuel Thibault
From: Marc-André Lureau 

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

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/Makefile.objs |   3 +-
 slirp/ip_icmp.c |   6 +-
 slirp/misc.c|  20 ++---
 slirp/socket.c  |  18 ++---
 slirp/tcp_subr.c|  18 ++---
 slirp/udp.c |   8 +-
 slirp/util.c| 176 
 slirp/util.h|  61 +++
 8 files changed, 274 insertions(+), 36 deletions(-)
 create mode 100644 slirp/util.c

diff --git a/slirp/Makefile.objs b/slirp/Makefile.objs
index 959558c732..d2ead94b3b 100644
--- a/slirp/Makefile.objs
+++ b/slirp/Makefile.objs
@@ -27,6 +27,7 @@ slirp.mo-objs = \
tftp.o \
udp.o \
udp6.o \
+   util.o \
$(NULL)
 
-slirp.mo-cflags = -DG_LOG_DOMAIN=\"Slirp\"
+slirp.mo-cflags = -DG_LOG_DOMAIN=\"Slirp\" -DWITH_QEMU
diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
index 7c7e042049..b59daa801d 100644
--- a/slirp/ip_icmp.c
+++ b/slirp/ip_icmp.c
@@ -83,7 +83,7 @@ static int icmp_send(struct socket *so, struct mbuf *m, int 
hlen)
 struct ip *ip = mtod(m, struct ip *);
 struct sockaddr_in addr;
 
-so->s = qemu_socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
+so->s = slirp_socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
 if (so->s == -1) {
 return -1;
 }
@@ -114,7 +114,7 @@ static int icmp_send(struct socket *so, struct mbuf *m, int 
hlen)
 
 void icmp_detach(struct socket *so)
 {
-closesocket(so->s);
+slirp_closesocket(so->s);
 sofree(so);
 }
 
@@ -421,7 +421,7 @@ void icmp_receive(struct socket *so)
 icp = mtod(m, struct icmp *);
 
 id = icp->icmp_id;
-len = qemu_recv(so->s, icp, M_ROOM(m), 0);
+len = slirp_recv(so->s, icp, M_ROOM(m), 0);
 /*
  * The behavior of reading SOCK_DGRAM+IPPROTO_ICMP sockets is inconsistent
  * between host OSes.  On Linux, only the ICMP header and payload is
diff --git a/slirp/misc.c b/slirp/misc.c
index b8a2bf971a..32ec02a525 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -72,14 +72,14 @@ slirp_socketpair_with_oob(int sv[2])
 int ret, s;
 
 sv[1] = -1;
-s = qemu_socket(AF_INET, SOCK_STREAM, 0);
+s = slirp_socket(AF_INET, SOCK_STREAM, 0);
 if (s < 0 || bind(s, (struct sockaddr *), addrlen) < 0 ||
 listen(s, 1) < 0 ||
 getsockname(s, (struct sockaddr *), ) < 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, , sizeof(int));
+slirp_setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, , sizeof(int));
 qemu_set_nonblock(so->s);
 return 1;
 }
diff --git a/slirp/socket.c b/slirp/socket.c
index 5ffbaa064a..5805d30f3d 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -187,7 +187,7 @@ soread(struct socket *so)
 */
sopreprbuf(so, iov, );
 
-   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, ) < 0) {
err = errno;
} else {
-   getsockopt(so->s, SOL_SOCKET, SO_ERROR,
+   slirp_getsockopt(so->s, SOL_SOCKET, 
SO_ERROR,
, );
}
}
@@ -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_b

[Qemu-devel] [PULLv3 12/32] slirp: replace qemu_set_nonblock()

2019-02-05 Thread Samuel Thibault
From: Marc-André Lureau 

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 
Signed-off-by: Samuel Thibault 
---
 net/slirp.c |  6 ++
 slirp/libslirp.h|  2 ++
 slirp/misc.c|  3 ++-
 slirp/tcp_subr.c|  6 --
 slirp/util.c| 14 ++
 slirp/util.h|  1 +
 stubs/Makefile.objs |  2 +-
 7 files changed, 30 insertions(+), 4 deletions(-)

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




[Qemu-devel] [PULLv3 09/32] slirp: replace trace functions with DEBUG calls

2019-02-05 Thread Samuel Thibault
From: Marc-André Lureau 

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

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 Makefile.objs  |  1 -
 slirp/debug.h  | 13 ++---
 slirp/slirp.c  |  1 +
 slirp/tftp.c   |  7 ---
 slirp/trace-events |  5 -
 5 files changed, 15 insertions(+), 12 deletions(-)
 delete mode 100644 slirp/trace-events

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




[Qemu-devel] [PULLv3 06/32] net/slirp: free forwarding rules on cleanup

2019-02-05 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 net/slirp.c | 25 ++---
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index b91741b8fc..750105a466 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -75,6 +75,13 @@ struct slirp_config_str {
 char str[1024];
 };
 
+struct GuestFwd {
+CharBackend hd;
+struct in_addr server;
+int port;
+Slirp *slirp;
+};
+
 typedef struct SlirpState {
 NetClientState nc;
 QTAILQ_ENTRY(SlirpState) entry;
@@ -83,6 +90,7 @@ typedef struct SlirpState {
 #ifndef _WIN32
 gchar *smb_dir;
 #endif
+GSList *fwd;
 } SlirpState;
 
 static struct slirp_config_str *slirp_configs;
@@ -122,10 +130,19 @@ static void slirp_smb_exit(Notifier *n, void *data)
 slirp_smb_cleanup(s);
 }
 
+static void slirp_free_fwd(gpointer data)
+{
+struct GuestFwd *fwd = data;
+
+qemu_chr_fe_deinit(>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(>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(>hd, guestfwd_can_read, guestfwd_read,
  NULL, NULL, fwd, NULL, true);
+s->fwd = g_slist_append(s->fwd, fwd);
 }
 return 0;
 
-- 
2.20.1




<    1   2   3   4   5   6   7   8   9   10   >