vlib: don't leak node frames on refork
[vpp.git] / src / vlib / drop.c
index 2b245b5..2a10225 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include <vlib/vlib.h>
+#include <vppinfra/vector/count_equal.h>
 
 typedef enum
 {
@@ -27,8 +28,8 @@ typedef enum
 static u8 *
 validate_error (vlib_main_t * vm, vlib_error_t * e, u32 index)
 {
-  uword node_index = vlib_error_get_node (e[0]);
-  uword code = vlib_error_get_code (e[0]);
+  uword node_index = vlib_error_get_node (&vm->node_main, e[0]);
+  uword code = vlib_error_get_code (&vm->node_main, e[0]);
   vlib_node_t *n;
 
   if (node_index >= vec_len (vm->node_main.nodes))
@@ -69,11 +70,12 @@ counter_index (vlib_main_t * vm, vlib_error_t e)
   vlib_node_t *n;
   u32 ci, ni;
 
-  ni = vlib_error_get_node (e);
+  ni = vlib_error_get_node (&vm->node_main, e);
   n = vlib_get_node (vm, ni);
 
-  ci = vlib_error_get_code (e);
-  ASSERT (ci < n->n_errors);
+  ci = vlib_error_get_code (&vm->node_main, e);
+  if (ci >= n->n_errors)
+    return CLIB_U32_MAX;
 
   ci += n->error_heap_index;
 
@@ -90,9 +92,11 @@ format_error_trace (u8 * s, va_list * va)
   vlib_error_main_t *em = &vm->error_main;
   u32 i;
 
-  error_node = vlib_get_node (vm, vlib_error_get_node (e[0]));
-  i = counter_index (vm, e[0]);
-  s = format (s, "%v: %s", error_node->name, em->error_strings_heap[i]);
+  error_node = vlib_get_node (vm, vlib_error_get_node (&vm->node_main, e[0]));
+  i = counter_index (vm, vlib_error_get_code (&vm->node_main, e[0])) +
+    error_node->error_heap_index;
+  if (i != CLIB_U32_MAX)
+    s = format (s, "%v: %s", error_node->name, em->counters_heap[i].desc);
 
   return s;
 }
@@ -220,7 +224,8 @@ process_drop_punt (vlib_main_t * vm,
       n_left -= count;
 
       c_index = counter_index (vm, error[0]);
-      em->counters[c_index] += count;
+      if (c_index != CLIB_U32_MAX)
+       em->counters[c_index] += count;
 
       vlib_error_elog_count (vm, c_index, count);
     }
@@ -231,7 +236,7 @@ process_drop_punt (vlib_main_t * vm,
 
       /* If there is no punt function, free the frame as well. */
       if (disposition == ERROR_DISPOSITION_PUNT && !vm->os_punt_frame)
-       vlib_frame_free (vm, node, frame);
+       vlib_frame_free (vm, frame);
     }
   else
     vm->os_punt_frame (vm, node, frame);