From 50eb7ec08c7a6c4e241c54da937da850a8326a34 Mon Sep 17 00:00:00 2001 From: bluhm Date: Tue, 16 Nov 2021 13:53:14 +0000 Subject: [PATCH] To debug IPsec and tdb refcounting it is useful to have "show tdb" and "show all tdbs" in ddb. tested by Hrvoje Popovski; OK mvs@ --- share/man/man4/ddb.4 | 28 +++++++++++++- sys/ddb/db_command.c | 37 ++++++++++++++++++- sys/netinet/ip_ipsp.c | 85 +++++++++++++++++++++++++++++++++++++++++-- sys/netinet/ip_ipsp.h | 14 +++++-- 4 files changed, 155 insertions(+), 9 deletions(-) diff --git a/share/man/man4/ddb.4 b/share/man/man4/ddb.4 index 27cca031558..bb41f802c5b 100644 --- a/share/man/man4/ddb.4 +++ b/share/man/man4/ddb.4 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ddb.4,v 1.99 2020/10/26 18:53:20 deraadt Exp $ +.\" $OpenBSD: ddb.4,v 1.100 2021/11/16 13:53:14 bluhm Exp $ .\" $NetBSD: ddb.4,v 1.5 1994/11/30 16:22:09 jtc Exp $ .\" .\" Mach Operating System @@ -25,7 +25,7 @@ .\" any improvements or extensions that they make and grant Carnegie Mellon .\" the rights to redistribute these changes. .\" -.Dd $Mdocdate: October 26 2020 $ +.Dd $Mdocdate: November 16 2021 $ .Dt DDB 4 .Os .Sh NAME @@ -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. .\" -------------------- @@ -941,6 +954,17 @@ See the 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 +.\" -------------------- .It Ic show all vnodes Op Cm /f Display information about all vnodes in the system. .Pp diff --git a/sys/ddb/db_command.c b/sys/ddb/db_command.c index 57f0b7c1257..f89595531f6 100644 --- a/sys/ddb/db_command.c +++ b/sys/ddb/db_command.c @@ -1,4 +1,4 @@ -/* $OpenBSD: db_command.c,v 1.91 2021/06/02 00:39:25 cheloha Exp $ */ +/* $OpenBSD: db_command.c,v 1.92 2021/11/16 13:53:14 bluhm Exp $ */ /* $NetBSD: db_command.c,v 1.20 1996/03/30 22:30:05 christos Exp $ */ /* @@ -56,6 +56,7 @@ #include #include +#include #include /* @@ -89,12 +90,14 @@ void db_mount_print_cmd(db_expr_t, int, db_expr_t, char *); 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 have_addr, db_expr_t count, char *modif) 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 have_addr, db_expr_t count, char *modif) 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 }, diff --git a/sys/netinet/ip_ipsp.c b/sys/netinet/ip_ipsp.c index 05b3987ee39..c516964f429 100644 --- a/sys/netinet/ip_ipsp.c +++ b/sys/netinet/ip_ipsp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ipsp.c,v 1.249 2021/10/27 16:58:44 bluhm Exp $ */ +/* $OpenBSD: ip_ipsp.c,v 1.250 2021/11/16 13:53:14 bluhm Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr), @@ -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, struct ipsecinit *ii) 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, char *buf, socklen_t size) return "(unknown address family)"; } } -#endif /* ENCDEBUG */ +#endif /* DDB || ENCDEBUG */ /* Check whether an IP{4,6} address is unspecified. */ int diff --git a/sys/netinet/ip_ipsp.h b/sys/netinet/ip_ipsp.h index efe90827f59..2774363605d 100644 --- a/sys/netinet/ip_ipsp.h +++ b/sys/netinet/ip_ipsp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ipsp.h,v 1.219 2021/10/25 18:25:01 bluhm Exp $ */ +/* $OpenBSD: ip_ipsp.h,v 1.220 2021/11/16 13:53:14 bluhm Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr), @@ -345,6 +345,14 @@ struct tdb { /* tunnel descriptor block */ #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, ipsec_policy) ipsec_policy_head; 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, struct ipsecinit *); 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); -- 2.20.1