Hi,
To debug IPsec and tdb refcounting it may be useful to have "show
tdb" and "show all tdbs" in ddb.
ok?
bluhm
Index: share/man/man4/ddb.4
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/share/man/man4/ddb.4,v
retrieving revision 1.99
diff -u -p -r1.99 ddb.4
--- share/man/man4/ddb.4 26 Oct 2020 18:53:20 -0000 1.99
+++ share/man/man4/ddb.4 15 Nov 2021 14:43:46 -0000
@@ -812,6 +812,19 @@ as a struct
Nested structures and bit fields are not printed.
Character arrays are printed as bytes.
.\" --------------------
+.It Xo
+.Ic show tdb
+.Op Cm /f
+.Ar addr
+.Xc
+Prints the
+.Li struct tdb
+at
+.Ar addr .
+If the
+.Cm /f
+modifier is specified prints out all fields of this IPsec SA.
+.\" --------------------
.It Ic show uvmexp
Displays a selection of uvm counters and statistics.
.\" --------------------
@@ -938,6 +951,17 @@ Display information for all outstanding
For each NFS requests, print a more detailed output.
See the
.Ic show nfsreq
+command for more information.
+.El
+.\" --------------------
+.It Ic show all tdbs Op Cm /f
+Display information about all IPsec SAs in the system.
+.Pp
+.Bl -tag -width foo -compact
+.It Cm /f
+For each tdb, print a more detailed output.
+See the
+.Ic show tdb
command for more information.
.El
.\" --------------------
Index: sys/ddb/db_command.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/ddb/db_command.c,v
retrieving revision 1.91
diff -u -p -r1.91 db_command.c
--- sys/ddb/db_command.c 2 Jun 2021 00:39:25 -0000 1.91
+++ sys/ddb/db_command.c 15 Nov 2021 13:54:41 -0000
@@ -56,6 +56,7 @@
#include <ddb/db_interface.h>
#include <ddb/db_extern.h>
+#include <netinet/ip_ipsp.h>
#include <uvm/uvm_ddb.h>
/*
@@ -89,12 +90,14 @@ void db_mount_print_cmd(db_expr_t, int,
void db_show_all_mounts(db_expr_t, int, db_expr_t, char *);
void db_show_all_vnodes(db_expr_t, int, db_expr_t, char *);
void db_show_all_bufs(db_expr_t, int, db_expr_t, char *);
+void db_show_all_tdbs(db_expr_t, int, db_expr_t, char *);
void db_object_print_cmd(db_expr_t, int, db_expr_t, char *);
void db_page_print_cmd(db_expr_t, int, db_expr_t, char *);
void db_extent_print_cmd(db_expr_t, int, db_expr_t, char *);
void db_pool_print_cmd(db_expr_t, int, db_expr_t, char *);
void db_proc_print_cmd(db_expr_t, int, db_expr_t, char *);
void db_uvmexp_print_cmd(db_expr_t, int, db_expr_t, char *);
+void db_tdb_print_cmd(db_expr_t, int, db_expr_t, char *);
void db_vnode_print_cmd(db_expr_t, int, db_expr_t, char *);
void db_nfsreq_print_cmd(db_expr_t, int, db_expr_t, char *);
void db_nfsnode_print_cmd(db_expr_t, int, db_expr_t, char *);
@@ -399,6 +402,19 @@ db_show_all_bufs(db_expr_t addr, int hav
pool_walk(&bufpool, full, db_printf, vfs_buf_print);
}
+#ifdef IPSEC
+void
+db_show_all_tdbs(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
+{
+ int full = 0;
+
+ if (modif[0] == 'f')
+ full = 1;
+
+ pool_walk(&tdb_pool, full, db_printf, tdb_printit);
+}
+#endif
+
/*ARGSUSED*/
void
db_object_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char
*modif)
@@ -509,6 +525,19 @@ db_proc_print_cmd(db_expr_t addr, int ha
proc_printit((struct proc *)addr, modif, db_printf);
}
+#ifdef IPSEC
+void
+db_tdb_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
+{
+ int full = 0;
+
+ if (modif[0] == 'f')
+ full = 1;
+
+ tdb_printit((void *)addr, full, db_printf);
+}
+#endif
+
/*ARGSUSED*/
void
db_uvmexp_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char
*modif)
@@ -540,6 +569,9 @@ struct db_command db_show_all_cmds[] = {
{ "nfsreqs", db_show_all_nfsreqs, 0, NULL },
{ "nfsnodes", db_show_all_nfsnodes, 0, NULL },
#endif
+#ifdef IPSEC
+ { "tdbs", db_show_all_tdbs, 0, NULL },
+#endif
#ifdef WITNESS
{ "locks", db_witness_list_all, 0, NULL },
#endif
@@ -571,6 +603,9 @@ struct db_command db_show_cmds[] = {
{ "registers", db_show_regs, 0, NULL },
{ "socket", db_socket_print_cmd, 0, NULL },
{ "struct", db_ctf_show_struct, CS_OWN, NULL },
+#ifdef IPSEC
+ { "tdb", db_tdb_print_cmd, 0, NULL },
+#endif
{ "uvmexp", db_uvmexp_print_cmd, 0, NULL },
{ "vnode", db_vnode_print_cmd, 0, NULL },
{ "watches", db_listwatch_cmd, 0, NULL },
Index: sys/netinet/ip_ipsp.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_ipsp.c,v
retrieving revision 1.249
diff -u -p -r1.249 ip_ipsp.c
--- sys/netinet/ip_ipsp.c 27 Oct 2021 16:58:44 -0000 1.249
+++ sys/netinet/ip_ipsp.c 15 Nov 2021 16:16:34 -0000
@@ -532,6 +532,85 @@ tdb_hashstats(void)
db_printf("%d%s\t\t%d\n", i, i == NBUCKETS - 1 ?
"+" : "", buckets[i]);
}
+
+#define DUMP(m, f) pr("%18s: " f "\n", #m, tdb->tdb_##m)
+void
+tdb_printit(void *addr, int full, int (*pr)(const char *, ...))
+{
+ struct tdb *tdb = addr;
+ char buf[INET6_ADDRSTRLEN];
+
+ if (full) {
+ pr("tdb at %p\n", tdb);
+ DUMP(hnext, "%p");
+ DUMP(dnext, "%p");
+ DUMP(snext, "%p");
+ DUMP(inext, "%p");
+ DUMP(onext, "%p");
+ DUMP(xform, "%p");
+ DUMP(encalgxform, "%p");
+ DUMP(authalgxform, "%p");
+ DUMP(compalgxform, "%p");
+ pr("%18s: %b\n", "flags", tdb->tdb_flags, TDBF_BITS);
+ /* tdb_XXX_tmo */
+ DUMP(seq, "%d");
+ DUMP(exp_allocations, "%d");
+ DUMP(soft_allocations, "%d");
+ DUMP(cur_allocations, "%d");
+ DUMP(exp_bytes, "%lld");
+ DUMP(soft_bytes, "%lld");
+ DUMP(cur_bytes, "%lld");
+ DUMP(exp_timeout, "%lld");
+ DUMP(soft_timeout, "%lld");
+ DUMP(established, "%lld");
+ DUMP(first_use, "%lld");
+ DUMP(soft_first_use, "%lld");
+ DUMP(exp_first_use, "%lld");
+ DUMP(last_used, "%lld");
+ DUMP(last_marked, "%lld");
+ /* tdb_data */
+ DUMP(cryptoid, "%lld");
+ pr("%18s: %08x\n", "tdb_spi", ntohl(tdb->tdb_spi));
+ DUMP(amxkeylen, "%d");
+ DUMP(emxkeylen, "%d");
+ DUMP(ivlen, "%d");
+ DUMP(sproto, "%d");
+ DUMP(wnd, "%d");
+ DUMP(satype, "%d");
+ DUMP(updates, "%d");
+ pr("%18s: %s\n", "dst",
+ ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)));
+ pr("%18s: %s\n", "src",
+ ipsp_address(&tdb->tdb_src, buf, sizeof(buf)));
+ DUMP(amxkey, "%p");
+ DUMP(emxkey, "%p");
+ DUMP(rpl, "%lld");
+ /* tdb_seen */
+ /* tdb_iv */
+ DUMP(ids, "%p");
+ DUMP(ids_swapped, "%d");
+ DUMP(mtu, "%d");
+ DUMP(mtutimeout, "%lld");
+ pr("%18s: %08x\n", "udpencap_port",
+ ntohl(tdb->tdb_udpencap_port));
+ DUMP(tag, "%d");
+ DUMP(tap, "%d");
+ DUMP(rdomain, "%d");
+ DUMP(rdomain_post, "%d");
+ /* tdb_filter */
+ /* tdb_filtermask */
+ /* tdb_policy_head */
+ /* tdb_sync_entry */
+ } else {
+ pr("%p:", tdb);
+ pr(" %08x", ntohl(tdb->tdb_spi));
+ pr(" %s", ipsp_address(&tdb->tdb_src, buf, sizeof(buf)));
+ pr("->%s", ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)));
+ pr(":%d", tdb->tdb_sproto);
+ pr(" %08x\n", tdb->tdb_flags);
+ }
+}
+#undef DUMP
#endif /* DDB */
int
@@ -939,7 +1018,7 @@ tdb_init(struct tdb *tdbp, u_int16_t alg
return EINVAL;
}
-#ifdef ENCDEBUG
+#if defined(DDB) || defined(ENCDEBUG)
/* Return a printable string for the address. */
const char *
ipsp_address(union sockaddr_union *sa, char *buf, socklen_t size)
@@ -959,7 +1038,7 @@ ipsp_address(union sockaddr_union *sa, c
return "(unknown address family)";
}
}
-#endif /* ENCDEBUG */
+#endif /* DDB || ENCDEBUG */
/* Check whether an IP{4,6} address is unspecified. */
int
Index: sys/netinet/ip_ipsp.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_ipsp.h,v
retrieving revision 1.219
diff -u -p -r1.219 ip_ipsp.h
--- sys/netinet/ip_ipsp.h 25 Oct 2021 18:25:01 -0000 1.219
+++ sys/netinet/ip_ipsp.h 15 Nov 2021 13:33:05 -0000
@@ -345,6 +345,14 @@ struct tdb { /* tunnel
descriptor blo
#define TDBF_PFSYNC_RPL 0x80000 /* Replay counter should be
bumped */
#define TDBF_ESN 0x100000 /* 64-bit sequence numbers
(ESN) */
+#define TDBF_BITS ("\20" \
+ "\1UNIQUE\2TIMER\3BYTES\4ALLOCATIONS" \
+ "\5INVALID\6FIRSTUSE\10SOFT_TIMER" \
+ "\11SOFT_BYTES\12SOFT_ALLOCATIONS\13SOFT_FIRSTUSE\14PFS" \
+ "\15TUNNELING" \
+ "\21USEDTUNNEL\22UDPENCAP\23PFSYNC\24PFSYNC_RPL" \
+ "\25ESN")
+
u_int32_t tdb_flags; /* Flags related to this TDB */
struct timeout tdb_timer_tmo;
@@ -486,6 +494,7 @@ struct xformsw {
extern int ipsec_in_use;
extern u_int64_t ipsec_last_added;
extern int encdebug; /* enable message reporting */
+extern struct pool tdb_pool;
extern int ipsec_keep_invalid; /* lifetime of embryonic SAs (in sec) */
extern int ipsec_require_pfs; /* use Perfect Forward Secrecy */
@@ -526,9 +535,7 @@ extern TAILQ_HEAD(ipsec_policy_head, ips
struct cryptop;
/* Misc. */
-#ifdef ENCDEBUG
const char *ipsp_address(union sockaddr_union *, char *, socklen_t);
-#endif /* ENCDEBUG */
/* SPD tables */
struct radix_node_head *spd_table_add(unsigned int);
@@ -560,6 +567,7 @@ int tdb_init(struct tdb *, u_int16_t, st
void tdb_unlink(struct tdb *);
void tdb_unlink_locked(struct tdb *);
int tdb_walk(u_int, int (*)(struct tdb *, void *, int), void *);
+void tdb_printit(void *, int, int (*)(const char *, ...));
/* XF_IP4 */
int ipe4_attach(void);