/*
 * ip/ip6_neighbor.c: IP6 neighbor handling
 *
 * Copyright (c) 2010 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.
 */

#include <vnet/ip6-nd/ip6_nd.h>
#include <vnet/ip6-nd/ip6_nd_inline.h>

#include <vnet/ip-neighbor/ip_neighbor.h>
#include <vnet/ip-neighbor/ip_neighbor_dp.h>

#include <vnet/fib/ip6_fib.h>
#include <vnet/ip/ip6_link.h>
#include <vnet/ip/ip6_ll_table.h>

/**
 * @file
 * @brief IPv6 Neighbor Adjacency and Neighbor Discovery.
 *
 * The files contains the API and CLI code for managing IPv6 neighbor
 * adjacency tables and neighbor discovery logic.
 */

#define DEF_MAX_RADV_INTERVAL 200
#define DEF_MIN_RADV_INTERVAL .75 * DEF_MAX_RADV_INTERVAL

typedef struct ip6_nd_t_
{
  /* local information */
  u32 sw_if_index;

  /* stats */
  u32 n_solicitations_rcvd;
  u32 n_solicitations_dropped;
} ip6_nd_t;

static ip6_link_delegate_id_t ip6_nd_delegate_id;
static ip6_nd_t *ip6_nd_pool;

static_always_inline uword
icmp6_neighbor_solicitation_or_advertisement (vlib_main_t * vm,
					      vlib_node_runtime_t * node,
					      vlib_frame_t * frame,
					      uword is_solicitation)
{
  ip6_main_t *im = &ip6_main;
  uword n_packets = frame->n_vectors;
  u32 *from, *to_next;
  u32 n_left_from, n_left_to_next, next_index, n_advertisements_sent;
  icmp6_neighbor_discovery_option_type_t option_type;
  vlib_node_runtime_t *error_node =
    vlib_node_get_runtime (vm, ip6_icmp_input_node.index);

  from = vlib_frame_vector_args (frame);
  n_left_from = n_packets;
  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 (icmp6_input_trace_t));

  option_type =
    (is_solicitation
     ? ICMP6_NEIGHBOR_DISCOVERY_OPTION_source_link_layer_address
     : ICMP6_NEIGHBOR_DISCOVERY_OPTION_target_link_layer_address);
  n_advertisements_sent = 0;

  while (n_left_from > 0)
    {
      vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);

      while (n_left_from > 0 && n_left_to_next > 0)
	{
	  vlib_buffer_t *p0;
	  ip6_header_t *ip0;
	  icmp6_neighbor_solicitation_or_advertisement_header_t *h0;
	  icmp6_neighbor_discovery_ethernet_link_layer_address_option_t *o0;
	  u32 bi0, options_len0, sw_if_index0, next0, error0;
	  u32 ip6_sadd_link_local, ip6_sadd_unspecified;
	  ip_neighbor_counter_type_t c_type;
	  int is_rewrite0;
	  u32 ni0;

	  bi0 = to_next[0] = from[0];

	  from += 1;
	  to_next += 1;
	  n_left_from -= 1;
	  n_left_to_next -= 1;

	  p0 = vlib_get_buffer (vm, bi0);
	  ip0 = vlib_buffer_get_current (p0);
	  h0 = ip6_next_header (ip0);
	  options_len0 =
	    clib_net_to_host_u16 (ip0->payload_length) - sizeof (h0[0]);

	  error0 = ICMP6_ERROR_NONE;
	  sw_if_index0 = vnet_buffer (p0)->sw_if_index[VLIB_RX];
	  ip6_sadd_link_local =
	    ip6_address_is_link_local_unicast (&ip0->src_address);
	  ip6_sadd_unspecified =
	    ip6_address_is_unspecified (&ip0->src_address);

	  /* Check that source address is unspecified, link-local or else on-link. */
	  if (!ip6_sadd_unspecified && !ip6_sadd_link_local)
	    {
	      u32 src_adj_index0 = ip6_src_lookup_for_packet (im, p0, ip0);

	      if (ADJ_INDEX_INVALID != src_adj_index0)
		{
		  ip_adjacency_t *adj0 = adj_get (src_adj_index0);

		  /* Allow all realistic-looking rewrite adjacencies to pass */
		  ni0 = adj0->lookup_next_index;
		  is_rewrite0 = (ni0 >= IP_LOOKUP_NEXT_ARP) &&
		    (ni0 < IP6_LOOKUP_N_NEXT);

		  error0 = ((adj0->rewrite_header.sw_if_index != sw_if_index0
			     || !is_rewrite0)
			    ?
			    ICMP6_ERROR_NEIGHBOR_SOLICITATION_SOURCE_NOT_ON_LINK
			    : error0);
		}
	      else
		{
		  error0 =
		    ICMP6_ERROR_NEIGHBOR_SOLICITATION_SOURCE_NOT_ON_LINK;
		}
	    }

	  o0 = (void *) (h0 + 1);
	  o0 = ((options_len0 == 8 && o0->header.type == option_type
		 && o0->header.n_data_u64s == 1) ? o0 : 0);

	  /* If src address unspecified or link local, donot learn neighbor MAC */
	  if (PREDICT_TRUE (error0 == ICMP6_ERROR_NONE && o0 != 0 &&
			    !ip6_sadd_unspecified))
	    {
              /* *INDENT-OFF* */
	      ip_neighbor_learn_t learn = {
		.sw_if_index = sw_if_index0,
		.ip = {
                  .version = AF_IP6,
                  .ip.ip6 = (is_solicitation ?
                             ip0->src_address :
                             h0->target_address),
                }
	      };
              /* *INDENT-ON* */
	      memcpy (&learn.mac, o0->ethernet_address, sizeof (learn.mac));
	      ip_neighbor_learn_dp (&learn);
	    }

	  if (is_solicitation && error0 == ICMP6_ERROR_NONE)
	    {
	      /* Check that target address is local to this router. */
	      fib_node_index_t fei;
	      u32 fib_index;

	      fib_index =
		ip6_fib_table_get_index_for_sw_if_index (sw_if_index0);

	      if (~0 == fib_index)
		{
		  error0 = ICMP6_ERROR_NEIGHBOR_SOLICITATION_SOURCE_UNKNOWN;
		}
	      else
		{
		  if (ip6_address_is_link_local_unicast (&h0->target_address))
		    {
		      fei = ip6_fib_table_lookup_exact_match
			(ip6_ll_fib_get (sw_if_index0),
			 &h0->target_address, 128);
		    }
		  else
		    {
		      fei = ip6_fib_table_lookup_exact_match (fib_index,
							      &h0->target_address,
							      128);
		    }

		  if (FIB_NODE_INDEX_INVALID == fei)
		    {
		      /* The target address is not in the FIB */
		      error0 =
			ICMP6_ERROR_NEIGHBOR_SOLICITATION_SOURCE_UNKNOWN;
		    }
		  else
		    {
		      if (FIB_ENTRY_FLAG_LOCAL &
			  fib_entry_get_flags_for_source (fei,
							  FIB_SOURCE_INTERFACE))
			{
			  /* It's an address that belongs to one of our interfaces
			   * that's good. */
			}
		      else if (FIB_ENTRY_FLAG_LOCAL &
			       fib_entry_get_flags_for_source (
				 fei, FIB_SOURCE_IP6_ND))
			{
			  /* It's one of our link local addresses
			   * that's good. */
			}
		      else if (fib_entry_is_sourced (fei,
						     FIB_SOURCE_IP6_ND_PROXY))
			{
			  /* The address was added by IPv6 Proxy ND config.
			   * We should only respond to these if the NS arrived on
			   * the link that has a matching covering prefix */
			}
		      else
			{
			  error0 =
			    ICMP6_ERROR_NEIGHBOR_SOLICITATION_SOURCE_UNKNOWN;
			}
		    }
		}
	    }

	  if (is_solicitation)
	    {
	      next0 = (error0 != ICMP6_ERROR_NONE ?
			       ICMP6_NEIGHBOR_SOLICITATION_NEXT_DROP :
			       ICMP6_NEIGHBOR_SOLICITATION_NEXT_REPLY);
	      c_type = IP_NEIGHBOR_CTR_REQUEST;
	    }
	  else
	    {
	      next0 = 0;
	      error0 = error0 == ICMP6_ERROR_NONE ?
		ICMP6_ERROR_NEIGHBOR_ADVERTISEMENTS_RX : error0;
	      c_type = IP_NEIGHBOR_CTR_REPLY;
	    }

	  vlib_increment_simple_counter (
	    &ip_neighbor_counters[AF_IP6].ipnc[VLIB_RX][c_type],
	    vm->thread_index, sw_if_index0, 1);

	  if (is_solicitation && error0 == ICMP6_ERROR_NONE)
	    {
	      icmp6_send_neighbor_advertisement (vm, p0, ip0, h0, o0,
						 sw_if_index0);
	      n_advertisements_sent++;
	    }

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

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

  /* Account for advertisements sent. */
  vlib_error_count (vm, error_node->node_index,
		    ICMP6_ERROR_NEIGHBOR_ADVERTISEMENTS_TX,
		    n_advertisements_sent);

  return frame->n_vectors;
}

static const ethernet_interface_t *
ip6_nd_get_eth_itf (u32 sw_if_index)
{
  const vnet_sw_interface_t *sw;

  /* lookup radv container  - ethernet interfaces only */
  sw = vnet_get_sup_sw_interface (vnet_get_main (), sw_if_index);
  if (sw->type == VNET_SW_INTERFACE_TYPE_HARDWARE)
    return (ethernet_get_interface (&ethernet_main, sw->hw_if_index));

  return (NULL);
}

/**
 * @brief called when IP6 is enabled on a link.
 * create and initialize router advertisement parameters with default
 * values for this intfc
 */
static void
ip6_nd_link_enable (u32 sw_if_index)
{
  const ethernet_interface_t *eth;
  ip6_nd_t *ind;

  eth = ip6_nd_get_eth_itf (sw_if_index);

  if (NULL == eth)
    return;

  ASSERT (INDEX_INVALID == ip6_link_delegate_get (sw_if_index,
						  ip6_nd_delegate_id));

  pool_get_zero (ip6_nd_pool, ind);

  ind->sw_if_index = sw_if_index;

  ip6_link_delegate_update (sw_if_index, ip6_nd_delegate_id,
			    ind - ip6_nd_pool);
}

static void
ip6_nd_delegate_disable (index_t indi)
{
  ip6_nd_t *ind;

  ind = pool_elt_at_index (ip6_nd_pool, indi);

  pool_put (ip6_nd_pool, ind);
}

static uword
icmp6_neighbor_solicitation (vlib_main_t * vm,
			     vlib_node_runtime_t * node, vlib_frame_t * frame)
{
  return icmp6_neighbor_solicitation_or_advertisement (vm, node, frame,
						       /* is_solicitation */
						       1);
}

static uword
icmp6_neighbor_advertisement (vlib_main_t * vm,
			      vlib_node_runtime_t * node,
			      vlib_frame_t * frame)
{
  return icmp6_neighbor_solicitation_or_advertisement (vm, node, frame,
						       /* is_solicitation */
						       0);
}

/* *INDENT-OFF* */
VLIB_REGISTER_NODE (ip6_icmp_neighbor_solicitation_node,static) =
{
  .function = icmp6_neighbor_solicitation,
  .name = "icmp6-neighbor-solicitation",

  .vector_size = sizeof (u32),

  .format_trace = format_icmp6_input_trace,

  .n_next_nodes = ICMP6_NEIGHBOR_SOLICITATION_N_NEXT,
  .next_nodes = {
    [ICMP6_NEIGHBOR_SOLICITATION_NEXT_DROP] = "ip6-drop",
    [ICMP6_NEIGHBOR_SOLICITATION_NEXT_REPLY] = "interface-output",
  },
};

VLIB_REGISTER_NODE (ip6_icmp_neighbor_advertisement_node,static) =
{
  .function = icmp6_neighbor_advertisement,
  .name = "icmp6-neighbor-advertisement",

  .vector_size = sizeof (u32),

  .format_trace = format_icmp6_input_trace,

  .n_next_nodes = 1,
  .next_nodes = {
    [0] = "ip6-punt",
  },
};
/* *INDENT-ON* */

static u8 *
format_ip6_nd (u8 * s, va_list * args)
{
  CLIB_UNUSED (index_t indi) = va_arg (*args, index_t);
  u32 indent = va_arg (*args, u32);

  s = format (s, "%UNeighbor Discovery: enabled\n",
	      format_white_space, indent);

  s = format (s, "%UICMP redirects are disabled\n",
	      format_white_space, indent + 2);
  s = format (s, "%UICMP unreachables are not sent\n",
	      format_white_space, indent + 2);
  s = format (s, "%UND DAD is disabled\n", format_white_space, indent + 2);
  //s = format (s, "%UND reachable time is %d milliseconds\n",);

  return (s);
}

/**
 * VFT to act as an implementation of a neighbour protocol
 */
const static ip_neighbor_vft_t ip6_nd_impl_vft = {
  .inv_proxy6_add = ip6_nd_proxy_add,
  .inv_proxy6_del = ip6_nd_proxy_del,
};

/**
 * VFT for registering as a delegate to an IP6 link
 */
const static ip6_link_delegate_vft_t ip6_nd_delegate_vft = {
  .ildv_disable = ip6_nd_delegate_disable,
  .ildv_enable = ip6_nd_link_enable,
  .ildv_format = format_ip6_nd,
};

static clib_error_t *
ip6_nd_init (vlib_main_t * vm)
{
  icmp6_register_type (vm, ICMP6_neighbor_solicitation,
		       ip6_icmp_neighbor_solicitation_node.index);
  icmp6_register_type (vm, ICMP6_neighbor_advertisement,
		       ip6_icmp_neighbor_advertisement_node.index);

  ip_neighbor_register (AF_IP6, &ip6_nd_impl_vft);

  ip6_nd_delegate_id = ip6_link_delegate_register (&ip6_nd_delegate_vft);

  return 0;
}

/* *INDENT-OFF* */
VLIB_INIT_FUNCTION (ip6_nd_init) =
{
  .runs_after = VLIB_INITS("icmp6_init"),
};
/* *INDENT-ON* */

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