Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F177294677
D50629.1794103902.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
11 KB
Referenced Files
None
Subscribers
None
D50629.1794103902.diff
View Options
diff --git a/share/man/man4/ddb.4 b/share/man/man4/ddb.4
--- a/share/man/man4/ddb.4
+++ b/share/man/man4/ddb.4
@@ -24,7 +24,7 @@
.\" any improvements or extensions that they make and grant Carnegie Mellon
.\" the rights to redistribute these changes.
.\"
-.Dd May 28, 2025
+.Dd June 10, 2025
.Dt DDB 4
.Os
.Sh NAME
@@ -604,9 +604,12 @@
modifier will print command line arguments for each process.
.\"
.Pp
-.It Ic show Cm all tcpcbs Ns Op Li / Ns Cm l
+.It Ic show Cm all tcpcbs Ns Op Li / Ns Cm b Ns Cm l
Show the same output as "show tcpcb" does, but for all
TCP control blocks within the system.
+The
+.Cm b
+modifier will request BBLog entries to be printed.
Using the
.Cm l
modifier will limit the output to TCP control blocks, which are locked.
@@ -1103,7 +1106,7 @@
Not present on some platforms.
.\"
.Pp
-.It Ic show Cm tcpcb Ar addr
+.It Ic show Cm tcpcb Ns Oo Li / Ns Cm b Oc Ar addr
Print TCP control block
.Vt struct tcpcb
lying at address
@@ -1111,6 +1114,9 @@
For exact interpretation of output, visit
.Pa netinet/tcp.h
header file.
+The
+.Cm b
+modifier will request BBLog entries to be printed.
.\"
.Pp
.It Ic show Cm thread Op Ar addr | tid
diff --git a/sys/netinet/tcp_log_buf.h b/sys/netinet/tcp_log_buf.h
--- a/sys/netinet/tcp_log_buf.h
+++ b/sys/netinet/tcp_log_buf.h
@@ -585,5 +585,9 @@
}
#endif /* TCP_BLACKBOX */
+#ifdef DDB
+void db_print_bblog_entries(struct tcp_log_stailq *log_entries, int indent);
+#endif
+
#endif /* _KERNEL */
#endif /* __tcp_log_buf_h__ */
diff --git a/sys/netinet/tcp_log_buf.c b/sys/netinet/tcp_log_buf.c
--- a/sys/netinet/tcp_log_buf.c
+++ b/sys/netinet/tcp_log_buf.c
@@ -29,6 +29,7 @@
#include <sys/cdefs.h>
#include "opt_inet.h"
+#include "opt_ddb.h"
#include <sys/param.h>
#include <sys/arb.h>
#include <sys/hash.h>
@@ -43,11 +44,18 @@
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/sysctl.h>
+#ifdef DDB
+#include <sys/time.h>
+#endif
#include <sys/tree.h>
#include <sys/stats.h> /* Must come after qmath.h and tree.h */
#include <sys/counter.h>
#include <dev/tcp_log/tcp_log_dev.h>
+#ifdef DDB
+#include <ddb/ddb.h>
+#endif
+
#include <net/if.h>
#include <net/if_var.h>
#include <net/vnet.h>
@@ -2972,3 +2980,376 @@
done:
INP_WUNLOCK(inp);
}
+
+#ifdef DDB
+static void
+db_print_indent(int indent)
+{
+ int i;
+
+ for (i = 0; i < indent; i++)
+ db_printf(" ");
+}
+
+static void
+db_print_tcphdr(struct tcp_log_buffer *tlm_buf)
+{
+ struct sackblk sack;
+ struct tcphdr *th;
+ int cnt, i, j, opt, optlen, num_sacks;
+ uint32_t val, ecr;
+ uint16_t mss;
+ uint16_t flags;
+
+ if ((tlm_buf->tlb_eventflags & TLB_FLAG_HDR) == 0) {
+ return;
+ }
+ th = &tlm_buf->tlb_th;
+ flags = tcp_get_flags(th);
+ if (flags & TH_FIN) {
+ db_printf("F");
+ }
+ if (flags & TH_SYN) {
+ db_printf("S");
+ }
+ if (flags & TH_RST) {
+ db_printf("R");
+ }
+ if (flags & TH_PUSH) {
+ db_printf("P");
+ }
+ if (flags & TH_ACK) {
+ db_printf(".");
+ }
+ if (flags & TH_URG) {
+ db_printf("U");
+ }
+ if (flags & TH_ECE) {
+ db_printf("E");
+ }
+ if (flags & TH_FIN) {
+ db_printf("F");
+ }
+ if (flags & TH_CWR) {
+ db_printf("W");
+ }
+ if (flags & TH_FIN) {
+ db_printf("F");
+ }
+ if (flags & TH_AE) {
+ db_printf("A");
+ }
+ db_printf(" %u:%u(%u)", ntohl(th->th_seq),
+ ntohl(th->th_seq) + tlm_buf->tlb_len, tlm_buf->tlb_len);
+ if (flags & TH_ACK) {
+ db_printf(" ack %u", ntohl(th->th_ack));
+ }
+ db_printf(" win %u", ntohs(th->th_win));
+ if (flags & TH_URG) {
+ db_printf(" urg %u", ntohs(th->th_urp));
+ }
+ cnt = (th->th_off << 2) - sizeof(struct tcphdr);
+ if (cnt > 0) {
+ db_printf(" <");
+ for (i = 0; i < cnt; i += optlen) {
+ opt = tlm_buf->tlb_opts[i];
+ if (opt == TCPOPT_EOL || opt == TCPOPT_NOP) {
+ optlen = 1;
+ } else {
+ if (cnt - i < 2) {
+ break;
+ }
+ optlen = tlm_buf->tlb_opts[i + 1];
+ if (optlen < 2 || optlen > cnt - i) {
+ break;
+ }
+ }
+ if (i > 0) {
+ db_printf(",");
+ }
+ switch (opt) {
+ case TCPOPT_EOL:
+ db_printf("eol");
+ break;
+ case TCPOPT_NOP:
+ db_printf("nop");
+ break;
+ case TCPOPT_MAXSEG:
+ if (optlen != TCPOLEN_MAXSEG) {
+ break;
+ }
+ bcopy(tlm_buf->tlb_opts + i + 2, &mss,
+ sizeof(uint16_t));
+ db_printf("mss %u", ntohs(mss));
+ break;
+ case TCPOPT_WINDOW:
+ if (optlen != TCPOLEN_WINDOW) {
+ break;
+ }
+ db_printf("wscale %u",
+ tlm_buf->tlb_opts[i + 2]);
+ break;
+ case TCPOPT_SACK_PERMITTED:
+ if (optlen != TCPOLEN_SACK_PERMITTED) {
+ break;
+ }
+ db_printf("sackOK");
+ break;
+ case TCPOPT_SACK:
+ if (optlen == TCPOLEN_SACKHDR ||
+ (optlen - 2) % TCPOLEN_SACK != 0) {
+ break;
+ }
+ num_sacks = (optlen - 2) / TCPOLEN_SACK;
+ db_printf("sack");
+ for (j = 0; j < num_sacks; j++) {
+ bcopy(tlm_buf->tlb_opts + i + 2 +
+ j * TCPOLEN_SACK, &sack,
+ TCPOLEN_SACK);
+ db_printf(" %u:%u", ntohl(sack.start),
+ ntohl(sack.end));
+ }
+ break;
+ case TCPOPT_TIMESTAMP:
+ if (optlen != TCPOLEN_TIMESTAMP) {
+ break;
+ }
+ bcopy(tlm_buf->tlb_opts + i + 2, &val,
+ sizeof(uint32_t));
+ bcopy(tlm_buf->tlb_opts + i + 6, &ecr,
+ sizeof(uint32_t));
+ db_printf("TS val %u ecr %u", ntohl(val),
+ ntohl(ecr));
+ break;
+ case TCPOPT_SIGNATURE:
+ db_printf("md5");
+ if (optlen > 2) {
+ db_printf(" ");
+ }
+ for (j = 0; j < optlen - 2; j++) {
+ db_printf("%02x",
+ tlm_buf->tlb_opts[i + 2 + j]);
+ }
+ break;
+ case TCPOPT_FAST_OPEN:
+ db_printf("FO");
+ if (optlen > 2) {
+ db_printf(" ");
+ }
+ for (j = 0; j < optlen - 2; j++) {
+ db_printf("%02x",
+ tlm_buf->tlb_opts[i + 2 + j]);
+ }
+ break;
+ default:
+ db_printf("opt=%u len=%u", opt, optlen);
+ break;
+ }
+ }
+ db_printf(">");
+ }
+}
+static void
+db_print_pru(struct tcp_log_buffer *tlm_buf)
+{
+ switch (tlm_buf->tlb_flex1) {
+ case PRU_ATTACH:
+ db_printf("ATTACH");
+ break;
+ case PRU_DETACH:
+ db_printf("DETACH");
+ break;
+ case PRU_BIND:
+ db_printf("BIND");
+ break;
+ case PRU_LISTEN:
+ db_printf("LISTEN");
+ break;
+ case PRU_CONNECT:
+ db_printf("CONNECT");
+ break;
+ case PRU_ACCEPT:
+ db_printf("ACCEPT");
+ break;
+ case PRU_DISCONNECT:
+ db_printf("DISCONNECT");
+ break;
+ case PRU_SHUTDOWN:
+ db_printf("SHUTDOWN");
+ break;
+ case PRU_RCVD:
+ db_printf("RCVD");
+ break;
+ case PRU_SEND:
+ db_printf("SEND");
+ break;
+ case PRU_ABORT:
+ db_printf("ABORT");
+ break;
+ case PRU_CONTROL:
+ db_printf("CONTROL");
+ break;
+ case PRU_SENSE:
+ db_printf("SENSE");
+ break;
+ case PRU_RCVOOB:
+ db_printf("RCVOOB");
+ break;
+ case PRU_SENDOOB:
+ db_printf("SENDOOB");
+ break;
+ case PRU_SOCKADDR:
+ db_printf("SOCKADDR");
+ break;
+ case PRU_PEERADDR:
+ db_printf("PEERADDR");
+ break;
+ case PRU_CONNECT2:
+ db_printf("CONNECT2");
+ break;
+ case PRU_FASTTIMO:
+ db_printf("FASTTIMO");
+ break;
+ case PRU_SLOWTIMO:
+ db_printf("SLOWTIMO");
+ break;
+ case PRU_PROTORCV:
+ db_printf("PROTORCV");
+ break;
+ case PRU_PROTOSEND:
+ db_printf("PROTOSEND");
+ break;
+ case PRU_SEND_EOF:
+ db_printf("SEND_EOF");
+ break;
+ case PRU_SOSETLABEL:
+ db_printf("SOSETLABEL");
+ break;
+ case PRU_CLOSE:
+ db_printf("CLOSE");
+ break;
+ case PRU_FLUSH:
+ db_printf("FLUSH");
+ break;
+ default:
+ db_printf("Unknown PRU (%u)", tlm_buf->tlb_flex1);
+ break;
+ }
+ if (tlm_buf->tlb_errno >= 0) {
+ db_printf(", error: %d", tlm_buf->tlb_errno);
+ }
+}
+
+static void
+db_print_rto(struct tcp_log_buffer *tlm_buf)
+{
+ tt_what what;
+ tt_which which;
+
+ what = (tlm_buf->tlb_flex1 & 0xffffff00) >> 8;
+ which = tlm_buf->tlb_flex1 & 0x000000ff;
+ switch (what) {
+ case TT_PROCESSING:
+ db_printf("Processing ");
+ break;
+ case TT_PROCESSED:
+ db_printf("Processed ");
+ break;
+ case TT_STARTING:
+ db_printf("Starting ");
+ break;
+ case TT_STOPPING:
+ db_printf("Stopping ");
+ break;
+ default:
+ db_printf("Unknown operation (%u) for ", what);
+ break;
+ }
+ switch (which) {
+ case TT_REXMT:
+ db_printf("Retransmission ");
+ break;
+ case TT_PERSIST:
+ db_printf("Persist ");
+ break;
+ case TT_KEEP:
+ db_printf("Keepalive ");
+ break;
+ case TT_2MSL:
+ db_printf("2 MSL ");
+ break;
+ case TT_DELACK:
+ db_printf("Delayed ACK ");
+ break;
+ default:
+ db_printf("Unknown (%u) ", which);
+ break;
+ }
+ db_printf("timer");
+ if (what == TT_STARTING) {
+ db_printf(": %u ms", tlm_buf->tlb_flex2);
+ }
+}
+
+static void
+db_print_usersend(struct tcp_log_buffer *tlm_buf)
+{
+ if ((tlm_buf->tlb_eventflags & TLB_FLAG_RXBUF) == 0) {
+ return;
+ }
+ if ((tlm_buf->tlb_eventflags & TLB_FLAG_TXBUF) == 0) {
+ return;
+ }
+ db_printf("usersend: rcv.acc: %u rcv.ccc: %u snd.acc: %u snd.ccc: %u",
+ tlm_buf->tlb_rxbuf.tls_sb_acc, tlm_buf->tlb_rxbuf.tls_sb_ccc,
+ tlm_buf->tlb_txbuf.tls_sb_acc, tlm_buf->tlb_txbuf.tls_sb_ccc);
+}
+
+void
+db_print_bblog_entries(struct tcp_log_stailq *log_entries, int indent)
+{
+ struct tcp_log_mem *log_entry;
+ struct tcp_log_buffer *tlm_buf, *prev_tlm_buf;
+ int64_t delta_t;
+
+ indent += 2;
+ prev_tlm_buf = NULL;
+ STAILQ_FOREACH(log_entry, log_entries, tlm_queue) {
+ db_print_indent(indent);
+ tlm_buf = &log_entry->tlm_buf;
+ if (prev_tlm_buf == NULL) {
+ db_printf(" 0.000 ");
+ } else {
+ delta_t = sbttoms(tvtosbt(tlm_buf->tlb_tv) -
+ tvtosbt(prev_tlm_buf->tlb_tv));
+ db_printf("+%u.%03u ", (uint32_t)(delta_t / 1000),
+ (uint32_t)(delta_t % 1000));
+ }
+ switch (tlm_buf->tlb_eventid) {
+ case TCP_LOG_IN:
+ db_printf("< ");
+ db_print_tcphdr(tlm_buf);
+ break;
+ case TCP_LOG_OUT:
+ db_printf("> ");
+ db_print_tcphdr(tlm_buf);
+ break;
+ case TCP_LOG_RTO:
+ db_print_rto(tlm_buf);
+ break;
+ case TCP_LOG_PRU:
+ db_print_pru(tlm_buf);
+ break;
+ case TCP_LOG_USERSEND:
+ db_print_usersend(tlm_buf);
+ break;
+ default:
+ break;
+ }
+ db_printf("\n");
+ prev_tlm_buf = tlm_buf;
+ if (db_pager_quit)
+ break;
+ }
+}
+#endif
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -3083,7 +3083,7 @@
}
static void
-db_print_tcpcb(struct tcpcb *tp, const char *name, int indent)
+db_print_tcpcb(struct tcpcb *tp, const char *name, int indent, bool show_bblog)
{
db_print_indent(indent);
@@ -3208,35 +3208,42 @@
db_print_indent(indent);
db_printf("t_lognum: %d t_loglimit: %d t_logsn: %u\n",
tp->t_lognum, tp->t_loglimit, tp->t_logsn);
+
+ if (show_bblog) {
+ db_print_bblog_entries(&tp->t_logs, indent);
+ }
}
DB_SHOW_COMMAND(tcpcb, db_show_tcpcb)
{
struct tcpcb *tp;
+ bool show_bblog;
if (!have_addr) {
db_printf("usage: show tcpcb <addr>\n");
return;
}
+ show_bblog = strchr(modif, 'b') != NULL;
tp = (struct tcpcb *)addr;
- db_print_tcpcb(tp, "tcpcb", 0);
+ db_print_tcpcb(tp, "tcpcb", 0, show_bblog);
}
DB_SHOW_ALL_COMMAND(tcpcbs, db_show_all_tcpcbs)
{
VNET_ITERATOR_DECL(vnet_iter);
struct inpcb *inp;
- bool only_locked;
+ bool only_locked, show_bblog;
only_locked = strchr(modif, 'l') != NULL;
+ show_bblog = strchr(modif, 'b') != NULL;
VNET_FOREACH(vnet_iter) {
CURVNET_SET(vnet_iter);
CK_LIST_FOREACH(inp, &V_tcbinfo.ipi_listhead, inp_list) {
if (only_locked &&
inp->inp_lock.rw_lock == RW_UNLOCKED)
continue;
- db_print_tcpcb(intotcpcb(inp), "tcpcb", 0);
+ db_print_tcpcb(intotcpcb(inp), "tcpcb", 0, show_bblog);
if (db_pager_quit)
break;
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Nov 8, 2:11 AM (15 h, 41 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41562343
Default Alt Text
D50629.1794103902.diff (11 KB)
Attached To
Mode
D50629: ddb: add optional printing of BBLog entries
Attached
Detach File
Event Timeline