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 [email protected]