/*
 * 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.
 */
/*
 * interface_output.c: interface output node
 *
 * 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.
 */

#include <vnet/vnet.h>
#include <vnet/ip/icmp46_packet.h>
#include <vnet/ethernet/packet.h>
#include <vnet/ip/format.h>
#include <vnet/ip/ip4.h>
#include <vnet/ip/ip6.h>
#include <vnet/udp/udp_packet.h>
#include <vnet/feature/feature.h>
#include <vnet/classify/pcap_classify.h>
#include <vnet/interface_output.h>
#include <vppinfra/vector_funcs.h>

typedef struct
{
  u32 sw_if_index;
  u32 flags;
  u8 data[128 - 2 * sizeof (u32)];
}
interface_output_trace_t;

#ifndef CLIB_MARCH_VARIANT
u8 *
format_vnet_interface_output_trace (u8 * s, va_list * va)
{
  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *);
  vlib_node_t *node = va_arg (*va, vlib_node_t *);
  interface_output_trace_t *t = va_arg (*va, interface_output_trace_t *);
  vnet_main_t *vnm = vnet_get_main ();
  vnet_sw_interface_t *si;
  u32 indent;

  if (t->sw_if_index != (u32) ~ 0)
    {
      indent = format_get_indent (s);

      if (pool_is_free_index
	  (vnm->interface_main.sw_interfaces, t->sw_if_index))
	{
	  /* the interface may have been deleted by the time the trace is printed */
	  s = format (s, "sw_if_index: %d ", t->sw_if_index);
	}
      else
	{
	  si = vnet_get_sw_interface (vnm, t->sw_if_index);
	  s =
	    format (s, "%U ", format_vnet_sw_interface_name, vnm, si,
		    t->flags);
	}
      s =
	format (s, "\n%U%U", format_white_space, indent,
		node->format_buffer ? node->format_buffer : format_hex_bytes,
		t->data, sizeof (t->data));
    }
  return s;
}
#endif /* CLIB_MARCH_VARIANT */

static void
vnet_interface_output_trace (vlib_main_t * vm,
			     vlib_node_runtime_t * node,
			     vlib_frame_t * frame, uword n_buffers)
{
  u32 n_left, *from;

  n_left = n_buffers;
  from = vlib_frame_vector_args (frame);

  while (n_left >= 4)
    {
      u32 bi0, bi1;
      vlib_buffer_t *b0, *b1;
      interface_output_trace_t *t0, *t1;

      /* Prefetch next iteration. */
      vlib_prefetch_buffer_with_index (vm, from[2], LOAD);
      vlib_prefetch_buffer_with_index (vm, from[3], LOAD);

      bi0 = from[0];
      bi1 = from[1];

      b0 = vlib_get_buffer (vm, bi0);
      b1 = vlib_get_buffer (vm, bi1);

      if (b0->flags & VLIB_BUFFER_IS_TRACED)
	{
	  t0 = vlib_add_trace (vm, node, b0, sizeof (t0[0]));
	  t0->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_TX];
	  t0->flags = b0->flags;
	  clib_memcpy_fast (t0->data, vlib_buffer_get_current (b0),
			    sizeof (t0->data));
	}
      if (b1->flags & VLIB_BUFFER_IS_TRACED)
	{
	  t1 = vlib_add_trace (vm, node, b1, sizeof (t1[0]));
	  t1->sw_if_index = vnet_buffer (b1)->sw_if_index[VLIB_TX];
	  t1->flags = b1->flags;
	  clib_memcpy_fast (t1->data, vlib_buffer_get_current (b1),
			    sizeof (t1->data));
	}
      from += 2;
      n_left -= 2;
    }

  while (n_left >= 1)
    {
      u32 bi0;
      vlib_buffer_t *b0;
      interface_output_trace_t *t0;

      bi0 = from[0];

      b0 = vlib_get_buffer (vm, bi0);

      if (b0->flags & VLIB_BUFFER_IS_TRACED)
	{
	  t0 = vlib_add_trace (vm, node, b0, sizeof (t0[0]));
	  t0->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_TX];
	  t0->flags = b0->flags;
	  clib_memcpy_fast (t0->data, vlib_buffer_get_current (b0),
			    sizeof (t0->data));
	}
      from += 1;
      n_left -= 1;
    }
}

static_always_inline void
vnet_interface_output_handle_offload (vlib_main_t *vm, vlib_buffer_t *b)
{
  vnet_calc_checksums_inline (vm, b, b->flags & VNET_BUFFER_F_IS_IP4,
			      b->flags & VNET_BUFFER_F_IS_IP6);
}

static_always_inline uword
vnet_interface_output_node_inline (vlib_main_t *vm, u32 sw_if_index,
				   vlib_combined_counter_main_t *ccm,
				   vlib_buffer_t **b, u32 config_index, u8 arc,
				   u32 n_left, int do_tx_offloads,
				   int arc_or_subif)
{
  u32 n_bytes = 0;
  u32 n_bytes0, n_bytes1, n_bytes2, n_bytes3;
  u32 ti = vm->thread_index;

  while (n_left >= 8)
    {
      u32 or_flags;

      /* Prefetch next iteration. */
      vlib_prefetch_buffer_header (b[4], LOAD);
      vlib_prefetch_buffer_header (b[5], LOAD);
      vlib_prefetch_buffer_header (b[6], LOAD);
      vlib_prefetch_buffer_header (b[7], LOAD);

      if (do_tx_offloads)
	or_flags = b[0]->flags | b[1]->flags | b[2]->flags | b[3]->flags;

      /* Be grumpy about zero length buffers for benefit of
	 driver tx function. */
      ASSERT (b[0]->current_length > 0);
      ASSERT (b[1]->current_length > 0);
      ASSERT (b[2]->current_length > 0);
      ASSERT (b[3]->current_length > 0);

      n_bytes += n_bytes0 = vlib_buffer_length_in_chain (vm, b[0]);
      n_bytes += n_bytes1 = vlib_buffer_length_in_chain (vm, b[1]);
      n_bytes += n_bytes2 = vlib_buffer_length_in_chain (vm, b[2]);
      n_bytes += n_bytes3 = vlib_buffer_length_in_chain (vm, b[3]);

      if (arc_or_subif)
	{
	  u32 tx_swif0, tx_swif1, tx_swif2, tx_swif3;
	  tx_swif0 = vnet_buffer (b[0])->sw_if_index[VLIB_TX];
	  tx_swif1 = vnet_buffer (b[1])->sw_if_index[VLIB_TX];
	  tx_swif2 = vnet_buffer (b[2])->sw_if_index[VLIB_TX];
	  tx_swif3 = vnet_buffer (b[3])->sw_if_index[VLIB_TX];

	  /* update vlan subif tx counts, if required */
	  if (PREDICT_FALSE (tx_swif0 != sw_if_index))
	    vlib_increment_combined_counter (ccm, ti, tx_swif0, 1, n_bytes0);

	  if (PREDICT_FALSE (tx_swif1 != sw_if_index))
	    vlib_increment_combined_counter (ccm, ti, tx_swif1, 1, n_bytes1);

	  if (PREDICT_FALSE (tx_swif2 != sw_if_index))
	    vlib_increment_combined_counter (ccm, ti, tx_swif2, 1, n_bytes2);

	  if (PREDICT_FALSE (tx_swif3 != sw_if_index))
	    vlib_increment_combined_counter (ccm, ti, tx_swif3, 1, n_bytes3);

	  if (PREDICT_FALSE (config_index != ~0))
	    {
	      vnet_buffer (b[0])->feature_arc_index = arc;
	      b[0]->current_config_index = config_index;
	      vnet_buffer (b[1])->feature_arc_index = arc;
	      b[1]->current_config_index = config_index;
	      vnet_buffer (b[2])->feature_arc_index = arc;
	      b[2]->current_config_index = config_index;
	      vnet_buffer (b[3])->feature_arc_index = arc;
	      b[3]->current_config_index = config_index;
	    }
	}

      if (do_tx_offloads && (or_flags & VNET_BUFFER_F_OFFLOAD))
	{
	  vnet_interface_output_handle_offload (vm, b[0]);
	  vnet_interface_output_handle_offload (vm, b[1]);
	  vnet_interface_output_handle_offload (vm, b[2]);
	  vnet_interface_output_handle_offload (vm, b[3]);
	}

      n_left -= 4;
      b += 4;
    }

  while (n_left)
    {
      /* Be grumpy about zero length buffers for benefit of
	 driver tx function. */
      ASSERT (b[0]->current_length > 0);

      n_bytes += n_bytes0 = vlib_buffer_length_in_chain (vm, b[0]);

      if (arc_or_subif)
	{
	  u32 tx_swif0 = vnet_buffer (b[0])->sw_if_index[VLIB_TX];

	  if (PREDICT_FALSE (config_index != ~0))
	    {
	      vnet_buffer (b[0])->feature_arc_index = arc;
	      b[0]->current_config_index = config_index;
	    }

	  if (PREDICT_FALSE (tx_swif0 != sw_if_index))
	    vlib_increment_combined_counter (ccm, ti, tx_swif0, 1, n_bytes0);
	}

      if (do_tx_offloads)
	vnet_interface_output_handle_offload (vm, b[0]);

      n_left -= 1;
      b += 1;
    }

  return n_bytes;
}

static_always_inline void vnet_interface_pcap_tx_trace
  (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame,
   int sw_if_index_from_buffer)
{
  vnet_main_t *vnm = vnet_get_main ();
  u32 n_left_from, *from;
  u32 sw_if_index;
  vnet_pcap_t *pp = &vnm->pcap;

  if (PREDICT_TRUE (pp->pcap_tx_enable == 0))
    return;

  if (sw_if_index_from_buffer == 0)
    {
      vnet_interface_output_runtime_t *rt = (void *) node->runtime_data;
      sw_if_index = rt->sw_if_index;
    }
  else
    sw_if_index = ~0;

  n_left_from = frame->n_vectors;
  from = vlib_frame_vector_args (frame);

  while (n_left_from > 0)
    {
      u32 bi0 = from[0];
      vlib_buffer_t *b0 = vlib_get_buffer (vm, bi0);
      from++;
      n_left_from--;

      if (sw_if_index_from_buffer)
	sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_TX];

      if (vnet_is_packet_pcaped (pp, b0, sw_if_index))
	pcap_add_buffer (&pp->pcap_main, vm, bi0, pp->max_bytes_per_pkt);
    }
}

static_always_inline void
store_tx_frame_scalar_data (vnet_hw_if_output_node_runtime_t *r,
			    vnet_hw_if_tx_frame_t *tf)
{
  if (r)
    clib_memcpy_fast (tf, &r->frame, sizeof (vnet_hw_if_tx_frame_t));
}

static_always_inline void
enqueu_to_tx_node (vlib_main_t *vm, vlib_node_runtime_t *node,
		   vnet_hw_interface_t *hi, u32 *from, u32 n_vectors)
{
  u32 next_index = VNET_INTERFACE_OUTPUT_NEXT_TX;
  vnet_hw_if_output_node_runtime_t *r = 0;
  u32 n_free, n_copy, *to;
  vnet_hw_if_tx_frame_t *tf;
  vlib_frame_t *f;

  ASSERT (n_vectors <= VLIB_FRAME_SIZE);

  if (hi->output_node_thread_runtimes)
    r = vec_elt_at_index (hi->output_node_thread_runtimes, vm->thread_index);

  f = vlib_get_next_frame_internal (vm, node, next_index, 0);
  tf = vlib_frame_scalar_args (f);

  if (f->n_vectors > 0 && (r == 0 || tf->queue_id == r->frame.queue_id))
    {
      /* append current next frame */
      n_free = VLIB_FRAME_SIZE - f->n_vectors;
      n_copy = clib_min (n_vectors, n_free);
      n_vectors -= n_copy;
      to = vlib_frame_vector_args (f);
      to += f->n_vectors;
    }
  else
    {
      if (f->n_vectors > 0)
	{
	  /* current frame doesn't fit - grab empty one */
	  f = vlib_get_next_frame_internal (vm, node, next_index, 1);
	  tf = vlib_frame_scalar_args (f);
	}

      /* empty frame - store scalar data */
      store_tx_frame_scalar_data (r, tf);
      to = vlib_frame_vector_args (f);
      n_free = VLIB_FRAME_SIZE;
      n_copy = n_vectors;
      n_vectors = 0;
    }

  vlib_buffer_copy_indices (to, from, n_copy);
  vlib_put_next_frame (vm, node, next_index, n_free - n_copy);

  if (n_vectors == 0)
    return;

  /* we have more indices to store, take empty frame */
  from += n_copy;
  f = vlib_get_next_frame_internal (vm, node, next_index, 1);
  store_tx_frame_scalar_data (r, vlib_frame_scalar_args (f));
  vlib_buffer_copy_indices (vlib_frame_vector_args (f), from, n_vectors);
  vlib_put_next_frame (vm, node, next_index, VLIB_FRAME_SIZE - n_vectors);
}

VLIB_NODE_FN (vnet_interface_output_node)
(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
{
  vnet_main_t *vnm = vnet_get_main ();
  vnet_interface_main_t *im = &vnm->interface_main;
  vlib_combined_counter_main_t *ccm;
  vnet_hw_interface_t *hi;
  vnet_sw_interface_t *si;
  vnet_interface_output_runtime_t *rt = (void *) node->runtime_data;
  vlib_buffer_t *bufs[VLIB_FRAME_SIZE];
  u32 n_bytes, n_buffers = frame->n_vectors;
  u32 config_index = ~0;
  u32 sw_if_index = rt->sw_if_index;
  u32 next_index = VNET_INTERFACE_OUTPUT_NEXT_TX;
  u32 ti = vm->thread_index;
  u8 arc = im->output_feature_arc_index;
  int arc_or_subif = 0;
  int do_tx_offloads = 0;
  u32 *from;

  if (node->flags & VLIB_NODE_FLAG_TRACE)
    vnet_interface_output_trace (vm, node, frame, n_buffers);

  from = vlib_frame_vector_args (frame);

  if (rt->is_deleted)
    return vlib_error_drop_buffers (
      vm, node, from,
      /* buffer stride */ 1, n_buffers, VNET_INTERFACE_OUTPUT_NEXT_DROP,
      node->node_index, VNET_INTERFACE_OUTPUT_ERROR_INTERFACE_DELETED);

  vnet_interface_pcap_tx_trace (vm, node, frame,
				0 /* sw_if_index_from_buffer */ );

  vlib_get_buffers (vm, from, bufs, n_buffers);

  si = vnet_get_sw_interface (vnm, sw_if_index);
  hi = vnet_get_sup_hw_interface (vnm, sw_if_index);

  if (!(si->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ||
      !(hi->flags & VNET_HW_INTERFACE_FLAG_LINK_UP))
    {
      vlib_simple_counter_main_t *cm;

      cm = vec_elt_at_index (vnm->interface_main.sw_if_counters,
			     VNET_INTERFACE_COUNTER_TX_ERROR);
      vlib_increment_simple_counter (cm, ti, sw_if_index, n_buffers);

      return vlib_error_drop_buffers (
	vm, node, from,
	/* buffer stride */ 1, n_buffers, VNET_INTERFACE_OUTPUT_NEXT_DROP,
	node->node_index, VNET_INTERFACE_OUTPUT_ERROR_INTERFACE_DOWN);
    }

  /* interface-output feature arc handling */
  if (PREDICT_FALSE (vnet_have_features (arc, sw_if_index)))
    {
      vnet_feature_config_main_t *fcm;
      fcm = vnet_feature_get_config_main (arc);
      config_index = vnet_get_feature_config_index (arc, sw_if_index);
      vnet_get_config_data (&fcm->config_main, &config_index, &next_index, 0);
      arc_or_subif = 1;
    }
  else if (hash_elts (hi->sub_interface_sw_if_index_by_id))
    arc_or_subif = 1;

  ccm = im->combined_sw_if_counters + VNET_INTERFACE_COUNTER_TX;

  if ((hi->caps & VNET_HW_INTERFACE_CAP_SUPPORTS_TX_CKSUM) == 0)
    do_tx_offloads = 1;

  if (do_tx_offloads == 0 && arc_or_subif == 0)
    n_bytes = vnet_interface_output_node_inline (
      vm, sw_if_index, ccm, bufs, config_index, arc, n_buffers, 0, 0);
  else if (do_tx_offloads == 0 && arc_or_subif == 1)
    n_bytes = vnet_interface_output_node_inline (
      vm, sw_if_index, ccm, bufs, config_index, arc, n_buffers, 0, 1);
  else if (do_tx_offloads == 1 && arc_or_subif == 0)
    n_bytes = vnet_interface_output_node_inline (
      vm, sw_if_index, ccm, bufs, config_index, arc, n_buffers, 1, 0);
  else
    n_bytes = vnet_interface_output_node_inline (
      vm, sw_if_index, ccm, bufs, config_index, arc, n_buffers, 1, 1);

  from = vlib_frame_vector_args (frame);
  if (PREDICT_TRUE (next_index == VNET_INTERFACE_OUTPUT_NEXT_TX))
    {
      enqueu_to_tx_node (vm, node, hi, from, frame->n_vectors);
    }
  else
    {
      vlib_buffer_enqueue_to_single_next (vm, node, from, next_index,
					  frame->n_vectors);
    }

  /* Update main interface stats. */
  vlib_increment_combined_counter (ccm, ti, sw_if_index, n_buffers, n_bytes);
  return n_buffers;
}

VLIB_REGISTER_NODE (vnet_interface_output_node) = {
  .name = "interface-output-template",
  .vector_size = sizeof (u32),
};

/* Use buffer's sw_if_index[VNET_TX] to choose output interface. */
VLIB_NODE_FN (vnet_per_buffer_interface_output_node) (vlib_main_t * vm,
						      vlib_node_runtime_t *
						      node,
						      vlib_frame_t * frame)
{
  vnet_main_t *vnm = vnet_get_main ();
  u32 n_left_to_next, *from, *to_next;
  u32 n_left_from, next_index;

  vnet_interface_pcap_tx_trace (vm, node, frame,
				1 /* sw_if_index_from_buffer */ );

  n_left_from = frame->n_vectors;

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

  while (n_left_from > 0)
    {
      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, bi1, next0, next1;
	  vlib_buffer_t *b0, *b1;
	  vnet_hw_interface_t *hi0, *hi1;

	  /* Prefetch next iteration. */
	  vlib_prefetch_buffer_with_index (vm, from[2], LOAD);
	  vlib_prefetch_buffer_with_index (vm, from[3], LOAD);

	  bi0 = from[0];
	  bi1 = from[1];
	  to_next[0] = bi0;
	  to_next[1] = bi1;
	  from += 2;
	  to_next += 2;
	  n_left_to_next -= 2;
	  n_left_from -= 2;

	  b0 = vlib_get_buffer (vm, bi0);
	  b1 = vlib_get_buffer (vm, bi1);

	  hi0 =
	    vnet_get_sup_hw_interface (vnm,
				       vnet_buffer (b0)->sw_if_index
				       [VLIB_TX]);
	  hi1 =
	    vnet_get_sup_hw_interface (vnm,
				       vnet_buffer (b1)->sw_if_index
				       [VLIB_TX]);

	  next0 = hi0->output_node_next_index;
	  next1 = hi1->output_node_next_index;

	  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, next0;
	  vlib_buffer_t *b0;
	  vnet_hw_interface_t *hi0;

	  bi0 = from[0];
	  to_next[0] = bi0;
	  from += 1;
	  to_next += 1;
	  n_left_to_next -= 1;
	  n_left_from -= 1;

	  b0 = vlib_get_buffer (vm, bi0);

	  hi0 =
	    vnet_get_sup_hw_interface (vnm,
				       vnet_buffer (b0)->sw_if_index
				       [VLIB_TX]);

	  next0 = hi0->output_node_next_index;

	  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);
    }

  return frame->n_vectors;
}

typedef struct vnet_error_trace_t_
{
  u32 sw_if_index;
  i8 details_valid;
  u8 is_ip6;
  u8 pad[2];
  u16 mactype;
  ip46_address_t src, dst;
} vnet_error_trace_t;

static u8 *
format_vnet_error_trace (u8 * s, va_list * va)
{
  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *);
  CLIB_UNUSED (vlib_node_t * node) = va_arg (*va, vlib_node_t *);
  vnet_error_trace_t *t = va_arg (*va, vnet_error_trace_t *);

  /* Normal, non-catchup trace */
  if (t->details_valid == 0)
    {
      s = format (s, "rx:%U", format_vnet_sw_if_index_name,
		  vnet_get_main (), t->sw_if_index);
    }
  else if (t->details_valid == 1)
    {
      /* The trace capture code didn't understant the mactype */
      s = format (s, "mactype 0x%4x (not decoded)", t->mactype);
    }
  else if (t->details_valid == 2)
    {
      /* Dump the src/dst addresses */
      if (t->is_ip6 == 0)
	s = format (s, "IP4: %U -> %U",
		    format_ip4_address, &t->src.ip4,
		    format_ip4_address, &t->dst.ip4);
      else
	s = format (s, "IP6: %U -> %U",
		    format_ip6_address, &t->src.ip6,
		    format_ip6_address, &t->dst.ip6);
    }
  return s;
}

static void
interface_trace_buffers (vlib_main_t * vm,
			 vlib_node_runtime_t * node, vlib_frame_t * frame)
{
  u32 n_left, *buffers;

  buffers = vlib_frame_vector_args (frame);
  n_left = frame->n_vectors;

  while (n_left >= 4)
    {
      u32 bi0, bi1;
      vlib_buffer_t *b0, *b1;
      vnet_error_trace_t *t0, *t1;

      /* Prefetch next iteration. */
      vlib_prefetch_buffer_with_index (vm, buffers[2], LOAD);
      vlib_prefetch_buffer_with_index (vm, buffers[3], LOAD);

      bi0 = buffers[0];
      bi1 = buffers[1];

      b0 = vlib_get_buffer (vm, bi0);
      b1 = vlib_get_buffer (vm, bi1);

      if (b0->flags & VLIB_BUFFER_IS_TRACED)
	{
	  t0 = vlib_add_trace (vm, node, b0,
			       STRUCT_OFFSET_OF (vnet_error_trace_t, pad));
	  t0->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX];
	  t0->details_valid = 0;
	}
      if (b1->flags & VLIB_BUFFER_IS_TRACED)
	{
	  t1 = vlib_add_trace (vm, node, b1,
			       STRUCT_OFFSET_OF (vnet_error_trace_t, pad));
	  t1->sw_if_index = vnet_buffer (b1)->sw_if_index[VLIB_RX];
	  t1->details_valid = 0;
	}
      buffers += 2;
      n_left -= 2;
    }

  while (n_left >= 1)
    {
      u32 bi0;
      vlib_buffer_t *b0;
      vnet_error_trace_t *t0;

      bi0 = buffers[0];

      b0 = vlib_get_buffer (vm, bi0);

      if (b0->flags & VLIB_BUFFER_IS_TRACED)
	{
	  t0 = vlib_add_trace (vm, node, b0,
			       STRUCT_OFFSET_OF (vnet_error_trace_t, pad));
	  t0->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX];
	  t0->details_valid = 0;
	}
      buffers += 1;
      n_left -= 1;
    }
}

typedef enum
{
  VNET_ERROR_DISPOSITION_DROP,
  VNET_ERROR_DISPOSITION_PUNT,
  VNET_ERROR_N_DISPOSITION,
} vnet_error_disposition_t;

static void
drop_catchup_trace (vlib_main_t * vm,
		    vlib_node_runtime_t * node, vlib_buffer_t * b)
{
  /* Can we safely rewind the buffer? If not, fagedaboudit */
  if (b->flags & VNET_BUFFER_F_L2_HDR_OFFSET_VALID)
    {
      vnet_error_trace_t *t;
      ip4_header_t *ip4;
      ip6_header_t *ip6;
      ethernet_header_t *eh;
      i16 delta;

      t = vlib_add_trace (vm, node, b, sizeof (*t));
      delta = vnet_buffer (b)->l2_hdr_offset - b->current_data;
      vlib_buffer_advance (b, delta);

      eh = vlib_buffer_get_current (b);
      /* Save mactype */
      t->mactype = clib_net_to_host_u16 (eh->type);
      t->details_valid = 1;
      switch (t->mactype)
	{
	case ETHERNET_TYPE_IP4:
	  ip4 = (void *) (eh + 1);
	  t->details_valid = 2;
	  t->is_ip6 = 0;
	  t->src.ip4.as_u32 = ip4->src_address.as_u32;
	  t->dst.ip4.as_u32 = ip4->dst_address.as_u32;
	  break;

	case ETHERNET_TYPE_IP6:
	  ip6 = (void *) (eh + 1);
	  t->details_valid = 2;
	  t->is_ip6 = 1;
	  clib_memcpy_fast (t->src.as_u8, ip6->src_address.as_u8,
			    sizeof (ip6_address_t));
	  clib_memcpy_fast (t->dst.as_u8, ip6->dst_address.as_u8,
			    sizeof (ip6_address_t));
	  break;

	default:
	  /* Dunno, do nothing, leave details_valid alone */
	  break;
	}
      /* Restore current data (probably unnecessary) */
      vlib_buffer_advance (b, -delta);
    }
}

static_always_inline uword
interface_drop_punt (vlib_main_t * vm,
		     vlib_node_runtime_t * node,
		     vlib_frame_t * frame,
		     vnet_error_disposition_t disposition)
{
  u32 *from, n_left, thread_index, *sw_if_index;
  vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b;
  u32 sw_if_indices[VLIB_FRAME_SIZE];
  vlib_simple_counter_main_t *cm;
  u16 nexts[VLIB_FRAME_SIZE];
  u32 n_trace;
  vnet_main_t *vnm;

  vnm = vnet_get_main ();
  thread_index = vm->thread_index;
  from = vlib_frame_vector_args (frame);
  n_left = frame->n_vectors;
  b = bufs;
  sw_if_index = sw_if_indices;

  vlib_get_buffers (vm, from, bufs, n_left);

  /* "trace add error-drop NNN?" */
  if (PREDICT_FALSE ((n_trace = vlib_get_trace_count (vm, node))))
    {
      /* If pkts aren't otherwise traced... */
      if ((node->flags & VLIB_NODE_FLAG_TRACE) == 0)
	{
	  /* Trace them from here */
	  node->flags |= VLIB_NODE_FLAG_TRACE;
	  while (n_trace && n_left)
	    {
	      if (PREDICT_TRUE
		  (vlib_trace_buffer (vm, node, 0 /* next_index */ , b[0],
				      0 /* follow chain */ )))
		{
		  /*
		   * Here we have a wireshark dissector problem.
		   * Packets may be well-formed, or not. We
		   * must not blow chunks in any case.
		   *
		   * Try to produce trace records which will help
		   * folks understand what's going on.
		   */
		  drop_catchup_trace (vm, node, b[0]);
		  n_trace--;
		}
	      n_left--;
	      b++;
	    }
	}

      vlib_set_trace_count (vm, node, n_trace);
      b = bufs;
      n_left = frame->n_vectors;
    }

  if (node->flags & VLIB_NODE_FLAG_TRACE)
    interface_trace_buffers (vm, node, frame);

  /* All going to drop regardless, this is just a counting exercise */
  clib_memset (nexts, 0, sizeof (nexts));

  cm = vec_elt_at_index (vnm->interface_main.sw_if_counters,
			 (disposition == VNET_ERROR_DISPOSITION_PUNT
			  ? VNET_INTERFACE_COUNTER_PUNT
			  : VNET_INTERFACE_COUNTER_DROP));

  /* collect the array of interfaces first ... */
  while (n_left >= 4)
    {
      if (n_left >= 12)
	{
	  /* Prefetch 8 ahead - there's not much going on in each iteration */
	  vlib_prefetch_buffer_header (b[4], LOAD);
	  vlib_prefetch_buffer_header (b[5], LOAD);
	  vlib_prefetch_buffer_header (b[6], LOAD);
	  vlib_prefetch_buffer_header (b[7], LOAD);
	}
      sw_if_index[0] = vnet_buffer (b[0])->sw_if_index[VLIB_RX];
      sw_if_index[1] = vnet_buffer (b[1])->sw_if_index[VLIB_RX];
      sw_if_index[2] = vnet_buffer (b[2])->sw_if_index[VLIB_RX];
      sw_if_index[3] = vnet_buffer (b[3])->sw_if_index[VLIB_RX];

      sw_if_index += 4;
      n_left -= 4;
      b += 4;
    }
  while (n_left)
    {
      sw_if_index[0] = vnet_buffer (b[0])->sw_if_index[VLIB_RX];

      sw_if_index += 1;
      n_left -= 1;
      b += 1;
    }

  /* ... then count against them in blocks */
  n_left = frame->n_vectors;

  while (n_left)
    {
      vnet_sw_interface_t *sw_if0;
      u16 off, count;

      off = frame->n_vectors - n_left;

      sw_if_index = sw_if_indices + off;

      count = clib_count_equal_u32 (sw_if_index, n_left);
      n_left -= count;

      vlib_increment_simple_counter (cm, thread_index, sw_if_index[0], count);

      /* Increment super-interface drop/punt counters for
         sub-interfaces. */
      sw_if0 = vnet_get_sw_interface (vnm, sw_if_index[0]);
      if (sw_if0->sup_sw_if_index != sw_if_index[0])
	vlib_increment_simple_counter
	  (cm, thread_index, sw_if0->sup_sw_if_index, count);
    }

  vlib_buffer_enqueue_to_next (vm, node, from, nexts, frame->n_vectors);

  return frame->n_vectors;
}

static inline void
pcap_drop_trace (vlib_main_t * vm,
		 vnet_interface_main_t * im,
		 vnet_pcap_t * pp, vlib_frame_t * f)
{
  u32 *from;
  u32 n_left = f->n_vectors;
  vlib_buffer_t *b0, *p1;
  u32 bi0;
  i16 save_current_data;
  u16 save_current_length;
  vlib_error_main_t *em = &vm->error_main;

  from = vlib_frame_vector_args (f);

  while (n_left > 0)
    {
      if (PREDICT_TRUE (n_left > 1))
	{
	  p1 = vlib_get_buffer (vm, from[1]);
	  vlib_prefetch_buffer_header (p1, LOAD);
	}

      bi0 = from[0];
      b0 = vlib_get_buffer (vm, bi0);
      from++;
      n_left--;

      /* See if we're pointedly ignoring this specific error */
      if (im->pcap_drop_filter_hash
	  && hash_get (im->pcap_drop_filter_hash, b0->error))
	continue;

      if (!vnet_is_packet_pcaped (pp, b0, ~0))
	continue; /* not matching, skip */

      /* Trace all drops, or drops received on a specific interface */
      save_current_data = b0->current_data;
      save_current_length = b0->current_length;

      /*
       * Typically, we'll need to rewind the buffer
       * if l2_hdr_offset is valid, make sure to rewind to the start of
       * the L2 header. This may not be the buffer start in case we pop-ed
       * vlan tags.
       * Otherwise, rewind to buffer start and hope for the best.
       */
      if (b0->flags & VNET_BUFFER_F_L2_HDR_OFFSET_VALID)
	{
	  if (b0->current_data > vnet_buffer (b0)->l2_hdr_offset)
	    vlib_buffer_advance (b0, vnet_buffer (b0)->l2_hdr_offset -
				       b0->current_data);
	}
      else if (b0->current_data > 0)
	{
	  vlib_buffer_advance (b0, (word) -b0->current_data);
	}

      {
	vlib_buffer_t *last = b0;
	u32 error_node_index;
	int drop_string_len;
	vlib_node_t *n;
	/* Length of the error string */
	int error_string_len =
	  clib_strnlen (em->counters_heap[b0->error].name, 128);

	/* Dig up the drop node */
	error_node_index = vm->node_main.node_by_error[b0->error];
	n = vlib_get_node (vm, error_node_index);

	/* Length of full drop string, w/ "nodename: " prepended */
	drop_string_len = error_string_len + vec_len (n->name) + 2;

	/* Find the last buffer in the chain */
	while (last->flags & VLIB_BUFFER_NEXT_PRESENT)
	  last = vlib_get_buffer (vm, last->next_buffer);

	/*
	 * Append <nodename>: <error-string> to the capture,
	 * only if we can do that without allocating a new buffer.
	 */
	if (PREDICT_TRUE ((last->current_data + last->current_length) <
			  (VLIB_BUFFER_DEFAULT_DATA_SIZE - drop_string_len)))
	  {
	    clib_memcpy_fast (last->data + last->current_data +
				last->current_length,
			      n->name, vec_len (n->name));
	    clib_memcpy_fast (last->data + last->current_data +
				last->current_length + vec_len (n->name),
			      ": ", 2);
	    clib_memcpy_fast (last->data + last->current_data +
				last->current_length + vec_len (n->name) + 2,
			      em->counters_heap[b0->error].name,
			      error_string_len);
	    last->current_length += drop_string_len;
	    b0->flags &= ~(VLIB_BUFFER_TOTAL_LENGTH_VALID);
	    pcap_add_buffer (&pp->pcap_main, vm, bi0, pp->max_bytes_per_pkt);
	    last->current_length -= drop_string_len;
	    b0->current_data = save_current_data;
	    b0->current_length = save_current_length;
	    continue;
	  }
      }

      /*
       * Didn't have space in the last buffer, here's the dropped
       * packet as-is
       */
      pcap_add_buffer (&pp->pcap_main, vm, bi0, pp->max_bytes_per_pkt);

      b0->current_data = save_current_data;
      b0->current_length = save_current_length;
    }
}

#ifndef CLIB_MARCH_VARIANT
void
vnet_pcap_drop_trace_filter_add_del (u32 error_index, int is_add)
{
  vnet_interface_main_t *im = &vnet_get_main ()->interface_main;

  if (im->pcap_drop_filter_hash == 0)
    im->pcap_drop_filter_hash = hash_create (0, sizeof (uword));

  if (is_add)
    hash_set (im->pcap_drop_filter_hash, error_index, 1);
  else
    hash_unset (im->pcap_drop_filter_hash, error_index);
}
#endif /* CLIB_MARCH_VARIANT */

VLIB_NODE_FN (interface_drop) (vlib_main_t * vm,
			       vlib_node_runtime_t * node,
			       vlib_frame_t * frame)
{
  vnet_main_t *vnm = vnet_get_main ();
  vnet_interface_main_t *im = &vnet_get_main ()->interface_main;
  vnet_pcap_t *pp = &vnm->pcap;

  if (PREDICT_FALSE (pp->pcap_drop_enable))
    pcap_drop_trace (vm, im, pp, frame);

  return interface_drop_punt (vm, node, frame, VNET_ERROR_DISPOSITION_DROP);
}

VLIB_NODE_FN (interface_punt) (vlib_main_t * vm,
			       vlib_node_runtime_t * node,
			       vlib_frame_t * frame)
{
  return interface_drop_punt (vm, node, frame, VNET_ERROR_DISPOSITION_PUNT);
}

/* *INDENT-OFF* */
VLIB_REGISTER_NODE (interface_drop) = {
  .name = "error-drop",
  .vector_size = sizeof (u32),
  .format_trace = format_vnet_error_trace,
  .flags = VLIB_NODE_FLAG_TRACE_SUPPORTED,
  .n_next_nodes = 1,
  .next_nodes = {
    [0] = "drop",
  },
};
/* *INDENT-ON* */

/* *INDENT-OFF* */
VLIB_REGISTER_NODE (interface_punt) = {
  .name = "error-punt",
  .vector_size = sizeof (u32),
  .format_trace = format_vnet_error_trace,
  .flags = VLIB_NODE_FLAG_TRACE_SUPPORTED,
  .n_next_nodes = 1,
  .next_nodes = {
    [0] = "punt",
  },
};
/* *INDENT-ON* */

VLIB_REGISTER_NODE (vnet_per_buffer_interface_output_node) = {
  .name = "interface-output",
  .vector_size = sizeof (u32),
};

VLIB_NODE_FN (vnet_interface_output_arc_end_node)
(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
{
  vnet_main_t *vnm = vnet_get_main ();
  vnet_interface_main_t *im = &vnm->interface_main;
  vnet_hw_if_output_node_runtime_t *r = 0;
  vnet_hw_interface_t *hi;
  vnet_hw_if_tx_frame_t *tf;
  vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b = bufs;
  u32 sw_if_indices[VLIB_FRAME_SIZE], *sw_if_index = sw_if_indices;
  u64 used_elts[VLIB_FRAME_SIZE / 64] = {};
  u64 mask[VLIB_FRAME_SIZE / 64] = {};
  u32 *tmp, *from, n_left, n_free, n_comp, *to, swif, off;
  u16 next_index;
  vlib_frame_t *f;

  from = vlib_frame_vector_args (frame);
  n_left = frame->n_vectors;
  vlib_get_buffers (vm, from, bufs, n_left);

  while (n_left >= 8)
    {
      vlib_prefetch_buffer_header (b[4], LOAD);
      vlib_prefetch_buffer_header (b[5], LOAD);
      vlib_prefetch_buffer_header (b[6], LOAD);
      vlib_prefetch_buffer_header (b[7], LOAD);
      sw_if_index[0] = vnet_buffer (b[0])->sw_if_index[VLIB_TX];
      sw_if_index[1] = vnet_buffer (b[1])->sw_if_index[VLIB_TX];
      sw_if_index[2] = vnet_buffer (b[2])->sw_if_index[VLIB_TX];
      sw_if_index[3] = vnet_buffer (b[3])->sw_if_index[VLIB_TX];

      b += 4;
      sw_if_index += 4;
      n_left -= 4;
    }

  while (n_left)
    {
      sw_if_index[0] = vnet_buffer (b[0])->sw_if_index[VLIB_TX];
      b++;
      sw_if_index++;
      n_left--;
    }

  n_left = frame->n_vectors;
  swif = sw_if_indices[0];
  off = 0;

  /* a bit ugly but it allows us to reuse stack space for temporary store
   * which may also improve memory latency */
  tmp = (u32 *) bufs;

more:
  next_index = vec_elt (im->if_out_arc_end_next_index_by_sw_if_index, swif);
  hi = vnet_get_sup_hw_interface (vnm, swif);
  if (hi->output_node_thread_runtimes)
    r = vec_elt_at_index (hi->output_node_thread_runtimes, vm->thread_index);
  f = vlib_get_next_frame_internal (vm, node, next_index, 0);
  tf = vlib_frame_scalar_args (f);

  if (f->n_vectors > 0 && (r == 0 || r->frame.queue_id == tf->queue_id))
    {
      /* append frame */
      n_free = VLIB_FRAME_SIZE - f->n_vectors;
      if (n_free >= f->n_vectors)
	to = (u32 *) vlib_frame_vector_args (f) + f->n_vectors;
      else
	to = tmp;
    }
  else
    {
      if (f->n_vectors > 0)
	{
	  /* current frame doesn't fit - grab empty one */
	  f = vlib_get_next_frame_internal (vm, node, next_index, 1);
	  tf = vlib_frame_scalar_args (f);
	}

      /* empty frame - store scalar data */
      store_tx_frame_scalar_data (r, tf);
      n_free = VLIB_FRAME_SIZE;
      to = vlib_frame_vector_args (f);
    }

  /* compare and compress based on comparison mask */
  clib_mask_compare_u32 (swif, sw_if_indices, mask, frame->n_vectors);
  n_comp = clib_compress_u32 (to, from, mask, frame->n_vectors);

  if (tmp != to)
    {
      /* indices already written to frame, just close it */
      vlib_put_next_frame (vm, node, next_index, n_free - n_comp);
    }
  else if (n_free >= n_comp)
    {
      /* enough space in the existing frame */
      to = (u32 *) vlib_frame_vector_args (f) + f->n_vectors;
      vlib_buffer_copy_indices (to, tmp, n_comp);
      vlib_put_next_frame (vm, node, next_index, n_free - n_comp);
    }
  else
    {
      /* full frame */
      to = (u32 *) vlib_frame_vector_args (f) + f->n_vectors;
      vlib_buffer_copy_indices (to, tmp, n_free);
      vlib_put_next_frame (vm, node, next_index, 0);

      /* second frame */
      u32 n_frame2 = n_comp - n_free;
      f = vlib_get_next_frame_internal (vm, node, next_index, 1);
      to = vlib_frame_vector_args (f);
      vlib_buffer_copy_indices (to, tmp + n_free, n_frame2);
      tf = vlib_frame_scalar_args (f);
      store_tx_frame_scalar_data (r, tf);
      vlib_put_next_frame (vm, node, next_index, VLIB_FRAME_SIZE - n_frame2);
    }

  n_left -= n_comp;
  if (n_left)
    {
      /* store comparison mask so we can find next unused element */
      for (int i = 0; i < ARRAY_LEN (used_elts); i++)
	used_elts[i] |= mask[i];

      /* fine first unused sw_if_index by scanning trough used_elts bitmap */
      while (PREDICT_FALSE (used_elts[off] == ~0))
	off++;

      swif =
	sw_if_indices[(off << 6) + count_trailing_zeros (~used_elts[off])];
      goto more;
    }

  return frame->n_vectors;
}

VLIB_REGISTER_NODE (vnet_interface_output_arc_end_node) = {
  .name = "interface-output-arc-end",
  .vector_size = sizeof (u32),
  .n_next_nodes = 1,
  .next_nodes = {
    [0] = "error-drop",
  },
};

VNET_FEATURE_ARC_INIT (interface_output, static) = {
  .arc_name = "interface-output",
  .start_nodes = VNET_FEATURES (0),
  .last_in_arc = "interface-output-arc-end",
  .arc_index_ptr = &vnet_main.interface_main.output_feature_arc_index,
};

VNET_FEATURE_INIT (span_tx, static) = {
  .arc_name = "interface-output",
  .node_name = "span-output",
  .runs_before = VNET_FEATURES ("interface-output-arc-end"),
};

VNET_FEATURE_INIT (ipsec_if_tx, static) = {
  .arc_name = "interface-output",
  .node_name = "ipsec-if-output",
  .runs_before = VNET_FEATURES ("interface-output-arc-end"),
};

VNET_FEATURE_INIT (interface_output_arc_end, static) = {
  .arc_name = "interface-output",
  .node_name = "interface-output-arc-end",
  .runs_before = 0,
};

#ifndef CLIB_MARCH_VARIANT
clib_error_t *
vnet_per_buffer_interface_output_hw_interface_add_del (vnet_main_t * vnm,
						       u32 hw_if_index,
						       u32 is_create)
{
  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
  u32 next_index;

  if (hi->output_node_index == 0)
    return 0;

  next_index = vlib_node_add_next
    (vnm->vlib_main, vnet_per_buffer_interface_output_node.index,
     hi->output_node_index);
  hi->output_node_next_index = next_index;

  return 0;
}

VNET_HW_INTERFACE_ADD_DEL_FUNCTION
  (vnet_per_buffer_interface_output_hw_interface_add_del);

void
vnet_set_interface_output_node (vnet_main_t * vnm,
				u32 hw_if_index, u32 node_index)
{
  ASSERT (node_index);
  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
  u32 next_index = vlib_node_add_next
    (vnm->vlib_main, vnet_per_buffer_interface_output_node.index, node_index);
  hi->output_node_next_index = next_index;
  hi->output_node_index = node_index;
}
#endif /* CLIB_MARCH_VARIANT */

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