/*
 * Copyright (c) 2015 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * trace_funcs.h: VLIB trace buffer.
 *
 * Copyright (c) 2008 Eliot Dresselhaus
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#ifndef included_vlib_trace_funcs_h
#define included_vlib_trace_funcs_h

extern u8 *vnet_trace_placeholder;

always_inline void
vlib_validate_trace (vlib_trace_main_t * tm, vlib_buffer_t * b)
{
  ASSERT (!pool_is_free_index (tm->trace_buffer_pool,
			       vlib_buffer_get_trace_index (b)));
}

int vlib_add_handoff_trace (vlib_main_t * vm, vlib_buffer_t * b);

always_inline void *
vlib_add_trace_inline (vlib_main_t * vm,
		       vlib_node_runtime_t * r, vlib_buffer_t * b,
		       u32 n_data_bytes)
{
  vlib_trace_main_t *tm = &vm->trace_main;
  vlib_trace_header_t *h;
  u32 n_data_words, trace_index;

  ASSERT (vnet_trace_placeholder);

  if (PREDICT_FALSE ((b->flags & VLIB_BUFFER_IS_TRACED) == 0))
    return vnet_trace_placeholder;

  if (PREDICT_FALSE (tm->add_trace_callback != 0))
    {
      return tm->add_trace_callback ((struct vlib_main_t *) vm,
				     (struct vlib_node_runtime_t *) r,
				     (struct vlib_buffer_t *) b,
				     n_data_bytes);
    }
  else if (PREDICT_FALSE (tm->trace_enable == 0))
    {
      ASSERT (vec_len (vnet_trace_placeholder) >= n_data_bytes + sizeof (*h));
      return vnet_trace_placeholder;
    }

  /* Are we trying to trace a handoff case? */
  if (PREDICT_FALSE (vlib_buffer_get_trace_thread (b) != vm->thread_index))
    if (PREDICT_FALSE (!vlib_add_handoff_trace (vm, b)))
      return vnet_trace_placeholder;

  /*
   * there is a small chance of a race condition with 'clear trace' here: if a
   * buffer was set to be traced before the 'clear trace' and is still going
   * through the graph after the 'clear trace', its trace_index is staled as
   * the pool was destroyed.
   * The pool may have been re-allocated because of a new traced buffer, and
   * the trace_index might be valid by pure (bad) luck. In that case the trace
   * will be a mix of both buffer traces, but this should be acceptable.
   */
  trace_index = vlib_buffer_get_trace_index (b);
  if (PREDICT_FALSE (pool_is_free_index (tm->trace_buffer_pool, trace_index)))
    return vnet_trace_placeholder;

  n_data_bytes = round_pow2 (n_data_bytes, sizeof (h[0]));
  n_data_words = n_data_bytes / sizeof (h[0]);
  vec_add2_aligned (tm->trace_buffer_pool[trace_index], h, 1 + n_data_words,
		    sizeof (h[0]));

  h->time = vm->cpu_time_last_node_dispatch;
  h->n_data = n_data_words;
  h->node_index = r->node_index;

  return h->data;
}

/* Non-inline (typical use-case) version of the above */
void *vlib_add_trace (vlib_main_t * vm,
		      vlib_node_runtime_t * r, vlib_buffer_t * b,
		      u32 n_data_bytes);

always_inline vlib_trace_header_t *
vlib_trace_header_next (vlib_trace_header_t * h)
{
  return h + 1 + h->n_data;
}

always_inline void
vlib_free_trace (vlib_main_t * vm, vlib_buffer_t * b)
{
  vlib_trace_main_t *tm = &vm->trace_main;
  u32 trace_index = vlib_buffer_get_trace_index (b);
  vlib_validate_trace (tm, b);
  vec_set_len (tm->trace_buffer_pool[trace_index], 0);
  pool_put_index (tm->trace_buffer_pool, trace_index);
}

always_inline void
vlib_trace_next_frame (vlib_main_t * vm,
		       vlib_node_runtime_t * r, u32 next_index)
{
  vlib_next_frame_t *nf;
  nf = vlib_node_runtime_get_next_frame (vm, r, next_index);
  nf->flags |= VLIB_FRAME_TRACE;
}

void trace_apply_filter (vlib_main_t *vm);

/*
 * Mark buffer as traced and allocate trace buffer.
 * return 1 if the buffer is successfully traced, 0 if not
 * A buffer might not be traced if tracing is off or if the packet did not
 * match the filter.
 */
always_inline __clib_warn_unused_result int
vlib_trace_buffer (vlib_main_t * vm,
		   vlib_node_runtime_t * r,
		   u32 next_index, vlib_buffer_t * b, int follow_chain)
{
  vlib_trace_main_t *tm = &vm->trace_main;
  vlib_trace_header_t **h;

  if (PREDICT_FALSE (tm->trace_enable == 0))
    return 0;

  /* Classifier filter in use? */
  if (PREDICT_FALSE (vlib_global_main.trace_filter.trace_filter_enable))
    {
      /* See if we're supposed to trace this packet... */
      if (tm->current_trace_filter_function (
	    b, vlib_global_main.trace_filter.classify_table_index,
	    0 /* full classify */) != 1)
	return 0;
    }

  /*
   * Apply filter to existing traces to keep number of allocated traces low.
   * Performed each time around the main loop.
   */
  if (tm->last_main_loop_count != vm->main_loop_count)
    {
      tm->last_main_loop_count = vm->main_loop_count;
      trace_apply_filter (vm);

      if (tm->trace_buffer_callback)
	(tm->trace_buffer_callback) ((struct vlib_main_t *) vm,
				     (struct vlib_trace_main_t *) tm);
    }

  vlib_trace_next_frame (vm, r, next_index);

  pool_get (tm->trace_buffer_pool, h);

  do
    {
      b->flags |= VLIB_BUFFER_IS_TRACED;
      b->trace_handle = vlib_buffer_make_trace_handle
	(vm->thread_index, h - tm->trace_buffer_pool);
    }
  while (follow_chain && (b = vlib_get_next_buffer (vm, b)));

  return 1;
}

always_inline void
vlib_buffer_copy_trace_flag (vlib_main_t * vm, vlib_buffer_t * b,
			     u32 bi_target)
{
  vlib_buffer_t *b_target = vlib_get_buffer (vm, bi_target);
  b_target->flags |= b->flags & VLIB_BUFFER_IS_TRACED;
  b_target->trace_handle = b->trace_handle;
}

always_inline u32
vlib_get_trace_count (vlib_main_t * vm, vlib_node_runtime_t * rt)
{
  vlib_trace_main_t *tm = &vm->trace_main;
  vlib_trace_node_t *tn;

  if (rt->node_index >= vec_len (tm->nodes))
    return 0;
  tn = tm->nodes + rt->node_index;
  ASSERT (tn->count <= tn->limit);

  return tn->limit - tn->count;
}

always_inline void
vlib_set_trace_count (vlib_main_t * vm, vlib_node_runtime_t * rt, u32 count)
{
  vlib_trace_main_t *tm = &vm->trace_main;
  vlib_trace_node_t *tn = vec_elt_at_index (tm->nodes, rt->node_index);

  ASSERT (count <= tn->limit);
  tn->count = tn->limit - count;
}

/* Helper function for nodes which only trace buffer data. */
void
vlib_trace_frame_buffers_only (vlib_main_t * vm,
			       vlib_node_runtime_t * node,
			       u32 * buffers,
			       uword n_buffers,
			       uword next_buffer_stride,
			       uword n_buffer_data_bytes_in_trace);

#endif /* included_vlib_trace_funcs_h */

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
