ipsec: Use .api declared error counters

Type: improvement

Signed-off-by: Neale Ranns <neale@graphiant.com>
Change-Id: Ica7de5a493389c6f53b7cf04e06939473a63d2b9
diff --git a/src/vnet/ipsec/ah_decrypt.c b/src/vnet/ipsec/ah_decrypt.c
index 1ad372a..c9209d6 100644
--- a/src/vnet/ipsec/ah_decrypt.c
+++ b/src/vnet/ipsec/ah_decrypt.c
@@ -23,6 +23,7 @@
 #include <vnet/ipsec/esp.h>
 #include <vnet/ipsec/ah.h>
 #include <vnet/ipsec/ipsec_io.h>
+#include <vnet/ipsec/ipsec.api_enum.h>
 
 #define foreach_ah_decrypt_next                 \
   _(DROP, "error-drop")                         \
@@ -38,28 +39,6 @@
     AH_DECRYPT_N_NEXT,
 } ah_decrypt_next_t;
 
-#define foreach_ah_decrypt_error                \
-  _ (RX_PKTS, "AH pkts received")               \
-  _ (DECRYPTION_FAILED, "AH decryption failed") \
-  _ (INTEG_ERROR, "Integrity check failed")     \
-  _ (NO_TAIL_SPACE, "not enough buffer tail space (dropped)")     \
-  _ (DROP_FRAGMENTS, "IP fragments drop")       \
-  _ (REPLAY, "SA replayed packet")
-
-typedef enum
-{
-#define _(sym,str) AH_DECRYPT_ERROR_##sym,
-  foreach_ah_decrypt_error
-#undef _
-    AH_DECRYPT_N_ERROR,
-} ah_decrypt_error_t;
-
-static char *ah_decrypt_error_strings[] = {
-#define _(sym,string) string,
-  foreach_ah_decrypt_error
-#undef _
-};
-
 typedef struct
 {
   ipsec_integ_alg_t integ_alg;
@@ -443,8 +422,8 @@
   .format_trace = format_ah_decrypt_trace,
   .type = VLIB_NODE_TYPE_INTERNAL,
 
-  .n_errors = ARRAY_LEN(ah_decrypt_error_strings),
-  .error_strings = ah_decrypt_error_strings,
+  .n_errors = AH_DECRYPT_N_ERROR,
+  .error_counters = ah_decrypt_error_counters,
 
   .n_next_nodes = AH_DECRYPT_N_NEXT,
   .next_nodes = {
@@ -470,8 +449,8 @@
   .format_trace = format_ah_decrypt_trace,
   .type = VLIB_NODE_TYPE_INTERNAL,
 
-  .n_errors = ARRAY_LEN(ah_decrypt_error_strings),
-  .error_strings = ah_decrypt_error_strings,
+  .n_errors = AH_DECRYPT_N_ERROR,
+  .error_counters = ah_decrypt_error_counters,
 
   .n_next_nodes = AH_DECRYPT_N_NEXT,
   .next_nodes = {
diff --git a/src/vnet/ipsec/ah_encrypt.c b/src/vnet/ipsec/ah_encrypt.c
index bb971e4..7116a16 100644
--- a/src/vnet/ipsec/ah_encrypt.c
+++ b/src/vnet/ipsec/ah_encrypt.c
@@ -22,6 +22,7 @@
 #include <vnet/ipsec/ipsec.h>
 #include <vnet/ipsec/esp.h>
 #include <vnet/ipsec/ah.h>
+#include <vnet/ipsec/ipsec.api_enum.h>
 #include <vnet/tunnel/tunnel_dp.h>
 
 #define foreach_ah_encrypt_next \
@@ -38,25 +39,6 @@
     AH_ENCRYPT_N_NEXT,
 } ah_encrypt_next_t;
 
-#define foreach_ah_encrypt_error                                              \
-  _ (RX_PKTS, "AH pkts received")                                             \
-  _ (CRYPTO_ENGINE_ERROR, "crypto engine error (packet dropped)")             \
-  _ (SEQ_CYCLED, "sequence number cycled (packet dropped)")
-
-typedef enum
-{
-#define _(sym,str) AH_ENCRYPT_ERROR_##sym,
-  foreach_ah_encrypt_error
-#undef _
-    AH_ENCRYPT_N_ERROR,
-} ah_encrypt_error_t;
-
-static char *ah_encrypt_error_strings[] = {
-#define _(sym,string) string,
-  foreach_ah_encrypt_error
-#undef _
-};
-
 typedef struct
 {
   u32 sa_index;
@@ -462,8 +444,8 @@
   .format_trace = format_ah_encrypt_trace,
   .type = VLIB_NODE_TYPE_INTERNAL,
 
-  .n_errors = ARRAY_LEN(ah_encrypt_error_strings),
-  .error_strings = ah_encrypt_error_strings,
+  .n_errors = AH_ENCRYPT_N_ERROR,
+  .error_counters = ah_encrypt_error_counters,
 
   .n_next_nodes = AH_ENCRYPT_N_NEXT,
   .next_nodes = {
@@ -488,8 +470,8 @@
   .format_trace = format_ah_encrypt_trace,
   .type = VLIB_NODE_TYPE_INTERNAL,
 
-  .n_errors = ARRAY_LEN(ah_encrypt_error_strings),
-  .error_strings = ah_encrypt_error_strings,
+  .n_errors = AH_ENCRYPT_N_ERROR,
+  .error_counters = ah_encrypt_error_counters,
 
   .n_next_nodes = AH_ENCRYPT_N_NEXT,
   .next_nodes = {
diff --git a/src/vnet/ipsec/esp_decrypt.c b/src/vnet/ipsec/esp_decrypt.c
index 21159fb..af90bc4 100644
--- a/src/vnet/ipsec/esp_decrypt.c
+++ b/src/vnet/ipsec/esp_decrypt.c
@@ -23,6 +23,7 @@
 #include <vnet/ipsec/esp.h>
 #include <vnet/ipsec/ipsec_io.h>
 #include <vnet/ipsec/ipsec_tun.h>
+#include <vnet/ipsec/ipsec.api_enum.h>
 
 #include <vnet/gre/packet.h>
 
@@ -57,35 +58,6 @@
     ESP_DECRYPT_POST_N_NEXT,
 } esp_decrypt_post_next_t;
 
-#define foreach_esp_decrypt_error                                             \
-  _ (RX_PKTS, "ESP pkts received")                                            \
-  _ (RX_POST_PKTS, "ESP-POST pkts received")                                  \
-  _ (HANDOFF, "hand-off")                                                     \
-  _ (DECRYPTION_FAILED, "ESP decryption failed")                              \
-  _ (INTEG_ERROR, "Integrity check failed")                                   \
-  _ (CRYPTO_ENGINE_ERROR, "crypto engine error (packet dropped)")             \
-  _ (REPLAY, "SA replayed packet")                                            \
-  _ (RUNT, "undersized packet")                                               \
-  _ (NO_BUFFERS, "no buffers (packet dropped)")                               \
-  _ (OVERSIZED_HEADER, "buffer with oversized header (dropped)")              \
-  _ (NO_TAIL_SPACE, "no enough buffer tail space (dropped)")                  \
-  _ (TUN_NO_PROTO, "no tunnel protocol")                                      \
-  _ (UNSUP_PAYLOAD, "unsupported payload")
-
-typedef enum
-{
-#define _(sym,str) ESP_DECRYPT_ERROR_##sym,
-  foreach_esp_decrypt_error
-#undef _
-    ESP_DECRYPT_N_ERROR,
-} esp_decrypt_error_t;
-
-static char *esp_decrypt_error_strings[] = {
-#define _(sym,string) string,
-  foreach_esp_decrypt_error
-#undef _
-};
-
 typedef struct
 {
   u32 seq;
@@ -96,6 +68,8 @@
   ipsec_integ_alg_t integ_alg;
 } esp_decrypt_trace_t;
 
+typedef vl_counter_esp_decrypt_enum_t esp_decrypt_error_t;
+
 /* The number of byres in the hisequence number */
 #define N_HI_ESN_BYTES 4
 
@@ -1481,8 +1455,8 @@
   .format_trace = format_esp_decrypt_trace,
   .type = VLIB_NODE_TYPE_INTERNAL,
 
-  .n_errors = ARRAY_LEN(esp_decrypt_error_strings),
-  .error_strings = esp_decrypt_error_strings,
+  .n_errors = ESP_DECRYPT_N_ERROR,
+  .error_counters = esp_decrypt_error_counters,
 
   .n_next_nodes = ESP_DECRYPT_N_NEXT,
   .next_nodes = {
@@ -1501,8 +1475,8 @@
   .format_trace = format_esp_decrypt_trace,
   .type = VLIB_NODE_TYPE_INTERNAL,
 
-  .n_errors = ARRAY_LEN(esp_decrypt_error_strings),
-  .error_strings = esp_decrypt_error_strings,
+  .n_errors = ESP_DECRYPT_N_ERROR,
+  .error_counters = esp_decrypt_error_counters,
 
   .sibling_of = "esp4-decrypt",
 };
@@ -1513,8 +1487,8 @@
   .format_trace = format_esp_decrypt_trace,
   .type = VLIB_NODE_TYPE_INTERNAL,
 
-  .n_errors = ARRAY_LEN(esp_decrypt_error_strings),
-  .error_strings = esp_decrypt_error_strings,
+  .n_errors = ESP_DECRYPT_N_ERROR,
+  .error_counters = esp_decrypt_error_counters,
 
   .n_next_nodes = ESP_DECRYPT_N_NEXT,
   .next_nodes = {
@@ -1533,8 +1507,8 @@
   .format_trace = format_esp_decrypt_trace,
   .type = VLIB_NODE_TYPE_INTERNAL,
 
-  .n_errors = ARRAY_LEN(esp_decrypt_error_strings),
-  .error_strings = esp_decrypt_error_strings,
+  .n_errors = ESP_DECRYPT_N_ERROR,
+  .error_counters = esp_decrypt_error_counters,
 
   .sibling_of = "esp6-decrypt",
 };
@@ -1544,8 +1518,8 @@
   .vector_size = sizeof (u32),
   .format_trace = format_esp_decrypt_trace,
   .type = VLIB_NODE_TYPE_INTERNAL,
-  .n_errors = ARRAY_LEN(esp_decrypt_error_strings),
-  .error_strings = esp_decrypt_error_strings,
+  .n_errors = ESP_DECRYPT_N_ERROR,
+  .error_counters = esp_decrypt_error_counters,
   .n_next_nodes = ESP_DECRYPT_N_NEXT,
   .next_nodes = {
     [ESP_DECRYPT_NEXT_DROP] = "ip4-drop",
@@ -1563,8 +1537,8 @@
   .format_trace = format_esp_decrypt_trace,
   .type = VLIB_NODE_TYPE_INTERNAL,
 
-  .n_errors = ARRAY_LEN(esp_decrypt_error_strings),
-  .error_strings = esp_decrypt_error_strings,
+  .n_errors = ESP_DECRYPT_N_ERROR,
+  .error_counters = esp_decrypt_error_counters,
 
   .sibling_of = "esp4-decrypt-tun",
 };
@@ -1574,8 +1548,8 @@
   .vector_size = sizeof (u32),
   .format_trace = format_esp_decrypt_trace,
   .type = VLIB_NODE_TYPE_INTERNAL,
-  .n_errors = ARRAY_LEN(esp_decrypt_error_strings),
-  .error_strings = esp_decrypt_error_strings,
+  .n_errors = ESP_DECRYPT_N_ERROR,
+  .error_counters = esp_decrypt_error_counters,
   .n_next_nodes = ESP_DECRYPT_N_NEXT,
   .next_nodes = {
     [ESP_DECRYPT_NEXT_DROP] = "ip6-drop",
@@ -1593,8 +1567,8 @@
   .format_trace = format_esp_decrypt_trace,
   .type = VLIB_NODE_TYPE_INTERNAL,
 
-  .n_errors = ARRAY_LEN(esp_decrypt_error_strings),
-  .error_strings = esp_decrypt_error_strings,
+  .n_errors = ESP_DECRYPT_N_ERROR,
+  .error_counters = esp_decrypt_error_counters,
 
   .sibling_of = "esp6-decrypt-tun",
 };
diff --git a/src/vnet/ipsec/esp_encrypt.c b/src/vnet/ipsec/esp_encrypt.c
index 9d3a835..d28f4f5 100644
--- a/src/vnet/ipsec/esp_encrypt.c
+++ b/src/vnet/ipsec/esp_encrypt.c
@@ -23,6 +23,7 @@
 
 #include <vnet/ipsec/ipsec.h>
 #include <vnet/ipsec/ipsec_tun.h>
+#include <vnet/ipsec/ipsec.api_enum.h>
 #include <vnet/ipsec/esp.h>
 #include <vnet/tunnel/tunnel_dp.h>
 
@@ -43,31 +44,6 @@
     ESP_ENCRYPT_N_NEXT,
 } esp_encrypt_next_t;
 
-#define foreach_esp_encrypt_error                                             \
-  _ (RX_PKTS, "ESP pkts received")                                            \
-  _ (POST_RX_PKTS, "ESP-post pkts received")                                  \
-  _ (HANDOFF, "Hand-off")                                                     \
-  _ (SEQ_CYCLED, "sequence number cycled (packet dropped)")                   \
-  _ (CRYPTO_ENGINE_ERROR, "crypto engine error (packet dropped)")             \
-  _ (CRYPTO_QUEUE_FULL, "crypto queue full (packet dropped)")                 \
-  _ (NO_BUFFERS, "no buffers (packet dropped)")                               \
-  _ (NO_PROTECTION, "no protecting SA (packet dropped)")                      \
-  _ (NO_ENCRYPTION, "no Encrypting SA (packet dropped)")
-
-typedef enum
-{
-#define _(sym,str) ESP_ENCRYPT_ERROR_##sym,
-  foreach_esp_encrypt_error
-#undef _
-    ESP_ENCRYPT_N_ERROR,
-} esp_encrypt_error_t;
-
-static char *esp_encrypt_error_strings[] = {
-#define _(sym,string) string,
-  foreach_esp_encrypt_error
-#undef _
-};
-
 typedef struct
 {
   u32 sa_index;
@@ -84,6 +60,8 @@
   u32 next_index;
 } esp_encrypt_post_trace_t;
 
+typedef vl_counter_esp_encrypt_enum_t esp_encrypt_error_t;
+
 /* packet trace format function */
 static u8 *
 format_esp_encrypt_trace (u8 * s, va_list * args)
@@ -1182,8 +1160,8 @@
   .format_trace = format_esp_encrypt_trace,
   .type = VLIB_NODE_TYPE_INTERNAL,
 
-  .n_errors = ARRAY_LEN (esp_encrypt_error_strings),
-  .error_strings = esp_encrypt_error_strings,
+  .n_errors = ESP_ENCRYPT_N_ERROR,
+  .error_counters = esp_encrypt_error_counters,
 
   .n_next_nodes = ESP_ENCRYPT_N_NEXT,
   .next_nodes = { [ESP_ENCRYPT_NEXT_DROP4] = "ip4-drop",
@@ -1211,8 +1189,8 @@
   .type = VLIB_NODE_TYPE_INTERNAL,
   .sibling_of = "esp4-encrypt",
 
-  .n_errors = ARRAY_LEN(esp_encrypt_error_strings),
-  .error_strings = esp_encrypt_error_strings,
+  .n_errors = ESP_ENCRYPT_N_ERROR,
+  .error_counters = esp_encrypt_error_counters,
 };
 /* *INDENT-ON* */
 
@@ -1232,8 +1210,8 @@
   .type = VLIB_NODE_TYPE_INTERNAL,
   .sibling_of = "esp4-encrypt",
 
-  .n_errors = ARRAY_LEN(esp_encrypt_error_strings),
-  .error_strings = esp_encrypt_error_strings,
+  .n_errors = ESP_ENCRYPT_N_ERROR,
+  .error_counters = esp_encrypt_error_counters,
 };
 /* *INDENT-ON* */
 
@@ -1252,8 +1230,8 @@
   .type = VLIB_NODE_TYPE_INTERNAL,
   .sibling_of = "esp4-encrypt",
 
-  .n_errors = ARRAY_LEN(esp_encrypt_error_strings),
-  .error_strings = esp_encrypt_error_strings,
+  .n_errors = ESP_ENCRYPT_N_ERROR,
+  .error_counters = esp_encrypt_error_counters,
 };
 /* *INDENT-ON* */
 
@@ -1272,8 +1250,8 @@
   .format_trace = format_esp_encrypt_trace,
   .type = VLIB_NODE_TYPE_INTERNAL,
 
-  .n_errors = ARRAY_LEN(esp_encrypt_error_strings),
-  .error_strings = esp_encrypt_error_strings,
+  .n_errors = ESP_ENCRYPT_N_ERROR,
+  .error_counters = esp_encrypt_error_counters,
 
   .n_next_nodes = ESP_ENCRYPT_N_NEXT,
   .next_nodes = {
@@ -1302,8 +1280,8 @@
   .type = VLIB_NODE_TYPE_INTERNAL,
   .sibling_of = "esp4-encrypt-tun",
 
-  .n_errors = ARRAY_LEN(esp_encrypt_error_strings),
-  .error_strings = esp_encrypt_error_strings,
+  .n_errors = ESP_ENCRYPT_N_ERROR,
+  .error_counters = esp_encrypt_error_counters,
 };
 /* *INDENT-ON* */
 
@@ -1322,8 +1300,8 @@
   .format_trace = format_esp_encrypt_trace,
   .type = VLIB_NODE_TYPE_INTERNAL,
 
-  .n_errors = ARRAY_LEN(esp_encrypt_error_strings),
-  .error_strings = esp_encrypt_error_strings,
+  .n_errors = ESP_ENCRYPT_N_ERROR,
+  .error_counters = esp_encrypt_error_counters,
 
   .n_next_nodes = ESP_ENCRYPT_N_NEXT,
   .next_nodes = {
@@ -1354,8 +1332,8 @@
   .type = VLIB_NODE_TYPE_INTERNAL,
   .sibling_of = "esp-mpls-encrypt-tun",
 
-  .n_errors = ARRAY_LEN (esp_encrypt_error_strings),
-  .error_strings = esp_encrypt_error_strings,
+  .n_errors = ESP_ENCRYPT_N_ERROR,
+  .error_counters = esp_encrypt_error_counters,
 };
 /* *INDENT-ON* */
 
@@ -1372,8 +1350,8 @@
   .format_trace = format_esp_encrypt_trace,
   .type = VLIB_NODE_TYPE_INTERNAL,
 
-  .n_errors = ARRAY_LEN(esp_encrypt_error_strings),
-  .error_strings = esp_encrypt_error_strings,
+  .n_errors = ESP_ENCRYPT_N_ERROR,
+  .error_counters = esp_encrypt_error_counters,
 
   .n_next_nodes = ESP_ENCRYPT_N_NEXT,
   .next_nodes = {
@@ -1400,8 +1378,8 @@
   .type = VLIB_NODE_TYPE_INTERNAL,
   .sibling_of = "esp-mpls-encrypt-tun",
 
-  .n_errors = ARRAY_LEN (esp_encrypt_error_strings),
-  .error_strings = esp_encrypt_error_strings,
+  .n_errors = ESP_ENCRYPT_N_ERROR,
+  .error_counters = esp_encrypt_error_counters,
 };
 
 #ifndef CLIB_MARCH_VARIANT
diff --git a/src/vnet/ipsec/ipsec.api b/src/vnet/ipsec/ipsec.api
index 18df893..401564b 100644
--- a/src/vnet/ipsec/ipsec.api
+++ b/src/vnet/ipsec/ipsec.api
@@ -505,6 +505,274 @@
   bool async_enable;
 };
 
+counters esp_decrypt {
+  rx_pkts {
+    severity info;
+    type counter64;
+    units "packets";
+    description "ESP pkts received";
+  };
+  rx_post_pkts {
+    severity info;
+    type counter64;
+    units "packets";
+    description "ESP-POST pkts received";
+  };
+  handoff {
+    severity info;
+    type counter64;
+    units "packets";
+    description "hand-off";
+  };
+  decryption_failed {
+    severity error;
+    type counter64;
+    units "packets";
+    description "ESP decryption failed";
+  };
+  integ_error {
+    severity error;
+    type counter64;
+    units "packets";
+    description "integrity check failed";
+  };
+  crypto_engine_error {
+    severity error;
+    type counter64;
+    units "packets";
+    description "crypto engine error (packet dropped)";
+  };
+  replay {
+    severity error;
+    type counter64;
+    units "packets";
+    description "SA replayed packet";
+  };
+  runt {
+    severity error;
+    type counter64;
+    units "packets";
+    description "undersized packet";
+  };
+  no_buffers {
+    severity error;
+    type counter64;
+    units "packets";
+    description "no buffers (packet dropped)";
+  };
+  oversized_header {
+    severity error;
+    type counter64;
+    units "packets";
+    description "buffer with oversized header (dropped)";
+  };
+  no_tail_space {
+    severity error;
+    type counter64;
+    units "packets";
+    description "no enough buffer tail space (dropped)";
+  };
+  tun_no_proto {
+    severity error;
+    type counter64;
+    units "packets";
+    description "no tunnel protocol";
+  };
+  unsup_payload {
+    severity error;
+    type counter64;
+    units "packets";
+    description "unsupported payload";
+  };
+};
+
+counters esp_encrypt {
+  rx_pkts {
+    severity info;
+    type counter64;
+    units "packets";
+    description "ESP pkts received";
+  };
+  post_rx_pkts {
+    severity info;
+    type counter64;
+    units "packets";
+    description "ESP-post pkts received";
+  };
+  handoff {
+    severity info;
+    type counter64;
+    units "packets";
+    description "Hand-off";
+  };
+  seq_cycled {
+    severity error;
+    type counter64;
+    units "packets";
+    description "sequence number cycled (packet dropped)";
+  };
+  crypto_engine_error {
+    severity error;
+    type counter64;
+    units "packets";
+    description "crypto engine error (packet dropped)";
+  };
+  crypto_queue_full {
+    severity error;
+    type counter64;
+    units "packets";
+    description "crypto queue full (packet dropped)";
+  };
+  no_buffers {
+    severity error;
+    type counter64;
+    units "packets";
+    description "no buffers (packet dropped)";
+  };
+  no_protection {
+    severity error;
+    type counter64;
+    units "packets";
+    description "no protecting SA (packet dropped)";
+  };
+  no_encryption {
+    severity error;
+    type counter64;
+    units "packets";
+    description "no Encrypting SA (packet dropped)";
+  };
+};
+
+counters ah_encrypt {
+  rx_pkts {
+    severity info;
+    type counter64;
+    units "packets";
+    description "AH pkts received";
+  };
+  crypto_engine_error {
+    severity error;
+    type counter64;
+    units "packets";
+    description "crypto engine error (packet dropped)";
+  };
+  seq_cycled {
+    severity error;
+    type counter64;
+    units "packets";
+    description "sequence number cycled (packet dropped)";
+  };
+};
+
+counters ah_decrypt {
+  rx_pkts {
+    severity info;
+    type counter64;
+    units "packets";
+    description "AH pkts received";
+  };
+  decryption_failed {
+    severity error;
+    type counter64;
+    units "packets";
+    description "AH decryption failed";
+  };
+  integ_error {
+    severity error;
+    type counter64;
+    units "packets";
+    description "Integrity check failed";
+  };
+  no_tail_space {
+    severity error;
+    type counter64;
+    units "packets";
+    description "not enough buffer tail space (dropped)";
+  };
+  drop_fragments {
+    severity error;
+    type counter64;
+    units "packets";
+    description "IP fragments drop";
+  };
+  replay {
+    severity error;
+    type counter64;
+    units "packets";
+    description "SA replayed packet";
+  };
+};
+
+counters ipsec_tun {
+  rx {
+    severity info;
+    type counter64;
+    units "packets";
+    description "good packets received";
+  };
+  disabled {
+    severity error;
+    type counter64;
+    units "packets";
+    description "ipsec packets received on disabled interface";
+  };
+  no_tunnel {
+    severity error;
+    type counter64;
+    units "packets";
+    description "no matching tunnel";
+  };
+  tunnel_mismatch {
+    severity error;
+    type counter64;
+    units "packets";
+    description "SPI-tunnel mismatch";
+  };
+  nat_keepalive {
+    severity info;
+    type counter64;
+    units "packets";
+    description "NAT Keepalive";
+  };
+  too_short {
+    severity error;
+    type counter64;
+    units "packets";
+    description "Too Short";
+  };
+  spi_0 {
+    severity info;
+    type counter64;
+    units "packets";
+    description "SPI 0";
+  };
+};
+
+paths {
+  "/err/esp4-encrypt" "esp_encrypt";
+  "/err/esp4-encrypt-post" "esp_encrypt";
+  "/err/esp4-encrypt-tun" "esp_encrypt";
+  "/err/esp4-encrypt-tun-post" "esp_encrypt";
+  "/err/esp6-encrypt" "esp_encrypt";
+  "/err/esp6-encrypt-post" "esp_encrypt";
+  "/err/esp6-encrypt-tun" "esp_encrypt";
+  "/err/esp6-encrypt-tun-post" "esp_encrypt";
+  "/err/esp-mpls-encrypt-tun" "esp_encrypt";
+  "/err/esp-mpls-encrypt-tun-post" "esp_encrypt";
+  "/err/esp4-decrypt" "esp_decrypt";
+  "/err/esp4-decrypt-post" "esp_decrypt";
+  "/err/esp4-decrypt-tun" "esp_decrypt";
+  "/err/esp4-decrypt-tun-post" "esp_decrypt";
+  "/err/esp6-decrypt" "esp_decrypt";
+  "/err/esp6-decrypt-post" "esp_decrypt";
+  "/err/esp6-decrypt-tun" "esp_decrypt";
+  "/err/esp6-decrypt-tun-post" "esp_decrypt";
+  "/err/ah4-encrypt" "ah_encrypt";
+  "/err/ah6-encrypt" "ah_encrypt";
+  "/err/ipsec4-tun-input" "ipsec_tun";
+  "/err/ipsec6-tun-input" "ipsec_tun";
+};
+
 /*
  * Local Variables:
  * eval: (c-set-style "gnu")
diff --git a/src/vnet/ipsec/ipsec_tun_in.c b/src/vnet/ipsec/ipsec_tun_in.c
index c414be0..8e97fbc 100644
--- a/src/vnet/ipsec/ipsec_tun_in.c
+++ b/src/vnet/ipsec/ipsec_tun_in.c
@@ -24,31 +24,10 @@
 #include <vnet/ipsec/ipsec_io.h>
 #include <vnet/ipsec/ipsec_punt.h>
 #include <vnet/ipsec/ipsec_tun.h>
+#include <vnet/ipsec/ipsec.api_enum.h>
 #include <vnet/ip/ip4_input.h>
 
-/* Statistics (not really errors) */
-#define foreach_ipsec_tun_protect_input_error                     \
-  _(RX, "good packets received")                                  \
-  _(DISABLED, "ipsec packets received on disabled interface")     \
-  _(NO_TUNNEL, "no matching tunnel")                              \
-  _(TUNNEL_MISMATCH, "SPI-tunnel mismatch")                       \
-  _(NAT_KEEPALIVE, "NAT Keepalive")                               \
-  _(TOO_SHORT, "Too Short")                                       \
-  _(SPI_0, "SPI 0")
-
-static char *ipsec_tun_protect_input_error_strings[] = {
-#define _(sym,string) string,
-  foreach_ipsec_tun_protect_input_error
-#undef _
-};
-
-typedef enum
-{
-#define _(sym,str) IPSEC_TUN_PROTECT_INPUT_ERROR_##sym,
-  foreach_ipsec_tun_protect_input_error
-#undef _
-    IPSEC_TUN_PROTECT_INPUT_N_ERROR,
-} ipsec_tun_protect_input_error_t;
+typedef vl_counter_ipsec_tun_enum_t ipsec_tun_protect_input_error_t;
 
 typedef enum ipsec_tun_next_t_
 {
@@ -93,14 +72,14 @@
 {
   if (PREDICT_FALSE (0 == esp->spi))
     {
-      b->error = node->errors[IPSEC_TUN_PROTECT_INPUT_ERROR_SPI_0];
+      b->error = node->errors[IPSEC_TUN_ERROR_SPI_0];
       b->punt_reason = ipsec_punt_reason[(ip4->protocol == IP_PROTOCOL_UDP ?
 					  IPSEC_PUNT_IP4_SPI_UDP_0 :
 					  IPSEC_PUNT_IP4_NO_SUCH_TUNNEL)];
     }
   else
     {
-      b->error = node->errors[IPSEC_TUN_PROTECT_INPUT_ERROR_NO_TUNNEL];
+      b->error = node->errors[IPSEC_TUN_ERROR_NO_TUNNEL];
       b->punt_reason = ipsec_punt_reason[IPSEC_PUNT_IP4_NO_SUCH_TUNNEL];
     }
   return VNET_DEVICE_INPUT_NEXT_PUNT;
@@ -110,7 +89,7 @@
 ipsec_ip6_if_no_tunnel (vlib_node_runtime_t * node,
 			vlib_buffer_t * b, const esp_header_t * esp)
 {
-  b->error = node->errors[IPSEC_TUN_PROTECT_INPUT_ERROR_NO_TUNNEL];
+  b->error = node->errors[IPSEC_TUN_ERROR_NO_TUNNEL];
   b->punt_reason = ipsec_punt_reason[IPSEC_PUNT_IP6_NO_SUCH_TUNNEL];
 
   return VNET_DEVICE_INPUT_NEXT_PUNT;
@@ -206,8 +185,7 @@
 	      if (clib_net_to_host_u16 (udp0->length) == 9 &&
 		  esp0->spi_bytes[0] == 0xff)
 		{
-		  b[0]->error =
-		    node->errors[IPSEC_TUN_PROTECT_INPUT_ERROR_NAT_KEEPALIVE];
+		  b[0]->error = node->errors[IPSEC_TUN_ERROR_NAT_KEEPALIVE];
 
 		  next[0] = VNET_DEVICE_INPUT_NEXT_IP4_DROP;
 		  len0 = 0;
@@ -230,7 +208,7 @@
 
       if (len0 < sizeof (esp_header_t))
 	{
-	  b[0]->error = node->errors[IPSEC_TUN_PROTECT_INPUT_ERROR_TOO_SHORT];
+	  b[0]->error = node->errors[IPSEC_TUN_ERROR_TOO_SHORT];
 
 	  next[0] = is_ip6 ? VNET_DEVICE_INPUT_NEXT_IP6_DROP :
 			     VNET_DEVICE_INPUT_NEXT_IP4_DROP;
@@ -309,7 +287,7 @@
 	  vlib_increment_combined_counter
 	    (drop_counter, thread_index, sw_if_index0, 1, len0);
 	  n_disabled++;
-	  b[0]->error = node->errors[IPSEC_TUN_PROTECT_INPUT_ERROR_DISABLED];
+	  b[0]->error = node->errors[IPSEC_TUN_ERROR_DISABLED];
 	  next[0] = is_ip6 ? VNET_DEVICE_INPUT_NEXT_IP6_DROP :
 			     VNET_DEVICE_INPUT_NEXT_IP4_DROP;
 	  goto trace00;
@@ -377,12 +355,10 @@
 				     thread_index,
 				     last_sw_if_index, n_packets, n_bytes);
 
-  vlib_node_increment_counter (vm, node->node_index,
-			       IPSEC_TUN_PROTECT_INPUT_ERROR_RX,
-			       from_frame->n_vectors - (n_disabled +
-							n_no_tunnel));
-  vlib_node_increment_counter (vm, node->node_index,
-			       IPSEC_TUN_PROTECT_INPUT_ERROR_NO_TUNNEL,
+  vlib_node_increment_counter (vm, node->node_index, IPSEC_TUN_ERROR_RX,
+			       from_frame->n_vectors -
+				 (n_disabled + n_no_tunnel));
+  vlib_node_increment_counter (vm, node->node_index, IPSEC_TUN_ERROR_NO_TUNNEL,
 			       n_no_tunnel);
 
   vlib_buffer_enqueue_to_next (vm, node, from, nexts, from_frame->n_vectors);
@@ -403,8 +379,8 @@
   .vector_size = sizeof (u32),
   .format_trace = format_ipsec_tun_protect_input_trace,
   .type = VLIB_NODE_TYPE_INTERNAL,
-  .n_errors = ARRAY_LEN (ipsec_tun_protect_input_error_strings),
-  .error_strings = ipsec_tun_protect_input_error_strings,
+  .n_errors = IPSEC_TUN_N_ERROR,
+  .error_counters = ipsec_tun_error_counters,
   .sibling_of = "device-input",
 };
 /* *INDENT-ON* */
@@ -422,8 +398,8 @@
   .vector_size = sizeof (u32),
   .format_trace = format_ipsec_tun_protect_input_trace,
   .type = VLIB_NODE_TYPE_INTERNAL,
-  .n_errors = ARRAY_LEN (ipsec_tun_protect_input_error_strings),
-  .error_strings = ipsec_tun_protect_input_error_strings,
+  .n_errors = IPSEC_TUN_N_ERROR,
+  .error_counters = ipsec_tun_error_counters,
   .sibling_of = "device-input",
 };
 /* *INDENT-ON* */