When I had playing with bluhm@'s ipsec(4) diffs I found my system
always manages to complete rekeying and I have no TDB's with hardlimit
excess. It seems I'm not the only such person and other testers also
don't have panics Hrvoje Popovski had.

I want to count the TDBs with hardlimit excess as the new `ipsec_exctdb'
ipsec(4) counter and export this statistics to userland. So if the
tester person will expose something like below, we could say he didn't
reach the fragile tdb_delete() paths.

[otto@obsd-test ~]$ netstat -s -p ipsec
ipsec:
        44684 input IPsec packets
        44603 output IPsec packets
        7505232 input bytes
        7490792 output bytes
        5405234 input bytes, decompressed
        5706290 output bytes, uncompressed
        1 packet dropped on input
        0 packets dropped on output
        0 packets that failed crypto processing
        0 packets for which no XFORM was set in TDB received
        0 packets for which no TDB was found
        0 TDBs with hard limit excess

Also I found the `ipsec_notdb' counter description in header doesn't
math to netstat(1) description. We never count `ipsec_notdb' and the
netstat(1) description looks more appropriate so I used it to avoid
confusion with the new counter added.

ok?

Index: sys/netinet/ip_ah.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_ah.c,v
retrieving revision 1.166
diff -u -p -r1.166 ip_ah.c
--- sys/netinet/ip_ah.c 11 Nov 2021 18:08:18 -0000      1.166
+++ sys/netinet/ip_ah.c 20 Nov 2021 23:32:57 -0000
@@ -616,6 +616,7 @@ ah_input(struct mbuf **mp, struct tdb *t
            tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes) {
                pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
                tdb_delete(tdb);
+               ipsecstat_inc(ipsec_exctdb);
                goto drop;
        }
 
@@ -955,6 +956,7 @@ ah_output(struct mbuf *m, struct tdb *td
            tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes) {
                pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
                tdb_delete(tdb);
+               ipsecstat_inc(ipsec_exctdb);
                error = EINVAL;
                goto drop;
        }
Index: sys/netinet/ip_esp.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_esp.c,v
retrieving revision 1.187
diff -u -p -r1.187 ip_esp.c
--- sys/netinet/ip_esp.c        11 Nov 2021 18:08:18 -0000      1.187
+++ sys/netinet/ip_esp.c        20 Nov 2021 23:32:57 -0000
@@ -428,6 +428,7 @@ esp_input(struct mbuf **mp, struct tdb *
            (tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes)) {
                pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
                tdb_delete(tdb);
+               ipsecstat_inc(ipsec_exctdb);
                goto drop;
        }
 
@@ -784,6 +785,7 @@ esp_output(struct mbuf *m, struct tdb *t
            tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes) {
                pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
                tdb_delete(tdb);
+               ipsecstat_inc(ipsec_exctdb);
                error = EINVAL;
                goto drop;
        }
Index: sys/netinet/ip_ipcomp.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_ipcomp.c,v
retrieving revision 1.87
diff -u -p -r1.87 ip_ipcomp.c
--- sys/netinet/ip_ipcomp.c     11 Nov 2021 18:08:18 -0000      1.87
+++ sys/netinet/ip_ipcomp.c     20 Nov 2021 23:32:57 -0000
@@ -201,6 +201,7 @@ ipcomp_input(struct mbuf **mp, struct td
            (tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes)) {
                pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
                tdb_delete(tdb);
+               ipsecstat_inc(ipsec_exctdb);
                goto drop;
        }
        /* Notify on soft expiration */
@@ -388,6 +389,7 @@ ipcomp_output(struct mbuf *m, struct tdb
            (tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes)) {
                pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
                tdb_delete(tdb);
+               ipsecstat_inc(ipsec_exctdb);
                error = EINVAL;
                goto drop;
        }
Index: sys/netinet/ip_ipsp.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_ipsp.c,v
retrieving revision 1.251
diff -u -p -r1.251 ip_ipsp.c
--- sys/netinet/ip_ipsp.c       18 Nov 2021 11:04:10 -0000      1.251
+++ sys/netinet/ip_ipsp.c       20 Nov 2021 23:32:57 -0000
@@ -652,8 +652,10 @@ tdb_timeout(void *v)
        NET_LOCK();
        if (tdb->tdb_flags & TDBF_TIMER) {
                /* If it's an "invalid" TDB do a silent expiration. */
-               if (!(tdb->tdb_flags & TDBF_INVALID))
+               if (!(tdb->tdb_flags & TDBF_INVALID)) {
                        pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
+                       ipsecstat_inc(ipsec_exctdb);
+               }
                tdb_delete(tdb);
        }
        NET_UNLOCK();
@@ -667,8 +669,10 @@ tdb_firstuse(void *v)
        NET_LOCK();
        if (tdb->tdb_flags & TDBF_SOFT_FIRSTUSE) {
                /* If the TDB hasn't been used, don't renew it. */
-               if (tdb->tdb_first_use != 0)
+               if (tdb->tdb_first_use != 0) {
                        pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
+                       ipsecstat_inc(ipsec_exctdb);
+               }
                tdb_delete(tdb);
        }
        NET_UNLOCK();
Index: sys/netinet/ip_ipsp.h
===================================================================
RCS file: /cvs/src/sys/netinet/ip_ipsp.h,v
retrieving revision 1.220
diff -u -p -r1.220 ip_ipsp.h
--- sys/netinet/ip_ipsp.h       16 Nov 2021 13:53:14 -0000      1.220
+++ sys/netinet/ip_ipsp.h       20 Nov 2021 23:32:57 -0000
@@ -131,8 +131,9 @@ struct ipsecstat {
        uint64_t        ipsec_idrops;           /* Dropped on input */
        uint64_t        ipsec_odrops;           /* Dropped on output */
        uint64_t        ipsec_crypto;           /* Crypto processing failure */
-       uint64_t        ipsec_notdb;            /* Expired while in crypto */
+       uint64_t        ipsec_notdb;            /* No TDB was found */
        uint64_t        ipsec_noxform;          /* Crypto error */
+       uint64_t        ipsec_exctdb;           /* TDBs with hardlimit excess */
 };
 
 struct tdb_data {
@@ -168,6 +169,7 @@ enum ipsec_counters {
        ipsec_crypto,
        ipsec_notdb,
        ipsec_noxform,
+       ipsec_exctdb,
        ipsec_ncounters
 };
 
Index: usr.bin/netstat/inet.c
===================================================================
RCS file: /cvs/src/usr.bin/netstat/inet.c,v
retrieving revision 1.171
diff -u -p -r1.171 inet.c
--- usr.bin/netstat/inet.c      26 Jan 2021 18:22:35 -0000      1.171
+++ usr.bin/netstat/inet.c      20 Nov 2021 23:32:59 -0000
@@ -1046,6 +1046,7 @@ ipsec_stats(char *name)
        p(ipsec_crypto, "\t%llu packet%s that failed crypto processing\n");
        p(ipsec_noxform, "\t%llu packet%s for which no XFORM was set in TDB 
received\n");
        p(ipsec_notdb, "\t%llu packet%s for which no TDB was found\n");
+       p(ipsec_exctdb, "\t%llu TDB%s with hardlimit excess\n");
 #undef p
 }
 

Reply via email to