Commit 6dbe553fe9ffdee008c1bbbe1af2d030e0f04aab
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>
Showing
9 changed files
with
102 additions
and
55 deletions
monitor.c
| ... | ... | @@ -1735,6 +1735,8 @@ static const mon_cmd_t info_cmds[] = { |
| 1735 | 1735 | #if defined(CONFIG_SLIRP) |
| 1736 | 1736 | { "slirp", "", do_info_slirp, |
| 1737 | 1737 | "", "show SLIRP statistics", }, |
| 1738 | + { "usernet", "", do_info_usernet, | |
| 1739 | + "", "show user network stack connection states", }, | |
| 1738 | 1740 | #endif |
| 1739 | 1741 | { "migrate", "", do_info_migrate, "", "show migration status" }, |
| 1740 | 1742 | { "balloon", "", do_info_balloon, | ... | ... |
net.c
| ... | ... | @@ -1198,6 +1198,12 @@ static void slirp_guestfwd(Monitor *mon, const char *config_str, |
| 1198 | 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 | 1207 | #endif /* CONFIG_SLIRP */ |
| 1202 | 1208 | |
| 1203 | 1209 | #if !defined(_WIN32) | ... | ... |
net.h
qemu-monitor.hx
slirp/debug.c
| ... | ... | @@ -291,47 +291,6 @@ mbufstats(void) |
| 291 | 291 | lprint(" %6d mbufs on used list\r\n", i); |
| 292 | 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 | 294 | #endif |
| 336 | 295 | |
| 337 | 296 | #ifndef CONFIG_QEMU |
| ... | ... | @@ -386,7 +345,6 @@ slirp_stats(void) |
| 386 | 345 | udpstats(); |
| 387 | 346 | icmpstats(); |
| 388 | 347 | mbufstats(); |
| 389 | - sockstats(); | |
| 390 | 348 | #else |
| 391 | 349 | lprint("SLIRP statistics code not compiled.\n"); |
| 392 | 350 | #endif | ... | ... |
slirp/libslirp.h
| ... | ... | @@ -5,6 +5,8 @@ |
| 5 | 5 | extern "C" { |
| 6 | 6 | #endif |
| 7 | 7 | |
| 8 | +#include <qemu-common.h> | |
| 9 | + | |
| 8 | 10 | void slirp_init(int restricted, struct in_addr vnetwork, |
| 9 | 11 | struct in_addr vnetmask, struct in_addr vhost, |
| 10 | 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 | 31 | int guest_port); |
| 30 | 32 | |
| 31 | 33 | void slirp_stats(void); |
| 34 | +void slirp_connection_info(Monitor *mon); | |
| 35 | + | |
| 32 | 36 | void slirp_socket_recv(struct in_addr guest_addr, int guest_port, |
| 33 | 37 | const uint8_t *buf, int size); |
| 34 | 38 | size_t slirp_socket_can_recv(struct in_addr guest_addr, int guest_port); | ... | ... |
slirp/misc.c
| ... | ... | @@ -6,6 +6,9 @@ |
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | 8 | #include <slirp.h> |
| 9 | +#include <libslirp.h> | |
| 10 | + | |
| 11 | +#include "monitor.h" | |
| 9 | 12 | |
| 10 | 13 | u_int curtime, time_fasttimo, last_slowtimo; |
| 11 | 14 | |
| ... | ... | @@ -906,3 +909,86 @@ rsh_exec(so,ns, user, host, args) |
| 906 | 909 | } |
| 907 | 910 | } |
| 908 | 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
slirp/tcp_output.c
| ... | ... | @@ -40,17 +40,6 @@ |
| 40 | 40 | |
| 41 | 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 | 43 | static const u_char tcp_outflags[TCP_NSTATES] = { |
| 55 | 44 | TH_RST|TH_ACK, 0, TH_SYN, TH_SYN|TH_ACK, |
| 56 | 45 | TH_ACK, TH_ACK, TH_FIN|TH_ACK, TH_FIN|TH_ACK, | ... | ... |