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>
This commit is contained in:
		
							parent
							
								
									4a82347a47
								
							
						
					
					
						commit
						6dbe553fe9
					
				| 
						 | 
					@ -1735,6 +1735,8 @@ static const mon_cmd_t info_cmds[] = {
 | 
				
			||||||
#if defined(CONFIG_SLIRP)
 | 
					#if defined(CONFIG_SLIRP)
 | 
				
			||||||
    { "slirp", "", do_info_slirp,
 | 
					    { "slirp", "", do_info_slirp,
 | 
				
			||||||
      "", "show SLIRP statistics", },
 | 
					      "", "show SLIRP statistics", },
 | 
				
			||||||
 | 
					    { "usernet", "", do_info_usernet,
 | 
				
			||||||
 | 
					      "", "show user network stack connection states", },
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    { "migrate", "", do_info_migrate, "", "show migration status" },
 | 
					    { "migrate", "", do_info_migrate, "", "show migration status" },
 | 
				
			||||||
    { "balloon", "", do_info_balloon,
 | 
					    { "balloon", "", do_info_balloon,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										6
									
								
								net.c
								
								
								
								
							
							
						
						
									
										6
									
								
								net.c
								
								
								
								
							| 
						 | 
					@ -1198,6 +1198,12 @@ static void slirp_guestfwd(Monitor *mon, const char *config_str,
 | 
				
			||||||
    config_error(mon, "invalid guest forwarding rule '%s'\n", config_str);
 | 
					    config_error(mon, "invalid guest forwarding rule '%s'\n", config_str);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void do_info_usernet(Monitor *mon)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    monitor_printf(mon, "VLAN %d (%s):\n", slirp_vc->vlan->id, slirp_vc->name);
 | 
				
			||||||
 | 
					    slirp_connection_info(mon);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* CONFIG_SLIRP */
 | 
					#endif /* CONFIG_SLIRP */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if !defined(_WIN32)
 | 
					#if !defined(_WIN32)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								net.h
								
								
								
								
							
							
						
						
									
										2
									
								
								net.h
								
								
								
								
							| 
						 | 
					@ -81,6 +81,8 @@ void qemu_handler_true(void *opaque);
 | 
				
			||||||
void do_info_network(Monitor *mon);
 | 
					void do_info_network(Monitor *mon);
 | 
				
			||||||
int do_set_link(Monitor *mon, const char *name, const char *up_or_down);
 | 
					int do_set_link(Monitor *mon, const char *name, const char *up_or_down);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void do_info_usernet(Monitor *mon);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* NIC info */
 | 
					/* NIC info */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MAX_NICS 8
 | 
					#define MAX_NICS 8
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -87,6 +87,8 @@ show the current VM UUID
 | 
				
			||||||
show CPU statistics
 | 
					show CPU statistics
 | 
				
			||||||
@item info slirp
 | 
					@item info slirp
 | 
				
			||||||
show SLIRP statistics (if available)
 | 
					show SLIRP statistics (if available)
 | 
				
			||||||
 | 
					@item info usernet
 | 
				
			||||||
 | 
					show user network stack connection states
 | 
				
			||||||
@item info migrate
 | 
					@item info migrate
 | 
				
			||||||
show migration status
 | 
					show migration status
 | 
				
			||||||
@item info balloon
 | 
					@item info balloon
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -291,47 +291,6 @@ mbufstats(void)
 | 
				
			||||||
	lprint("  %6d mbufs on used list\r\n",  i);
 | 
						lprint("  %6d mbufs on used list\r\n",  i);
 | 
				
			||||||
        lprint("  %6d mbufs queued as packets\r\n\r\n", if_queued);
 | 
					        lprint("  %6d mbufs queued as packets\r\n\r\n", if_queued);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
sockstats(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	char buff[256];
 | 
					 | 
				
			||||||
	int n;
 | 
					 | 
				
			||||||
	struct socket *so;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        lprint(" \r\n");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	lprint(
 | 
					 | 
				
			||||||
	   "Proto[state]     Sock     Local Address, Port  Remote Address, Port RecvQ SendQ\r\n");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for (so = tcb.so_next; so != &tcb; so = so->so_next) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		n = sprintf(buff, "tcp[%s]", so->so_tcpcb?tcpstates[so->so_tcpcb->t_state]:"NONE");
 | 
					 | 
				
			||||||
		while (n < 17)
 | 
					 | 
				
			||||||
		   buff[n++] = ' ';
 | 
					 | 
				
			||||||
		buff[17] = 0;
 | 
					 | 
				
			||||||
		lprint("%s %3d   %15s %5d ",
 | 
					 | 
				
			||||||
				buff, so->s,
 | 
					 | 
				
			||||||
				inet_ntoa(so->so_laddr), ntohs(so->so_lport));
 | 
					 | 
				
			||||||
		lprint("%15s %5d %5d %5d\r\n",
 | 
					 | 
				
			||||||
				inet_ntoa(so->so_faddr), ntohs(so->so_fport),
 | 
					 | 
				
			||||||
				so->so_rcv.sb_cc, so->so_snd.sb_cc);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for (so = udb.so_next; so != &udb; so = so->so_next) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		n = sprintf(buff, "udp[%d sec]", (so->so_expire - curtime) / 1000);
 | 
					 | 
				
			||||||
		while (n < 17)
 | 
					 | 
				
			||||||
		   buff[n++] = ' ';
 | 
					 | 
				
			||||||
		buff[17] = 0;
 | 
					 | 
				
			||||||
		lprint("%s %3d  %15s %5d  ",
 | 
					 | 
				
			||||||
				buff, so->s,
 | 
					 | 
				
			||||||
				inet_ntoa(so->so_laddr), ntohs(so->so_lport));
 | 
					 | 
				
			||||||
		lprint("%15s %5d %5d %5d\r\n",
 | 
					 | 
				
			||||||
				inet_ntoa(so->so_faddr), ntohs(so->so_fport),
 | 
					 | 
				
			||||||
				so->so_rcv.sb_cc, so->so_snd.sb_cc);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef CONFIG_QEMU
 | 
					#ifndef CONFIG_QEMU
 | 
				
			||||||
| 
						 | 
					@ -386,7 +345,6 @@ slirp_stats(void)
 | 
				
			||||||
    udpstats();
 | 
					    udpstats();
 | 
				
			||||||
    icmpstats();
 | 
					    icmpstats();
 | 
				
			||||||
    mbufstats();
 | 
					    mbufstats();
 | 
				
			||||||
    sockstats();
 | 
					 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
    lprint("SLIRP statistics code not compiled.\n");
 | 
					    lprint("SLIRP statistics code not compiled.\n");
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,6 +5,8 @@
 | 
				
			||||||
extern "C" {
 | 
					extern "C" {
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <qemu-common.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void slirp_init(int restricted, struct in_addr vnetwork,
 | 
					void slirp_init(int restricted, struct in_addr vnetwork,
 | 
				
			||||||
                struct in_addr vnetmask, struct in_addr vhost,
 | 
					                struct in_addr vnetmask, struct in_addr vhost,
 | 
				
			||||||
                const char *vhostname, const char *tftp_path,
 | 
					                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,
 | 
				
			||||||
                   int guest_port);
 | 
					                   int guest_port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void slirp_stats(void);
 | 
					void slirp_stats(void);
 | 
				
			||||||
 | 
					void slirp_connection_info(Monitor *mon);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void slirp_socket_recv(struct in_addr guest_addr, int guest_port,
 | 
					void slirp_socket_recv(struct in_addr guest_addr, int guest_port,
 | 
				
			||||||
                       const uint8_t *buf, int size);
 | 
					                       const uint8_t *buf, int size);
 | 
				
			||||||
size_t slirp_socket_can_recv(struct in_addr guest_addr, int guest_port);
 | 
					size_t slirp_socket_can_recv(struct in_addr guest_addr, int guest_port);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										86
									
								
								slirp/misc.c
								
								
								
								
							
							
						
						
									
										86
									
								
								slirp/misc.c
								
								
								
								
							| 
						 | 
					@ -6,6 +6,9 @@
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <slirp.h>
 | 
					#include <slirp.h>
 | 
				
			||||||
 | 
					#include <libslirp.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "monitor.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
u_int curtime, time_fasttimo, last_slowtimo;
 | 
					u_int curtime, time_fasttimo, last_slowtimo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -906,3 +909,86 @@ rsh_exec(so,ns, user, host, args)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void slirp_connection_info(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",
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    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];
 | 
				
			||||||
 | 
					    int n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    monitor_printf(mon, "  Protocol[State]    FD  Source Address  Port   "
 | 
				
			||||||
 | 
					                        "Dest. Address  Port RecvQ SendQ\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (so = tcb.so_next; so != &tcb; so = so->so_next) {
 | 
				
			||||||
 | 
					        if (so->so_state & SS_HOSTFWD) {
 | 
				
			||||||
 | 
					            state = "HOST_FORWARD";
 | 
				
			||||||
 | 
					        } else if (so->so_tcpcb) {
 | 
				
			||||||
 | 
					            state = tcpstates[so->so_tcpcb->t_state];
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            state = "NONE";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (so->so_state & (SS_HOSTFWD | SS_INCOMING)) {
 | 
				
			||||||
 | 
					            src_len = sizeof(src);
 | 
				
			||||||
 | 
					            getsockname(so->s, (struct sockaddr *)&src, &src_len);
 | 
				
			||||||
 | 
					            dst_addr = so->so_laddr;
 | 
				
			||||||
 | 
					            dst_port = so->so_lport;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            src.sin_addr = so->so_laddr;
 | 
				
			||||||
 | 
					            src.sin_port = so->so_lport;
 | 
				
			||||||
 | 
					            dst_addr = so->so_faddr;
 | 
				
			||||||
 | 
					            dst_port = so->so_fport;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        n = snprintf(buf, sizeof(buf), "  TCP[%s]", state);
 | 
				
			||||||
 | 
					        memset(&buf[n], ' ', 19 - n);
 | 
				
			||||||
 | 
					        buf[19] = 0;
 | 
				
			||||||
 | 
					        monitor_printf(mon, "%s %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);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (so = udb.so_next; so != &udb; so = so->so_next) {
 | 
				
			||||||
 | 
					        if (so->so_state & SS_HOSTFWD) {
 | 
				
			||||||
 | 
					            n = snprintf(buf, sizeof(buf), "  UDP[HOST_FORWARD]");
 | 
				
			||||||
 | 
					            src_len = sizeof(src);
 | 
				
			||||||
 | 
					            getsockname(so->s, (struct sockaddr *)&src, &src_len);
 | 
				
			||||||
 | 
					            dst_addr = so->so_laddr;
 | 
				
			||||||
 | 
					            dst_port = so->so_lport;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            n = snprintf(buf, sizeof(buf), "  UDP[%d sec]",
 | 
				
			||||||
 | 
					                         (so->so_expire - curtime) / 1000);
 | 
				
			||||||
 | 
					            src.sin_addr = so->so_laddr;
 | 
				
			||||||
 | 
					            src.sin_port = so->so_lport;
 | 
				
			||||||
 | 
					            dst_addr = so->so_faddr;
 | 
				
			||||||
 | 
					            dst_port = so->so_fport;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        memset(&buf[n], ' ', 19 - n);
 | 
				
			||||||
 | 
					        buf[19] = 0;
 | 
				
			||||||
 | 
					        monitor_printf(mon, "%s %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);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -166,6 +166,4 @@ struct tcphdr {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern tcp_seq tcp_iss;                /* tcp initial send seq # */
 | 
					extern tcp_seq tcp_iss;                /* tcp initial send seq # */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern const char * const tcpstates[];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,17 +40,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <slirp.h>
 | 
					#include <slirp.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Since this is only used in "stats socket", we give meaning
 | 
					 | 
				
			||||||
 * names instead of the REAL names
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
const char * const tcpstates[] = {
 | 
					 | 
				
			||||||
/*	"CLOSED",       "LISTEN",       "SYN_SENT",     "SYN_RCVD", */
 | 
					 | 
				
			||||||
	"REDIRECT",	"LISTEN",	"SYN_SENT",     "SYN_RCVD",
 | 
					 | 
				
			||||||
	"ESTABLISHED",  "CLOSE_WAIT",   "FIN_WAIT_1",   "CLOSING",
 | 
					 | 
				
			||||||
	"LAST_ACK",     "FIN_WAIT_2",   "TIME_WAIT",
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const u_char  tcp_outflags[TCP_NSTATES] = {
 | 
					static const u_char  tcp_outflags[TCP_NSTATES] = {
 | 
				
			||||||
	TH_RST|TH_ACK, 0,      TH_SYN,        TH_SYN|TH_ACK,
 | 
						TH_RST|TH_ACK, 0,      TH_SYN,        TH_SYN|TH_ACK,
 | 
				
			||||||
	TH_ACK,        TH_ACK, TH_FIN|TH_ACK, TH_FIN|TH_ACK,
 | 
						TH_ACK,        TH_ACK, TH_FIN|TH_ACK, TH_FIN|TH_ACK,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue