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

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

static u8 *
format_ip6_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 *);
  ip6_input_trace_t *t = va_arg (*va, ip6_input_trace_t *);

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

  return s;
}

typedef enum
{
  IP6_INPUT_NEXT_DROP,
  IP6_INPUT_NEXT_LOOKUP,
  IP6_INPUT_NEXT_LOOKUP_MULTICAST,
  IP6_INPUT_NEXT_ICMP_ERROR,
  IP6_INPUT_N_NEXT,
} ip6_input_next_t;

/* Validate IP v6 packets and pass them either to forwarding code
   or drop exception packets. */
static uword
ip6_input (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
{
  vnet_main_t *vnm = vnet_get_main ();
  ip6_main_t *im = &ip6_main;
  ip_lookup_main_t *lm = &im->lookup_main;
  u32 n_left_from, *from, *to_next;
  ip6_input_next_t next_index;
  vlib_node_runtime_t *error_node =
    vlib_node_get_runtime (vm, ip6_input_node.index);
  vlib_simple_counter_main_t *cm;
  u32 thread_index = vlib_get_thread_index ();

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

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

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

  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)
	{
	  vlib_buffer_t *p0, *p1;
	  ip6_header_t *ip0, *ip1;
	  u32 pi0, sw_if_index0, next0 = 0;
	  u32 pi1, sw_if_index1, next1 = 0;
	  u8 error0, error1, arc0, arc1;

	  /* Prefetch next iteration. */
	  {
	    vlib_buffer_t *p2, *p3;

	    p2 = vlib_get_buffer (vm, from[2]);
	    p3 = vlib_get_buffer (vm, from[3]);

	    vlib_prefetch_buffer_header (p2, LOAD);
	    vlib_prefetch_buffer_header (p3, LOAD);

	    CLIB_PREFETCH (p2->data, sizeof (ip0[0]), LOAD);
	    CLIB_PREFETCH (p3->data, sizeof (ip1[0]), LOAD);
	  }

	  pi0 = from[0];
	  pi1 = from[1];

	  to_next[0] = pi0;
	  to_next[1] = pi1;
	  from += 2;
	  to_next += 2;
	  n_left_from -= 2;
	  n_left_to_next -= 2;

	  p0 = vlib_get_buffer (vm, pi0);
	  p1 = vlib_get_buffer (vm, pi1);

	  ip0 = vlib_buffer_get_current (p0);
	  ip1 = vlib_buffer_get_current (p1);

	  sw_if_index0 = vnet_buffer (p0)->sw_if_index[VLIB_RX];
	  sw_if_index1 = vnet_buffer (p1)->sw_if_index[VLIB_RX];

	  if (PREDICT_FALSE (ip6_address_is_multicast (&ip0->dst_address)))
	    {
	      arc0 = lm->mcast_feature_arc_index;
	      next0 = IP6_INPUT_NEXT_LOOKUP_MULTICAST;
	    }
	  else
	    {
	      arc0 = lm->ucast_feature_arc_index;
	      next0 = IP6_INPUT_NEXT_LOOKUP;
	    }

	  if (PREDICT_FALSE (ip6_address_is_multicast (&ip1->dst_address)))
	    {
	      arc1 = lm->mcast_feature_arc_index;
	      next1 = IP6_INPUT_NEXT_LOOKUP_MULTICAST;
	    }
	  else
	    {
	      arc1 = lm->ucast_feature_arc_index;
	      next1 = IP6_INPUT_NEXT_LOOKUP;
	    }

	  vnet_buffer (p0)->ip.adj_index[VLIB_RX] = ~0;
	  vnet_buffer (p1)->ip.adj_index[VLIB_RX] = ~0;

	  vnet_feature_arc_start (arc0, sw_if_index0, &next0, p0);
	  vnet_feature_arc_start (arc1, sw_if_index1, &next1, p1);

	  vlib_increment_simple_counter (cm, thread_index, sw_if_index0, 1);
	  vlib_increment_simple_counter (cm, thread_index, sw_if_index1, 1);

	  error0 = error1 = IP6_ERROR_NONE;

	  /* Version != 6?  Drop it. */
	  error0 =
	    (clib_net_to_host_u32
	     (ip0->ip_version_traffic_class_and_flow_label) >> 28) !=
	    6 ? IP6_ERROR_VERSION : error0;
	  error1 =
	    (clib_net_to_host_u32
	     (ip1->ip_version_traffic_class_and_flow_label) >> 28) !=
	    6 ? IP6_ERROR_VERSION : error1;

	  /* hop limit < 1? Drop it.  for link-local broadcast packets,
	   * like dhcpv6 packets from client has hop-limit 1, which should not
	   * be dropped.
	   */
	  error0 = ip0->hop_limit < 1 ? IP6_ERROR_TIME_EXPIRED : error0;
	  error1 = ip1->hop_limit < 1 ? IP6_ERROR_TIME_EXPIRED : error1;

	  /* L2 length must be at least minimal IP header. */
	  error0 =
	    p0->current_length <
	    sizeof (ip0[0]) ? IP6_ERROR_TOO_SHORT : error0;
	  error1 =
	    p1->current_length <
	    sizeof (ip1[0]) ? IP6_ERROR_TOO_SHORT : error1;

	  if (PREDICT_FALSE (error0 != IP6_ERROR_NONE))
	    {
	      if (error0 == IP6_ERROR_TIME_EXPIRED)
		{
		  icmp6_error_set_vnet_buffer (p0, ICMP6_time_exceeded,
					       ICMP6_time_exceeded_ttl_exceeded_in_transit,
					       0);
		  next0 = IP6_INPUT_NEXT_ICMP_ERROR;
		}
	      else
		{
		  next0 = IP6_INPUT_NEXT_DROP;
		}
	    }
	  if (PREDICT_FALSE (error1 != IP6_ERROR_NONE))
	    {
	      if (error1 == IP6_ERROR_TIME_EXPIRED)
		{
		  icmp6_error_set_vnet_buffer (p1, ICMP6_time_exceeded,
					       ICMP6_time_exceeded_ttl_exceeded_in_transit,
					       0);
		  next1 = IP6_INPUT_NEXT_ICMP_ERROR;
		}
	      else
		{
		  next1 = IP6_INPUT_NEXT_DROP;
		}
	    }

	  p0->error = error_node->errors[error0];
	  p1->error = error_node->errors[error1];

	  vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
					   to_next, n_left_to_next,
					   pi0, pi1, next0, next1);
	}

      while (n_left_from > 0 && n_left_to_next > 0)
	{
	  vlib_buffer_t *p0;
	  ip6_header_t *ip0;
	  u32 pi0, sw_if_index0, next0 = 0;
	  u8 error0, arc0;

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

	  p0 = vlib_get_buffer (vm, pi0);
	  ip0 = vlib_buffer_get_current (p0);

	  sw_if_index0 = vnet_buffer (p0)->sw_if_index[VLIB_RX];
	  if (PREDICT_FALSE (ip6_address_is_multicast (&ip0->dst_address)))
	    {
	      arc0 = lm->mcast_feature_arc_index;
	      next0 = IP6_INPUT_NEXT_LOOKUP_MULTICAST;
	    }
	  else
	    {
	      arc0 = lm->ucast_feature_arc_index;
	      next0 = IP6_INPUT_NEXT_LOOKUP;
	    }

	  vnet_buffer (p0)->ip.adj_index[VLIB_RX] = ~0;
	  vnet_feature_arc_start (arc0, sw_if_index0, &next0, p0);

	  vlib_increment_simple_counter (cm, thread_index, sw_if_index0, 1);
	  error0 = IP6_ERROR_NONE;

	  /* Version != 6?  Drop it. */
	  error0 =
	    (clib_net_to_host_u32
	     (ip0->ip_version_traffic_class_and_flow_label) >> 28) !=
	    6 ? IP6_ERROR_VERSION : error0;

	  /* hop limit < 1? Drop it. for link-local broadcast packets,
	   * like dhcpv6 packets from client has hop-limit 1, which should not
	   * be dropped.
	   */
	  error0 = ip0->hop_limit < 1 ? IP6_ERROR_TIME_EXPIRED : error0;

	  /* L2 length must be at least minimal IP header. */
	  error0 =
	    p0->current_length <
	    sizeof (ip0[0]) ? IP6_ERROR_TOO_SHORT : error0;

	  if (PREDICT_FALSE (error0 != IP6_ERROR_NONE))
	    {
	      if (error0 == IP6_ERROR_TIME_EXPIRED)
		{
		  icmp6_error_set_vnet_buffer (p0, ICMP6_time_exceeded,
					       ICMP6_time_exceeded_ttl_exceeded_in_transit,
					       0);
		  next0 = IP6_INPUT_NEXT_ICMP_ERROR;
		}
	      else
		{
		  next0 = IP6_INPUT_NEXT_DROP;
		}
	    }
	  p0->error = error_node->errors[error0];

	  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
					   to_next, n_left_to_next,
					   pi0, next0);
	}

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

  return frame->n_vectors;
}

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

/* *INDENT-OFF* */
VLIB_REGISTER_NODE (ip6_input_node) = {
  .function = ip6_input,
  .name = "ip6-input",
  .vector_size = sizeof (u32),

  .n_errors = IP6_N_ERROR,
  .error_strings = ip6_error_strings,

  .n_next_nodes = IP6_INPUT_N_NEXT,
  .next_nodes = {
    [IP6_INPUT_NEXT_DROP] = "error-drop",
    [IP6_INPUT_NEXT_LOOKUP] = "ip6-lookup",
    [IP6_INPUT_NEXT_ICMP_ERROR] = "ip6-icmp-error",
    [IP6_INPUT_NEXT_LOOKUP_MULTICAST] = "ip6-mfib-forward-lookup",
  },

  .format_buffer = format_ip6_header,
  .format_trace = format_ip6_input_trace,
};
/* *INDENT-ON* */

VLIB_NODE_FUNCTION_MULTIARCH (ip6_input_node, ip6_input)
     static clib_error_t *ip6_init (vlib_main_t * vm)
{
  ethernet_register_input_type (vm, ETHERNET_TYPE_IP6, ip6_input_node.index);
  ppp_register_input_protocol (vm, PPP_PROTOCOL_ip6, ip6_input_node.index);
  hdlc_register_input_protocol (vm, HDLC_PROTOCOL_ip6, ip6_input_node.index);

  {
    pg_node_t *pn;
    pn = pg_get_node (ip6_input_node.index);
    pn->unformat_edit = unformat_pg_ip6_header;
  }

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

  /* Default hop limit for packets we generate. */
  ip6_main.host_config.ttl = 64;

  return /* no error */ 0;
}

VLIB_INIT_FUNCTION (ip6_init);

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