All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v6 0/4] slirp: Add query-usernet QMP command
@ 2018-05-04  7:42 Fam Zheng
  2018-05-04  7:42 ` [Qemu-devel] [PATCH v6 1/4] qapi: Introduce UsernetTcpState Fam Zheng
                   ` (5 more replies)
  0 siblings, 6 replies; 10+ messages in thread
From: Fam Zheng @ 2018-05-04  7:42 UTC (permalink / raw)
  To: qemu-devel
  Cc: Alex Bennée, berrange, Fam Zheng, Jason Wang, Eric Blake,
	Philippe Mathieu-Daudé,
	Markus Armbruster, Jan Kiszka, Samuel Thibault

v6: Rename QAPI enum: TCPS -> UsernetTcpState. [Daniel]

v5: Fix QAPI example in comments. [Eric]
v4: vlan -> hub. [Samuel]
    Free 'info. [Samuel]

v3: - Add Eric's rev-by to patch 2.
    - Address Eric's comments on patch 1:
      * Fix spell/grammar: "programmed", "awaiting".
      * Fix include "qapi/qapi-commands-net.h".
      * Underscores to dashes.
      * "Since 2.13" now.

v2: Fix compiler error. [patchew]

The command is a counterpart of HMP "info usernet" and is at least very useful
for the VM tests. So add it.

Fam Zheng (4):
  qapi: Introduce UsernetTcpState
  slirp: Use QAPI enum to replace TCPS_* macros
  slirp: Add "query-usernet" QMP command
  tests: Use query-usernet instead of 'info usernet'

 net/slirp.c        |  26 +++++++
 qapi/net.json      | 214 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 slirp/libslirp.h   |   2 +
 slirp/misc.c       | 159 ++++++++++++++++++++++++++++-----------
 slirp/tcp.h        |  21 +-----
 slirp/tcp_input.c  | 103 +++++++++++++-------------
 slirp/tcp_subr.c   |  25 ++++---
 slirp/tcp_timer.c  |   7 +-
 tests/vm/basevm.py |  14 ++--
 9 files changed, 435 insertions(+), 136 deletions(-)

-- 
2.14.3

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

* [Qemu-devel] [PATCH v6 1/4] qapi: Introduce UsernetTcpState
  2018-05-04  7:42 [Qemu-devel] [PATCH v6 0/4] slirp: Add query-usernet QMP command Fam Zheng
@ 2018-05-04  7:42 ` Fam Zheng
  2018-05-04  7:42 ` [Qemu-devel] [PATCH v6 2/4] slirp: Use QAPI enum to replace TCPS_* macros Fam Zheng
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Fam Zheng @ 2018-05-04  7:42 UTC (permalink / raw)
  To: qemu-devel
  Cc: Alex Bennée, berrange, Fam Zheng, Jason Wang, Eric Blake,
	Philippe Mathieu-Daudé,
	Markus Armbruster, Jan Kiszka, Samuel Thibault

This will be a drop-in replacement for the current TCPS_ macro/enum and
what we will return to users in the coming qmp command.

The next patch will drop TCPS_ to avoid duplication and keep further
refactoring simple.

Signed-off-by: Fam Zheng <famz@redhat.com>
---
 qapi/net.json | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/qapi/net.json b/qapi/net.json
index 9117c56972..fcddce62d6 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -689,3 +689,37 @@
 ##
 { 'event': 'NIC_RX_FILTER_CHANGED',
   'data': { '*name': 'str', 'path': 'str' } }
+
+##
+# @UsernetTcpState:
+#
+# TCP States of a SLIRP connection.
+#
+# - States where connections are not established: none, closed, listen, syn-sent,
+#   syn-received
+#
+# - States where user has closed: fin-wait-1, closing, last-ack, fin-wait-2,
+#   time-wait
+#
+# - States awaiting ACK of FIN: fin-wait-1, closing, last-ack
+#
+# 'none' state is used only when host forwarding
+#
+# Since 2.13
+#
+##
+{ 'enum': 'UsernetTcpState',
+  'data':
+   ['closed',
+    'listen',
+    'syn-sent',
+    'syn-received',
+    'established',
+    'close-wait',
+    'fin-wait-1',
+    'closing',
+    'last-ack',
+    'fin-wait-2',
+    'time-wait',
+    'none'
+   ] }
-- 
2.14.3

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

* [Qemu-devel] [PATCH v6 2/4] slirp: Use QAPI enum to replace TCPS_* macros
  2018-05-04  7:42 [Qemu-devel] [PATCH v6 0/4] slirp: Add query-usernet QMP command Fam Zheng
  2018-05-04  7:42 ` [Qemu-devel] [PATCH v6 1/4] qapi: Introduce UsernetTcpState Fam Zheng
@ 2018-05-04  7:42 ` Fam Zheng
  2018-05-16  6:59   ` Markus Armbruster
  2018-05-04  7:42 ` [Qemu-devel] [PATCH v6 3/4] slirp: Add "query-usernet" QMP command Fam Zheng
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 10+ messages in thread
From: Fam Zheng @ 2018-05-04  7:42 UTC (permalink / raw)
  To: qemu-devel
  Cc: Alex Bennée, berrange, Fam Zheng, Jason Wang, Eric Blake,
	Philippe Mathieu-Daudé,
	Markus Armbruster, Jan Kiszka, Samuel Thibault

This is a mechanical patch that does search-and-replace and adding
necessary "#include" for pulling in the QAPI enum definition. The string
lookup could use the QAPI helper, and is left for the next patch.

Signed-off-by: Fam Zheng <famz@redhat.com>
---
 slirp/misc.c      |  23 ++++++------
 slirp/tcp.h       |  21 ++---------
 slirp/tcp_input.c | 103 +++++++++++++++++++++++++++---------------------------
 slirp/tcp_subr.c  |  25 ++++++-------
 slirp/tcp_timer.c |   7 ++--
 5 files changed, 84 insertions(+), 95 deletions(-)

diff --git a/slirp/misc.c b/slirp/misc.c
index 260187b6b6..ee617bc3c4 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -11,6 +11,7 @@
 #include "monitor/monitor.h"
 #include "qemu/error-report.h"
 #include "qemu/main-loop.h"
+#include "qapi/qapi-commands-net.h"
 
 #ifdef DEBUG
 int slirp_debug = DBG_CALL|DBG_MISC|DBG_ERROR;
@@ -208,17 +209,17 @@ fork_exec(struct socket *so, const char *ex, int do_pty)
 void slirp_connection_info(Slirp *slirp, Monitor *mon)
 {
     const char * const tcpstates[] = {
-        [TCPS_CLOSED]       = "CLOSED",
-        [TCPS_LISTEN]       = "LISTEN",
-        [TCPS_SYN_SENT]     = "SYN_SENT",
-        [TCPS_SYN_RECEIVED] = "SYN_RCVD",
-        [TCPS_ESTABLISHED]  = "ESTABLISHED",
-        [TCPS_CLOSE_WAIT]   = "CLOSE_WAIT",
-        [TCPS_FIN_WAIT_1]   = "FIN_WAIT_1",
-        [TCPS_CLOSING]      = "CLOSING",
-        [TCPS_LAST_ACK]     = "LAST_ACK",
-        [TCPS_FIN_WAIT_2]   = "FIN_WAIT_2",
-        [TCPS_TIME_WAIT]    = "TIME_WAIT",
+        [USERNET_TCP_STATE_CLOSED]       = "CLOSED",
+        [USERNET_TCP_STATE_LISTEN]       = "LISTEN",
+        [USERNET_TCP_STATE_SYN_SENT]     = "SYN_SENT",
+        [USERNET_TCP_STATE_SYN_RECEIVED] = "SYN_RCVD",
+        [USERNET_TCP_STATE_ESTABLISHED]  = "ESTABLISHED",
+        [USERNET_TCP_STATE_CLOSE_WAIT]   = "CLOSE_WAIT",
+        [USERNET_TCP_STATE_FIN_WAIT_1]   = "FIN_WAIT_1",
+        [USERNET_TCP_STATE_CLOSING]      = "CLOSING",
+        [USERNET_TCP_STATE_LAST_ACK]     = "LAST_ACK",
+        [USERNET_TCP_STATE_FIN_WAIT_2]   = "FIN_WAIT_2",
+        [USERNET_TCP_STATE_TIME_WAIT]    = "TIME_WAIT",
     };
     struct in_addr dst_addr;
     struct sockaddr_in src;
diff --git a/slirp/tcp.h b/slirp/tcp.h
index 174d3d960c..f766e684e6 100644
--- a/slirp/tcp.h
+++ b/slirp/tcp.h
@@ -133,24 +133,9 @@ struct tcphdr {
 
 #define TCP_NSTATES     11
 
-#define TCPS_CLOSED             0       /* closed */
-#define TCPS_LISTEN             1       /* listening for connection */
-#define TCPS_SYN_SENT           2       /* active, have sent syn */
-#define TCPS_SYN_RECEIVED       3       /* have send and received syn */
-/* states < TCPS_ESTABLISHED are those where connections not established */
-#define TCPS_ESTABLISHED        4       /* established */
-#define TCPS_CLOSE_WAIT         5       /* rcvd fin, waiting for close */
-/* states > TCPS_CLOSE_WAIT are those where user has closed */
-#define TCPS_FIN_WAIT_1         6       /* have closed, sent fin */
-#define TCPS_CLOSING            7       /* closed xchd FIN; await FIN ACK */
-#define TCPS_LAST_ACK           8       /* had fin and close; await FIN ACK */
-/* states > TCPS_CLOSE_WAIT && < TCPS_FIN_WAIT_2 await ACK of FIN */
-#define TCPS_FIN_WAIT_2         9       /* have closed, fin is acked */
-#define TCPS_TIME_WAIT          10      /* in 2*msl quiet wait after close */
-
-#define TCPS_HAVERCVDSYN(s)     ((s) >= TCPS_SYN_RECEIVED)
-#define TCPS_HAVEESTABLISHED(s) ((s) >= TCPS_ESTABLISHED)
-#define TCPS_HAVERCVDFIN(s)     ((s) >= TCPS_TIME_WAIT)
+#define TCPS_HAVERCVDSYN(s)     ((s) >= USERNET_TCP_STATE_SYN_RECEIVED)
+#define TCPS_HAVEESTABLISHED(s) ((s) >= USERNET_TCP_STATE_ESTABLISHED)
+#define TCPS_HAVERCVDFIN(s)     ((s) >= USERNET_TCP_STATE_TIME_WAIT)
 
 /*
  * TCP sequence numbers are 32 bit integers operated
diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
index 07bcbdb2dd..c8b0c9db03 100644
--- a/slirp/tcp_input.c
+++ b/slirp/tcp_input.c
@@ -41,6 +41,7 @@
 #include "qemu/osdep.h"
 #include "slirp.h"
 #include "ip_icmp.h"
+#include "qapi/qapi-commands-net.h"
 
 #define	TCPREXMTTHRESH 3
 
@@ -64,7 +65,7 @@
 #define TCP_REASS(tp, ti, m, so, flags) {\
        if ((ti)->ti_seq == (tp)->rcv_nxt && \
            tcpfrag_list_empty(tp) && \
-           (tp)->t_state == TCPS_ESTABLISHED) {\
+           (tp)->t_state == USERNET_TCP_STATE_ESTABLISHED) {\
                if (ti->ti_flags & TH_PUSH) \
                        tp->t_flags |= TF_ACKNOW; \
                else \
@@ -84,7 +85,7 @@
 #define	TCP_REASS(tp, ti, m, so, flags) { \
 	if ((ti)->ti_seq == (tp)->rcv_nxt && \
         tcpfrag_list_empty(tp) && \
-	    (tp)->t_state == TCPS_ESTABLISHED) { \
+	    (tp)->t_state == USERNET_TCP_STATE_ESTABLISHED) { \
 		tp->t_flags |= TF_DELACK; \
 		(tp)->rcv_nxt += (ti)->ti_len; \
 		flags = (ti)->ti_flags & TH_FIN; \
@@ -189,7 +190,7 @@ present:
 	ti = tcpfrag_list_first(tp);
 	if (tcpfrag_list_end(ti, tp) || ti->ti_seq != tp->rcv_nxt)
 		return (0);
-	if (tp->t_state == TCPS_SYN_RECEIVED && ti->ti_len)
+	if (tp->t_state == USERNET_TCP_STATE_SYN_RECEIVED && ti->ti_len)
 		return (0);
 	do {
 		tp->rcv_nxt += ti->ti_len;
@@ -456,7 +457,7 @@ findso:
 	  }
 
 	  tp = sototcpcb(so);
-	  tp->t_state = TCPS_LISTEN;
+	  tp->t_state = USERNET_TCP_STATE_LISTEN;
 	}
 
         /*
@@ -472,7 +473,7 @@ findso:
 	/* XXX Should never fail */
         if (tp == NULL)
 		goto dropwithreset;
-	if (tp->t_state == TCPS_CLOSED)
+	if (tp->t_state == USERNET_TCP_STATE_CLOSED)
 		goto drop;
 
 	tiwin = ti->ti_win;
@@ -491,7 +492,7 @@ findso:
 	 * Process options if not in LISTEN state,
 	 * else do it below (after getting remote address).
 	 */
-	if (optp && tp->t_state != TCPS_LISTEN)
+	if (optp && tp->t_state != USERNET_TCP_STATE_LISTEN)
 		tcp_dooptions(tp, (u_char *)optp, optlen, ti);
 
 	/*
@@ -512,7 +513,7 @@ findso:
 	 * eg: the tiwin == tp->snd_wnd prevents many more
 	 * predictions.. with no *real* advantage..
 	 */
-	if (tp->t_state == TCPS_ESTABLISHED &&
+	if (tp->t_state == USERNET_TCP_STATE_ESTABLISHED &&
 	    (tiflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK)) == TH_ACK &&
 	    ti->ti_seq == tp->rcv_nxt &&
 	    tiwin && tiwin == tp->snd_wnd &&
@@ -614,7 +615,7 @@ findso:
 	 * Enter SYN_RECEIVED state, and process any other fields of this
 	 * segment in this state.
 	 */
-	case TCPS_LISTEN: {
+	case USERNET_TCP_STATE_LISTEN: {
 
 	  if (tiflags & TH_RST)
 	    goto drop;
@@ -725,7 +726,7 @@ findso:
 	    so->so_m = m;
 	    so->so_ti = ti;
 	    tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
-	    tp->t_state = TCPS_SYN_RECEIVED;
+	    tp->t_state = USERNET_TCP_STATE_SYN_RECEIVED;
 	    /*
 	     * Initialize receive sequence numbers now so that we can send a
 	     * valid RST if the remote end rejects our connection.
@@ -759,10 +760,10 @@ findso:
 	  tcp_sendseqinit(tp);
 	  tcp_rcvseqinit(tp);
 	  tp->t_flags |= TF_ACKNOW;
-	  tp->t_state = TCPS_SYN_RECEIVED;
+	  tp->t_state = USERNET_TCP_STATE_SYN_RECEIVED;
 	  tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
 	  goto trimthenstep6;
-	} /* case TCPS_LISTEN */
+	} /* case USERNET_TCP_STATE_LISTEN */
 
 	/*
 	 * If the state is SYN_SENT:
@@ -776,7 +777,7 @@ findso:
 	 *	arrange for segment to be acked (eventually)
 	 *	continue processing rest of data/controls, beginning with URG
 	 */
-	case TCPS_SYN_SENT:
+	case USERNET_TCP_STATE_SYN_SENT:
 		if ((tiflags & TH_ACK) &&
 		    (SEQ_LEQ(ti->ti_ack, tp->iss) ||
 		     SEQ_GT(ti->ti_ack, tp->snd_max)))
@@ -803,7 +804,7 @@ findso:
 		tp->t_flags |= TF_ACKNOW;
 		if (tiflags & TH_ACK && SEQ_GT(tp->snd_una, tp->iss)) {
 			soisfconnected(so);
-			tp->t_state = TCPS_ESTABLISHED;
+			tp->t_state = USERNET_TCP_STATE_ESTABLISHED;
 
 			(void) tcp_reass(tp, (struct tcpiphdr *)0,
 				(struct mbuf *)0);
@@ -814,7 +815,7 @@ findso:
 			if (tp->t_rtt)
 				tcp_xmit_timer(tp, tp->t_rtt);
 		} else
-			tp->t_state = TCPS_SYN_RECEIVED;
+			tp->t_state = USERNET_TCP_STATE_SYN_RECEIVED;
 
 trimthenstep6:
 		/*
@@ -884,7 +885,7 @@ trimthenstep6:
 	 * user processes are gone, then RST the other end.
 	 */
 	if ((so->so_state & SS_NOFDREF) &&
-	    tp->t_state > TCPS_CLOSE_WAIT && ti->ti_len) {
+	    tp->t_state > USERNET_TCP_STATE_CLOSE_WAIT && ti->ti_len) {
 		tp = tcp_close(tp);
 		goto dropwithreset;
 	}
@@ -903,7 +904,7 @@ trimthenstep6:
 			 * are above the previous ones.
 			 */
 			if (tiflags & TH_SYN &&
-			    tp->t_state == TCPS_TIME_WAIT &&
+			    tp->t_state == USERNET_TCP_STATE_TIME_WAIT &&
 			    SEQ_GT(ti->ti_seq, tp->rcv_nxt)) {
 				iss = tp->rcv_nxt + TCP_ISSINCR;
 				tp = tcp_close(tp);
@@ -939,18 +940,18 @@ trimthenstep6:
 	 */
 	if (tiflags&TH_RST) switch (tp->t_state) {
 
-	case TCPS_SYN_RECEIVED:
-	case TCPS_ESTABLISHED:
-	case TCPS_FIN_WAIT_1:
-	case TCPS_FIN_WAIT_2:
-	case TCPS_CLOSE_WAIT:
-		tp->t_state = TCPS_CLOSED;
+	case USERNET_TCP_STATE_SYN_RECEIVED:
+	case USERNET_TCP_STATE_ESTABLISHED:
+	case USERNET_TCP_STATE_FIN_WAIT_1:
+	case USERNET_TCP_STATE_FIN_WAIT_2:
+	case USERNET_TCP_STATE_CLOSE_WAIT:
+		tp->t_state = USERNET_TCP_STATE_CLOSED;
                 tcp_close(tp);
 		goto drop;
 
-	case TCPS_CLOSING:
-	case TCPS_LAST_ACK:
-	case TCPS_TIME_WAIT:
+	case USERNET_TCP_STATE_CLOSING:
+	case USERNET_TCP_STATE_LAST_ACK:
+	case USERNET_TCP_STATE_TIME_WAIT:
                 tcp_close(tp);
 		goto drop;
 	}
@@ -978,12 +979,12 @@ trimthenstep6:
 	 * ESTABLISHED state and continue processing, otherwise
 	 * send an RST.  una<=ack<=max
 	 */
-	case TCPS_SYN_RECEIVED:
+	case USERNET_TCP_STATE_SYN_RECEIVED:
 
 		if (SEQ_GT(tp->snd_una, ti->ti_ack) ||
 		    SEQ_GT(ti->ti_ack, tp->snd_max))
 			goto dropwithreset;
-		tp->t_state = TCPS_ESTABLISHED;
+		tp->t_state = USERNET_TCP_STATE_ESTABLISHED;
 		/*
 		 * The sent SYN is ack'ed with our sequence number +1
 		 * The first data byte already in the buffer will get
@@ -1003,7 +1004,7 @@ trimthenstep6:
 		    so->so_state |= SS_NOFDREF; /* CTL_CMD */
 		  } else {
 		    needoutput = 1;
-		    tp->t_state = TCPS_FIN_WAIT_1;
+		    tp->t_state = USERNET_TCP_STATE_FIN_WAIT_1;
 		  }
 		} else {
 		  soisfconnected(so);
@@ -1023,13 +1024,13 @@ trimthenstep6:
 	 * data from the retransmission queue.  If this ACK reflects
 	 * more up to date window information we update our window information.
 	 */
-	case TCPS_ESTABLISHED:
-	case TCPS_FIN_WAIT_1:
-	case TCPS_FIN_WAIT_2:
-	case TCPS_CLOSE_WAIT:
-	case TCPS_CLOSING:
-	case TCPS_LAST_ACK:
-	case TCPS_TIME_WAIT:
+	case USERNET_TCP_STATE_ESTABLISHED:
+	case USERNET_TCP_STATE_FIN_WAIT_1:
+	case USERNET_TCP_STATE_FIN_WAIT_2:
+	case USERNET_TCP_STATE_CLOSE_WAIT:
+	case USERNET_TCP_STATE_CLOSING:
+	case USERNET_TCP_STATE_LAST_ACK:
+	case USERNET_TCP_STATE_TIME_WAIT:
 
 		if (SEQ_LEQ(ti->ti_ack, tp->snd_una)) {
 			if (ti->ti_len == 0 && tiwin == tp->snd_wnd) {
@@ -1160,7 +1161,7 @@ trimthenstep6:
 		 * for the ESTABLISHED state if our FIN is now acknowledged
 		 * then enter FIN_WAIT_2.
 		 */
-		case TCPS_FIN_WAIT_1:
+		case USERNET_TCP_STATE_FIN_WAIT_1:
 			if (ourfinisacked) {
 				/*
 				 * If we can't receive any more
@@ -1172,7 +1173,7 @@ trimthenstep6:
 				if (so->so_state & SS_FCANTRCVMORE) {
 					tp->t_timer[TCPT_2MSL] = TCP_MAXIDLE;
 				}
-				tp->t_state = TCPS_FIN_WAIT_2;
+				tp->t_state = USERNET_TCP_STATE_FIN_WAIT_2;
 			}
 			break;
 
@@ -1182,9 +1183,9 @@ trimthenstep6:
 		 * then enter the TIME-WAIT state, otherwise ignore
 		 * the segment.
 		 */
-		case TCPS_CLOSING:
+		case USERNET_TCP_STATE_CLOSING:
 			if (ourfinisacked) {
-				tp->t_state = TCPS_TIME_WAIT;
+				tp->t_state = USERNET_TCP_STATE_TIME_WAIT;
 				tcp_canceltimers(tp);
 				tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
 			}
@@ -1196,7 +1197,7 @@ trimthenstep6:
 		 * If our FIN is now acknowledged, delete the TCB,
 		 * enter the closed state and return.
 		 */
-		case TCPS_LAST_ACK:
+		case USERNET_TCP_STATE_LAST_ACK:
 			if (ourfinisacked) {
                                 tcp_close(tp);
 				goto drop;
@@ -1208,7 +1209,7 @@ trimthenstep6:
 		 * is a retransmission of the remote FIN.  Acknowledge
 		 * it and restart the finack timer.
 		 */
-		case TCPS_TIME_WAIT:
+		case USERNET_TCP_STATE_TIME_WAIT:
 			tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
 			goto dropafterack;
 		}
@@ -1316,7 +1317,7 @@ dodata:
                          * Shutdown the socket if there is no rx data in the
 			 * buffer.
 			 * soread() is called on completion of shutdown() and
-			 * will got to TCPS_LAST_ACK, and use tcp_output()
+			 * will got to USERNET_TCP_STATE_LAST_ACK, and use tcp_output()
 			 * to send the FIN.
 			 */
 			sofwdrain(so);
@@ -1330,20 +1331,20 @@ dodata:
 		 * In SYN_RECEIVED and ESTABLISHED STATES
 		 * enter the CLOSE_WAIT state.
 		 */
-		case TCPS_SYN_RECEIVED:
-		case TCPS_ESTABLISHED:
+		case USERNET_TCP_STATE_SYN_RECEIVED:
+		case USERNET_TCP_STATE_ESTABLISHED:
 		  if(so->so_emu == EMU_CTL)        /* no shutdown on socket */
-		    tp->t_state = TCPS_LAST_ACK;
+		    tp->t_state = USERNET_TCP_STATE_LAST_ACK;
 		  else
-		    tp->t_state = TCPS_CLOSE_WAIT;
+		    tp->t_state = USERNET_TCP_STATE_CLOSE_WAIT;
 		  break;
 
 	 	/*
 		 * If still in FIN_WAIT_1 STATE FIN has not been acked so
 		 * enter the CLOSING state.
 		 */
-		case TCPS_FIN_WAIT_1:
-			tp->t_state = TCPS_CLOSING;
+		case USERNET_TCP_STATE_FIN_WAIT_1:
+			tp->t_state = USERNET_TCP_STATE_CLOSING;
 			break;
 
 	 	/*
@@ -1351,8 +1352,8 @@ dodata:
 		 * starting the time-wait timer, turning off the other
 		 * standard timers.
 		 */
-		case TCPS_FIN_WAIT_2:
-			tp->t_state = TCPS_TIME_WAIT;
+		case USERNET_TCP_STATE_FIN_WAIT_2:
+			tp->t_state = USERNET_TCP_STATE_TIME_WAIT;
 			tcp_canceltimers(tp);
 			tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
 			break;
@@ -1360,7 +1361,7 @@ dodata:
 		/*
 		 * In TIME_WAIT state restart the 2 MSL time_wait timer.
 		 */
-		case TCPS_TIME_WAIT:
+		case USERNET_TCP_STATE_TIME_WAIT:
 			tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
 			break;
 		}
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index da0d53743f..8dd5a70044 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -40,6 +40,7 @@
 
 #include "qemu/osdep.h"
 #include "slirp.h"
+#include "qapi/qapi-commands-net.h"
 
 /* patchable/settable parameters for tcp */
 /* Don't do rfc1323 performance enhancements */
@@ -282,7 +283,7 @@ tcp_newtcpcb(struct socket *so)
 
 	tp->snd_cwnd = TCP_MAXWIN << TCP_MAX_WINSHIFT;
 	tp->snd_ssthresh = TCP_MAXWIN << TCP_MAX_WINSHIFT;
-	tp->t_state = TCPS_CLOSED;
+	tp->t_state = USERNET_TCP_STATE_CLOSED;
 
 	so->so_tcpcb = tp;
 
@@ -301,7 +302,7 @@ struct tcpcb *tcp_drop(struct tcpcb *tp, int err)
 	DEBUG_ARG("errno = %d", errno);
 
 	if (TCPS_HAVERCVDSYN(tp->t_state)) {
-		tp->t_state = TCPS_CLOSED;
+		tp->t_state = USERNET_TCP_STATE_CLOSED;
 		(void) tcp_output(tp);
 	}
 	return (tcp_close(tp));
@@ -371,20 +372,20 @@ tcp_sockclosed(struct tcpcb *tp)
 
 	switch (tp->t_state) {
 
-	case TCPS_CLOSED:
-	case TCPS_LISTEN:
-	case TCPS_SYN_SENT:
-		tp->t_state = TCPS_CLOSED;
+	case USERNET_TCP_STATE_CLOSED:
+	case USERNET_TCP_STATE_LISTEN:
+	case USERNET_TCP_STATE_SYN_SENT:
+		tp->t_state = USERNET_TCP_STATE_CLOSED;
 		tp = tcp_close(tp);
 		break;
 
-	case TCPS_SYN_RECEIVED:
-	case TCPS_ESTABLISHED:
-		tp->t_state = TCPS_FIN_WAIT_1;
+	case USERNET_TCP_STATE_SYN_RECEIVED:
+	case USERNET_TCP_STATE_ESTABLISHED:
+		tp->t_state = USERNET_TCP_STATE_FIN_WAIT_1;
 		break;
 
-	case TCPS_CLOSE_WAIT:
-		tp->t_state = TCPS_LAST_ACK;
+	case USERNET_TCP_STATE_CLOSE_WAIT:
+		tp->t_state = USERNET_TCP_STATE_LAST_ACK;
 		break;
 	}
 	tcp_output(tp);
@@ -513,7 +514,7 @@ void tcp_connect(struct socket *inso)
 
     tcp_template(tp);
 
-    tp->t_state = TCPS_SYN_SENT;
+    tp->t_state = USERNET_TCP_STATE_SYN_SENT;
     tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
     tp->iss = slirp->tcp_iss;
     slirp->tcp_iss += TCP_ISSINCR/2;
diff --git a/slirp/tcp_timer.c b/slirp/tcp_timer.c
index 52ef5f9100..d45dfe2da8 100644
--- a/slirp/tcp_timer.c
+++ b/slirp/tcp_timer.c
@@ -32,6 +32,7 @@
 
 #include "qemu/osdep.h"
 #include "slirp.h"
+#include "qapi/qapi-commands-net.h"
 
 static struct tcpcb *tcp_timers(register struct tcpcb *tp, int timer);
 
@@ -135,7 +136,7 @@ tcp_timers(register struct tcpcb *tp, int timer)
 	 * control block.  Otherwise, check again in a bit.
 	 */
 	case TCPT_2MSL:
-		if (tp->t_state != TCPS_TIME_WAIT &&
+		if (tp->t_state != USERNET_TCP_STATE_TIME_WAIT &&
 		    tp->t_idle <= TCP_MAXIDLE)
 			tp->t_timer[TCPT_2MSL] = TCPTV_KEEPINTVL;
 		else
@@ -259,10 +260,10 @@ tcp_timers(register struct tcpcb *tp, int timer)
 	 * or drop connection if idle for too long.
 	 */
 	case TCPT_KEEP:
-		if (tp->t_state < TCPS_ESTABLISHED)
+		if (tp->t_state < USERNET_TCP_STATE_ESTABLISHED)
 			goto dropit;
 
-		if ((SO_OPTIONS) && tp->t_state <= TCPS_CLOSE_WAIT) {
+		if ((SO_OPTIONS) && tp->t_state <= USERNET_TCP_STATE_CLOSE_WAIT) {
 		    	if (tp->t_idle >= TCPTV_KEEP_IDLE + TCP_MAXIDLE)
 				goto dropit;
 			/*
-- 
2.14.3

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

* [Qemu-devel] [PATCH v6 3/4] slirp: Add "query-usernet" QMP command
  2018-05-04  7:42 [Qemu-devel] [PATCH v6 0/4] slirp: Add query-usernet QMP command Fam Zheng
  2018-05-04  7:42 ` [Qemu-devel] [PATCH v6 1/4] qapi: Introduce UsernetTcpState Fam Zheng
  2018-05-04  7:42 ` [Qemu-devel] [PATCH v6 2/4] slirp: Use QAPI enum to replace TCPS_* macros Fam Zheng
@ 2018-05-04  7:42 ` Fam Zheng
  2018-05-16  8:07   ` Markus Armbruster
  2018-05-04  7:42 ` [Qemu-devel] [PATCH v6 4/4] tests: Use query-usernet instead of 'info usernet' Fam Zheng
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 10+ messages in thread
From: Fam Zheng @ 2018-05-04  7:42 UTC (permalink / raw)
  To: qemu-devel
  Cc: Alex Bennée, berrange, Fam Zheng, Jason Wang, Eric Blake,
	Philippe Mathieu-Daudé,
	Markus Armbruster, Jan Kiszka, Samuel Thibault

HMP "info usernet" has been available but it isn't ideal for programmed
use cases. This closes the gap in QMP by adding a counterpart
"query-usernet" command. It is basically translated from
the HMP slirp_connection_info() loop, which now calls the QMP
implementation and prints the data, just like other HMP info_* commands.

Signed-off-by: Fam Zheng <famz@redhat.com>
---
 net/slirp.c      |  26 ++++++++
 qapi/net.json    | 180 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 slirp/libslirp.h |   2 +
 slirp/misc.c     | 158 ++++++++++++++++++++++++++++++++++--------------
 4 files changed, 321 insertions(+), 45 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index 8991816bbf..9c48a882ec 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -36,6 +36,7 @@
 #include "monitor/monitor.h"
 #include "qemu/error-report.h"
 #include "qemu/sockets.h"
+#include "slirp/slirp.h"
 #include "slirp/libslirp.h"
 #include "slirp/ip6.h"
 #include "chardev/char-fe.h"
@@ -43,6 +44,7 @@
 #include "qemu/cutils.h"
 #include "qapi/error.h"
 #include "qapi/qmp/qdict.h"
+#include "qapi/qapi-commands-net.h"
 
 static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
 {
@@ -864,6 +866,30 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str,
     return -1;
 }
 
+UsernetInfoList *qmp_query_usernet(Error **errp)
+{
+    SlirpState *s;
+    UsernetInfoList *list = NULL;
+    UsernetInfoList **p = &list;
+
+    QTAILQ_FOREACH(s, &slirp_stacks, entry) {
+        int hub;
+        UsernetInfoList *il = g_new0(UsernetInfoList, 1);
+        UsernetInfo *info = il->value = g_new0(UsernetInfo, 1);
+
+        info->id = g_strdup(s->nc.name);
+        if (!net_hub_id_for_client(&s->nc, &hub)) {
+            info->hub = hub;
+        } else {
+            info->hub = -1;
+        }
+        usernet_get_info(s->slirp, info);
+        *p = il;
+        p = &il->next;
+    }
+    return list;
+}
+
 void hmp_info_usernet(Monitor *mon, const QDict *qdict)
 {
     SlirpState *s;
diff --git a/qapi/net.json b/qapi/net.json
index fcddce62d6..3cdcda125d 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -723,3 +723,183 @@
     'time-wait',
     'none'
    ] }
+
+##
+# @UsernetTCPConnection:
+#
+# SLIRP TCP information.
+#
+# @state: tcp connection state
+#
+# @hostfwd: whether this connection has host port forwarding
+#
+# @fd: the file descriptor of the connection
+#
+# @src-addr: source address of host port forwarding
+#
+# @src-port: source port of host port forwarding
+#
+# @dest-addr: destination address of host port forwarding
+#
+# @dest-port: destination port of host port forwarding
+#
+# @recv-buffered: number of bytes queued in the receive buffer
+#
+# @send-buffered: number of bytes queued in the send buffer
+#
+# Since: 2.13
+##
+{ 'struct': 'UsernetTCPConnection',
+  'data': {
+    'state': 'UsernetTcpState',
+    'hostfwd': 'bool',
+    'fd': 'int',
+    'src-addr': 'str',
+    'src-port': 'int',
+    'dest-addr': 'str',
+    'dest-port': 'int',
+    'recv-buffered': 'int',
+    'send-buffered': 'int'
+  } }
+
+##
+# @UsernetUDPConnection:
+#
+# SLIRP UDP information.
+#
+# @hostfwd: whether this connection has host port forwarding
+#
+# @expire-time-ms: time in microseconds after which this connection will expire
+#
+# @fd: the file descriptor of the connection
+#
+# @src-addr: source address of host port forwarding
+#
+# @src-port: source port of host port forwarding
+#
+# @dest-addr: destination address of host port forwarding
+#
+# @dest-port: destination port of host port forwarding
+#
+# @recv-buffered: number of bytes queued in the receive buffer
+#
+# @send-buffered: number of bytes queued in the send buffer
+#
+# Since: 2.13
+##
+{ 'struct': 'UsernetUDPConnection',
+  'data': {
+    'hostfwd': 'bool',
+    'expire-time-ms': 'int',
+    'fd': 'int',
+    'src-addr': 'str',
+    'src-port': 'int',
+    'dest-addr': 'str',
+    'dest-port': 'int',
+    'recv-buffered': 'int',
+    'send-buffered': 'int'
+    } }
+
+##
+# @UsernetICMPConnection:
+#
+# SLIRP ICMP information.
+#
+# @expire-time-ms: time in microseconds after which this connection will expire
+#
+# @fd: the file descriptor of the connection
+#
+# @src-addr: source address of host port forwarding
+#
+# @dest-addr: destination address of host port forwarding
+#
+# @recv-buffered: number of bytes queued in the receive buffer
+#
+# @send-buffered: number of bytes queued in the send buffer
+#
+# Since: 2.13
+##
+{ 'struct': 'UsernetICMPConnection',
+  'data': {
+    'expire-time-ms': 'int',
+    'fd': 'int',
+    'src-addr': 'str',
+    'dest-addr': 'str',
+    'recv-buffered': 'int',
+    'send-buffered': 'int'
+    } }
+
+##
+# @UsernetType:
+#
+# Available netdev drivers.
+#
+# Since: 2.13
+##
+{ 'enum': 'UsernetType',
+  'data': [ 'tcp', 'udp', 'icmp' ] }
+
+##
+# @UsernetConnection:
+#
+# SLIRP usernet connection information.
+#
+# Since: 2.13
+##
+{ 'union': 'UsernetConnection',
+  'discriminator': 'type',
+  'base': { 'type': 'UsernetType' },
+  'data': {
+    'tcp':     'UsernetTCPConnection',
+    'udp':     'UsernetUDPConnection',
+    'icmp':    'UsernetICMPConnection'
+    } }
+
+##
+# @UsernetInfo:
+#
+# SLIRP usernet information.
+#
+# Since: 2.13
+##
+{ 'struct': 'UsernetInfo',
+  'data': {
+    'id':              'str',
+    'hub':             'int',
+    'connections':     ['UsernetConnection']
+} }
+
+##
+# @query-usernet:
+#
+# Return SLIRP network information.
+#
+# Since: 2.13
+#
+# Example:
+#
+# -> { "execute": "query-usernet", "arguments": { } }
+# <- { "return": [
+#      {
+#        "hub": -1,
+#        "connections": [
+#          {
+#            "dest-addr": "10.0.2.15",
+#            "recv-buffered": 0,
+#            "src-port": 10022,
+#            "state": "closed",
+#            "fd": 16,
+#            "src-addr": "*",
+#            "send-buffered": 0,
+#            "dest-port": 22,
+#            "type": "tcp",
+#            "hostfwd": true
+#          }
+#        ],
+#        "id": "vnet"
+#      }
+#   ]}
+#
+##
+{ 'command': 'query-usernet',
+  'returns': ['UsernetInfo'] }
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 540b3e5903..3ba361ea41 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -2,6 +2,7 @@
 #define LIBSLIRP_H
 
 #include "qemu-common.h"
+#include "qapi/qapi-commands-net.h"
 
 typedef struct Slirp Slirp;
 
@@ -37,6 +38,7 @@ int slirp_add_exec(Slirp *slirp, int do_pty, const void *args,
                    struct in_addr *guest_addr, int guest_port);
 
 void slirp_connection_info(Slirp *slirp, Monitor *mon);
+void usernet_get_info(Slirp *slirp, UsernetInfo *info);
 
 void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr,
                        int guest_port, const uint8_t *buf, int size);
diff --git a/slirp/misc.c b/slirp/misc.c
index ee617bc3c4..1d310d7d1f 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -206,39 +206,28 @@ fork_exec(struct socket *so, const char *ex, int do_pty)
 }
 #endif
 
-void slirp_connection_info(Slirp *slirp, Monitor *mon)
+void usernet_get_info(Slirp *slirp, UsernetInfo *info)
 {
-    const char * const tcpstates[] = {
-        [USERNET_TCP_STATE_CLOSED]       = "CLOSED",
-        [USERNET_TCP_STATE_LISTEN]       = "LISTEN",
-        [USERNET_TCP_STATE_SYN_SENT]     = "SYN_SENT",
-        [USERNET_TCP_STATE_SYN_RECEIVED] = "SYN_RCVD",
-        [USERNET_TCP_STATE_ESTABLISHED]  = "ESTABLISHED",
-        [USERNET_TCP_STATE_CLOSE_WAIT]   = "CLOSE_WAIT",
-        [USERNET_TCP_STATE_FIN_WAIT_1]   = "FIN_WAIT_1",
-        [USERNET_TCP_STATE_CLOSING]      = "CLOSING",
-        [USERNET_TCP_STATE_LAST_ACK]     = "LAST_ACK",
-        [USERNET_TCP_STATE_FIN_WAIT_2]   = "FIN_WAIT_2",
-        [USERNET_TCP_STATE_TIME_WAIT]    = "TIME_WAIT",
-    };
     struct in_addr dst_addr;
     struct sockaddr_in src;
     socklen_t src_len;
     uint16_t dst_port;
     struct socket *so;
-    const char *state;
-    char buf[20];
-
-    monitor_printf(mon, "  Protocol[State]    FD  Source Address  Port   "
-                        "Dest. Address  Port RecvQ SendQ\n");
+    UsernetConnectionList **p_next = &info->connections;
 
     for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so->so_next) {
+        UsernetConnection *conn = g_new0(UsernetConnection, 1);
+        UsernetTCPConnection *tcp = &conn->u.tcp;
+        UsernetConnectionList *list = g_new0(UsernetConnectionList, 1);
+
+        list->value = conn;
         if (so->so_state & SS_HOSTFWD) {
-            state = "HOST_FORWARD";
+            tcp->hostfwd = true;
+            tcp->state = so->so_tcpcb->t_state;
         } else if (so->so_tcpcb) {
-            state = tcpstates[so->so_tcpcb->t_state];
+            tcp->state = so->so_tcpcb->t_state;
         } else {
-            state = "NONE";
+            tcp->state = USERNET_TCP_STATE_NONE;
         }
         if (so->so_state & (SS_HOSTFWD | SS_INCOMING)) {
             src_len = sizeof(src);
@@ -251,46 +240,125 @@ void slirp_connection_info(Slirp *slirp, Monitor *mon)
             dst_addr = so->so_faddr;
             dst_port = so->so_fport;
         }
-        snprintf(buf, sizeof(buf), "  TCP[%s]", state);
-        monitor_printf(mon, "%-19s %3d %15s %5d ", buf, so->s,
-                       src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*",
-                       ntohs(src.sin_port));
-        monitor_printf(mon, "%15s %5d %5d %5d\n",
-                       inet_ntoa(dst_addr), ntohs(dst_port),
-                       so->so_rcv.sb_cc, so->so_snd.sb_cc);
+        tcp->fd = so->s;
+        tcp->src_addr =
+            g_strdup(src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*");
+        tcp->src_port = ntohs(src.sin_port);
+        tcp->dest_addr = g_strdup(inet_ntoa(dst_addr));
+        tcp->dest_port = ntohs(dst_port);
+        tcp->recv_buffered = so->so_rcv.sb_cc;
+        tcp->send_buffered = so->so_snd.sb_cc;
+        *p_next = list;
+        p_next = &list->next;
     }
-
     for (so = slirp->udb.so_next; so != &slirp->udb; so = so->so_next) {
+        UsernetConnection *conn = g_new0(UsernetConnection, 1);
+        UsernetUDPConnection *udp = &conn->u.udp;
+        UsernetConnectionList *list = g_new0(UsernetConnectionList, 1);
+
+        list->value = conn;
         if (so->so_state & SS_HOSTFWD) {
-            snprintf(buf, sizeof(buf), "  UDP[HOST_FORWARD]");
+            udp->hostfwd = true;
             src_len = sizeof(src);
             getsockname(so->s, (struct sockaddr *)&src, &src_len);
             dst_addr = so->so_laddr;
             dst_port = so->so_lport;
         } else {
-            snprintf(buf, sizeof(buf), "  UDP[%d sec]",
-                         (so->so_expire - curtime) / 1000);
+            udp->expire_time_ms = so->so_expire - curtime;
             src.sin_addr = so->so_laddr;
             src.sin_port = so->so_lport;
             dst_addr = so->so_faddr;
             dst_port = so->so_fport;
         }
-        monitor_printf(mon, "%-19s %3d %15s %5d ", buf, so->s,
-                       src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*",
-                       ntohs(src.sin_port));
-        monitor_printf(mon, "%15s %5d %5d %5d\n",
-                       inet_ntoa(dst_addr), ntohs(dst_port),
-                       so->so_rcv.sb_cc, so->so_snd.sb_cc);
+        udp->fd = so->s;
+        udp->src_addr =
+            g_strdup(src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*");
+        udp->src_port = ntohs(src.sin_port);
+        udp->dest_addr = g_strdup(inet_ntoa(dst_addr));
+        udp->dest_port = ntohs(dst_port);
+        udp->recv_buffered = so->so_rcv.sb_cc;
+        udp->send_buffered = so->so_snd.sb_cc;
+        *p_next = list;
+        p_next = &list->next;
     }
 
     for (so = slirp->icmp.so_next; so != &slirp->icmp; so = so->so_next) {
-        snprintf(buf, sizeof(buf), "  ICMP[%d sec]",
-                     (so->so_expire - curtime) / 1000);
+        UsernetConnection *conn = g_new0(UsernetConnection, 1);
+        UsernetICMPConnection *icmp = &conn->u.icmp;
+        UsernetConnectionList *list = g_new0(UsernetConnectionList, 1);
+
+        icmp->expire_time_ms = so->so_expire - curtime;
         src.sin_addr = so->so_laddr;
         dst_addr = so->so_faddr;
-        monitor_printf(mon, "%-19s %3d %15s  -    ", buf, so->s,
-                       src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*");
-        monitor_printf(mon, "%15s  -    %5d %5d\n", inet_ntoa(dst_addr),
-                       so->so_rcv.sb_cc, so->so_snd.sb_cc);
+        icmp->fd = so->s;
+        icmp->src_addr =
+            g_strdup(src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*");
+        icmp->dest_addr = g_strdup(inet_ntoa(dst_addr));
+        icmp->recv_buffered = so->so_rcv.sb_cc;
+        icmp->send_buffered = so->so_snd.sb_cc;
+        *p_next = list;
+        p_next = &list->next;
     }
 }
+
+
+void slirp_connection_info(Slirp *slirp, Monitor *mon)
+{
+    const char *state;
+    char buf[64];
+    UsernetInfo *info = g_new0(UsernetInfo, 1);
+    UsernetConnectionList *cl;
+
+    monitor_printf(mon, "  Protocol[State]    FD  Source Address  Port   "
+                        "Dest. Address  Port RecvQ SendQ\n");
+
+    usernet_get_info(slirp, info);
+    for (cl = info->connections; cl && cl->value; cl = cl->next) {
+        UsernetConnection *conn = cl->value;
+
+        if (conn->type == USERNET_TYPE_TCP) {
+            UsernetTCPConnection *tcp = &conn->u.tcp;
+
+            if (tcp->hostfwd) {
+                state = "HOST_FORWARD";
+            } else {
+                state = UsernetTcpState_str(tcp->state);
+            }
+            snprintf(buf, sizeof(buf), "  TCP[%s]", state);
+            monitor_printf(mon, "%-19s %3" PRId64 " %15s %5" PRId64 " ",
+                           buf, tcp->fd,
+                           tcp->src_addr, tcp->src_port);
+            monitor_printf(mon, "%15s %5" PRId64 " %5" PRId64 " %5" PRId64 "\n",
+                           tcp->dest_addr, tcp->dest_port,
+                           tcp->recv_buffered, tcp->send_buffered);
+        } else if (conn->type == USERNET_TYPE_UDP) {
+            UsernetUDPConnection *udp = &conn->u.udp;
+
+            if (udp->hostfwd) {
+                snprintf(buf, sizeof(buf), "  UDP[HOST_FORWARD]");
+            } else {
+                snprintf(buf, sizeof(buf), "  UDP[%" PRId64 " sec]",
+                         udp->expire_time_ms / 1000);
+            }
+            monitor_printf(mon, "%-19s %3" PRId64 " %15s %5" PRId64 " ",
+                           buf, udp->fd,
+                           udp->src_addr, udp->src_port);
+            monitor_printf(mon, "%15s %5" PRId64 " %5" PRId64 " %5" PRId64 "\n",
+                           udp->dest_addr, udp->dest_port,
+                           udp->recv_buffered, udp->send_buffered);
+        } else {
+            UsernetICMPConnection *icmp = &conn->u.icmp;
+
+            assert(conn->type == USERNET_TYPE_ICMP);
+            snprintf(buf, sizeof(buf), "  ICMP[%" PRId64 " sec]",
+                     icmp->expire_time_ms / 1000);
+            monitor_printf(mon, "%-19s %3" PRId64 " %15s  -    ", buf, icmp->fd,
+                           icmp->src_addr);
+            monitor_printf(mon, "%15s  -    %5" PRId64 " %5" PRId64 "\n",
+                           icmp->dest_addr,
+                           icmp->recv_buffered, icmp->send_buffered);
+        }
+    }
+
+    qapi_free_UsernetInfo(info);
+}
-- 
2.14.3

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

* [Qemu-devel] [PATCH v6 4/4] tests: Use query-usernet instead of 'info usernet'
  2018-05-04  7:42 [Qemu-devel] [PATCH v6 0/4] slirp: Add query-usernet QMP command Fam Zheng
                   ` (2 preceding siblings ...)
  2018-05-04  7:42 ` [Qemu-devel] [PATCH v6 3/4] slirp: Add "query-usernet" QMP command Fam Zheng
@ 2018-05-04  7:42 ` Fam Zheng
  2018-05-04  7:49 ` [Qemu-devel] [PATCH v6 0/4] slirp: Add query-usernet QMP command no-reply
  2018-05-16  2:30 ` Fam Zheng
  5 siblings, 0 replies; 10+ messages in thread
From: Fam Zheng @ 2018-05-04  7:42 UTC (permalink / raw)
  To: qemu-devel
  Cc: Alex Bennée, berrange, Fam Zheng, Jason Wang, Eric Blake,
	Philippe Mathieu-Daudé,
	Markus Armbruster, Jan Kiszka, Samuel Thibault

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
 tests/vm/basevm.py | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
index 3a2d508c35..dcfa6597ad 100755
--- a/tests/vm/basevm.py
+++ b/tests/vm/basevm.py
@@ -101,7 +101,7 @@ class BaseVM(object):
                    "-o", "StrictHostKeyChecking=no",
                    "-o", "UserKnownHostsFile=" + os.devnull,
                    "-o", "ConnectTimeout=1",
-                   "-p", self.ssh_port, "-i", self._ssh_key_file]
+                   "-p", str(self.ssh_port), "-i", self._ssh_key_file]
         if interactive:
             ssh_cmd += ['-t']
         assert not isinstance(cmd, str)
@@ -163,13 +163,13 @@ class BaseVM(object):
             raise
         atexit.register(self.shutdown)
         self._guest = guest
-        usernet_info = guest.qmp("human-monitor-command",
-                                 command_line="info usernet")
+        usernet_info = guest.qmp("query-usernet")
         self.ssh_port = None
-        for l in usernet_info["return"].splitlines():
-            fields = l.split()
-            if "TCP[HOST_FORWARD]" in fields and "22" in fields:
-                self.ssh_port = l.split()[3]
+        for i in usernet_info["return"]:
+            if i.get("id") != "vnet":
+                continue
+            self.ssh_port = i["connections"][0]["src_port"]
+            break
         if not self.ssh_port:
             raise Exception("Cannot find ssh port from 'info usernet':\n%s" % \
                             usernet_info)
-- 
2.14.3

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

* Re: [Qemu-devel] [PATCH v6 0/4] slirp: Add query-usernet QMP command
  2018-05-04  7:42 [Qemu-devel] [PATCH v6 0/4] slirp: Add query-usernet QMP command Fam Zheng
                   ` (3 preceding siblings ...)
  2018-05-04  7:42 ` [Qemu-devel] [PATCH v6 4/4] tests: Use query-usernet instead of 'info usernet' Fam Zheng
@ 2018-05-04  7:49 ` no-reply
  2018-05-08  0:45   ` Fam Zheng
  2018-05-16  2:30 ` Fam Zheng
  5 siblings, 1 reply; 10+ messages in thread
From: no-reply @ 2018-05-04  7:49 UTC (permalink / raw)
  To: famz
  Cc: qemu-devel, samuel.thibault, jasowang, f4bug, armbru, jan.kiszka,
	alex.bennee

Hi,

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

Type: series
Message-id: 20180504074207.22634-1-famz@redhat.com
Subject: [Qemu-devel] [PATCH v6 0/4] slirp: Add query-usernet QMP command

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
    echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
    if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
        failed=1
        echo
    fi
    n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag]               patchew/20180504074207.22634-1-famz@redhat.com -> patchew/20180504074207.22634-1-famz@redhat.com
Switched to a new branch 'test'
c08e6e3a7f tests: Use query-usernet instead of 'info usernet'
c493a69267 slirp: Add "query-usernet" QMP command
5150e445b4 slirp: Use QAPI enum to replace TCPS_* macros
0f3b1a240b qapi: Introduce UsernetTcpState

=== OUTPUT BEGIN ===
Checking PATCH 1/4: qapi: Introduce UsernetTcpState...
Checking PATCH 2/4: slirp: Use QAPI enum to replace TCPS_* macros...
ERROR: code indent should never use tabs
#112: FILE: slirp/tcp_input.c:88:
+^I    (tp)->t_state == USERNET_TCP_STATE_ESTABLISHED) { \$

ERROR: code indent should never use tabs
#121: FILE: slirp/tcp_input.c:193:
+^Iif (tp->t_state == USERNET_TCP_STATE_SYN_RECEIVED && ti->ti_len)$

ERROR: code indent should never use tabs
#130: FILE: slirp/tcp_input.c:460:
+^I  tp->t_state = USERNET_TCP_STATE_LISTEN;$

ERROR: code indent should never use tabs
#139: FILE: slirp/tcp_input.c:476:
+^Iif (tp->t_state == USERNET_TCP_STATE_CLOSED)$

ERROR: braces {} are necessary for all arms of this statement
#139: FILE: slirp/tcp_input.c:476:
+	if (tp->t_state == USERNET_TCP_STATE_CLOSED)
[...]

ERROR: code indent should never use tabs
#148: FILE: slirp/tcp_input.c:495:
+^Iif (optp && tp->t_state != USERNET_TCP_STATE_LISTEN)$

ERROR: braces {} are necessary for all arms of this statement
#148: FILE: slirp/tcp_input.c:495:
+	if (optp && tp->t_state != USERNET_TCP_STATE_LISTEN)
[...]

ERROR: code indent should never use tabs
#157: FILE: slirp/tcp_input.c:516:
+^Iif (tp->t_state == USERNET_TCP_STATE_ESTABLISHED &&$

ERROR: code indent should never use tabs
#166: FILE: slirp/tcp_input.c:618:
+^Icase USERNET_TCP_STATE_LISTEN: {$

ERROR: code indent should never use tabs
#175: FILE: slirp/tcp_input.c:729:
+^I    tp->t_state = USERNET_TCP_STATE_SYN_RECEIVED;$

ERROR: code indent should never use tabs
#184: FILE: slirp/tcp_input.c:763:
+^I  tp->t_state = USERNET_TCP_STATE_SYN_RECEIVED;$

ERROR: code indent should never use tabs
#188: FILE: slirp/tcp_input.c:766:
+^I} /* case USERNET_TCP_STATE_LISTEN */$

ERROR: code indent should never use tabs
#197: FILE: slirp/tcp_input.c:780:
+^Icase USERNET_TCP_STATE_SYN_SENT:$

ERROR: code indent should never use tabs
#206: FILE: slirp/tcp_input.c:807:
+^I^I^Itp->t_state = USERNET_TCP_STATE_ESTABLISHED;$

ERROR: code indent should never use tabs
#215: FILE: slirp/tcp_input.c:818:
+^I^I^Itp->t_state = USERNET_TCP_STATE_SYN_RECEIVED;$

ERROR: code indent should never use tabs
#224: FILE: slirp/tcp_input.c:888:
+^I    tp->t_state > USERNET_TCP_STATE_CLOSE_WAIT && ti->ti_len) {$

ERROR: code indent should never use tabs
#233: FILE: slirp/tcp_input.c:907:
+^I^I^I    tp->t_state == USERNET_TCP_STATE_TIME_WAIT &&$

ERROR: code indent should never use tabs
#247: FILE: slirp/tcp_input.c:943:
+^Icase USERNET_TCP_STATE_SYN_RECEIVED:$

ERROR: code indent should never use tabs
#248: FILE: slirp/tcp_input.c:944:
+^Icase USERNET_TCP_STATE_ESTABLISHED:$

ERROR: code indent should never use tabs
#249: FILE: slirp/tcp_input.c:945:
+^Icase USERNET_TCP_STATE_FIN_WAIT_1:$

ERROR: code indent should never use tabs
#250: FILE: slirp/tcp_input.c:946:
+^Icase USERNET_TCP_STATE_FIN_WAIT_2:$

ERROR: code indent should never use tabs
#251: FILE: slirp/tcp_input.c:947:
+^Icase USERNET_TCP_STATE_CLOSE_WAIT:$

ERROR: code indent should never use tabs
#252: FILE: slirp/tcp_input.c:948:
+^I^Itp->t_state = USERNET_TCP_STATE_CLOSED;$

ERROR: code indent should never use tabs
#259: FILE: slirp/tcp_input.c:952:
+^Icase USERNET_TCP_STATE_CLOSING:$

ERROR: code indent should never use tabs
#260: FILE: slirp/tcp_input.c:953:
+^Icase USERNET_TCP_STATE_LAST_ACK:$

ERROR: code indent should never use tabs
#261: FILE: slirp/tcp_input.c:954:
+^Icase USERNET_TCP_STATE_TIME_WAIT:$

ERROR: code indent should never use tabs
#270: FILE: slirp/tcp_input.c:982:
+^Icase USERNET_TCP_STATE_SYN_RECEIVED:$

ERROR: code indent should never use tabs
#276: FILE: slirp/tcp_input.c:987:
+^I^Itp->t_state = USERNET_TCP_STATE_ESTABLISHED;$

ERROR: code indent should never use tabs
#285: FILE: slirp/tcp_input.c:1007:
+^I^I    tp->t_state = USERNET_TCP_STATE_FIN_WAIT_1;$

ERROR: code indent should never use tabs
#300: FILE: slirp/tcp_input.c:1027:
+^Icase USERNET_TCP_STATE_ESTABLISHED:$

ERROR: code indent should never use tabs
#301: FILE: slirp/tcp_input.c:1028:
+^Icase USERNET_TCP_STATE_FIN_WAIT_1:$

ERROR: code indent should never use tabs
#302: FILE: slirp/tcp_input.c:1029:
+^Icase USERNET_TCP_STATE_FIN_WAIT_2:$

ERROR: code indent should never use tabs
#303: FILE: slirp/tcp_input.c:1030:
+^Icase USERNET_TCP_STATE_CLOSE_WAIT:$

ERROR: code indent should never use tabs
#304: FILE: slirp/tcp_input.c:1031:
+^Icase USERNET_TCP_STATE_CLOSING:$

ERROR: code indent should never use tabs
#305: FILE: slirp/tcp_input.c:1032:
+^Icase USERNET_TCP_STATE_LAST_ACK:$

ERROR: code indent should never use tabs
#306: FILE: slirp/tcp_input.c:1033:
+^Icase USERNET_TCP_STATE_TIME_WAIT:$

ERROR: code indent should never use tabs
#315: FILE: slirp/tcp_input.c:1164:
+^I^Icase USERNET_TCP_STATE_FIN_WAIT_1:$

ERROR: code indent should never use tabs
#324: FILE: slirp/tcp_input.c:1176:
+^I^I^I^Itp->t_state = USERNET_TCP_STATE_FIN_WAIT_2;$

ERROR: code indent should never use tabs
#333: FILE: slirp/tcp_input.c:1186:
+^I^Icase USERNET_TCP_STATE_CLOSING:$

ERROR: code indent should never use tabs
#336: FILE: slirp/tcp_input.c:1188:
+^I^I^I^Itp->t_state = USERNET_TCP_STATE_TIME_WAIT;$

ERROR: code indent should never use tabs
#345: FILE: slirp/tcp_input.c:1200:
+^I^Icase USERNET_TCP_STATE_LAST_ACK:$

ERROR: code indent should never use tabs
#354: FILE: slirp/tcp_input.c:1212:
+^I^Icase USERNET_TCP_STATE_TIME_WAIT:$

WARNING: line over 80 characters
#363: FILE: slirp/tcp_input.c:1320:
+			 * will got to USERNET_TCP_STATE_LAST_ACK, and use tcp_output()

ERROR: code indent should never use tabs
#363: FILE: slirp/tcp_input.c:1320:
+^I^I^I * will got to USERNET_TCP_STATE_LAST_ACK, and use tcp_output()$

ERROR: code indent should never use tabs
#373: FILE: slirp/tcp_input.c:1334:
+^I^Icase USERNET_TCP_STATE_SYN_RECEIVED:$

ERROR: code indent should never use tabs
#374: FILE: slirp/tcp_input.c:1335:
+^I^Icase USERNET_TCP_STATE_ESTABLISHED:$

ERROR: code indent should never use tabs
#377: FILE: slirp/tcp_input.c:1337:
+^I^I    tp->t_state = USERNET_TCP_STATE_LAST_ACK;$

ERROR: code indent should never use tabs
#380: FILE: slirp/tcp_input.c:1339:
+^I^I    tp->t_state = USERNET_TCP_STATE_CLOSE_WAIT;$

ERROR: code indent should never use tabs
#389: FILE: slirp/tcp_input.c:1346:
+^I^Icase USERNET_TCP_STATE_FIN_WAIT_1:$

ERROR: code indent should never use tabs
#390: FILE: slirp/tcp_input.c:1347:
+^I^I^Itp->t_state = USERNET_TCP_STATE_CLOSING;$

ERROR: code indent should never use tabs
#400: FILE: slirp/tcp_input.c:1355:
+^I^Icase USERNET_TCP_STATE_FIN_WAIT_2:$

ERROR: code indent should never use tabs
#401: FILE: slirp/tcp_input.c:1356:
+^I^I^Itp->t_state = USERNET_TCP_STATE_TIME_WAIT;$

ERROR: code indent should never use tabs
#410: FILE: slirp/tcp_input.c:1364:
+^I^Icase USERNET_TCP_STATE_TIME_WAIT:$

ERROR: code indent should never use tabs
#431: FILE: slirp/tcp_subr.c:286:
+^Itp->t_state = USERNET_TCP_STATE_CLOSED;$

ERROR: code indent should never use tabs
#440: FILE: slirp/tcp_subr.c:305:
+^I^Itp->t_state = USERNET_TCP_STATE_CLOSED;$

ERROR: code indent should never use tabs
#452: FILE: slirp/tcp_subr.c:375:
+^Icase USERNET_TCP_STATE_CLOSED:$

ERROR: code indent should never use tabs
#453: FILE: slirp/tcp_subr.c:376:
+^Icase USERNET_TCP_STATE_LISTEN:$

ERROR: code indent should never use tabs
#454: FILE: slirp/tcp_subr.c:377:
+^Icase USERNET_TCP_STATE_SYN_SENT:$

ERROR: code indent should never use tabs
#455: FILE: slirp/tcp_subr.c:378:
+^I^Itp->t_state = USERNET_TCP_STATE_CLOSED;$

ERROR: code indent should never use tabs
#462: FILE: slirp/tcp_subr.c:382:
+^Icase USERNET_TCP_STATE_SYN_RECEIVED:$

ERROR: code indent should never use tabs
#463: FILE: slirp/tcp_subr.c:383:
+^Icase USERNET_TCP_STATE_ESTABLISHED:$

ERROR: code indent should never use tabs
#464: FILE: slirp/tcp_subr.c:384:
+^I^Itp->t_state = USERNET_TCP_STATE_FIN_WAIT_1;$

ERROR: code indent should never use tabs
#469: FILE: slirp/tcp_subr.c:387:
+^Icase USERNET_TCP_STATE_CLOSE_WAIT:$

ERROR: code indent should never use tabs
#470: FILE: slirp/tcp_subr.c:388:
+^I^Itp->t_state = USERNET_TCP_STATE_LAST_ACK;$

ERROR: code indent should never use tabs
#500: FILE: slirp/tcp_timer.c:139:
+^I^Iif (tp->t_state != USERNET_TCP_STATE_TIME_WAIT &&$

ERROR: code indent should never use tabs
#509: FILE: slirp/tcp_timer.c:263:
+^I^Iif (tp->t_state < USERNET_TCP_STATE_ESTABLISHED)$

WARNING: line over 80 characters
#513: FILE: slirp/tcp_timer.c:266:
+		if ((SO_OPTIONS) && tp->t_state <= USERNET_TCP_STATE_CLOSE_WAIT) {

ERROR: code indent should never use tabs
#513: FILE: slirp/tcp_timer.c:266:
+^I^Iif ((SO_OPTIONS) && tp->t_state <= USERNET_TCP_STATE_CLOSE_WAIT) {$

total: 66 errors, 2 warnings, 444 lines checked

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

Checking PATCH 3/4: slirp: Add "query-usernet" QMP command...
Checking PATCH 4/4: tests: Use query-usernet instead of 'info usernet'...
=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@redhat.com

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

* Re: [Qemu-devel] [PATCH v6 0/4] slirp: Add query-usernet QMP command
  2018-05-04  7:49 ` [Qemu-devel] [PATCH v6 0/4] slirp: Add query-usernet QMP command no-reply
@ 2018-05-08  0:45   ` Fam Zheng
  0 siblings, 0 replies; 10+ messages in thread
From: Fam Zheng @ 2018-05-08  0:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: samuel.thibault, jasowang, f4bug, armbru, jan.kiszka, alex.bennee

On Fri, 05/04 00:49, no-reply@patchew.org wrote:
> Hi,
> 
> This series seems to have some coding style problems. See output below for
> more information:

Code indentation issues are due to the pre-existing style in the file and is
not changed by the patch.

Fam

> 
> Type: series
> Message-id: 20180504074207.22634-1-famz@redhat.com
> Subject: [Qemu-devel] [PATCH v6 0/4] slirp: Add query-usernet QMP command
> 
> === TEST SCRIPT BEGIN ===
> #!/bin/bash
> 
> BASE=base
> n=1
> total=$(git log --oneline $BASE.. | wc -l)
> failed=0
> 
> git config --local diff.renamelimit 0
> git config --local diff.renames True
> git config --local diff.algorithm histogram
> 
> commits="$(git log --format=%H --reverse $BASE..)"
> for c in $commits; do
>     echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
>     if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
>         failed=1
>         echo
>     fi
>     n=$((n+1))
> done
> 
> exit $failed
> === TEST SCRIPT END ===
> 
> Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
> From https://github.com/patchew-project/qemu
>  * [new tag]               patchew/20180504074207.22634-1-famz@redhat.com -> patchew/20180504074207.22634-1-famz@redhat.com
> Switched to a new branch 'test'
> c08e6e3a7f tests: Use query-usernet instead of 'info usernet'
> c493a69267 slirp: Add "query-usernet" QMP command
> 5150e445b4 slirp: Use QAPI enum to replace TCPS_* macros
> 0f3b1a240b qapi: Introduce UsernetTcpState
> 
> === OUTPUT BEGIN ===
> Checking PATCH 1/4: qapi: Introduce UsernetTcpState...
> Checking PATCH 2/4: slirp: Use QAPI enum to replace TCPS_* macros...
> ERROR: code indent should never use tabs
> #112: FILE: slirp/tcp_input.c:88:
> +^I    (tp)->t_state == USERNET_TCP_STATE_ESTABLISHED) { \$
> 
> ERROR: code indent should never use tabs
> #121: FILE: slirp/tcp_input.c:193:
> +^Iif (tp->t_state == USERNET_TCP_STATE_SYN_RECEIVED && ti->ti_len)$
> 
> ERROR: code indent should never use tabs
> #130: FILE: slirp/tcp_input.c:460:
> +^I  tp->t_state = USERNET_TCP_STATE_LISTEN;$
> 
> ERROR: code indent should never use tabs
> #139: FILE: slirp/tcp_input.c:476:
> +^Iif (tp->t_state == USERNET_TCP_STATE_CLOSED)$
> 
> ERROR: braces {} are necessary for all arms of this statement
> #139: FILE: slirp/tcp_input.c:476:
> +	if (tp->t_state == USERNET_TCP_STATE_CLOSED)
> [...]
> 
> ERROR: code indent should never use tabs
> #148: FILE: slirp/tcp_input.c:495:
> +^Iif (optp && tp->t_state != USERNET_TCP_STATE_LISTEN)$
> 
> ERROR: braces {} are necessary for all arms of this statement
> #148: FILE: slirp/tcp_input.c:495:
> +	if (optp && tp->t_state != USERNET_TCP_STATE_LISTEN)
> [...]
> 
> ERROR: code indent should never use tabs
> #157: FILE: slirp/tcp_input.c:516:
> +^Iif (tp->t_state == USERNET_TCP_STATE_ESTABLISHED &&$
> 
> ERROR: code indent should never use tabs
> #166: FILE: slirp/tcp_input.c:618:
> +^Icase USERNET_TCP_STATE_LISTEN: {$
> 
> ERROR: code indent should never use tabs
> #175: FILE: slirp/tcp_input.c:729:
> +^I    tp->t_state = USERNET_TCP_STATE_SYN_RECEIVED;$
> 
> ERROR: code indent should never use tabs
> #184: FILE: slirp/tcp_input.c:763:
> +^I  tp->t_state = USERNET_TCP_STATE_SYN_RECEIVED;$
> 
> ERROR: code indent should never use tabs
> #188: FILE: slirp/tcp_input.c:766:
> +^I} /* case USERNET_TCP_STATE_LISTEN */$
> 
> ERROR: code indent should never use tabs
> #197: FILE: slirp/tcp_input.c:780:
> +^Icase USERNET_TCP_STATE_SYN_SENT:$
> 
> ERROR: code indent should never use tabs
> #206: FILE: slirp/tcp_input.c:807:
> +^I^I^Itp->t_state = USERNET_TCP_STATE_ESTABLISHED;$
> 
> ERROR: code indent should never use tabs
> #215: FILE: slirp/tcp_input.c:818:
> +^I^I^Itp->t_state = USERNET_TCP_STATE_SYN_RECEIVED;$
> 
> ERROR: code indent should never use tabs
> #224: FILE: slirp/tcp_input.c:888:
> +^I    tp->t_state > USERNET_TCP_STATE_CLOSE_WAIT && ti->ti_len) {$
> 
> ERROR: code indent should never use tabs
> #233: FILE: slirp/tcp_input.c:907:
> +^I^I^I    tp->t_state == USERNET_TCP_STATE_TIME_WAIT &&$
> 
> ERROR: code indent should never use tabs
> #247: FILE: slirp/tcp_input.c:943:
> +^Icase USERNET_TCP_STATE_SYN_RECEIVED:$
> 
> ERROR: code indent should never use tabs
> #248: FILE: slirp/tcp_input.c:944:
> +^Icase USERNET_TCP_STATE_ESTABLISHED:$
> 
> ERROR: code indent should never use tabs
> #249: FILE: slirp/tcp_input.c:945:
> +^Icase USERNET_TCP_STATE_FIN_WAIT_1:$
> 
> ERROR: code indent should never use tabs
> #250: FILE: slirp/tcp_input.c:946:
> +^Icase USERNET_TCP_STATE_FIN_WAIT_2:$
> 
> ERROR: code indent should never use tabs
> #251: FILE: slirp/tcp_input.c:947:
> +^Icase USERNET_TCP_STATE_CLOSE_WAIT:$
> 
> ERROR: code indent should never use tabs
> #252: FILE: slirp/tcp_input.c:948:
> +^I^Itp->t_state = USERNET_TCP_STATE_CLOSED;$
> 
> ERROR: code indent should never use tabs
> #259: FILE: slirp/tcp_input.c:952:
> +^Icase USERNET_TCP_STATE_CLOSING:$
> 
> ERROR: code indent should never use tabs
> #260: FILE: slirp/tcp_input.c:953:
> +^Icase USERNET_TCP_STATE_LAST_ACK:$
> 
> ERROR: code indent should never use tabs
> #261: FILE: slirp/tcp_input.c:954:
> +^Icase USERNET_TCP_STATE_TIME_WAIT:$
> 
> ERROR: code indent should never use tabs
> #270: FILE: slirp/tcp_input.c:982:
> +^Icase USERNET_TCP_STATE_SYN_RECEIVED:$
> 
> ERROR: code indent should never use tabs
> #276: FILE: slirp/tcp_input.c:987:
> +^I^Itp->t_state = USERNET_TCP_STATE_ESTABLISHED;$
> 
> ERROR: code indent should never use tabs
> #285: FILE: slirp/tcp_input.c:1007:
> +^I^I    tp->t_state = USERNET_TCP_STATE_FIN_WAIT_1;$
> 
> ERROR: code indent should never use tabs
> #300: FILE: slirp/tcp_input.c:1027:
> +^Icase USERNET_TCP_STATE_ESTABLISHED:$
> 
> ERROR: code indent should never use tabs
> #301: FILE: slirp/tcp_input.c:1028:
> +^Icase USERNET_TCP_STATE_FIN_WAIT_1:$
> 
> ERROR: code indent should never use tabs
> #302: FILE: slirp/tcp_input.c:1029:
> +^Icase USERNET_TCP_STATE_FIN_WAIT_2:$
> 
> ERROR: code indent should never use tabs
> #303: FILE: slirp/tcp_input.c:1030:
> +^Icase USERNET_TCP_STATE_CLOSE_WAIT:$
> 
> ERROR: code indent should never use tabs
> #304: FILE: slirp/tcp_input.c:1031:
> +^Icase USERNET_TCP_STATE_CLOSING:$
> 
> ERROR: code indent should never use tabs
> #305: FILE: slirp/tcp_input.c:1032:
> +^Icase USERNET_TCP_STATE_LAST_ACK:$
> 
> ERROR: code indent should never use tabs
> #306: FILE: slirp/tcp_input.c:1033:
> +^Icase USERNET_TCP_STATE_TIME_WAIT:$
> 
> ERROR: code indent should never use tabs
> #315: FILE: slirp/tcp_input.c:1164:
> +^I^Icase USERNET_TCP_STATE_FIN_WAIT_1:$
> 
> ERROR: code indent should never use tabs
> #324: FILE: slirp/tcp_input.c:1176:
> +^I^I^I^Itp->t_state = USERNET_TCP_STATE_FIN_WAIT_2;$
> 
> ERROR: code indent should never use tabs
> #333: FILE: slirp/tcp_input.c:1186:
> +^I^Icase USERNET_TCP_STATE_CLOSING:$
> 
> ERROR: code indent should never use tabs
> #336: FILE: slirp/tcp_input.c:1188:
> +^I^I^I^Itp->t_state = USERNET_TCP_STATE_TIME_WAIT;$
> 
> ERROR: code indent should never use tabs
> #345: FILE: slirp/tcp_input.c:1200:
> +^I^Icase USERNET_TCP_STATE_LAST_ACK:$
> 
> ERROR: code indent should never use tabs
> #354: FILE: slirp/tcp_input.c:1212:
> +^I^Icase USERNET_TCP_STATE_TIME_WAIT:$
> 
> WARNING: line over 80 characters
> #363: FILE: slirp/tcp_input.c:1320:
> +			 * will got to USERNET_TCP_STATE_LAST_ACK, and use tcp_output()
> 
> ERROR: code indent should never use tabs
> #363: FILE: slirp/tcp_input.c:1320:
> +^I^I^I * will got to USERNET_TCP_STATE_LAST_ACK, and use tcp_output()$
> 
> ERROR: code indent should never use tabs
> #373: FILE: slirp/tcp_input.c:1334:
> +^I^Icase USERNET_TCP_STATE_SYN_RECEIVED:$
> 
> ERROR: code indent should never use tabs
> #374: FILE: slirp/tcp_input.c:1335:
> +^I^Icase USERNET_TCP_STATE_ESTABLISHED:$
> 
> ERROR: code indent should never use tabs
> #377: FILE: slirp/tcp_input.c:1337:
> +^I^I    tp->t_state = USERNET_TCP_STATE_LAST_ACK;$
> 
> ERROR: code indent should never use tabs
> #380: FILE: slirp/tcp_input.c:1339:
> +^I^I    tp->t_state = USERNET_TCP_STATE_CLOSE_WAIT;$
> 
> ERROR: code indent should never use tabs
> #389: FILE: slirp/tcp_input.c:1346:
> +^I^Icase USERNET_TCP_STATE_FIN_WAIT_1:$
> 
> ERROR: code indent should never use tabs
> #390: FILE: slirp/tcp_input.c:1347:
> +^I^I^Itp->t_state = USERNET_TCP_STATE_CLOSING;$
> 
> ERROR: code indent should never use tabs
> #400: FILE: slirp/tcp_input.c:1355:
> +^I^Icase USERNET_TCP_STATE_FIN_WAIT_2:$
> 
> ERROR: code indent should never use tabs
> #401: FILE: slirp/tcp_input.c:1356:
> +^I^I^Itp->t_state = USERNET_TCP_STATE_TIME_WAIT;$
> 
> ERROR: code indent should never use tabs
> #410: FILE: slirp/tcp_input.c:1364:
> +^I^Icase USERNET_TCP_STATE_TIME_WAIT:$
> 
> ERROR: code indent should never use tabs
> #431: FILE: slirp/tcp_subr.c:286:
> +^Itp->t_state = USERNET_TCP_STATE_CLOSED;$
> 
> ERROR: code indent should never use tabs
> #440: FILE: slirp/tcp_subr.c:305:
> +^I^Itp->t_state = USERNET_TCP_STATE_CLOSED;$
> 
> ERROR: code indent should never use tabs
> #452: FILE: slirp/tcp_subr.c:375:
> +^Icase USERNET_TCP_STATE_CLOSED:$
> 
> ERROR: code indent should never use tabs
> #453: FILE: slirp/tcp_subr.c:376:
> +^Icase USERNET_TCP_STATE_LISTEN:$
> 
> ERROR: code indent should never use tabs
> #454: FILE: slirp/tcp_subr.c:377:
> +^Icase USERNET_TCP_STATE_SYN_SENT:$
> 
> ERROR: code indent should never use tabs
> #455: FILE: slirp/tcp_subr.c:378:
> +^I^Itp->t_state = USERNET_TCP_STATE_CLOSED;$
> 
> ERROR: code indent should never use tabs
> #462: FILE: slirp/tcp_subr.c:382:
> +^Icase USERNET_TCP_STATE_SYN_RECEIVED:$
> 
> ERROR: code indent should never use tabs
> #463: FILE: slirp/tcp_subr.c:383:
> +^Icase USERNET_TCP_STATE_ESTABLISHED:$
> 
> ERROR: code indent should never use tabs
> #464: FILE: slirp/tcp_subr.c:384:
> +^I^Itp->t_state = USERNET_TCP_STATE_FIN_WAIT_1;$
> 
> ERROR: code indent should never use tabs
> #469: FILE: slirp/tcp_subr.c:387:
> +^Icase USERNET_TCP_STATE_CLOSE_WAIT:$
> 
> ERROR: code indent should never use tabs
> #470: FILE: slirp/tcp_subr.c:388:
> +^I^Itp->t_state = USERNET_TCP_STATE_LAST_ACK;$
> 
> ERROR: code indent should never use tabs
> #500: FILE: slirp/tcp_timer.c:139:
> +^I^Iif (tp->t_state != USERNET_TCP_STATE_TIME_WAIT &&$
> 
> ERROR: code indent should never use tabs
> #509: FILE: slirp/tcp_timer.c:263:
> +^I^Iif (tp->t_state < USERNET_TCP_STATE_ESTABLISHED)$
> 
> WARNING: line over 80 characters
> #513: FILE: slirp/tcp_timer.c:266:
> +		if ((SO_OPTIONS) && tp->t_state <= USERNET_TCP_STATE_CLOSE_WAIT) {
> 
> ERROR: code indent should never use tabs
> #513: FILE: slirp/tcp_timer.c:266:
> +^I^Iif ((SO_OPTIONS) && tp->t_state <= USERNET_TCP_STATE_CLOSE_WAIT) {$
> 
> total: 66 errors, 2 warnings, 444 lines checked
> 
> Your patch has style problems, please review.  If any of these errors
> are false positives report them to the maintainer, see
> CHECKPATCH in MAINTAINERS.
> 
> Checking PATCH 3/4: slirp: Add "query-usernet" QMP command...
> Checking PATCH 4/4: tests: Use query-usernet instead of 'info usernet'...
> === OUTPUT END ===
> 
> Test command exited with code: 1
> 
> 
> ---
> Email generated automatically by Patchew [http://patchew.org/].
> Please send your feedback to patchew-devel@redhat.com

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

* Re: [Qemu-devel] [PATCH v6 0/4] slirp: Add query-usernet QMP command
  2018-05-04  7:42 [Qemu-devel] [PATCH v6 0/4] slirp: Add query-usernet QMP command Fam Zheng
                   ` (4 preceding siblings ...)
  2018-05-04  7:49 ` [Qemu-devel] [PATCH v6 0/4] slirp: Add query-usernet QMP command no-reply
@ 2018-05-16  2:30 ` Fam Zheng
  5 siblings, 0 replies; 10+ messages in thread
From: Fam Zheng @ 2018-05-16  2:30 UTC (permalink / raw)
  To: qemu-devel, Samuel Thibault
  Cc: Alex Bennée, berrange, Jason Wang, Eric Blake,
	Philippe Mathieu-Daudé,
	Markus Armbruster, Jan Kiszka

On Fri, 05/04 15:42, Fam Zheng wrote:
> v6: Rename QAPI enum: TCPS -> UsernetTcpState. [Daniel]

Ping?

Fam

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

* Re: [Qemu-devel] [PATCH v6 2/4] slirp: Use QAPI enum to replace TCPS_* macros
  2018-05-04  7:42 ` [Qemu-devel] [PATCH v6 2/4] slirp: Use QAPI enum to replace TCPS_* macros Fam Zheng
@ 2018-05-16  6:59   ` Markus Armbruster
  0 siblings, 0 replies; 10+ messages in thread
From: Markus Armbruster @ 2018-05-16  6:59 UTC (permalink / raw)
  To: Fam Zheng
  Cc: qemu-devel, Samuel Thibault, Jason Wang,
	Philippe Mathieu-Daudé,
	Jan Kiszka, Alex Bennée

Fam Zheng <famz@redhat.com> writes:

> This is a mechanical patch that does search-and-replace and adding
> necessary "#include" for pulling in the QAPI enum definition. The string
> lookup could use the QAPI helper, and is left for the next patch.
>
> Signed-off-by: Fam Zheng <famz@redhat.com>
> ---
>  slirp/misc.c      |  23 ++++++------
>  slirp/tcp.h       |  21 ++---------
>  slirp/tcp_input.c | 103 +++++++++++++++++++++++++++---------------------------
>  slirp/tcp_subr.c  |  25 ++++++-------
>  slirp/tcp_timer.c |   7 ++--
>  5 files changed, 84 insertions(+), 95 deletions(-)
>
> diff --git a/slirp/misc.c b/slirp/misc.c
> index 260187b6b6..ee617bc3c4 100644
> --- a/slirp/misc.c
> +++ b/slirp/misc.c
> @@ -11,6 +11,7 @@
>  #include "monitor/monitor.h"
>  #include "qemu/error-report.h"
>  #include "qemu/main-loop.h"
> +#include "qapi/qapi-commands-net.h"

Uh, why doesn't "qapi/qapi-types-net.h" suffice?

Same elsewhere.

>  
>  #ifdef DEBUG
>  int slirp_debug = DBG_CALL|DBG_MISC|DBG_ERROR;
> @@ -208,17 +209,17 @@ fork_exec(struct socket *so, const char *ex, int do_pty)
>  void slirp_connection_info(Slirp *slirp, Monitor *mon)
>  {
>      const char * const tcpstates[] = {
> -        [TCPS_CLOSED]       = "CLOSED",
> -        [TCPS_LISTEN]       = "LISTEN",
> -        [TCPS_SYN_SENT]     = "SYN_SENT",
> -        [TCPS_SYN_RECEIVED] = "SYN_RCVD",
> -        [TCPS_ESTABLISHED]  = "ESTABLISHED",
> -        [TCPS_CLOSE_WAIT]   = "CLOSE_WAIT",
> -        [TCPS_FIN_WAIT_1]   = "FIN_WAIT_1",
> -        [TCPS_CLOSING]      = "CLOSING",
> -        [TCPS_LAST_ACK]     = "LAST_ACK",
> -        [TCPS_FIN_WAIT_2]   = "FIN_WAIT_2",
> -        [TCPS_TIME_WAIT]    = "TIME_WAIT",
> +        [USERNET_TCP_STATE_CLOSED]       = "CLOSED",
> +        [USERNET_TCP_STATE_LISTEN]       = "LISTEN",
> +        [USERNET_TCP_STATE_SYN_SENT]     = "SYN_SENT",
> +        [USERNET_TCP_STATE_SYN_RECEIVED] = "SYN_RCVD",
> +        [USERNET_TCP_STATE_ESTABLISHED]  = "ESTABLISHED",
> +        [USERNET_TCP_STATE_CLOSE_WAIT]   = "CLOSE_WAIT",
> +        [USERNET_TCP_STATE_FIN_WAIT_1]   = "FIN_WAIT_1",
> +        [USERNET_TCP_STATE_CLOSING]      = "CLOSING",
> +        [USERNET_TCP_STATE_LAST_ACK]     = "LAST_ACK",
> +        [USERNET_TCP_STATE_FIN_WAIT_2]   = "FIN_WAIT_2",
> +        [USERNET_TCP_STATE_TIME_WAIT]    = "TIME_WAIT",
>      };
>      struct in_addr dst_addr;
>      struct sockaddr_in src;

This is "the string lookup" mentioned in the commit message.

> diff --git a/slirp/tcp.h b/slirp/tcp.h
> index 174d3d960c..f766e684e6 100644
> --- a/slirp/tcp.h
> +++ b/slirp/tcp.h
> @@ -133,24 +133,9 @@ struct tcphdr {
   /*
    * TCP FSM state definitions.
    * Per RFC793, September, 1981.
    */
>  
>  #define TCP_NSTATES     11

Let's replace this one by USERNET_TCP_STATE_NONE or
USERNET_TCP_STATE__MAX - 1.

>  
> -#define TCPS_CLOSED             0       /* closed */
> -#define TCPS_LISTEN             1       /* listening for connection */
> -#define TCPS_SYN_SENT           2       /* active, have sent syn */
> -#define TCPS_SYN_RECEIVED       3       /* have send and received syn */
> -/* states < TCPS_ESTABLISHED are those where connections not established */
> -#define TCPS_ESTABLISHED        4       /* established */
> -#define TCPS_CLOSE_WAIT         5       /* rcvd fin, waiting for close */
> -/* states > TCPS_CLOSE_WAIT are those where user has closed */
> -#define TCPS_FIN_WAIT_1         6       /* have closed, sent fin */
> -#define TCPS_CLOSING            7       /* closed xchd FIN; await FIN ACK */
> -#define TCPS_LAST_ACK           8       /* had fin and close; await FIN ACK */
> -/* states > TCPS_CLOSE_WAIT && < TCPS_FIN_WAIT_2 await ACK of FIN */
> -#define TCPS_FIN_WAIT_2         9       /* have closed, fin is acked */
> -#define TCPS_TIME_WAIT          10      /* in 2*msl quiet wait after close */

The replacements added in the previous patch lack these comments.
Should we copy them over?  Including the reference to RFC793 above.

> -
> -#define TCPS_HAVERCVDSYN(s)     ((s) >= TCPS_SYN_RECEIVED)
> -#define TCPS_HAVEESTABLISHED(s) ((s) >= TCPS_ESTABLISHED)
> -#define TCPS_HAVERCVDFIN(s)     ((s) >= TCPS_TIME_WAIT)
> +#define TCPS_HAVERCVDSYN(s)     ((s) >= USERNET_TCP_STATE_SYN_RECEIVED)
> +#define TCPS_HAVEESTABLISHED(s) ((s) >= USERNET_TCP_STATE_ESTABLISHED)
> +#define TCPS_HAVERCVDFIN(s)     ((s) >= USERNET_TCP_STATE_TIME_WAIT)

New in the previous patch is USERNET_TCP_STATE_NONE.  Are these macros
prepared for it?  The comments on _NONE make me doubt:

  +# - States where connections are not established: none, closed, listen, syn-sent,
  +#   syn-received

Yet TCPS_HAVEESTABLISHED(USERNET_TCP_STATE_NONE) yields true.

  +# 'none' state is used only when host forwarding

Should we document that it must not be passed to these macros?

Do we really need USERNET_TCP_STATE_NONE?  See next patch.

>  
>  /*
>   * TCP sequence numbers are 32 bit integers operated
[Remainder of the patch snipped; it looks completely mechanical]

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

* Re: [Qemu-devel] [PATCH v6 3/4] slirp: Add "query-usernet" QMP command
  2018-05-04  7:42 ` [Qemu-devel] [PATCH v6 3/4] slirp: Add "query-usernet" QMP command Fam Zheng
@ 2018-05-16  8:07   ` Markus Armbruster
  0 siblings, 0 replies; 10+ messages in thread
From: Markus Armbruster @ 2018-05-16  8:07 UTC (permalink / raw)
  To: Fam Zheng
  Cc: qemu-devel, Samuel Thibault, Jason Wang,
	Philippe Mathieu-Daudé,
	Jan Kiszka, Alex Bennée

Fam Zheng <famz@redhat.com> writes:

> HMP "info usernet" has been available but it isn't ideal for programmed
> use cases. This closes the gap in QMP by adding a counterpart
> "query-usernet" command. It is basically translated from
> the HMP slirp_connection_info() loop, which now calls the QMP
> implementation and prints the data, just like other HMP info_* commands.
>
> Signed-off-by: Fam Zheng <famz@redhat.com>
> ---
>  net/slirp.c      |  26 ++++++++
>  qapi/net.json    | 180 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  slirp/libslirp.h |   2 +
>  slirp/misc.c     | 158 ++++++++++++++++++++++++++++++++++--------------
>  4 files changed, 321 insertions(+), 45 deletions(-)
>
> diff --git a/net/slirp.c b/net/slirp.c
> index 8991816bbf..9c48a882ec 100644
> --- a/net/slirp.c
> +++ b/net/slirp.c
> @@ -36,6 +36,7 @@
>  #include "monitor/monitor.h"
>  #include "qemu/error-report.h"
>  #include "qemu/sockets.h"
> +#include "slirp/slirp.h"
>  #include "slirp/libslirp.h"
>  #include "slirp/ip6.h"
>  #include "chardev/char-fe.h"
> @@ -43,6 +44,7 @@
>  #include "qemu/cutils.h"
>  #include "qapi/error.h"
>  #include "qapi/qmp/qdict.h"
> +#include "qapi/qapi-commands-net.h"
>  
>  static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
>  {
> @@ -864,6 +866,30 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str,
>      return -1;
>  }
>  
> +UsernetInfoList *qmp_query_usernet(Error **errp)
> +{
> +    SlirpState *s;
> +    UsernetInfoList *list = NULL;
> +    UsernetInfoList **p = &list;
> +
> +    QTAILQ_FOREACH(s, &slirp_stacks, entry) {
> +        int hub;
> +        UsernetInfoList *il = g_new0(UsernetInfoList, 1);
> +        UsernetInfo *info = il->value = g_new0(UsernetInfo, 1);
> +
> +        info->id = g_strdup(s->nc.name);
> +        if (!net_hub_id_for_client(&s->nc, &hub)) {
> +            info->hub = hub;
> +        } else {
> +            info->hub = -1;
> +        }
> +        usernet_get_info(s->slirp, info);
> +        *p = il;
> +        p = &il->next;
> +    }
> +    return list;
> +}
> +
>  void hmp_info_usernet(Monitor *mon, const QDict *qdict)
>  {
>      SlirpState *s;

       QTAILQ_FOREACH(s, &slirp_stacks, entry) {
           int id;
           bool got_hub_id = net_hub_id_for_client(&s->nc, &id) == 0;
           monitor_printf(mon, "Hub %d (%s):\n",
                          got_hub_id ? id : -1,
                          s->nc.name);
           slirp_connection_info(s->slirp, mon);
       }
   }

Our policy is to have HMP commands wrap themselves around QMP commands,
or at least common helpers.  That way, "QMP can do everything HMP can
do" is trivial.

hmp_info_usernet() uses common helpers net_hub_id_for_client(),
s->nc.name, usernet_get_info(), the latter via slirp_connection_info().
I guess that's okay, although wrapping around qmp_query_usernet() would
be cleaner.

> diff --git a/qapi/net.json b/qapi/net.json
> index fcddce62d6..3cdcda125d 100644
> --- a/qapi/net.json
> +++ b/qapi/net.json
> @@ -723,3 +723,183 @@
>      'time-wait',
>      'none'
>     ] }
> +
> +##
> +# @UsernetTCPConnection:
> +#
> +# SLIRP TCP information.
> +#
> +# @state: tcp connection state
> +#
> +# @hostfwd: whether this connection has host port forwarding
> +#
> +# @fd: the file descriptor of the connection

Why is @fd useful?  Hmm, I guess the argument is "info usernet has
always printed it".  Is it useful there?

> +#
> +# @src-addr: source address of host port forwarding
> +#
> +# @src-port: source port of host port forwarding
> +#
> +# @dest-addr: destination address of host port forwarding
> +#
> +# @dest-port: destination port of host port forwarding
> +#
> +# @recv-buffered: number of bytes queued in the receive buffer
> +#
> +# @send-buffered: number of bytes queued in the send buffer
> +#
> +# Since: 2.13
> +##
> +{ 'struct': 'UsernetTCPConnection',
> +  'data': {
> +    'state': 'UsernetTcpState',
> +    'hostfwd': 'bool',
> +    'fd': 'int',
> +    'src-addr': 'str',
> +    'src-port': 'int',

Shouldn't these two be an InetSocketAddressBase instead?

> +    'dest-addr': 'str',
> +    'dest-port': 'int',

Likewise.

> +    'recv-buffered': 'int',
> +    'send-buffered': 'int'

Make these 'uint32' to match the type of struct sbuf member sb_cc.

> +  } }
> +
> +##
> +# @UsernetUDPConnection:
> +#
> +# SLIRP UDP information.
> +#
> +# @hostfwd: whether this connection has host port forwarding
> +#
> +# @expire-time-ms: time in microseconds after which this connection will expire
> +#
> +# @fd: the file descriptor of the connection
> +#
> +# @src-addr: source address of host port forwarding
> +#
> +# @src-port: source port of host port forwarding
> +#
> +# @dest-addr: destination address of host port forwarding
> +#
> +# @dest-port: destination port of host port forwarding
> +#
> +# @recv-buffered: number of bytes queued in the receive buffer
> +#
> +# @send-buffered: number of bytes queued in the send buffer
> +#
> +# Since: 2.13
> +##
> +{ 'struct': 'UsernetUDPConnection',
> +  'data': {
> +    'hostfwd': 'bool',
> +    'expire-time-ms': 'int',

'uint', to match the type of so->so_expire - curtime.

> +    'fd': 'int',
> +    'src-addr': 'str',
> +    'src-port': 'int',
> +    'dest-addr': 'str',
> +    'dest-port': 'int',
> +    'recv-buffered': 'int',
> +    'send-buffered': 'int'
> +    } }

Remarks on UsernetTCPConnection apply.

> +
> +##
> +# @UsernetICMPConnection:
> +#
> +# SLIRP ICMP information.
> +#
> +# @expire-time-ms: time in microseconds after which this connection will expire
> +#
> +# @fd: the file descriptor of the connection
> +#
> +# @src-addr: source address of host port forwarding
> +#
> +# @dest-addr: destination address of host port forwarding
> +#
> +# @recv-buffered: number of bytes queued in the receive buffer
> +#
> +# @send-buffered: number of bytes queued in the send buffer
> +#
> +# Since: 2.13
> +##
> +{ 'struct': 'UsernetICMPConnection',
> +  'data': {
> +    'expire-time-ms': 'int',
> +    'fd': 'int',
> +    'src-addr': 'str',
> +    'dest-addr': 'str',
> +    'recv-buffered': 'int',
> +    'send-buffered': 'int'
> +    } }

Remarks on UsernetTCPConnection and UsernetUDPConnection apply.

> +
> +##
> +# @UsernetType:
> +#
> +# Available netdev drivers.
> +#
> +# Since: 2.13
> +##
> +{ 'enum': 'UsernetType',
> +  'data': [ 'tcp', 'udp', 'icmp' ] }
> +
> +##
> +# @UsernetConnection:
> +#
> +# SLIRP usernet connection information.
> +#
> +# Since: 2.13
> +##
> +{ 'union': 'UsernetConnection',
> +  'discriminator': 'type',
> +  'base': { 'type': 'UsernetType' },
> +  'data': {
> +    'tcp':     'UsernetTCPConnection',
> +    'udp':     'UsernetUDPConnection',
> +    'icmp':    'UsernetICMPConnection'
> +    } }
> +
> +##
> +# @UsernetInfo:
> +#
> +# SLIRP usernet information.
> +#
> +# Since: 2.13
> +##
> +{ 'struct': 'UsernetInfo',
> +  'data': {
> +    'id':              'str',
> +    'hub':             'int',
> +    'connections':     ['UsernetConnection']
> +} }
> +
> +##
> +# @query-usernet:
> +#
> +# Return SLIRP network information.
> +#
> +# Since: 2.13
> +#
> +# Example:
> +#
> +# -> { "execute": "query-usernet", "arguments": { } }
> +# <- { "return": [
> +#      {
> +#        "hub": -1,
> +#        "connections": [
> +#          {
> +#            "dest-addr": "10.0.2.15",
> +#            "recv-buffered": 0,
> +#            "src-port": 10022,
> +#            "state": "closed",
> +#            "fd": 16,
> +#            "src-addr": "*",
> +#            "send-buffered": 0,
> +#            "dest-port": 22,
> +#            "type": "tcp",
> +#            "hostfwd": true
> +#          }
> +#        ],
> +#        "id": "vnet"
> +#      }
> +#   ]}
> +#
> +##
> +{ 'command': 'query-usernet',
> +  'returns': ['UsernetInfo'] }
> diff --git a/slirp/libslirp.h b/slirp/libslirp.h
> index 540b3e5903..3ba361ea41 100644
> --- a/slirp/libslirp.h
> +++ b/slirp/libslirp.h
> @@ -2,6 +2,7 @@
>  #define LIBSLIRP_H
>  
>  #include "qemu-common.h"
> +#include "qapi/qapi-commands-net.h"

"qapi/qapi-types-net.h"?

>  
>  typedef struct Slirp Slirp;
>  
> @@ -37,6 +38,7 @@ int slirp_add_exec(Slirp *slirp, int do_pty, const void *args,
>                     struct in_addr *guest_addr, int guest_port);
>  
>  void slirp_connection_info(Slirp *slirp, Monitor *mon);
> +void usernet_get_info(Slirp *slirp, UsernetInfo *info);
>  
>  void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr,
>                         int guest_port, const uint8_t *buf, int size);

I'm only skimming the remainder of this patch for now.

> diff --git a/slirp/misc.c b/slirp/misc.c
> index ee617bc3c4..1d310d7d1f 100644
> --- a/slirp/misc.c
> +++ b/slirp/misc.c
> @@ -206,39 +206,28 @@ fork_exec(struct socket *so, const char *ex, int do_pty)
>  }
>  #endif
>  
> -void slirp_connection_info(Slirp *slirp, Monitor *mon)
> +void usernet_get_info(Slirp *slirp, UsernetInfo *info)
>  {
> -    const char * const tcpstates[] = {
> -        [USERNET_TCP_STATE_CLOSED]       = "CLOSED",
> -        [USERNET_TCP_STATE_LISTEN]       = "LISTEN",
> -        [USERNET_TCP_STATE_SYN_SENT]     = "SYN_SENT",
> -        [USERNET_TCP_STATE_SYN_RECEIVED] = "SYN_RCVD",
> -        [USERNET_TCP_STATE_ESTABLISHED]  = "ESTABLISHED",
> -        [USERNET_TCP_STATE_CLOSE_WAIT]   = "CLOSE_WAIT",
> -        [USERNET_TCP_STATE_FIN_WAIT_1]   = "FIN_WAIT_1",
> -        [USERNET_TCP_STATE_CLOSING]      = "CLOSING",
> -        [USERNET_TCP_STATE_LAST_ACK]     = "LAST_ACK",
> -        [USERNET_TCP_STATE_FIN_WAIT_2]   = "FIN_WAIT_2",
> -        [USERNET_TCP_STATE_TIME_WAIT]    = "TIME_WAIT",
> -    };
>      struct in_addr dst_addr;
>      struct sockaddr_in src;
>      socklen_t src_len;
>      uint16_t dst_port;
>      struct socket *so;
> -    const char *state;
> -    char buf[20];
> -
> -    monitor_printf(mon, "  Protocol[State]    FD  Source Address  Port   "
> -                        "Dest. Address  Port RecvQ SendQ\n");
> +    UsernetConnectionList **p_next = &info->connections;
>  
>      for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so->so_next) {
> +        UsernetConnection *conn = g_new0(UsernetConnection, 1);
> +        UsernetTCPConnection *tcp = &conn->u.tcp;
> +        UsernetConnectionList *list = g_new0(UsernetConnectionList, 1);
> +
> +        list->value = conn;
>          if (so->so_state & SS_HOSTFWD) {
> -            state = "HOST_FORWARD";
> +            tcp->hostfwd = true;
> +            tcp->state = so->so_tcpcb->t_state;
>          } else if (so->so_tcpcb) {
> -            state = tcpstates[so->so_tcpcb->t_state];
> +            tcp->state = so->so_tcpcb->t_state;
>          } else {
> -            state = "NONE";
> +            tcp->state = USERNET_TCP_STATE_NONE;
>          }
>          if (so->so_state & (SS_HOSTFWD | SS_INCOMING)) {
>              src_len = sizeof(src);
> @@ -251,46 +240,125 @@ void slirp_connection_info(Slirp *slirp, Monitor *mon)
>              dst_addr = so->so_faddr;
>              dst_port = so->so_fport;
>          }
> -        snprintf(buf, sizeof(buf), "  TCP[%s]", state);
> -        monitor_printf(mon, "%-19s %3d %15s %5d ", buf, so->s,
> -                       src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*",
> -                       ntohs(src.sin_port));
> -        monitor_printf(mon, "%15s %5d %5d %5d\n",
> -                       inet_ntoa(dst_addr), ntohs(dst_port),
> -                       so->so_rcv.sb_cc, so->so_snd.sb_cc);
> +        tcp->fd = so->s;
> +        tcp->src_addr =
> +            g_strdup(src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*");
> +        tcp->src_port = ntohs(src.sin_port);
> +        tcp->dest_addr = g_strdup(inet_ntoa(dst_addr));
> +        tcp->dest_port = ntohs(dst_port);
> +        tcp->recv_buffered = so->so_rcv.sb_cc;
> +        tcp->send_buffered = so->so_snd.sb_cc;
> +        *p_next = list;
> +        p_next = &list->next;
>      }
> -
>      for (so = slirp->udb.so_next; so != &slirp->udb; so = so->so_next) {
> +        UsernetConnection *conn = g_new0(UsernetConnection, 1);
> +        UsernetUDPConnection *udp = &conn->u.udp;
> +        UsernetConnectionList *list = g_new0(UsernetConnectionList, 1);
> +
> +        list->value = conn;
>          if (so->so_state & SS_HOSTFWD) {
> -            snprintf(buf, sizeof(buf), "  UDP[HOST_FORWARD]");
> +            udp->hostfwd = true;
>              src_len = sizeof(src);
>              getsockname(so->s, (struct sockaddr *)&src, &src_len);
>              dst_addr = so->so_laddr;
>              dst_port = so->so_lport;
>          } else {
> -            snprintf(buf, sizeof(buf), "  UDP[%d sec]",
> -                         (so->so_expire - curtime) / 1000);
> +            udp->expire_time_ms = so->so_expire - curtime;
>              src.sin_addr = so->so_laddr;
>              src.sin_port = so->so_lport;
>              dst_addr = so->so_faddr;
>              dst_port = so->so_fport;
>          }

@expire_time_ms appears to be left at zero when @hostfwd is true.
Should it be optional?

> -        monitor_printf(mon, "%-19s %3d %15s %5d ", buf, so->s,
> -                       src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*",
> -                       ntohs(src.sin_port));
> -        monitor_printf(mon, "%15s %5d %5d %5d\n",
> -                       inet_ntoa(dst_addr), ntohs(dst_port),
> -                       so->so_rcv.sb_cc, so->so_snd.sb_cc);
> +        udp->fd = so->s;
> +        udp->src_addr =
> +            g_strdup(src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*");
> +        udp->src_port = ntohs(src.sin_port);
> +        udp->dest_addr = g_strdup(inet_ntoa(dst_addr));
> +        udp->dest_port = ntohs(dst_port);
> +        udp->recv_buffered = so->so_rcv.sb_cc;
> +        udp->send_buffered = so->so_snd.sb_cc;
> +        *p_next = list;
> +        p_next = &list->next;
>      }
>  
>      for (so = slirp->icmp.so_next; so != &slirp->icmp; so = so->so_next) {
> -        snprintf(buf, sizeof(buf), "  ICMP[%d sec]",
> -                     (so->so_expire - curtime) / 1000);
> +        UsernetConnection *conn = g_new0(UsernetConnection, 1);
> +        UsernetICMPConnection *icmp = &conn->u.icmp;
> +        UsernetConnectionList *list = g_new0(UsernetConnectionList, 1);
> +
> +        icmp->expire_time_ms = so->so_expire - curtime;
>          src.sin_addr = so->so_laddr;
>          dst_addr = so->so_faddr;
> -        monitor_printf(mon, "%-19s %3d %15s  -    ", buf, so->s,
> -                       src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*");
> -        monitor_printf(mon, "%15s  -    %5d %5d\n", inet_ntoa(dst_addr),
> -                       so->so_rcv.sb_cc, so->so_snd.sb_cc);
> +        icmp->fd = so->s;
> +        icmp->src_addr =
> +            g_strdup(src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*");
> +        icmp->dest_addr = g_strdup(inet_ntoa(dst_addr));
> +        icmp->recv_buffered = so->so_rcv.sb_cc;
> +        icmp->send_buffered = so->so_snd.sb_cc;
> +        *p_next = list;
> +        p_next = &list->next;
>      }
>  }
> +
> +
> +void slirp_connection_info(Slirp *slirp, Monitor *mon)
> +{
> +    const char *state;
> +    char buf[64];
> +    UsernetInfo *info = g_new0(UsernetInfo, 1);
> +    UsernetConnectionList *cl;
> +
> +    monitor_printf(mon, "  Protocol[State]    FD  Source Address  Port   "
> +                        "Dest. Address  Port RecvQ SendQ\n");
> +
> +    usernet_get_info(slirp, info);
> +    for (cl = info->connections; cl && cl->value; cl = cl->next) {
> +        UsernetConnection *conn = cl->value;
> +
> +        if (conn->type == USERNET_TYPE_TCP) {
> +            UsernetTCPConnection *tcp = &conn->u.tcp;
> +
> +            if (tcp->hostfwd) {
> +                state = "HOST_FORWARD";
> +            } else {
> +                state = UsernetTcpState_str(tcp->state);
> +            }
> +            snprintf(buf, sizeof(buf), "  TCP[%s]", state);
> +            monitor_printf(mon, "%-19s %3" PRId64 " %15s %5" PRId64 " ",
> +                           buf, tcp->fd,
> +                           tcp->src_addr, tcp->src_port);
> +            monitor_printf(mon, "%15s %5" PRId64 " %5" PRId64 " %5" PRId64 "\n",
> +                           tcp->dest_addr, tcp->dest_port,
> +                           tcp->recv_buffered, tcp->send_buffered);
> +        } else if (conn->type == USERNET_TYPE_UDP) {
> +            UsernetUDPConnection *udp = &conn->u.udp;
> +
> +            if (udp->hostfwd) {
> +                snprintf(buf, sizeof(buf), "  UDP[HOST_FORWARD]");
> +            } else {
> +                snprintf(buf, sizeof(buf), "  UDP[%" PRId64 " sec]",
> +                         udp->expire_time_ms / 1000);
> +            }
> +            monitor_printf(mon, "%-19s %3" PRId64 " %15s %5" PRId64 " ",
> +                           buf, udp->fd,
> +                           udp->src_addr, udp->src_port);
> +            monitor_printf(mon, "%15s %5" PRId64 " %5" PRId64 " %5" PRId64 "\n",
> +                           udp->dest_addr, udp->dest_port,
> +                           udp->recv_buffered, udp->send_buffered);
> +        } else {
> +            UsernetICMPConnection *icmp = &conn->u.icmp;
> +
> +            assert(conn->type == USERNET_TYPE_ICMP);
> +            snprintf(buf, sizeof(buf), "  ICMP[%" PRId64 " sec]",
> +                     icmp->expire_time_ms / 1000);
> +            monitor_printf(mon, "%-19s %3" PRId64 " %15s  -    ", buf, icmp->fd,
> +                           icmp->src_addr);
> +            monitor_printf(mon, "%15s  -    %5" PRId64 " %5" PRId64 "\n",
> +                           icmp->dest_addr,
> +                           icmp->recv_buffered, icmp->send_buffered);
> +        }
> +    }
> +
> +    qapi_free_UsernetInfo(info);
> +}

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

end of thread, other threads:[~2018-05-16  8:07 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-04  7:42 [Qemu-devel] [PATCH v6 0/4] slirp: Add query-usernet QMP command Fam Zheng
2018-05-04  7:42 ` [Qemu-devel] [PATCH v6 1/4] qapi: Introduce UsernetTcpState Fam Zheng
2018-05-04  7:42 ` [Qemu-devel] [PATCH v6 2/4] slirp: Use QAPI enum to replace TCPS_* macros Fam Zheng
2018-05-16  6:59   ` Markus Armbruster
2018-05-04  7:42 ` [Qemu-devel] [PATCH v6 3/4] slirp: Add "query-usernet" QMP command Fam Zheng
2018-05-16  8:07   ` Markus Armbruster
2018-05-04  7:42 ` [Qemu-devel] [PATCH v6 4/4] tests: Use query-usernet instead of 'info usernet' Fam Zheng
2018-05-04  7:49 ` [Qemu-devel] [PATCH v6 0/4] slirp: Add query-usernet QMP command no-reply
2018-05-08  0:45   ` Fam Zheng
2018-05-16  2:30 ` Fam Zheng

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