To debug IPsec and tdb refcounting it is useful to have "show tdb"
authorbluhm <bluhm@openbsd.org>
Tue, 16 Nov 2021 13:53:14 +0000 (13:53 +0000)
committerbluhm <bluhm@openbsd.org>
Tue, 16 Nov 2021 13:53:14 +0000 (13:53 +0000)
and "show all tdbs" in ddb.
tested by Hrvoje Popovski; OK mvs@

share/man/man4/ddb.4
sys/ddb/db_command.c
sys/netinet/ip_ipsp.c
sys/netinet/ip_ipsp.h

index 27cca03..bb41f80 100644 (file)
@@ -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
index 57f0b7c..f895955 100644 (file)
@@ -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 <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, 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 },
index 05b3987..c516964 100644 (file)
@@ -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
index efe9082..2774363 100644 (file)
@@ -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);