Commit 6dbe553fe9ffdee008c1bbbe1af2d030e0f04aab

Authored by Jan Kiszka
Committed by Anthony Liguori
1 parent 4a82347a

slirp: Add info usernet for dumping connection states

Break out sockstats from the slirp statistics and present them under the
new info category "usernet". This patch also improves the current output
/wrt proper reporting connection source and destination.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
monitor.c
@@ -1735,6 +1735,8 @@ static const mon_cmd_t info_cmds[] = { @@ -1735,6 +1735,8 @@ static const mon_cmd_t info_cmds[] = {
1735 #if defined(CONFIG_SLIRP) 1735 #if defined(CONFIG_SLIRP)
1736 { "slirp", "", do_info_slirp, 1736 { "slirp", "", do_info_slirp,
1737 "", "show SLIRP statistics", }, 1737 "", "show SLIRP statistics", },
  1738 + { "usernet", "", do_info_usernet,
  1739 + "", "show user network stack connection states", },
1738 #endif 1740 #endif
1739 { "migrate", "", do_info_migrate, "", "show migration status" }, 1741 { "migrate", "", do_info_migrate, "", "show migration status" },
1740 { "balloon", "", do_info_balloon, 1742 { "balloon", "", do_info_balloon,
@@ -1198,6 +1198,12 @@ static void slirp_guestfwd(Monitor *mon, const char *config_str, @@ -1198,6 +1198,12 @@ static void slirp_guestfwd(Monitor *mon, const char *config_str,
1198 config_error(mon, "invalid guest forwarding rule '%s'\n", config_str); 1198 config_error(mon, "invalid guest forwarding rule '%s'\n", config_str);
1199 } 1199 }
1200 1200
  1201 +void do_info_usernet(Monitor *mon)
  1202 +{
  1203 + monitor_printf(mon, "VLAN %d (%s):\n", slirp_vc->vlan->id, slirp_vc->name);
  1204 + slirp_connection_info(mon);
  1205 +}
  1206 +
1201 #endif /* CONFIG_SLIRP */ 1207 #endif /* CONFIG_SLIRP */
1202 1208
1203 #if !defined(_WIN32) 1209 #if !defined(_WIN32)
@@ -81,6 +81,8 @@ void qemu_handler_true(void *opaque); @@ -81,6 +81,8 @@ void qemu_handler_true(void *opaque);
81 void do_info_network(Monitor *mon); 81 void do_info_network(Monitor *mon);
82 int do_set_link(Monitor *mon, const char *name, const char *up_or_down); 82 int do_set_link(Monitor *mon, const char *name, const char *up_or_down);
83 83
  84 +void do_info_usernet(Monitor *mon);
  85 +
84 /* NIC info */ 86 /* NIC info */
85 87
86 #define MAX_NICS 8 88 #define MAX_NICS 8
qemu-monitor.hx
@@ -87,6 +87,8 @@ show the current VM UUID @@ -87,6 +87,8 @@ show the current VM UUID
87 show CPU statistics 87 show CPU statistics
88 @item info slirp 88 @item info slirp
89 show SLIRP statistics (if available) 89 show SLIRP statistics (if available)
  90 +@item info usernet
  91 +show user network stack connection states
90 @item info migrate 92 @item info migrate
91 show migration status 93 show migration status
92 @item info balloon 94 @item info balloon
slirp/debug.c
@@ -291,47 +291,6 @@ mbufstats(void) @@ -291,47 +291,6 @@ mbufstats(void)
291 lprint(" %6d mbufs on used list\r\n", i); 291 lprint(" %6d mbufs on used list\r\n", i);
292 lprint(" %6d mbufs queued as packets\r\n\r\n", if_queued); 292 lprint(" %6d mbufs queued as packets\r\n\r\n", if_queued);
293 } 293 }
294 -  
295 -static void  
296 -sockstats(void)  
297 -{  
298 - char buff[256];  
299 - int n;  
300 - struct socket *so;  
301 -  
302 - lprint(" \r\n");  
303 -  
304 - lprint(  
305 - "Proto[state] Sock Local Address, Port Remote Address, Port RecvQ SendQ\r\n");  
306 -  
307 - for (so = tcb.so_next; so != &tcb; so = so->so_next) {  
308 -  
309 - n = sprintf(buff, "tcp[%s]", so->so_tcpcb?tcpstates[so->so_tcpcb->t_state]:"NONE");  
310 - while (n < 17)  
311 - buff[n++] = ' ';  
312 - buff[17] = 0;  
313 - lprint("%s %3d %15s %5d ",  
314 - buff, so->s,  
315 - inet_ntoa(so->so_laddr), ntohs(so->so_lport));  
316 - lprint("%15s %5d %5d %5d\r\n",  
317 - inet_ntoa(so->so_faddr), ntohs(so->so_fport),  
318 - so->so_rcv.sb_cc, so->so_snd.sb_cc);  
319 - }  
320 -  
321 - for (so = udb.so_next; so != &udb; so = so->so_next) {  
322 -  
323 - n = sprintf(buff, "udp[%d sec]", (so->so_expire - curtime) / 1000);  
324 - while (n < 17)  
325 - buff[n++] = ' ';  
326 - buff[17] = 0;  
327 - lprint("%s %3d %15s %5d ",  
328 - buff, so->s,  
329 - inet_ntoa(so->so_laddr), ntohs(so->so_lport));  
330 - lprint("%15s %5d %5d %5d\r\n",  
331 - inet_ntoa(so->so_faddr), ntohs(so->so_fport),  
332 - so->so_rcv.sb_cc, so->so_snd.sb_cc);  
333 - }  
334 -}  
335 #endif 294 #endif
336 295
337 #ifndef CONFIG_QEMU 296 #ifndef CONFIG_QEMU
@@ -386,7 +345,6 @@ slirp_stats(void) @@ -386,7 +345,6 @@ slirp_stats(void)
386 udpstats(); 345 udpstats();
387 icmpstats(); 346 icmpstats();
388 mbufstats(); 347 mbufstats();
389 - sockstats();  
390 #else 348 #else
391 lprint("SLIRP statistics code not compiled.\n"); 349 lprint("SLIRP statistics code not compiled.\n");
392 #endif 350 #endif
slirp/libslirp.h
@@ -5,6 +5,8 @@ @@ -5,6 +5,8 @@
5 extern "C" { 5 extern "C" {
6 #endif 6 #endif
7 7
  8 +#include <qemu-common.h>
  9 +
8 void slirp_init(int restricted, struct in_addr vnetwork, 10 void slirp_init(int restricted, struct in_addr vnetwork,
9 struct in_addr vnetmask, struct in_addr vhost, 11 struct in_addr vnetmask, struct in_addr vhost,
10 const char *vhostname, const char *tftp_path, 12 const char *vhostname, const char *tftp_path,
@@ -29,6 +31,8 @@ int slirp_add_exec(int do_pty, const void *args, struct in_addr guest_addr, @@ -29,6 +31,8 @@ int slirp_add_exec(int do_pty, const void *args, struct in_addr guest_addr,
29 int guest_port); 31 int guest_port);
30 32
31 void slirp_stats(void); 33 void slirp_stats(void);
  34 +void slirp_connection_info(Monitor *mon);
  35 +
32 void slirp_socket_recv(struct in_addr guest_addr, int guest_port, 36 void slirp_socket_recv(struct in_addr guest_addr, int guest_port,
33 const uint8_t *buf, int size); 37 const uint8_t *buf, int size);
34 size_t slirp_socket_can_recv(struct in_addr guest_addr, int guest_port); 38 size_t slirp_socket_can_recv(struct in_addr guest_addr, int guest_port);
slirp/misc.c
@@ -6,6 +6,9 @@ @@ -6,6 +6,9 @@
6 */ 6 */
7 7
8 #include <slirp.h> 8 #include <slirp.h>
  9 +#include <libslirp.h>
  10 +
  11 +#include "monitor.h"
9 12
10 u_int curtime, time_fasttimo, last_slowtimo; 13 u_int curtime, time_fasttimo, last_slowtimo;
11 14
@@ -906,3 +909,86 @@ rsh_exec(so,ns, user, host, args) @@ -906,3 +909,86 @@ rsh_exec(so,ns, user, host, args)
906 } 909 }
907 } 910 }
908 #endif 911 #endif
  912 +
  913 +void slirp_connection_info(Monitor *mon)
  914 +{
  915 + const char * const tcpstates[] = {
  916 + [TCPS_CLOSED] = "CLOSED",
  917 + [TCPS_LISTEN] = "LISTEN",
  918 + [TCPS_SYN_SENT] = "SYN_SENT",
  919 + [TCPS_SYN_RECEIVED] = "SYN_RCVD",
  920 + [TCPS_ESTABLISHED] = "ESTABLISHED",
  921 + [TCPS_CLOSE_WAIT] = "CLOSE_WAIT",
  922 + [TCPS_FIN_WAIT_1] = "FIN_WAIT_1",
  923 + [TCPS_CLOSING] = "CLOSING",
  924 + [TCPS_LAST_ACK] = "LAST_ACK",
  925 + [TCPS_FIN_WAIT_2] = "FIN_WAIT_2",
  926 + [TCPS_TIME_WAIT] = "TIME_WAIT",
  927 + };
  928 + struct in_addr dst_addr;
  929 + struct sockaddr_in src;
  930 + socklen_t src_len;
  931 + uint16_t dst_port;
  932 + struct socket *so;
  933 + const char *state;
  934 + char buf[20];
  935 + int n;
  936 +
  937 + monitor_printf(mon, " Protocol[State] FD Source Address Port "
  938 + "Dest. Address Port RecvQ SendQ\n");
  939 +
  940 + for (so = tcb.so_next; so != &tcb; so = so->so_next) {
  941 + if (so->so_state & SS_HOSTFWD) {
  942 + state = "HOST_FORWARD";
  943 + } else if (so->so_tcpcb) {
  944 + state = tcpstates[so->so_tcpcb->t_state];
  945 + } else {
  946 + state = "NONE";
  947 + }
  948 + if (so->so_state & (SS_HOSTFWD | SS_INCOMING)) {
  949 + src_len = sizeof(src);
  950 + getsockname(so->s, (struct sockaddr *)&src, &src_len);
  951 + dst_addr = so->so_laddr;
  952 + dst_port = so->so_lport;
  953 + } else {
  954 + src.sin_addr = so->so_laddr;
  955 + src.sin_port = so->so_lport;
  956 + dst_addr = so->so_faddr;
  957 + dst_port = so->so_fport;
  958 + }
  959 + n = snprintf(buf, sizeof(buf), " TCP[%s]", state);
  960 + memset(&buf[n], ' ', 19 - n);
  961 + buf[19] = 0;
  962 + monitor_printf(mon, "%s %3d %15s %5d ", buf, so->s,
  963 + src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*",
  964 + ntohs(src.sin_port));
  965 + monitor_printf(mon, "%15s %5d %5d %5d\n",
  966 + inet_ntoa(dst_addr), ntohs(dst_port),
  967 + so->so_rcv.sb_cc, so->so_snd.sb_cc);
  968 + }
  969 +
  970 + for (so = udb.so_next; so != &udb; so = so->so_next) {
  971 + if (so->so_state & SS_HOSTFWD) {
  972 + n = snprintf(buf, sizeof(buf), " UDP[HOST_FORWARD]");
  973 + src_len = sizeof(src);
  974 + getsockname(so->s, (struct sockaddr *)&src, &src_len);
  975 + dst_addr = so->so_laddr;
  976 + dst_port = so->so_lport;
  977 + } else {
  978 + n = snprintf(buf, sizeof(buf), " UDP[%d sec]",
  979 + (so->so_expire - curtime) / 1000);
  980 + src.sin_addr = so->so_laddr;
  981 + src.sin_port = so->so_lport;
  982 + dst_addr = so->so_faddr;
  983 + dst_port = so->so_fport;
  984 + }
  985 + memset(&buf[n], ' ', 19 - n);
  986 + buf[19] = 0;
  987 + monitor_printf(mon, "%s %3d %15s %5d ", buf, so->s,
  988 + src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*",
  989 + ntohs(src.sin_port));
  990 + monitor_printf(mon, "%15s %5d %5d %5d\n",
  991 + inet_ntoa(dst_addr), ntohs(dst_port),
  992 + so->so_rcv.sb_cc, so->so_snd.sb_cc);
  993 + }
  994 +}
slirp/tcp.h
@@ -166,6 +166,4 @@ struct tcphdr { @@ -166,6 +166,4 @@ struct tcphdr {
166 166
167 extern tcp_seq tcp_iss; /* tcp initial send seq # */ 167 extern tcp_seq tcp_iss; /* tcp initial send seq # */
168 168
169 -extern const char * const tcpstates[];  
170 -  
171 #endif 169 #endif
slirp/tcp_output.c
@@ -40,17 +40,6 @@ @@ -40,17 +40,6 @@
40 40
41 #include <slirp.h> 41 #include <slirp.h>
42 42
43 -/*  
44 - * Since this is only used in "stats socket", we give meaning  
45 - * names instead of the REAL names  
46 - */  
47 -const char * const tcpstates[] = {  
48 -/* "CLOSED", "LISTEN", "SYN_SENT", "SYN_RCVD", */  
49 - "REDIRECT", "LISTEN", "SYN_SENT", "SYN_RCVD",  
50 - "ESTABLISHED", "CLOSE_WAIT", "FIN_WAIT_1", "CLOSING",  
51 - "LAST_ACK", "FIN_WAIT_2", "TIME_WAIT",  
52 -};  
53 -  
54 static const u_char tcp_outflags[TCP_NSTATES] = { 43 static const u_char tcp_outflags[TCP_NSTATES] = {
55 TH_RST|TH_ACK, 0, TH_SYN, TH_SYN|TH_ACK, 44 TH_RST|TH_ACK, 0, TH_SYN, TH_SYN|TH_ACK,
56 TH_ACK, TH_ACK, TH_FIN|TH_ACK, TH_FIN|TH_ACK, 45 TH_ACK, TH_ACK, TH_FIN|TH_ACK, TH_FIN|TH_ACK,