/*
 * Copyright (c) 2016 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.
 */

#include <vlib/vlib.h>
#include <vnet/vnet.h>
#include <vppinfra/error.h>

#include <vnet/span/span.h>
#include <vnet/l2/l2_input.h>
#include <vnet/l2/l2_output.h>
#include <vnet/l2/feat_bitmap.h>

#include <vppinfra/error.h>
#include <vppinfra/elog.h>

vlib_node_registration_t span_node;

/* packet trace format function */
u8 *
format_span_trace (u8 * s, va_list * args)
{
  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
  span_trace_t *t = va_arg (*args, span_trace_t *);

  vnet_main_t *vnm = &vnet_main;
  s = format (s, "SPAN: mirrored %U -> %U",
	      format_vnet_sw_if_index_name, vnm, t->src_sw_if_index,
	      format_vnet_sw_if_index_name, vnm, t->mirror_sw_if_index);

  return s;
}

#define foreach_span_error                      \
_(HITS, "SPAN incomming packets processed")

typedef enum
{
#define _(sym,str) SPAN_ERROR_##sym,
  foreach_span_error
#undef _
    SPAN_N_ERROR,
} span_error_t;

static char *span_error_strings[] = {
#define _(sym,string) string,
  foreach_span_error
#undef _
};

static_always_inline void
span_mirror (vlib_main_t * vm, vlib_node_runtime_t * node, u32 sw_if_index0,
	     vlib_buffer_t * b0, vlib_frame_t ** mirror_frames,
	     vlib_rx_or_tx_t rxtx, span_feat_t sf)
{
  vlib_buffer_t *c0;
  span_main_t *sm = &span_main;
  vnet_main_t *vnm = &vnet_main;
  u32 *to_mirror_next = 0;
  u32 i;
  span_interface_t *si0;
  span_mirror_t *sm0;

  if (sw_if_index0 >= vec_len (sm->interfaces))
    return;

  si0 = vec_elt_at_index (sm->interfaces, sw_if_index0);
  sm0 = &si0->mirror_rxtx[sf][rxtx];

  if (sm0->num_mirror_ports == 0)
    return;

  /* Don't do it again */
  if (PREDICT_FALSE (b0->flags & VNET_BUFFER_F_SPAN_CLONE))
    return;

  /* *INDENT-OFF* */
  clib_bitmap_foreach (i, sm0->mirror_ports, (
    {
      if (mirror_frames[i] == 0)
        {
          if (sf == SPAN_FEAT_L2)
            mirror_frames[i] = vlib_get_frame_to_node (vnm->vlib_main,
						       l2output_node.index);
          else
            mirror_frames[i] = vnet_get_frame_to_sw_interface (vnm, i);
	}
      to_mirror_next = vlib_frame_vector_args (mirror_frames[i]);
      to_mirror_next += mirror_frames[i]->n_vectors;
      /* This can fail */
      c0 = vlib_buffer_copy (vm, b0);
      if (PREDICT_TRUE(c0 != 0))
        {
          vnet_buffer (c0)->sw_if_index[VLIB_TX] = i;
          c0->flags |= VNET_BUFFER_F_SPAN_CLONE;
          if (sf == SPAN_FEAT_L2)
	    vnet_buffer (c0)->l2.feature_bitmap = L2OUTPUT_FEAT_OUTPUT;
          to_mirror_next[0] = vlib_get_buffer_index (vm, c0);
          mirror_frames[i]->n_vectors++;
          if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
            {
              span_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
              t->src_sw_if_index = sw_if_index0;
              t->mirror_sw_if_index = i;
#if 0
	      /* Enable this path to allow packet trace of SPAN packets.
	         Note that all SPAN packets will show up on the trace output
	         with the first SPAN packet (since they are in the same frame)
	         thus making trace output of the original packet confusing */
	      mirror_frames[i]->flags |= VLIB_FRAME_TRACE;
	      c0->flags |= VLIB_BUFFER_IS_TRACED;
#endif
	    }
	}
    }));
  /* *INDENT-ON* */
}

static_always_inline uword
span_node_inline_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
		     vlib_frame_t * frame, vlib_rx_or_tx_t rxtx,
		     span_feat_t sf)
{
  span_main_t *sm = &span_main;
  vnet_main_t *vnm = &vnet_main;
  u32 n_left_from, *from, *to_next;
  u32 n_span_packets = 0;
  u32 next_index;
  u32 sw_if_index;
  static __thread vlib_frame_t **mirror_frames = 0;

  from = vlib_frame_vector_args (frame);
  n_left_from = frame->n_vectors;
  next_index = node->cached_next_index;

  vec_validate_aligned (mirror_frames, sm->max_sw_if_index,
			CLIB_CACHE_LINE_BYTES);

  while (n_left_from > 0)
    {
      u32 n_left_to_next;

      vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);

      while (n_left_from >= 4 && n_left_to_next >= 2)
	{
	  u32 bi0;
	  u32 bi1;
	  vlib_buffer_t *b0;
	  vlib_buffer_t *b1;
	  u32 sw_if_index0;
	  u32 next0 = 0;
	  u32 sw_if_index1;
	  u32 next1 = 0;

	  /* speculatively enqueue b0, b1 to the current next frame */
	  to_next[0] = bi0 = from[0];
	  to_next[1] = bi1 = from[1];
	  to_next += 2;
	  n_left_to_next -= 2;
	  from += 2;
	  n_left_from -= 2;

	  b0 = vlib_get_buffer (vm, bi0);
	  b1 = vlib_get_buffer (vm, bi1);
	  sw_if_index0 = vnet_buffer (b0)->sw_if_index[rxtx];
	  sw_if_index1 = vnet_buffer (b1)->sw_if_index[rxtx];

	  span_mirror (vm, node, sw_if_index0, b0, mirror_frames, rxtx, sf);
	  span_mirror (vm, node, sw_if_index1, b1, mirror_frames, rxtx, sf);

	  switch (sf)
	    {
	    case SPAN_FEAT_L2:
	      if (rxtx == VLIB_RX)
		{
		  next0 = vnet_l2_feature_next (b0, sm->l2_input_next,
						L2INPUT_FEAT_SPAN);
		  next1 = vnet_l2_feature_next (b1, sm->l2_input_next,
						L2INPUT_FEAT_SPAN);
		}
	      else
		{
		  next0 = vnet_l2_feature_next (b0, sm->l2_output_next,
						L2OUTPUT_FEAT_SPAN);
		  next1 = vnet_l2_feature_next (b1, sm->l2_output_next,
						L2OUTPUT_FEAT_SPAN);
		}
	      break;
	    case SPAN_FEAT_DEVICE:
	    default:
	      vnet_feature_next (&next0, b0);
	      vnet_feature_next (&next1, b1);
	      break;
	    }

	  /* verify speculative enqueue, maybe switch current next frame */
	  vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
					   to_next, n_left_to_next,
					   bi0, bi1, next0, next1);
	}
      while (n_left_from > 0 && n_left_to_next > 0)
	{
	  u32 bi0;
	  vlib_buffer_t *b0;
	  u32 sw_if_index0;
	  u32 next0 = 0;

	  /* speculatively enqueue b0 to the current next frame */
	  to_next[0] = bi0 = from[0];
	  to_next += 1;
	  n_left_to_next -= 1;
	  from += 1;
	  n_left_from -= 1;

	  b0 = vlib_get_buffer (vm, bi0);
	  sw_if_index0 = vnet_buffer (b0)->sw_if_index[rxtx];

	  span_mirror (vm, node, sw_if_index0, b0, mirror_frames, rxtx, sf);

	  switch (sf)
	    {
	    case SPAN_FEAT_L2:
	      if (rxtx == VLIB_RX)
		next0 = vnet_l2_feature_next (b0, sm->l2_input_next,
					      L2INPUT_FEAT_SPAN);
	      else
		next0 = vnet_l2_feature_next (b0, sm->l2_output_next,
					      L2OUTPUT_FEAT_SPAN);
	      break;
	    case SPAN_FEAT_DEVICE:
	    default:
	      vnet_feature_next (&next0, b0);
	      break;
	    }

	  /* verify speculative enqueue, maybe switch current next frame */
	  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
					   n_left_to_next, bi0, next0);
	}

      vlib_put_next_frame (vm, node, next_index, n_left_to_next);
    }


  for (sw_if_index = 0; sw_if_index < vec_len (mirror_frames); sw_if_index++)
    {
      vlib_frame_t *f = mirror_frames[sw_if_index];
      if (f == 0)
	continue;

      if (sf == SPAN_FEAT_L2)
	vlib_put_frame_to_node (vnm->vlib_main, l2output_node.index, f);
      else
	vnet_put_frame_to_sw_interface (vnm, sw_if_index, f);
      mirror_frames[sw_if_index] = 0;
    }
  vlib_node_increment_counter (vm, span_node.index, SPAN_ERROR_HITS,
			       n_span_packets);

  return frame->n_vectors;
}

static uword
span_device_input_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
			   vlib_frame_t * frame)
{
  return span_node_inline_fn (vm, node, frame, VLIB_RX, SPAN_FEAT_DEVICE);
}

static uword
span_device_output_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
			    vlib_frame_t * frame)
{
  return span_node_inline_fn (vm, node, frame, VLIB_TX, SPAN_FEAT_DEVICE);
}

static uword
span_l2_input_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
		       vlib_frame_t * frame)
{
  return span_node_inline_fn (vm, node, frame, VLIB_RX, SPAN_FEAT_L2);
}

static uword
span_l2_output_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
			vlib_frame_t * frame)
{
  return span_node_inline_fn (vm, node, frame, VLIB_TX, SPAN_FEAT_L2);
}

#define span_node_defs                           \
  .vector_size = sizeof (u32),                   \
  .format_trace = format_span_trace,             \
  .type = VLIB_NODE_TYPE_INTERNAL,               \
  .n_errors = ARRAY_LEN(span_error_strings),     \
  .error_strings = span_error_strings,           \
  .n_next_nodes = 0,                             \
  .next_nodes = {                                \
    [0] = "error-drop"                           \
  }

/* *INDENT-OFF* */
VLIB_REGISTER_NODE (span_input_node) = {
  span_node_defs,
  .function = span_device_input_node_fn,
  .name = "span-input",
};

VLIB_NODE_FUNCTION_MULTIARCH (span_input_node, span_device_input_node_fn)

VLIB_REGISTER_NODE (span_output_node) = {
  span_node_defs,
  .function = span_device_output_node_fn,
  .name = "span-output",
};

VLIB_NODE_FUNCTION_MULTIARCH (span_output_node, span_device_output_node_fn)

VLIB_REGISTER_NODE (span_l2_input_node) = {
  span_node_defs,
  .function = span_l2_input_node_fn,
  .name = "span-l2-input",
};

VLIB_NODE_FUNCTION_MULTIARCH (span_l2_input_node, span_l2_input_node_fn)

VLIB_REGISTER_NODE (span_l2_output_node) = {
  span_node_defs,
  .function = span_l2_output_node_fn,
  .name = "span-l2-output",
};

VLIB_NODE_FUNCTION_MULTIARCH (span_l2_output_node, span_l2_output_node_fn)

clib_error_t *span_init (vlib_main_t * vm)
{
  span_main_t *sm = &span_main;

  sm->vlib_main = vm;
  sm->vnet_main = vnet_get_main ();

  /* Initialize the feature next-node indexes */
  feat_bitmap_init_next_nodes (vm,
			       span_l2_input_node.index,
			       L2INPUT_N_FEAT,
			       l2input_get_feat_names (),
			       sm->l2_input_next);

  feat_bitmap_init_next_nodes (vm,
			       span_l2_output_node.index,
			       L2OUTPUT_N_FEAT,
			       l2output_get_feat_names (),
			       sm->l2_output_next);
  return 0;
}

VLIB_INIT_FUNCTION (span_init);
/* *INDENT-ON* */

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