/*
 * 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/mask_compare.h>
#include <vppinfra/vector/compress.h>
#include <vppinfra/vector/count_equal.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 processing_level)
{
  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 (processing_level >= 1)
	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 (processing_level >= 2)
	{
	  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 (processing_level >= 1 && (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 (processing_level >= 2)
	{
	  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 (processing_level >= 1)
	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 in_interface_ouput)
{
  vnet_main_t *vnm = vnet_get_main ();
  u32 n_left_from, *from;
  u32 sw_if_index = ~0, hw_if_index = ~0;
  vnet_pcap_t *pp = &vnm->pcap;

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

  if (in_interface_ouput)
    {
      /* interface-output is called right before interface-output-template.
       * We only want to capture packets here if there is a per-interface
       * filter, in case it matches the sub-interface sw_if_index.
       * If there is no per-interface filter configured, let the
       * interface-output-template node deal with it */
      if (pp->pcap_sw_if_index == 0)
	return;
    }
  else
    {
      vnet_interface_output_runtime_t *rt = (void *) node->runtime_data;
      sw_if_index = rt->sw_if_index;
    }

  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 (in_interface_ouput)
	{
	  const u32 sii = vnet_buffer (b0)->sw_if_index[VLIB_TX];
	  if (PREDICT_FALSE (sii != sw_if_index))
	    {
	      const vnet_hw_interface_t *hi =
		vnet_get_sup_hw_interface (vnm, sii);
	      hw_if_index = hi->sw_if_index;
	      sw_if_index = sii;
	    }
	  if (hw_if_index == sw_if_index)
	    continue; /* defer to interface-output-template */
	}

      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 /* in_interface_ouput */);

  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 not all three flags IP4_,TCP_,UDP_CKSUM set, do compute them
   * here before sending to the interface */
  if ((hi->caps & VNET_HW_INTERFACE_CAP_SUPPORTS_TX_CKSUM) !=
      VNET_HW_INTERFACE_CAP_SUPPORTS_TX_CKSUM)
    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);
  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);
  else
    n_bytes = vnet_interface_output_node_inline (
      vm, sw_if_index, ccm, bufs, config_index, arc, n_buffers, 2);

  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 /* in_interface_ouput */);

  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:
 */
