ip-neighbor: ARP and ND stats per-interface.

Type: feature

stats of the like from:
  https://datatracker.ietf.org/doc/html/draft-ietf-rtgwg-arp-yang-model-03#section-4

Signed-off-by: Neale Ranns <neale@graphiant.com>
Change-Id: Icb1bf4f6f7e6ccc2f44b0008d4774b61cae96184
diff --git a/src/vnet/ip6-nd/ip6_nd.c b/src/vnet/ip6-nd/ip6_nd.c
index 772c811..513d2bf 100644
--- a/src/vnet/ip6-nd/ip6_nd.c
+++ b/src/vnet/ip6-nd/ip6_nd.c
@@ -90,6 +90,7 @@
 	  icmp6_neighbor_discovery_ethernet_link_layer_address_option_t *o0;
 	  u32 bi0, options_len0, sw_if_index0, next0, error0;
 	  u32 ip6_sadd_link_local, ip6_sadd_unspecified;
+	  ip_neighbor_counter_type_t c_type;
 	  int is_rewrite0;
 	  u32 ni0;
 
@@ -230,16 +231,24 @@
 	    }
 
 	  if (is_solicitation)
-	    next0 = (error0 != ICMP6_ERROR_NONE
-		     ? ICMP6_NEIGHBOR_SOLICITATION_NEXT_DROP
-		     : ICMP6_NEIGHBOR_SOLICITATION_NEXT_REPLY);
+	    {
+	      next0 = (error0 != ICMP6_ERROR_NONE ?
+			       ICMP6_NEIGHBOR_SOLICITATION_NEXT_DROP :
+			       ICMP6_NEIGHBOR_SOLICITATION_NEXT_REPLY);
+	      c_type = IP_NEIGHBOR_CTR_REQUEST;
+	    }
 	  else
 	    {
 	      next0 = 0;
 	      error0 = error0 == ICMP6_ERROR_NONE ?
 		ICMP6_ERROR_NEIGHBOR_ADVERTISEMENTS_RX : error0;
+	      c_type = IP_NEIGHBOR_CTR_REPLY;
 	    }
 
+	  vlib_increment_simple_counter (
+	    &ip_neighbor_counters[AF_IP6].ipnc[VLIB_RX][c_type],
+	    vm->thread_index, sw_if_index0, 1);
+
 	  if (is_solicitation && error0 == ICMP6_ERROR_NONE)
 	    {
 	      icmp6_send_neighbor_advertisement (vm, p0, ip0, h0, o0,
diff --git a/src/vnet/ip6-nd/ip6_nd_inline.h b/src/vnet/ip6-nd/ip6_nd_inline.h
index ad0c3a3..5e8b9d6 100644
--- a/src/vnet/ip6-nd/ip6_nd_inline.h
+++ b/src/vnet/ip6-nd/ip6_nd_inline.h
@@ -22,6 +22,7 @@
 #include <vnet/ethernet/ethernet.h>
 #include <vnet/ip/icmp46_packet.h>
 #include <vnet/ip/ip6.h>
+#include <vnet/ip-neighbor/ip_neighbor_types.h>
 
 typedef enum
 {
@@ -88,6 +89,10 @@
   vnet_buffer (b)->sw_if_index[VLIB_TX] = sw_if_index0;
   vnet_buffer (b)->sw_if_index[VLIB_RX] =
     vnet_main.local_interface_sw_if_index;
+
+  vlib_increment_simple_counter (
+    &ip_neighbor_counters[AF_IP6].ipnc[VLIB_TX][IP_NEIGHBOR_CTR_REPLY],
+    vm->thread_index, sw_if_index0, 1);
 }
 
 #endif /* included_ip6_nd_inline_h */