netstat -ss presented me with these IPsec statistics:

esp:
        40 packets where counter wrapping was detected
ah:
        36520954 input AH packets
        34978358 output AH packets
        6 packets that failed verification received
        10 packets attempted to use an invalid TDB
        22286834673 input bytes
        19241478783 output bytes

So out of a total of 0 ESP packets, 40 were bad.  Curious.

The problem is checkreplaywindow32() in ip_esp.c.  It returns values
0 to 3 to classify the packet.  For some of these values it increments
the statistics counter itself, for other values the caller must do
so.  Ugh.  The same function is also used in ip_ah.c, where it ends
up incrementing ESP counters for AH packets.

The diff below takes the statistics increments out of
checkreplaywindow32() and puts them all into the calling functions,
incrementing the counters for the correct protocol.

ok?

Index: netinet/ip_ah.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_ah.c,v
retrieving revision 1.99
diff -u -p -r1.99 ip_ah.c
--- netinet/ip_ah.c     11 Jan 2011 15:42:05 -0000      1.99
+++ netinet/ip_ah.c     3 Jun 2012 15:19:39 -0000
@@ -580,11 +580,20 @@ ah_input(struct mbuf *m, struct tdb *tdb
                        return ENOBUFS;
 
                case 2:
+                       DPRINTF(("ah_input(): duplicate packet received in "
+                           "SA %s/%08x\n", ipsp_address(tdb->tdb_dst),
+                           ntohl(tdb->tdb_spi)));
+
+                       ahstat.ahs_wrap++;
+                       m_freem(m);
+                       return ENOBUFS;
+
                case 3:
                        DPRINTF(("ah_input(): duplicate packet received in "
                            "SA %s/%08x\n", ipsp_address(tdb->tdb_dst),
                            ntohl(tdb->tdb_spi)));
 
+                       ahstat.ahs_replay++;
                        m_freem(m);
                        return ENOBUFS;
 
@@ -864,11 +873,20 @@ ah_input_cb(void *op)
                        goto baddone;
 
                case 2:
+                       DPRINTF(("ah_input_cb(): duplicate packet received in "
+                           "SA %s/%08x\n", ipsp_address(tdb->tdb_dst),
+                           ntohl(tdb->tdb_spi)));
+
+                       ahstat.ahs_wrap++;
+                       error = ENOBUFS;
+                       goto baddone;
+
                case 3:
                        DPRINTF(("ah_input_cb(): duplicate packet received in "
                            "SA %s/%08x\n", ipsp_address(tdb->tdb_dst),
                            ntohl(tdb->tdb_spi)));
 
+                       ahstat.ahs_replay++;
                        error = ENOBUFS;
                        goto baddone;
 
Index: netinet/ip_esp.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_esp.c,v
retrieving revision 1.116
diff -u -p -r1.116 ip_esp.c
--- netinet/ip_esp.c    11 Jan 2011 15:42:05 -0000      1.116
+++ netinet/ip_esp.c    3 Jun 2012 15:16:29 -0000
@@ -376,9 +376,15 @@ esp_input(struct mbuf *m, struct tdb *td
                        return EACCES;
 
                case 2:
-               case 3:
+                       m_freem(m);
                        DPRINTF(("esp_input(): duplicate packet received in SA 
%s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
+                       espstat.esps_wrap++;
+                       return EACCES;
+
+               case 3:
                        m_freem(m);
+                       DPRINTF(("esp_input(): duplicate packet received in SA 
%s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
+                       espstat.esps_replay++;
                        return EACCES;
 
                default:
@@ -634,8 +640,14 @@ esp_input_cb(void *op)
                        goto baddone;
 
                case 2:
+                       DPRINTF(("esp_input_cb(): duplicate packet received in 
SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
+                       espstat.esps_wrap++;
+                       error = EACCES;
+                       goto baddone;
+
                case 3:
                        DPRINTF(("esp_input_cb(): duplicate packet received in 
SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
+                       espstat.esps_replay++;
                        error = EACCES;
                        goto baddone;
 
@@ -1164,15 +1176,11 @@ checkreplaywindow32(u_int32_t seq, u_int
        }
 
        diff = *lastseq - initial - seq;
-       if (diff >= window) {
-               espstat.esps_wrap++;
+       if (diff >= window)
                return 2;
-       }
 
-       if ((*bitmap) & (((u_int32_t) 1) << diff)) {
-               espstat.esps_replay++;
+       if ((*bitmap) & (((u_int32_t) 1) << diff))
                return 3;
-       }
 
        *bitmap |= (((u_int32_t) 1) << diff);
        return 0;
-- 
Christian "naddy" Weisgerber                          na...@mips.inka.de

Reply via email to