On Mon, Nov 15, 2021 at 05:23:43PM +0100, Alexander Bluhm wrote: > Hi, > > To debug IPsec and tdb refcounting it may be useful to have "show > tdb" and "show all tdbs" in ddb. > > ok? >
Indeed this is useful. ok mvs@ > 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); >