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

Reply via email to