ip-neighbor: add api for getting neighbor db config

There is an API call to change neighbor database configuration (i.e.
limit on peer number, aging, and recycling). With this change, make
getting current values of these settings available via the API.

Type: improvement

Change-Id: Ie9394e086b68cf9b28ad98dea162f203f8043cbb
Signed-off-by: Alexander Chernavin <achernavin@netgate.com>
diff --git a/src/vnet/ip-neighbor/ip_neighbor.api b/src/vnet/ip-neighbor/ip_neighbor.api
index a04fcbc..24cddd4 100644
--- a/src/vnet/ip-neighbor/ip_neighbor.api
+++ b/src/vnet/ip-neighbor/ip_neighbor.api
@@ -20,7 +20,7 @@
     called through a shared memory interface. 
 */
 
-option version = "1.0.0";
+option version = "1.0.1";
 
 import "vnet/ip/ip_types.api";
 import "vnet/ethernet/ethernet_types.api";
@@ -126,6 +126,40 @@
   bool recycle;
 };
 
+/** \brief Get neighbor database configuration per AF
+    @param client_index - opaque cookie to identify the sender
+    @param context - sender context, to match reply w/ request
+    @param af - Address family (v4/v6)
+*/
+define ip_neighbor_config_get
+{
+  option in_progress;
+  u32 client_index;
+  u32 context;
+  vl_api_address_family_t af;
+};
+
+/** \brief Neighbor database configuration reply
+    @param context - sender context, to match reply w/ request
+    @param retval - error (0 is "no error")
+    @param af - Address family (v4/v6)
+    @param max_number - The maximum number of neighbours that will be created
+    @param max_age - The maximum age (in seconds) before an inactive neighbour
+                     is flushed
+    @param recycle - If max_number of neighbours is reached and new ones need
+                      to be created, should the oldest neighbour be 'recycled'
+*/
+define ip_neighbor_config_get_reply
+{
+  option in_progress;
+  u32 context;
+  i32 retval;
+  vl_api_address_family_t af;
+  u32 max_number;
+  u32 max_age;
+  bool recycle;
+};
+
 /** \brief IP neighbour replace begin
 
     The use-case is that, for some unspecified reason, the control plane
diff --git a/src/vnet/ip-neighbor/ip_neighbor.c b/src/vnet/ip-neighbor/ip_neighbor.c
index 8e997e4..d7450f9 100644
--- a/src/vnet/ip-neighbor/ip_neighbor.c
+++ b/src/vnet/ip-neighbor/ip_neighbor.c
@@ -1759,6 +1759,17 @@
   return (0);
 }
 
+int
+ip_neighbor_get_config (ip_address_family_t af, u32 *limit, u32 *age,
+			bool *recycle)
+{
+  *limit = ip_neighbor_db[af].ipndb_limit;
+  *age = ip_neighbor_db[af].ipndb_age;
+  *recycle = ip_neighbor_db[af].ipndb_recycle;
+
+  return (0);
+}
+
 static clib_error_t *
 ip_neighbor_config_show (vlib_main_t * vm,
 			 unformat_input_t * input, vlib_cli_command_t * cmd)
diff --git a/src/vnet/ip-neighbor/ip_neighbor.h b/src/vnet/ip-neighbor/ip_neighbor.h
index 8c07df8..cc888ba 100644
--- a/src/vnet/ip-neighbor/ip_neighbor.h
+++ b/src/vnet/ip-neighbor/ip_neighbor.h
@@ -36,6 +36,8 @@
 
 extern int ip_neighbor_config (ip_address_family_t af,
 			       u32 limit, u32 age, bool recycle);
+extern int ip_neighbor_get_config (ip_address_family_t af, u32 *limit,
+				   u32 *age, bool *recycle);
 
 extern void ip_neighbor_del_all (ip_address_family_t af, u32 sw_if_index);
 
diff --git a/src/vnet/ip-neighbor/ip_neighbor_api.c b/src/vnet/ip-neighbor/ip_neighbor_api.c
index 81af862..a5ed546 100644
--- a/src/vnet/ip-neighbor/ip_neighbor_api.c
+++ b/src/vnet/ip-neighbor/ip_neighbor_api.c
@@ -314,6 +314,32 @@
 }
 
 static void
+vl_api_ip_neighbor_config_get_t_handler (vl_api_ip_neighbor_config_get_t *mp)
+{
+  vl_api_ip_neighbor_config_get_reply_t *rmp;
+  int rv;
+  ip_address_family_t af = AF_IP4;
+  u32 max_number = ~0;
+  u32 max_age = ~0;
+  bool recycle = false;
+
+  rv = ip_address_family_decode (mp->af, &af);
+
+  if (!rv)
+    rv = ip_neighbor_get_config (af, &max_number, &max_age, &recycle);
+
+  // clang-format off
+  REPLY_MACRO2 (VL_API_IP_NEIGHBOR_CONFIG_GET_REPLY,
+  ({
+    rmp->af = ip_address_family_encode (af);
+    rmp->max_number = htonl (max_number);
+    rmp->max_age = htonl (max_age);
+    rmp->recycle = recycle;
+  }));
+  // clang-format on
+}
+
+static void
 vl_api_ip_neighbor_replace_begin_t_handler (vl_api_ip_neighbor_replace_begin_t
 					    * mp)
 {