ip: Use .api declared error counters
[vpp.git] / src / vnet / ip / ip_api.c
index f9f9ac7..e03b010 100644 (file)
@@ -514,7 +514,9 @@ vl_api_add_del_ip_punt_redirect_v2_t_handler (
     goto out;
 
   if (0 != n_paths)
-    vec_validate (rpaths, n_paths - 1);
+    {
+      vec_validate (rpaths, n_paths - 1);
+    }
 
   for (ii = 0; ii < n_paths; ii++)
     {
@@ -601,6 +603,32 @@ ip_table_delete (fib_protocol_t fproto, u32 table_id, u8 is_api)
     }
 }
 
+/*
+ * Returns an unused table id, and ~0 if it can't find one.
+ */
+u32
+ip_table_get_unused_id (fib_protocol_t fproto)
+{
+  int i, j;
+  static u32 seed = 0;
+  /* limit to 1M tries */
+  for (j = 0; j < 1 << 10; j++)
+    {
+      seed = random_u32 (&seed);
+      for (i = 0; i < 1 << 10; i++)
+       {
+         /* look around randomly generated id */
+         seed += (2 * (i % 2) - 1) * i;
+         if (seed == ~0)
+           continue;
+         if (fib_table_find (fproto, seed) == ~0)
+           return seed;
+       }
+    }
+
+  return ~0;
+}
+
 void
 vl_api_ip_table_add_del_t_handler (vl_api_ip_table_add_del_t * mp)
 {
@@ -622,6 +650,29 @@ vl_api_ip_table_add_del_t_handler (vl_api_ip_table_add_del_t * mp)
   REPLY_MACRO (VL_API_IP_TABLE_ADD_DEL_REPLY);
 }
 
+void
+vl_api_ip_table_allocate_t_handler (vl_api_ip_table_allocate_t *mp)
+{
+  vl_api_ip_table_allocate_reply_t *rmp;
+  fib_protocol_t fproto =
+    (mp->table.is_ip6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4);
+  u32 table_id = ntohl (mp->table.table_id);
+  int rv = 0;
+
+  if (~0 == table_id)
+    table_id = ip_table_get_unused_id (fproto);
+
+  if (~0 == table_id)
+    rv = VNET_API_ERROR_EAGAIN;
+  else
+    ip_table_create (fproto, table_id, 1, mp->table.name);
+
+  REPLY_MACRO2 (VL_API_IP_TABLE_ALLOCATE_REPLY, {
+    clib_memcpy_fast (&rmp->table, &mp->table, sizeof (mp->table));
+    rmp->table.table_id = htonl (table_id);
+  })
+}
+
 static int
 ip_route_add_del_t_handler (vl_api_ip_route_add_del_t * mp, u32 * stats_index)
 {
@@ -895,20 +946,14 @@ ip_table_create (fib_protocol_t fproto,
       fib_index = fib_table_find (fproto, table_id);
       mfib_index = mfib_table_find (fproto, table_id);
 
-      if (~0 == fib_index)
-       {
-         fib_table_find_or_create_and_lock_w_name (fproto, table_id,
-                                                   (is_api ?
-                                                    FIB_SOURCE_API :
-                                                    FIB_SOURCE_CLI), name);
-       }
-      if (~0 == mfib_index)
-       {
-         mfib_table_find_or_create_and_lock_w_name (fproto, table_id,
-                                                    (is_api ?
-                                                     MFIB_SOURCE_API :
-                                                     MFIB_SOURCE_CLI), name);
-       }
+      /*
+       * Always try to re-lock in case the fib was deleted by an API call
+       * but was not yet freed because some other locks were held
+       */
+      fib_table_find_or_create_and_lock_w_name (
+       fproto, table_id, (is_api ? FIB_SOURCE_API : FIB_SOURCE_CLI), name);
+      mfib_table_find_or_create_and_lock_w_name (
+       fproto, table_id, (is_api ? MFIB_SOURCE_API : MFIB_SOURCE_CLI), name);
 
       if ((~0 == fib_index) || (~0 == mfib_index))
        call_elf_section_ip_table_callbacks (vnm, table_id, 1 /* is_add */ ,
@@ -936,9 +981,8 @@ mroute_add_del_handler (u8 is_add,
     {
       if (is_add)
        {
-         mfib_entry_index =
-           mfib_table_entry_paths_update (fib_index, prefix,
-                                          MFIB_SOURCE_API, rpaths);
+         mfib_entry_index = mfib_table_entry_paths_update (
+           fib_index, prefix, MFIB_SOURCE_API, entry_flags, rpaths);
        }
       else
        {
@@ -1193,7 +1237,7 @@ vl_api_ip_dump_t_handler (vl_api_ip_dump_t * mp)
 
   /* Gather interfaces. */
   sorted_sis = vec_new (vnet_sw_interface_t, pool_elts (im->sw_interfaces));
-  _vec_len (sorted_sis) = 0;
+  vec_set_len (sorted_sis, 0);
   /* *INDENT-OFF* */
   pool_foreach (si, im->sw_interfaces)
    {
@@ -1831,6 +1875,30 @@ void
   REPLY_MACRO (VL_API_IP_REASSEMBLY_ENABLE_DISABLE_REPLY);
 }
 
+void
+vl_api_ip_local_reass_enable_disable_t_handler (
+  vl_api_ip_local_reass_enable_disable_t *mp)
+{
+  vl_api_ip_local_reass_enable_disable_reply_t *rmp;
+  int rv = 0;
+
+  ip4_local_full_reass_enable_disable (mp->enable_ip4);
+  ip6_local_full_reass_enable_disable (mp->enable_ip6);
+
+  REPLY_MACRO (VL_API_IP_LOCAL_REASS_ENABLE_DISABLE_REPLY);
+}
+
+void
+vl_api_ip_local_reass_get_t_handler (vl_api_ip_local_reass_get_t *mp)
+{
+  vl_api_ip_local_reass_get_reply_t *rmp;
+  int rv = 0;
+  REPLY_MACRO2 (VL_API_IP_LOCAL_REASS_GET, {
+    rmp->ip4_is_enabled = ip4_local_full_reass_enabled ();
+    rmp->ip6_is_enabled = ip6_local_full_reass_enabled ();
+  });
+}
+
 static walk_rc_t
 send_ip_punt_redirect_details (u32 rx_sw_if_index,
                               const ip_punt_redirect_rx_t * ipr, void *arg)
@@ -2051,10 +2119,10 @@ ip_api_hookup (vlib_main_t * vm)
   /*
    * Mark the route add/del API as MP safe
    */
-  am->is_mp_safe[VL_API_IP_ROUTE_ADD_DEL] = 1;
-  am->is_mp_safe[VL_API_IP_ROUTE_ADD_DEL_REPLY] = 1;
-  am->is_mp_safe[VL_API_IP_ROUTE_ADD_DEL_V2] = 1;
-  am->is_mp_safe[VL_API_IP_ROUTE_ADD_DEL_V2_REPLY] = 1;
+  vl_api_set_msg_thread_safe (am, VL_API_IP_ROUTE_ADD_DEL, 1);
+  vl_api_set_msg_thread_safe (am, VL_API_IP_ROUTE_ADD_DEL_REPLY, 1);
+  vl_api_set_msg_thread_safe (am, VL_API_IP_ROUTE_ADD_DEL_V2, 1);
+  vl_api_set_msg_thread_safe (am, VL_API_IP_ROUTE_ADD_DEL_V2_REPLY, 1);
 
   /*
    * Set up the (msg_name, crc, message-id) table