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

#ifndef included_ip6_input_h
#define included_ip6_input_h

#include <vnet/ip/ip.h>
#include <vnet/ip/icmp6.h>

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;

always_inline void
ip6_input_check_x2 (vlib_main_t *vm, vlib_node_runtime_t *error_node,
		    vlib_buffer_t *p0, vlib_buffer_t *p1, ip6_header_t *ip0,
		    ip6_header_t *ip1, u32 *next0, u32 *next1)
{
  u8 error0, error1;

  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))
    {
      p0->error = error_node->errors[error0];

      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))
    {
      p1->error = error_node->errors[error1];

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

always_inline void
ip6_input_check_x1 (vlib_main_t *vm, vlib_node_runtime_t *error_node,
		    vlib_buffer_t *p0, ip6_header_t *ip0, u32 *next0)
{
  u8 error0;

  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))
    {
      p0->error = error_node->errors[error0];
      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;
	}
    }
}

#endif

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