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
Block a user