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);

Reply via email to