/*
 * 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.
 */
/*
 * ip/ip4_input.c: IP v4 input 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/ip/ip4_input.h>
#include <vnet/ethernet/ethernet.h>
#include <vnet/ppp/ppp.h>
#include <vnet/hdlc/hdlc.h>

typedef struct
{
  u8 packet_data[64];
} ip4_input_trace_t;

#ifndef CLIB_MARCH_VARIANT
static u8 *
format_ip4_input_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 *);
  ip4_input_trace_t *t = va_arg (*va, ip4_input_trace_t *);

  s = format (s, "%U",
	      format_ip4_header, t->packet_data, sizeof (t->packet_data));

  return s;
}
#endif

static_always_inline u32
ip4_input_set_next (u32 sw_if_index, vlib_buffer_t * b, int arc_enabled)
{
  ip4_main_t *im = &ip4_main;
  ip_lookup_main_t *lm = &im->lookup_main;
  u32 next;
  u8 arc;

  ip4_header_t *ip = vlib_buffer_get_current (b);

  if (PREDICT_FALSE (ip4_address_is_multicast (&ip->dst_address)))
    {
      next = IP4_INPUT_NEXT_LOOKUP_MULTICAST;
      arc = lm->mcast_feature_arc_index;
    }
  else
    {
      next = IP4_INPUT_NEXT_LOOKUP;
      arc = lm->ucast_feature_arc_index;
    }

  if (arc_enabled)
    vnet_feature_arc_start (arc, sw_if_index, &next, b);

  return next;
}

static_always_inline void
ip4_input_check_sw_if_index (vlib_main_t * vm,
			     vlib_simple_counter_main_t * cm, u32 sw_if_index,
			     u32 * last_sw_if_index, u32 * cnt,
			     int *arc_enabled)
{
  ip4_main_t *im = &ip4_main;
  ip_lookup_main_t *lm = &im->lookup_main;
  u32 thread_index;
  if (*last_sw_if_index == sw_if_index)
    {
      (*cnt)++;
      return;
    }

  thread_index = vm->thread_index;
  if (*cnt)
    vlib_increment_simple_counter (cm, thread_index, *last_sw_if_index, *cnt);
  *cnt = 1;
  *last_sw_if_index = sw_if_index;

  if (vnet_have_features (lm->ucast_feature_arc_index, sw_if_index) ||
      vnet_have_features (lm->mcast_feature_arc_index, sw_if_index))
    *arc_enabled = 1;
  else
    *arc_enabled = 0;
}

/* Validate IP v4 packets and pass them either to forwarding code
   or drop/punt exception packets. */
always_inline uword
ip4_input_inline (vlib_main_t * vm,
		  vlib_node_runtime_t * node,
		  vlib_frame_t * frame, int verify_checksum)
{
  vnet_main_t *vnm = vnet_get_main ();
  u32 n_left_from, *from;
  u32 thread_index = vm->thread_index;
  vlib_node_runtime_t *error_node =
    vlib_node_get_runtime (vm, ip4_input_node.index);
  vlib_simple_counter_main_t *cm;
  vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b;
  ip4_header_t *ip[4];
  u16 nexts[VLIB_FRAME_SIZE], *next;
  u32 sw_if_index[4];
  u32 last_sw_if_index = ~0;
  u32 cnt = 0;
  int arc_enabled = 0;

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

  if (node->flags & VLIB_NODE_FLAG_TRACE)
    vlib_trace_frame_buffers_only (vm, node, from, frame->n_vectors,
				   /* stride */ 1,
				   sizeof (ip4_input_trace_t));

  cm = vec_elt_at_index (vnm->interface_main.sw_if_counters,
			 VNET_INTERFACE_COUNTER_IP4);

  vlib_get_buffers (vm, from, bufs, n_left_from);
  b = bufs;
  next = nexts;
  while (n_left_from >= 4)
    {
      u32 x = 0;

      /* Prefetch next iteration. */
      if (n_left_from >= 12)
	{
	  vlib_prefetch_buffer_header (b[8], LOAD);
	  vlib_prefetch_buffer_header (b[9], LOAD);
	  vlib_prefetch_buffer_header (b[10], LOAD);
	  vlib_prefetch_buffer_header (b[11], LOAD);

	  CLIB_PREFETCH (b[4]->data, sizeof (ip4_header_t), LOAD);
	  CLIB_PREFETCH (b[5]->data, sizeof (ip4_header_t), LOAD);
	  CLIB_PREFETCH (b[6]->data, sizeof (ip4_header_t), LOAD);
	  CLIB_PREFETCH (b[7]->data, sizeof (ip4_header_t), LOAD);
	}

      vnet_buffer (b[0])->ip.adj_index[VLIB_RX] = ~0;
      vnet_buffer (b[1])->ip.adj_index[VLIB_RX] = ~0;
      vnet_buffer (b[2])->ip.adj_index[VLIB_RX] = ~0;
      vnet_buffer (b[3])->ip.adj_index[VLIB_RX] = ~0;

      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];

      x |= sw_if_index[0] ^ last_sw_if_index;
      x |= sw_if_index[1] ^ last_sw_if_index;
      x |= sw_if_index[2] ^ last_sw_if_index;
      x |= sw_if_index[3] ^ last_sw_if_index;

      if (PREDICT_TRUE (x == 0))
	{
	  /* we deal with 4 more packets sharing the same sw_if_index
	     with the previous one, so we can optimize */
	  cnt += 4;
	  if (arc_enabled)
	    {
	      next[0] = ip4_input_set_next (sw_if_index[0], b[0], 1);
	      next[1] = ip4_input_set_next (sw_if_index[1], b[1], 1);
	      next[2] = ip4_input_set_next (sw_if_index[2], b[2], 1);
	      next[3] = ip4_input_set_next (sw_if_index[3], b[3], 1);
	    }
	  else
	    {
	      next[0] = ip4_input_set_next (sw_if_index[0], b[0], 0);
	      next[1] = ip4_input_set_next (sw_if_index[1], b[1], 0);
	      next[2] = ip4_input_set_next (sw_if_index[2], b[2], 0);
	      next[3] = ip4_input_set_next (sw_if_index[3], b[3], 0);
	    }
	}
      else
	{
	  ip4_input_check_sw_if_index (vm, cm, sw_if_index[0],
				       &last_sw_if_index, &cnt, &arc_enabled);
	  ip4_input_check_sw_if_index (vm, cm, sw_if_index[1],
				       &last_sw_if_index, &cnt, &arc_enabled);
	  ip4_input_check_sw_if_index (vm, cm, sw_if_index[2],
				       &last_sw_if_index, &cnt, &arc_enabled);
	  ip4_input_check_sw_if_index (vm, cm, sw_if_index[3],
				       &last_sw_if_index, &cnt, &arc_enabled);

	  next[0] = ip4_input_set_next (sw_if_index[0], b[0], 1);
	  next[1] = ip4_input_set_next (sw_if_index[1], b[1], 1);
	  next[2] = ip4_input_set_next (sw_if_index[2], b[2], 1);
	  next[3] = ip4_input_set_next (sw_if_index[3], b[3], 1);
	}

      ip[0] = vlib_buffer_get_current (b[0]);
      ip[1] = vlib_buffer_get_current (b[1]);
      ip[2] = vlib_buffer_get_current (b[2]);
      ip[3] = vlib_buffer_get_current (b[3]);

      ip4_input_check_x4 (vm, error_node, b, ip, next, verify_checksum);

      /* next */
      b += 4;
      next += 4;
      n_left_from -= 4;
    }
  while (n_left_from)
    {
      u32 next0;
      vnet_buffer (b[0])->ip.adj_index[VLIB_RX] = ~0;
      sw_if_index[0] = vnet_buffer (b[0])->sw_if_index[VLIB_RX];
      ip4_input_check_sw_if_index (vm, cm, sw_if_index[0], &last_sw_if_index,
				   &cnt, &arc_enabled);
      next0 = ip4_input_set_next (sw_if_index[0], b[0], arc_enabled);
      ip[0] = vlib_buffer_get_current (b[0]);
      ip4_input_check_x1 (vm, error_node, b[0], ip[0], &next0,
			  verify_checksum);
      next[0] = next0;

      /* next */
      b += 1;
      next += 1;
      n_left_from -= 1;
    }

  vlib_increment_simple_counter (cm, thread_index, last_sw_if_index, cnt);
  vlib_buffer_enqueue_to_next (vm, node, from, nexts, frame->n_vectors);
  return frame->n_vectors;
}

/** \brief IPv4 input node.
    @node ip4-input

    This is the IPv4 input node: validates ip4 header checksums,
    verifies ip header lengths, discards pkts with expired TTLs,
    and sends pkts to the set of ip feature nodes configured on
    the rx interface.

    @param vm vlib_main_t corresponding to the current thread
    @param node vlib_node_runtime_t
    @param frame vlib_frame_t whose contents should be dispatched

    @par Graph mechanics: buffer metadata, next index usage

    @em Uses:
    - vnet_feature_config_main_t cm corresponding to each pkt's dst address unicast /
      multicast status.
    - <code>b->current_config_index</code> corresponding to each pkt's
      rx sw_if_index.
         - This sets the per-packet graph trajectory, ensuring that
           each packet visits the per-interface features in order.

    - <code>vnet_buffer(b)->sw_if_index[VLIB_RX]</code>
        - Indicates the @c sw_if_index value of the interface that the
	  packet was received on.

    @em Sets:
    - <code>vnet_buffer(b)->ip.adj_index[VLIB_TX]</code>
        - The lookup result adjacency index.

    <em>Next Indices:</em>
    - Dispatches pkts to the (first) feature node:
      <code> vnet_get_config_data (... &next0 ...); </code>
      or @c error-drop
*/
VLIB_NODE_FN (ip4_input_node) (vlib_main_t * vm, vlib_node_runtime_t * node,
			       vlib_frame_t * frame)
{
  return ip4_input_inline (vm, node, frame, /* verify_checksum */ 1);
}

VLIB_NODE_FN (ip4_input_no_checksum_node) (vlib_main_t * vm,
					   vlib_node_runtime_t * node,
					   vlib_frame_t * frame)
{
  return ip4_input_inline (vm, node, frame, /* verify_checksum */ 0);
}

#ifndef CLIB_MARCH_VARIANT
char *ip4_error_strings[] = {
#define _(sym,string) string,
  foreach_ip4_error
#undef _
};

/* *INDENT-OFF* */
VLIB_REGISTER_NODE (ip4_input_node) = {
  .name = "ip4-input",
  .vector_size = sizeof (u32),

  .n_errors = IP4_N_ERROR,
  .error_strings = ip4_error_strings,

  .n_next_nodes = IP4_INPUT_N_NEXT,
  .next_nodes = {
    [IP4_INPUT_NEXT_DROP] = "error-drop",
    [IP4_INPUT_NEXT_PUNT] = "error-punt",
    [IP4_INPUT_NEXT_OPTIONS] = "ip4-options",
    [IP4_INPUT_NEXT_LOOKUP] = "ip4-lookup",
    [IP4_INPUT_NEXT_LOOKUP_MULTICAST] = "ip4-mfib-forward-lookup",
    [IP4_INPUT_NEXT_ICMP_ERROR] = "ip4-icmp-error",
    [IP4_INPUT_NEXT_REASSEMBLY] = "ip4-reassembly",
  },

  .format_buffer = format_ip4_header,
  .format_trace = format_ip4_input_trace,
};

VLIB_REGISTER_NODE (ip4_input_no_checksum_node) = {
  .name = "ip4-input-no-checksum",
  .vector_size = sizeof (u32),

  .sibling_of = "ip4-input",
  .format_buffer = format_ip4_header,
  .format_trace = format_ip4_input_trace,
};
/* *INDENT-ON* */

static clib_error_t *
ip4_init (vlib_main_t * vm)
{
  clib_error_t *error;

  ethernet_register_input_type (vm, ETHERNET_TYPE_IP4, ip4_input_node.index);
  ppp_register_input_protocol (vm, PPP_PROTOCOL_ip4, ip4_input_node.index);
  hdlc_register_input_protocol (vm, HDLC_PROTOCOL_ip4, ip4_input_node.index);

  {
    pg_node_t *pn;
    pn = pg_get_node (ip4_input_node.index);
    pn->unformat_edit = unformat_pg_ip4_header;
    pn = pg_get_node (ip4_input_no_checksum_node.index);
    pn->unformat_edit = unformat_pg_ip4_header;
  }

  if ((error = vlib_call_init_function (vm, ip4_cli_init)))
    return error;

  if ((error = vlib_call_init_function (vm, ip4_source_check_init)))
    return error;

  if ((error = vlib_call_init_function
       (vm, ip4_source_and_port_range_check_init)))
    return error;

  /* Set flow hash to something non-zero. */
  ip4_main.flow_hash_seed = 0xdeadbeef;

  /* Default TTL for packets we generate. */
  ip4_main.host_config.ttl = 64;

  return error;
}

VLIB_INIT_FUNCTION (ip4_init);

static clib_error_t *
ip4_main_loop_enter (vlib_main_t * vm)
{
  ip4_main_t *im = &ip4_main;
  vlib_thread_main_t *tm = &vlib_thread_main;
  u32 n_vlib_mains = tm->n_vlib_mains;
  int i;


  vec_validate (im->arp_throttle_bitmaps, n_vlib_mains);
  vec_validate (im->arp_throttle_seeds, n_vlib_mains);
  vec_validate (im->arp_throttle_last_seed_change_time, n_vlib_mains);

  for (i = 0; i < n_vlib_mains; i++)
    vec_validate (im->arp_throttle_bitmaps[i],
		  (ARP_THROTTLE_BITS / BITS (uword)) - 1);
  return 0;
}

VLIB_MAIN_LOOP_ENTER_FUNCTION (ip4_main_loop_enter);

#endif

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