vppinfra: add mapped pcap file support
[vpp.git] / src / vlib / main.c
index 89202be..0786465 100644 (file)
@@ -91,10 +91,11 @@ vlib_frame_find_magic (vlib_frame_t * f, vlib_node_t * node)
   return p;
 }
 
-static vlib_frame_size_t *
+static inline vlib_frame_size_t *
 get_frame_size_info (vlib_node_main_t * nm,
                     u32 n_scalar_bytes, u32 n_vector_bytes)
 {
+#ifdef VLIB_SUPPORTS_ARBITRARY_SCALAR_SIZES
   uword key = (n_scalar_bytes << 16) | n_vector_bytes;
   uword *p, i;
 
@@ -109,9 +110,14 @@ get_frame_size_info (vlib_node_main_t * nm,
     }
 
   return vec_elt_at_index (nm->frame_sizes, i);
+#else
+  ASSERT (vlib_frame_bytes (n_scalar_bytes, n_vector_bytes)
+         == (vlib_frame_bytes (0, 4)));
+  return vec_elt_at_index (nm->frame_sizes, 0);
+#endif
 }
 
-static u32
+static vlib_frame_t *
 vlib_frame_alloc_to_node (vlib_main_t * vm, u32 to_node_index,
                          u32 frame_flags)
 {
@@ -119,7 +125,7 @@ vlib_frame_alloc_to_node (vlib_main_t * vm, u32 to_node_index,
   vlib_frame_size_t *fs;
   vlib_node_t *to_node;
   vlib_frame_t *f;
-  u32 fi, l, n, scalar_size, vector_size;
+  u32 l, n, scalar_size, vector_size;
 
   to_node = vlib_get_node (vm, to_node_index);
 
@@ -128,17 +134,15 @@ vlib_frame_alloc_to_node (vlib_main_t * vm, u32 to_node_index,
 
   fs = get_frame_size_info (nm, scalar_size, vector_size);
   n = vlib_frame_bytes (scalar_size, vector_size);
-  if ((l = vec_len (fs->free_frame_indices)) > 0)
+  if ((l = vec_len (fs->free_frames)) > 0)
     {
       /* Allocate from end of free list. */
-      fi = fs->free_frame_indices[l - 1];
-      f = vlib_get_frame_no_check (vm, fi);
-      _vec_len (fs->free_frame_indices) = l - 1;
+      f = fs->free_frames[l - 1];
+      _vec_len (fs->free_frames) = l - 1;
     }
   else
     {
       f = clib_mem_alloc_aligned_no_fail (n, VLIB_FRAME_ALIGN);
-      fi = vlib_frame_index_no_check (vm, f);
     }
 
   /* Poison frame when debugging. */
@@ -161,12 +165,12 @@ vlib_frame_alloc_to_node (vlib_main_t * vm, u32 to_node_index,
 
   fs->n_alloc_frames += 1;
 
-  return fi;
+  return f;
 }
 
 /* Allocate a frame for from FROM_NODE to TO_NODE via TO_NEXT_INDEX.
    Returns frame index. */
-static u32
+static vlib_frame_t *
 vlib_frame_alloc (vlib_main_t * vm, vlib_node_runtime_t * from_node_runtime,
                  u32 to_next_index)
 {
@@ -182,10 +186,10 @@ vlib_frame_alloc (vlib_main_t * vm, vlib_node_runtime_t * from_node_runtime,
 vlib_frame_t *
 vlib_get_frame_to_node (vlib_main_t * vm, u32 to_node_index)
 {
-  u32 fi = vlib_frame_alloc_to_node (vm, to_node_index,
-                                    /* frame_flags */
-                                    VLIB_FRAME_FREE_AFTER_DISPATCH);
-  return vlib_get_frame (vm, fi);
+  vlib_frame_t *f = vlib_frame_alloc_to_node (vm, to_node_index,
+                                             /* frame_flags */
+                                             VLIB_FRAME_FREE_AFTER_DISPATCH);
+  return vlib_get_frame (vm, f);
 }
 
 void
@@ -202,7 +206,7 @@ vlib_put_frame_to_node (vlib_main_t * vm, u32 to_node_index, vlib_frame_t * f)
   vec_add2 (vm->node_main.pending_frames, p, 1);
 
   f->frame_flags |= VLIB_FRAME_PENDING;
-  p->frame_index = vlib_frame_index (vm, f);
+  p->frame = vlib_get_frame (vm, f);
   p->node_runtime_index = to_node->runtime_index;
   p->next_frame_index = VLIB_PENDING_FRAME_NO_NEXT_FRAME;
 }
@@ -214,28 +218,24 @@ vlib_frame_free (vlib_main_t * vm, vlib_node_runtime_t * r, vlib_frame_t * f)
   vlib_node_main_t *nm = &vm->node_main;
   vlib_node_t *node;
   vlib_frame_size_t *fs;
-  u32 frame_index;
 
   ASSERT (f->frame_flags & VLIB_FRAME_IS_ALLOCATED);
 
   node = vlib_get_node (vm, r->node_index);
   fs = get_frame_size_info (nm, node->scalar_size, node->vector_size);
 
-  frame_index = vlib_frame_index (vm, f);
-
   ASSERT (f->frame_flags & VLIB_FRAME_IS_ALLOCATED);
 
   /* No next frames may point to freed frame. */
   if (CLIB_DEBUG > 0)
     {
       vlib_next_frame_t *nf;
-      vec_foreach (nf, vm->node_main.next_frames)
-       ASSERT (nf->frame_index != frame_index);
+      vec_foreach (nf, vm->node_main.next_frames) ASSERT (nf->frame != f);
     }
 
   f->frame_flags &= ~(VLIB_FRAME_IS_ALLOCATED | VLIB_FRAME_NO_APPEND);
 
-  vec_add1 (fs->free_frame_indices, frame_index);
+  vec_add1 (fs->free_frames, f);
   ASSERT (fs->n_alloc_frames > 0);
   fs->n_alloc_frames -= 1;
 }
@@ -251,7 +251,7 @@ show_frame_stats (vlib_main_t * vm,
   vec_foreach (fs, nm->frame_sizes)
   {
     u32 n_alloc = fs->n_alloc_frames;
-    u32 n_free = vec_len (fs->free_frame_indices);
+    u32 n_free = vec_len (fs->free_frames);
 
     if (n_alloc + n_free > 0)
       vlib_cli_output (vm, "%=6d%=12d%=12d",
@@ -315,11 +315,11 @@ vlib_next_frame_change_ownership (vlib_main_t * vm,
       if (next_frame->flags & VLIB_FRAME_PENDING)
        {
          vlib_pending_frame_t *p;
-         if (next_frame->frame_index != ~0)
+         if (next_frame->frame != NULL)
            {
              vec_foreach (p, nm->pending_frames)
              {
-               if (p->frame_index == next_frame->frame_index)
+               if (p->frame == next_frame->frame)
                  {
                    p->next_frame_index =
                      next_frame - vm->node_main.next_frames;
@@ -371,11 +371,11 @@ vlib_get_next_frame_internal (vlib_main_t * vm,
   /* ??? Don't need valid flag: can use frame_index == ~0 */
   if (PREDICT_FALSE (!(nf->flags & VLIB_FRAME_IS_ALLOCATED)))
     {
-      nf->frame_index = vlib_frame_alloc (vm, node, next_index);
+      nf->frame = vlib_frame_alloc (vm, node, next_index);
       nf->flags |= VLIB_FRAME_IS_ALLOCATED;
     }
 
-  f = vlib_get_frame (vm, nf->frame_index);
+  f = nf->frame;
 
   /* Has frame been removed from pending vector (e.g. finished dispatching)?
      If so we can reuse frame. */
@@ -397,13 +397,12 @@ vlib_get_next_frame_internal (vlib_main_t * vm,
          two redundant frames from node -> next node. */
       if (!(nf->flags & VLIB_FRAME_NO_FREE_AFTER_DISPATCH))
        {
-         vlib_frame_t *f_old = vlib_get_frame (vm, nf->frame_index);
+         vlib_frame_t *f_old = vlib_get_frame (vm, nf->frame);
          f_old->frame_flags |= VLIB_FRAME_FREE_AFTER_DISPATCH;
        }
 
       /* Allocate new frame to replace full one. */
-      nf->frame_index = vlib_frame_alloc (vm, node, next_index);
-      f = vlib_get_frame (vm, nf->frame_index);
+      f = nf->frame = vlib_frame_alloc (vm, node, next_index);
       n_used = f->n_vectors;
     }
 
@@ -432,7 +431,7 @@ vlib_put_next_frame_validate (vlib_main_t * vm,
   u32 n_before, n_after;
 
   nf = vlib_node_runtime_get_next_frame (vm, rt, next_index);
-  f = vlib_get_frame (vm, nf->frame_index);
+  f = vlib_get_frame (vm, nf->frame);
 
   ASSERT (n_vectors_left <= VLIB_FRAME_SIZE);
   n_after = VLIB_FRAME_SIZE - n_vectors_left;
@@ -469,7 +468,7 @@ vlib_put_next_frame (vlib_main_t * vm,
     vlib_put_next_frame_validate (vm, r, next_index, n_vectors_left);
 
   nf = vlib_node_runtime_get_next_frame (vm, r, next_index);
-  f = vlib_get_frame (vm, nf->frame_index);
+  f = vlib_get_frame (vm, nf->frame);
 
   /* Make sure that magic number is still there.  Otherwise, caller
      has overrun frame meta data. */
@@ -505,7 +504,7 @@ vlib_put_next_frame (vlib_main_t * vm,
 
          vec_add2 (nm->pending_frames, p, 1);
 
-         p->frame_index = nf->frame_index;
+         p->frame = nf->frame;
          p->node_runtime_index = nf->node_runtime_index;
          p->next_frame_index = nf - nm->next_frames;
          nf->flags |= VLIB_FRAME_PENDING;
@@ -519,7 +518,7 @@ vlib_put_next_frame (vlib_main_t * vm,
           */
          if (0 && r->thread_index != next_runtime->thread_index)
            {
-             nf->frame_index = ~0;
+             nf->frame = NULL;
              nf->flags &= ~(VLIB_FRAME_PENDING | VLIB_FRAME_IS_ALLOCATED);
            }
        }
@@ -674,13 +673,16 @@ vlib_node_runtime_update_stats (vlib_main_t * vm,
   return r;
 }
 
-static inline void
-vlib_node_runtime_perf_counter (vlib_main_t * vm, u64 * pmc0, u64 * pmc1)
+always_inline void
+vlib_node_runtime_perf_counter (vlib_main_t * vm, u64 * pmc0, u64 * pmc1,
+                               vlib_node_runtime_t * node,
+                               vlib_frame_t * frame, int before_or_after)
 {
   *pmc0 = 0;
   *pmc1 = 0;
-  if (PREDICT_FALSE (vm->vlib_node_runtime_perf_counter_cb != 0))
-    (*vm->vlib_node_runtime_perf_counter_cb) (vm, pmc0, pmc1);
+  if (PREDICT_FALSE (vec_len (vm->vlib_node_runtime_perf_counter_cbs) != 0))
+    clib_call_callbacks (vm->vlib_node_runtime_perf_counter_cbs, vm, pmc0,
+                        pmc1, node, frame, before_or_after);
 }
 
 always_inline void
@@ -1010,8 +1012,8 @@ format_buffer_metadata (u8 * s, va_list * args)
              (u32) (b->error), (u32) (b->ref_count),
              (u32) (b->buffer_pool_index));
   s = format (s,
-             "trace_index: %d, len_not_first_buf: %d\n",
-             b->trace_index, b->total_length_not_including_first_buffer);
+             "trace_handle: 0x%x, len_not_first_buf: %d\n",
+             b->trace_handle, b->total_length_not_including_first_buffer);
   return s;
 }
 
@@ -1082,7 +1084,8 @@ dispatch_pcap_trace (vlib_main_t * vm,
          if (PREDICT_FALSE (b->flags & VLIB_BUFFER_IS_TRACED))
            {
              vlib_trace_header_t **h
-               = pool_elt_at_index (tm->trace_buffer_pool, b->trace_index);
+               = pool_elt_at_index (tm->trace_buffer_pool,
+                                    vlib_buffer_get_trace_index (b));
 
              vm->pcap_buffer = format (vm->pcap_buffer, "%U%c",
                                        format_vlib_trace, vm, h[0], 0);
@@ -1175,7 +1178,8 @@ dispatch_node (vlib_main_t * vm,
                             last_time_stamp, frame ? frame->n_vectors : 0,
                             /* is_after */ 0);
 
-  vlib_node_runtime_perf_counter (vm, &pmc_before[0], &pmc_before[1]);
+  vlib_node_runtime_perf_counter (vm, &pmc_before[0], &pmc_before[1],
+                                 node, frame, 0 /* before */ );
 
   /*
    * Turn this on if you run into
@@ -1209,7 +1213,8 @@ dispatch_node (vlib_main_t * vm,
    * To validate accounting: pmc_delta = t - pmc_before;
    * perf ticks should equal clocks/pkt...
    */
-  vlib_node_runtime_perf_counter (vm, &pmc_after[0], &pmc_after[1]);
+  vlib_node_runtime_perf_counter (vm, &pmc_after[0], &pmc_after[1], node,
+                                 frame, 1 /* after */ );
 
   pmc_delta[0] = pmc_after[0] - pmc_before[0];
   pmc_delta[1] = pmc_after[1] - pmc_before[1];
@@ -1323,7 +1328,7 @@ dispatch_pending_node (vlib_main_t * vm, uword pending_frame_index,
   vlib_frame_t *f;
   vlib_next_frame_t *nf, nf_dummy;
   vlib_node_runtime_t *n;
-  u32 restore_frame_index;
+  vlib_frame_t *restore_frame;
   vlib_pending_frame_t *p;
 
   /* See comment below about dangling references to nm->pending_frames */
@@ -1332,13 +1337,13 @@ dispatch_pending_node (vlib_main_t * vm, uword pending_frame_index,
   n = vec_elt_at_index (nm->nodes_by_type[VLIB_NODE_TYPE_INTERNAL],
                        p->node_runtime_index);
 
-  f = vlib_get_frame (vm, p->frame_index);
+  f = vlib_get_frame (vm, p->frame);
   if (p->next_frame_index == VLIB_PENDING_FRAME_NO_NEXT_FRAME)
     {
       /* No next frame: so use dummy on stack. */
       nf = &nf_dummy;
       nf->flags = f->frame_flags & VLIB_NODE_FLAG_TRACE;
-      nf->frame_index = ~p->frame_index;
+      nf->frame = NULL;
     }
   else
     nf = vec_elt_at_index (nm->next_frames, p->next_frame_index);
@@ -1347,13 +1352,13 @@ dispatch_pending_node (vlib_main_t * vm, uword pending_frame_index,
 
   /* Force allocation of new frame while current frame is being
      dispatched. */
-  restore_frame_index = ~0;
-  if (nf->frame_index == p->frame_index)
+  restore_frame = NULL;
+  if (nf->frame == p->frame)
     {
-      nf->frame_index = ~0;
+      nf->frame = NULL;
       nf->flags &= ~VLIB_FRAME_IS_ALLOCATED;
       if (!(n->flags & VLIB_NODE_FLAG_FRAME_NO_FREE_AFTER_DISPATCH))
-       restore_frame_index = p->frame_index;
+       restore_frame = p->frame;
     }
 
   /* Frame must be pending. */
@@ -1375,7 +1380,7 @@ dispatch_pending_node (vlib_main_t * vm, uword pending_frame_index,
   f->frame_flags &= ~(VLIB_FRAME_PENDING | VLIB_FRAME_NO_APPEND);
 
   /* Frame is ready to be used again, so restore it. */
-  if (restore_frame_index != ~0)
+  if (restore_frame != NULL)
     {
       /*
        * We musn't restore a frame that is flagged to be freed. This
@@ -1403,10 +1408,10 @@ dispatch_pending_node (vlib_main_t * vm, uword pending_frame_index,
       nf = vec_elt_at_index (nm->next_frames, p->next_frame_index);
       nf->flags |= VLIB_FRAME_IS_ALLOCATED;
 
-      if (~0 == nf->frame_index)
+      if (NULL == nf->frame)
        {
          /* no new frame has been assigned to this node, use the saved one */
-         nf->frame_index = restore_frame_index;
+         nf->frame = restore_frame;
          f->n_vectors = 0;
        }
       else
@@ -1540,7 +1545,7 @@ dispatch_process (vlib_main_t * vm,
       n_vectors = 0;
       pool_get (nm->suspended_process_frames, pf);
       pf->node_runtime_index = node->runtime_index;
-      pf->frame_index = f ? vlib_frame_index (vm, f) : ~0;
+      pf->frame = f;
       pf->next_frame_index = ~0;
 
       p->n_suspends += 1;
@@ -1608,7 +1613,7 @@ dispatch_suspended_process (vlib_main_t * vm,
 
   node_runtime = &p->node_runtime;
   node = vlib_get_node (vm, node_runtime->node_index);
-  f = pf->frame_index != ~0 ? vlib_get_frame (vm, pf->frame_index) : 0;
+  f = pf->frame;
 
   vlib_elog_main_loop_event (vm, node_runtime->node_index, t,
                             f ? f->n_vectors : 0, /* is_after */ 0);
@@ -1673,6 +1678,7 @@ vlib_main_or_worker_loop (vlib_main_t * vm, int is_main)
   u64 cpu_time_now;
   vlib_frame_queue_main_t *fqm;
   u32 *last_node_runtime_indices = 0;
+  u32 frame_queue_check_counter = 0;
 
   /* Initialize pending node vector. */
   if (is_main)
@@ -1709,6 +1715,14 @@ vlib_main_or_worker_loop (vlib_main_t * vm, int is_main)
   if (is_main)
     {
       uword i;
+
+      /*
+       * Perform an initial barrier sync. Pays no attention to
+       * the barrier sync hold-down timer scheme, which won't work
+       * at this point in time.
+       */
+      vlib_worker_thread_initial_barrier_sync_and_release (vm);
+
       nm->current_process_index = ~0;
       for (i = 0; i < vec_len (nm->processes); i++)
        cpu_time_now = dispatch_process (vm, nm->processes[i], /* frame */ 0,
@@ -1728,11 +1742,28 @@ vlib_main_or_worker_loop (vlib_main_t * vm, int is_main)
       if (!is_main)
        {
          vlib_worker_thread_barrier_check ();
-         vec_foreach (fqm, tm->frame_queue_mains)
-           vlib_frame_queue_dequeue (vm, fqm);
-         if (PREDICT_FALSE (vm->worker_thread_main_loop_callback != 0))
-           ((void (*)(vlib_main_t *)) vm->worker_thread_main_loop_callback)
-             (vm);
+         if (PREDICT_FALSE (vm->check_frame_queues +
+                            frame_queue_check_counter))
+           {
+             u32 processed = 0;
+
+             if (vm->check_frame_queues)
+               {
+                 frame_queue_check_counter = 100;
+                 vm->check_frame_queues = 0;
+               }
+
+             vec_foreach (fqm, tm->frame_queue_mains)
+               processed += vlib_frame_queue_dequeue (vm, fqm);
+
+             /* No handoff queue work found? */
+             if (processed)
+               frame_queue_check_counter = 100;
+             else
+               frame_queue_check_counter--;
+           }
+         if (PREDICT_FALSE (vec_len (vm->worker_thread_main_loop_callbacks)))
+           clib_call_callbacks (vm->worker_thread_main_loop_callbacks, vm);
        }
 
       /* Process pre-input nodes. */
@@ -1952,6 +1983,29 @@ clib_error_t *name (vlib_main_t *vm) { return 0; }
 foreach_weak_reference_stub;
 #undef _
 
+void vl_api_set_elog_main (elog_main_t * m) __attribute__ ((weak));
+void
+vl_api_set_elog_main (elog_main_t * m)
+{
+  clib_warning ("STUB");
+}
+
+int vl_api_set_elog_trace_api_messages (int enable) __attribute__ ((weak));
+int
+vl_api_set_elog_trace_api_messages (int enable)
+{
+  clib_warning ("STUB");
+  return 0;
+}
+
+int vl_api_get_elog_trace_api_messages (void) __attribute__ ((weak));
+int
+vl_api_get_elog_trace_api_messages (void)
+{
+  clib_warning ("STUB");
+  return 0;
+}
+
 /* Main function. */
 int
 vlib_main (vlib_main_t * volatile vm, unformat_input_t * input)
@@ -1968,6 +2022,8 @@ vlib_main (vlib_main_t * volatile vm, unformat_input_t * input)
     vm->elog_main.event_ring_size = 128 << 10;
   elog_init (&vm->elog_main, vm->elog_main.event_ring_size);
   elog_enable_disable (&vm->elog_main, 1);
+  vl_api_set_elog_main (&vm->elog_main);
+  (void) vl_api_set_elog_trace_api_messages (1);
 
   /* Default name. */
   if (!vm->name)
@@ -1979,19 +2035,19 @@ vlib_main (vlib_main_t * volatile vm, unformat_input_t * input)
       goto done;
     }
 
-  if ((error = vlib_buffer_main_init (vm)))
+  if ((error = vlib_map_stat_segment_init (vm)))
     {
       clib_error_report (error);
       goto done;
     }
 
-  if ((error = vlib_thread_init (vm)))
+  if ((error = vlib_buffer_main_init (vm)))
     {
       clib_error_report (error);
       goto done;
     }
 
-  if ((error = vlib_map_stat_segment_init (vm)))
+  if ((error = vlib_thread_init (vm)))
     {
       clib_error_report (error);
       goto done;
@@ -2058,6 +2114,20 @@ vlib_main (vlib_main_t * volatile vm, unformat_input_t * input)
   vec_validate (vm->processing_rpc_requests, 0);
   _vec_len (vm->processing_rpc_requests) = 0;
 
+  if ((error = vlib_call_all_config_functions (vm, input, 0 /* is_early */ )))
+    goto done;
+
+  /* Sort per-thread init functions before we start threads */
+  vlib_sort_init_exit_functions (&vm->worker_init_function_registrations);
+
+  /* Call all main loop enter functions. */
+  {
+    clib_error_t *sub_error;
+    sub_error = vlib_call_all_main_loop_enter_functions (vm);
+    if (sub_error)
+      clib_error_report (sub_error);
+  }
+
   switch (clib_setjmp (&vm->main_loop_exit, VLIB_MAIN_LOOP_EXIT_NONE))
     {
     case VLIB_MAIN_LOOP_EXIT_NONE:
@@ -2072,17 +2142,6 @@ vlib_main (vlib_main_t * volatile vm, unformat_input_t * input)
       goto done;
     }
 
-  if ((error = vlib_call_all_config_functions (vm, input, 0 /* is_early */ )))
-    goto done;
-
-  /* Call all main loop enter functions. */
-  {
-    clib_error_t *sub_error;
-    sub_error = vlib_call_all_main_loop_enter_functions (vm);
-    if (sub_error)
-      clib_error_report (sub_error);
-  }
-
   vlib_main_loop (vm);
 
 done:
@@ -2105,15 +2164,12 @@ pcap_dispatch_trace_command_internal (vlib_main_t * vm,
                                      unformat_input_t * input,
                                      vlib_cli_command_t * cmd, int rx_tx)
 {
-#define PCAP_DEF_PKT_TO_CAPTURE (100)
-
   unformat_input_t _line_input, *line_input = &_line_input;
   pcap_main_t *pm = &vm->dispatch_pcap_main;
-  u8 *filename;
-  u8 *chroot_filename = 0;
-  u32 max = 0;
+  u8 *filename = 0;
+  u32 max = 1000;
   int enabled = 0;
-  int errorFlag = 0;
+  int is_error = 0;
   clib_error_t *error = 0;
   u32 node_index, add;
   vlib_trace_main_t *tm;
@@ -2134,7 +2190,7 @@ pcap_dispatch_trace_command_internal (vlib_main_t * vm,
          else
            {
              vlib_cli_output (vm, "pcap dispatch capture already on...");
-             errorFlag = 1;
+             is_error = 1;
              break;
            }
        }
@@ -2158,7 +2214,7 @@ pcap_dispatch_trace_command_internal (vlib_main_t * vm,
          else
            {
              vlib_cli_output (vm, "pcap tx capture already off...");
-             errorFlag = 1;
+             is_error = 1;
              break;
            }
        }
@@ -2169,7 +2225,7 @@ pcap_dispatch_trace_command_internal (vlib_main_t * vm,
              vlib_cli_output
                (vm,
                 "can't change max value while pcap tx capture active...");
-             errorFlag = 1;
+             is_error = 1;
              break;
            }
          pm->n_packets_to_capture = max;
@@ -2182,7 +2238,7 @@ pcap_dispatch_trace_command_internal (vlib_main_t * vm,
            {
              vlib_cli_output
                (vm, "can't change file while pcap tx capture active...");
-             errorFlag = 1;
+             is_error = 1;
              break;
            }
        }
@@ -2227,32 +2283,27 @@ pcap_dispatch_trace_command_internal (vlib_main_t * vm,
        {
          error = clib_error_return (0, "unknown input `%U'",
                                     format_unformat_error, line_input);
-         errorFlag = 1;
+         is_error = 1;
          break;
        }
     }
   unformat_free (line_input);
 
-
-  if (errorFlag == 0)
+  if (is_error == 0)
     {
-      /* Since no error, save configured values. */
-      if (chroot_filename)
-       {
-         if (pm->file_name)
-           vec_free (pm->file_name);
-         vec_add1 (chroot_filename, 0);
-         pm->file_name = (char *) chroot_filename;
-       }
+      /* Clean up from previous run */
+      vec_free (pm->file_name);
+      vec_free (pm->pcap_data);
 
-      if (max)
-       pm->n_packets_to_capture = max;
+      memset (pm, 0, sizeof (*pm));
+      pm->n_packets_to_capture = max;
 
       if (enabled)
        {
-         if (pm->file_name == 0)
-           pm->file_name = (char *) format (0, "/tmp/dispatch.pcap%c", 0);
+         if (filename == 0)
+           filename = format (0, "/tmp/dispatch.pcap%c", 0);
 
+         pm->file_name = (char *) filename;
          pm->n_packets_captured = 0;
          pm->packet_type = PCAP_PACKET_TYPE_vpp;
          if (pm->lock == 0)
@@ -2261,8 +2312,6 @@ pcap_dispatch_trace_command_internal (vlib_main_t * vm,
          vlib_cli_output (vm, "pcap dispatch capture on...");
        }
     }
-  else if (chroot_filename)
-    vec_free (chroot_filename);
 
   return error;
 }