ipsec: Record the number of packets lost from an SA

Type: feature

Gaps in the sequence numbers received on an SA indicate packets that were lost.
Gaps are identified using the anti-replay window that records the sequences seen.

Publish the number of lost packets in the stats segment at /net/ipsec/sa/lost

Signed-off-by: Neale Ranns <neale@graphiant.com>
Change-Id: I8af1c09b7b25a705e18bf82e1623b3ce19e5a74d
diff --git a/src/vnet/ipsec/ah_decrypt.c b/src/vnet/ipsec/ah_decrypt.c
index 182ed3d..1ad372a 100644
--- a/src/vnet/ipsec/ah_decrypt.c
+++ b/src/vnet/ipsec/ah_decrypt.c
@@ -315,6 +315,7 @@
     {
       ip4_header_t *oh4;
       ip6_header_t *oh6;
+      u64 n_lost = 0;
 
       if (next[0] < AH_DECRYPT_N_NEXT)
 	goto trace;
@@ -323,7 +324,7 @@
 
       if (PREDICT_TRUE (sa0->integ_alg != IPSEC_INTEG_ALG_NONE))
 	{
-	  /* redo the anit-reply check. see esp_decrypt for details */
+	  /* redo the anti-reply check. see esp_decrypt for details */
 	  if (ipsec_sa_anti_replay_and_sn_advance (sa0, pd->seq, pd->seq_hi,
 						   true, NULL))
 	    {
@@ -331,7 +332,10 @@
 	      next[0] = AH_DECRYPT_NEXT_DROP;
 	      goto trace;
 	    }
-	  ipsec_sa_anti_replay_advance (sa0, pd->seq, pd->seq_hi);
+	  n_lost = ipsec_sa_anti_replay_advance (sa0, thread_index, pd->seq,
+						 pd->seq_hi);
+	  vlib_prefetch_simple_counter (&ipsec_sa_lost_counters, thread_index,
+					pd->sa_index);
 	}
 
       u16 ah_hdr_len = sizeof (ah_header_t) + pd->icv_size
@@ -398,6 +402,10 @@
 	    }
 	}
 
+      if (PREDICT_FALSE (n_lost))
+	vlib_increment_simple_counter (&ipsec_sa_lost_counters, thread_index,
+				       pd->sa_index, n_lost);
+
       vnet_buffer (b[0])->sw_if_index[VLIB_TX] = (u32) ~ 0;
     trace:
       if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED))