/*
 * ethernet/arp.c: IP v4 ARP node
 *
 * 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/arp/arp.h>
#include <vnet/arp/arp_packet.h>

#include <vnet/fib/ip4_fib.h>
#include <vnet/fib/fib_entry_src.h>
#include <vnet/adj/adj_nbr.h>
#include <vnet/adj/adj_mcast.h>
#include <vnet/pg/pg.h>

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

#include <vlibmemory/api.h>

/**
 * @file
 * @brief IPv4 ARP.
 *
 * This file contains code to manage the IPv4 ARP tables (IP Address
 * to MAC Address lookup).
 */

/**
 * @brief Per-interface ARP configuration and state
 */
typedef struct ethernet_arp_interface_t_
{
  /**
   * Is ARP enabled on this interface
   */
  u32 enabled;
} ethernet_arp_interface_t;

typedef struct
{
  /* Hash tables mapping name to opcode. */
  uword *opcode_by_name;

  /** Per interface state */
  ethernet_arp_interface_t *ethernet_arp_by_sw_if_index;

  /* ARP feature arc index */
  u8 feature_arc_index;
} ethernet_arp_main_t;

static ethernet_arp_main_t ethernet_arp_main;

static const u8 vrrp_prefix[] = { 0x00, 0x00, 0x5E, 0x00, 0x01 };

static uword
unformat_ethernet_arp_opcode_host_byte_order (unformat_input_t * input,
					      va_list * args)
{
  int *result = va_arg (*args, int *);
  ethernet_arp_main_t *am = &ethernet_arp_main;
  int x, i;

  /* Numeric opcode. */
  if (unformat (input, "0x%x", &x) || unformat (input, "%d", &x))
    {
      if (x >= (1 << 16))
	return 0;
      *result = x;
      return 1;
    }

  /* Named type. */
  if (unformat_user (input, unformat_vlib_number_by_name,
		     am->opcode_by_name, &i))
    {
      *result = i;
      return 1;
    }

  return 0;
}

static uword
unformat_ethernet_arp_opcode_net_byte_order (unformat_input_t * input,
					     va_list * args)
{
  int *result = va_arg (*args, int *);
  if (!unformat_user
      (input, unformat_ethernet_arp_opcode_host_byte_order, result))
    return 0;

  *result = clib_host_to_net_u16 ((u16) * result);
  return 1;
}

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

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

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

  return s;
}

static int
arp_is_enabled (ethernet_arp_main_t * am, u32 sw_if_index)
{
  if (vec_len (am->ethernet_arp_by_sw_if_index) <= sw_if_index)
    return 0;

  return (am->ethernet_arp_by_sw_if_index[sw_if_index].enabled);
}

static void
arp_enable (ethernet_arp_main_t * am, u32 sw_if_index)
{
  if (arp_is_enabled (am, sw_if_index))
    return;

  vec_validate (am->ethernet_arp_by_sw_if_index, sw_if_index);

  am->ethernet_arp_by_sw_if_index[sw_if_index].enabled = 1;

  vnet_feature_enable_disable ("arp", "arp-reply", sw_if_index, 1, NULL, 0);
  vnet_feature_enable_disable ("arp", "arp-disabled", sw_if_index, 0, NULL,
			       0);
}

static void
arp_disable (ethernet_arp_main_t * am, u32 sw_if_index)
{
  if (!arp_is_enabled (am, sw_if_index))
    return;

  vnet_feature_enable_disable ("arp", "arp-disabled", sw_if_index, 1, NULL,
			       0);
  vnet_feature_enable_disable ("arp", "arp-reply", sw_if_index, 0, NULL, 0);

  am->ethernet_arp_by_sw_if_index[sw_if_index].enabled = 0;
}

static int
arp_unnumbered (vlib_buffer_t * p0,
		u32 input_sw_if_index, u32 conn_sw_if_index)
{
  vnet_main_t *vnm = vnet_get_main ();
  vnet_interface_main_t *vim = &vnm->interface_main;
  vnet_sw_interface_t *si;

  /* verify that the input interface is unnumbered to the connected.
   * the connected interface is the interface on which the subnet is
   * configured */
  si = &vim->sw_interfaces[input_sw_if_index];

  if (!(si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED &&
	(si->unnumbered_sw_if_index == conn_sw_if_index)))
    {
      /* the input interface is not unnumbered to the interface on which
       * the sub-net is configured that covers the ARP request.
       * So this is not the case for unnumbered.. */
      return 0;
    }

  return !0;
}

always_inline u32
arp_learn (u32 sw_if_index,
	   const ethernet_arp_ip4_over_ethernet_address_t * addr)
{
  ip_neighbor_learn_t l = {
    .ip = {
      .ip.ip4 = addr->ip4,
      .version = AF_IP4,
    },
    .mac = addr->mac,
    .sw_if_index = sw_if_index,
  };

  ip_neighbor_learn_dp (&l);

  return (ARP_ERROR_L3_SRC_ADDRESS_LEARNED);
}

typedef enum arp_input_next_t_
{
  ARP_INPUT_NEXT_DROP,
  ARP_INPUT_NEXT_DISABLED,
  ARP_INPUT_N_NEXT,
} arp_input_next_t;

static uword
arp_input (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
{
  u32 n_left_from, next_index, *from, *to_next, n_left_to_next;
  ethernet_arp_main_t *am = &ethernet_arp_main;

  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 (ethernet_arp_input_trace_t));

  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)
	{
	  const ethernet_arp_header_t *arp0;
	  arp_input_next_t next0;
	  vlib_buffer_t *p0;
	  u32 pi0, error0;

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

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

	  error0 = ARP_ERROR_REPLIES_SENT;
	  next0 = ARP_INPUT_NEXT_DROP;

	  error0 = (arp0->l2_type != clib_net_to_host_u16 (
				       ETHERNET_ARP_HARDWARE_TYPE_ethernet) ?
			    ARP_ERROR_L2_TYPE_NOT_ETHERNET :
			    error0);
	  error0 = (arp0->l3_type != clib_net_to_host_u16 (ETHERNET_TYPE_IP4) ?
			    ARP_ERROR_L3_TYPE_NOT_IP4 :
			    error0);
	  error0 = (0 == arp0->ip4_over_ethernet[0].ip4.as_u32 ?
			    ARP_ERROR_L3_DST_ADDRESS_UNSET :
			    error0);

	  if (ARP_ERROR_REPLIES_SENT == error0)
	    {
	      next0 = ARP_INPUT_NEXT_DISABLED;
	      vnet_feature_arc_start (am->feature_arc_index,
				      vnet_buffer (p0)->sw_if_index[VLIB_RX],
				      &next0, p0);
	    }
	  else
	    p0->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;
}

typedef enum arp_disabled_next_t_
{
  ARP_DISABLED_NEXT_DROP,
  ARP_DISABLED_N_NEXT,
} arp_disabled_next_t;

static uword
arp_disabled (vlib_main_t * vm,
	      vlib_node_runtime_t * node, vlib_frame_t * frame)
{
  u32 n_left_from, next_index, *from, *to_next, n_left_to_next;

  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 (ethernet_arp_input_trace_t));

  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)
	{
	  arp_disabled_next_t next0 = ARP_DISABLED_NEXT_DROP;
	  vlib_buffer_t *p0;
	  u32 pi0, error0;

	  next0 = ARP_DISABLED_NEXT_DROP;
	  error0 = ARP_ERROR_DISABLED;

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

	  p0 = vlib_get_buffer (vm, pi0);
	  p0->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;
}

enum arp_dst_fib_type
{
  ARP_DST_FIB_NONE,
  ARP_DST_FIB_ADJ,
  ARP_DST_FIB_CONN
};

/*
 * we're looking for FIB sources that indicate the destination
 * is attached. There may be interposed DPO prior to the one
 * we are looking for
 */
static enum arp_dst_fib_type
arp_dst_fib_check (const fib_node_index_t fei, fib_entry_flag_t * flags)
{
  const fib_entry_t *entry = fib_entry_get (fei);
  const fib_entry_src_t *entry_src;
  fib_source_t src;
  FOR_EACH_SRC_ADDED(entry, entry_src, src,
  ({
    *flags = fib_entry_get_flags_for_source (fei, src);
    if (fib_entry_is_sourced (fei, FIB_SOURCE_ADJ))
        return ARP_DST_FIB_ADJ;
      else if (FIB_ENTRY_FLAG_CONNECTED & *flags)
        return ARP_DST_FIB_CONN;
  }))

  return ARP_DST_FIB_NONE;
}

static uword
arp_reply (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
{
  vnet_main_t *vnm = vnet_get_main ();
  u32 n_left_from, next_index, *from, *to_next;
  u32 n_replies_sent = 0;

  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 (ethernet_arp_input_trace_t));

  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 > 0 && n_left_to_next > 0)
	{
	  vlib_buffer_t *p0;
	  ethernet_arp_header_t *arp0;
	  ethernet_header_t *eth_rx;
	  const ip4_address_t *if_addr0;
	  u32 pi0, error0, next0, sw_if_index0, conn_sw_if_index0, fib_index0;
	  u8 dst_is_local0, is_vrrp_reply0;
	  fib_node_index_t dst_fei, src_fei;
	  const fib_prefix_t *pfx0;
	  fib_entry_flag_t src_flags, dst_flags;

	  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);
	  arp0 = vlib_buffer_get_current (p0);
	  /* Fill in ethernet header. */
	  eth_rx = ethernet_buffer_get_header (p0);

	  next0 = ARP_REPLY_NEXT_DROP;
	  error0 = ARP_ERROR_REPLIES_SENT;
	  sw_if_index0 = vnet_buffer (p0)->sw_if_index[VLIB_RX];

	  /* Check that IP address is local and matches incoming interface. */
	  fib_index0 = ip4_fib_table_get_index_for_sw_if_index (sw_if_index0);
	  if (~0 == fib_index0)
	    {
	      error0 = ARP_ERROR_INTERFACE_NO_TABLE;
	      goto drop;

	    }

	  dst_fei = ip4_fib_table_lookup (ip4_fib_get (fib_index0),
					  &arp0->ip4_over_ethernet[1].ip4, 32);
	  conn_sw_if_index0 = fib_entry_get_any_resolving_interface (dst_fei);

	  {
	    /*
	     * we're looking for FIB entries that indicate the source
	     * is attached. There may be more specific non-attached
	     * routes that match the source, but these do not influence
	     * whether we respond to an ARP request, i.e. they do not
	     * influence whether we are the correct way for the sender
	     * to reach us, they only affect how we reach the sender.
	     */
	    fib_entry_t *src_fib_entry;
	    const fib_prefix_t *pfx;
	    fib_entry_src_t *src;
	    fib_source_t source;
	    int attached;
	    int mask;

	    mask = 32;
	    attached = 0;

	    do
	      {
		src_fei = ip4_fib_table_lookup (ip4_fib_get (fib_index0),
						&arp0->
						ip4_over_ethernet[0].ip4,
						mask);
		src_fib_entry = fib_entry_get (src_fei);

		/*
		 * It's possible that the source that provides the
		 * flags we need, or the flags we must not have,
		 * is not the best source, so check then all.
		 */
                FOR_EACH_SRC_ADDED(src_fib_entry, src, source,
                ({
                  src_flags = fib_entry_get_flags_for_source (src_fei, source);

                  /* Reject requests/replies with our local interface
                     address. */
                  if (FIB_ENTRY_FLAG_LOCAL & src_flags)
                    {
		      error0 = ARP_ERROR_L3_SRC_ADDRESS_IS_LOCAL;
		      /*
		       * When VPP has an interface whose address is also
		       * applied to a TAP interface on the host, then VPP's
		       * TAP interface will be unnumbered  to the 'real'
		       * interface and do proxy ARP from the host.
		       * The curious aspect of this setup is that ARP requests
		       * from the host will come from the VPP's own address.
		       * So don't drop immediately here, instead go see if this
		       * is a proxy ARP case.
		       */
		      goto next_feature;
		    }
		  /* A Source must also be local to subnet of matching
		   * interface address. */
		  if ((FIB_ENTRY_FLAG_ATTACHED & src_flags) ||
		      (FIB_ENTRY_FLAG_CONNECTED & src_flags))
		    {
		      attached = 1;
		      break;
		    }
		  /*
		   * else
		   *  The packet was sent from an address that is not
		   *  connected nor attached i.e. it is not from an
		   *  address that is covered by a link's sub-net,
		   *  nor is it a already learned host resp.
		   */
                }));

		/*
		 * shorter mask lookup for the next iteration.
		 */
		pfx = fib_entry_get_prefix (src_fei);
		mask = pfx->fp_len - 1;

		/*
		 * continue until we hit the default route or we find
		 * the attached we are looking for. The most likely
		 * outcome is we find the attached with the first source
		 * on the first lookup.
		 */
	      }
	    while (!attached &&
		   !fib_entry_is_sourced (src_fei, FIB_SOURCE_DEFAULT_ROUTE));

	    if (!attached &&
		!arp_unnumbered (p0, sw_if_index0, conn_sw_if_index0))
	      {
		/*
		 * the matching route is a not attached and not unnumbered,
		 * i.e. it was added as a result of routing, rather than
		 * interface/ARP configuration. If the matching route is not
		 * a host route (i.e. a /32)
		 */
		error0 = ARP_ERROR_L3_SRC_ADDRESS_NOT_LOCAL;
		goto drop;
	      }
	  }

	  switch (arp_dst_fib_check (dst_fei, &dst_flags))
	    {
	    case ARP_DST_FIB_ADJ:
	      /*
	       * We matched an adj-fib on ths source subnet (a /32 previously
	       * added as a result of ARP). If this request is a gratuitous
	       * ARP, then learn from it.
	       * The check for matching an adj-fib, is to prevent hosts
	       * from spamming us with gratuitous ARPS that might otherwise
	       * blow our ARP cache
	       */
	      if (conn_sw_if_index0 != sw_if_index0)
		error0 = ARP_ERROR_L3_DST_ADDRESS_NOT_LOCAL;
	      else if (arp0->ip4_over_ethernet[0].ip4.as_u32 ==
		       arp0->ip4_over_ethernet[1].ip4.as_u32)
		{
		  vlib_increment_simple_counter (
		    &ip_neighbor_counters[AF_IP4]
		       .ipnc[VLIB_RX][IP_NEIGHBOR_CTR_GRAT],
		    vm->thread_index, sw_if_index0, 1);
		  error0 =
		    arp_learn (sw_if_index0, &arp0->ip4_over_ethernet[0]);
		}
	      goto next_feature;
	    case ARP_DST_FIB_CONN:
	      /* destination is connected, continue to process */
	      break;
	    case ARP_DST_FIB_NONE:
	      /* destination is not connected, stop here */
	      error0 = ARP_ERROR_L3_DST_ADDRESS_NOT_LOCAL;
	      goto next_feature;
	    }

	  dst_is_local0 = (FIB_ENTRY_FLAG_LOCAL & dst_flags);
	  pfx0 = fib_entry_get_prefix (dst_fei);
	  if_addr0 = &pfx0->fp_addr.ip4;

	  is_vrrp_reply0 =
	    ((arp0->opcode ==
	      clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_reply))
	     &&
	     (!memcmp
	      (arp0->ip4_over_ethernet[0].mac.bytes, vrrp_prefix,
	       sizeof (vrrp_prefix))));

	  /* Trash ARP packets whose ARP-level source addresses do not
	     match their L2-frame-level source addresses, unless it's
	     a reply from a VRRP virtual router */
	  if (!ethernet_mac_address_equal
	      (eth_rx->src_address,
	       arp0->ip4_over_ethernet[0].mac.bytes) && !is_vrrp_reply0)
	    {
	      error0 = ARP_ERROR_L2_ADDRESS_MISMATCH;
	      goto drop;
	    }

	  vlib_increment_simple_counter (
	    &ip_neighbor_counters[AF_IP4]
	       .ipnc[VLIB_RX][arp0->opcode == clib_host_to_net_u16 (
						ETHERNET_ARP_OPCODE_reply) ?
				      IP_NEIGHBOR_CTR_REPLY :
				      IP_NEIGHBOR_CTR_REQUEST],
	    vm->thread_index, sw_if_index0, 1);

	  /* Learn or update sender's mapping only for replies to addresses
	   * that are local to the subnet */
	  if (arp0->opcode ==
	      clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_reply))
	    {
	      if (dst_is_local0)
		error0 =
		  arp_learn (sw_if_index0, &arp0->ip4_over_ethernet[0]);
	      else
		/* a reply for a non-local destination could be a GARP.
		 * GARPs for hosts we know were handled above, so this one
		 * we drop */
		error0 = ARP_ERROR_L3_DST_ADDRESS_NOT_LOCAL;

	      goto next_feature;
	    }
	  else if (arp0->opcode ==
		   clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_request) &&
		   (dst_is_local0 == 0))
	    {
	      goto next_feature;
	    }

	  /* Honor unnumbered interface, if any */
	  if (sw_if_index0 != conn_sw_if_index0 ||
	      sw_if_index0 != fib_entry_get_resolving_interface (src_fei))
	    {
	      /*
	       * The interface the ARP is sent to or was received on is
	       * not the interface on which the covering prefix is
	       * configured. Maybe this is a case for unnumbered.
	       */
	      if (!arp_unnumbered (p0, sw_if_index0, conn_sw_if_index0))
		{
		  error0 = ARP_ERROR_UNNUMBERED_MISMATCH;
		  goto drop;
		}
	    }
	  if (arp0->ip4_over_ethernet[0].ip4.as_u32 ==
	      arp0->ip4_over_ethernet[1].ip4.as_u32)
	    {
	      error0 = ARP_ERROR_GRATUITOUS_ARP;
	      goto drop;
	    }

	  next0 = arp_mk_reply (vnm, p0, sw_if_index0, if_addr0, arp0, eth_rx);

	  /* We are going to reply to this request, so, in the absence of
	     errors, learn the sender */
	  if (!error0)
	    error0 = arp_learn (sw_if_index0, &arp0->ip4_over_ethernet[1]);

	  vlib_increment_simple_counter (
	    &ip_neighbor_counters[AF_IP4].ipnc[VLIB_TX][IP_NEIGHBOR_CTR_REPLY],
	    vm->thread_index, sw_if_index0, 1);
	  n_replies_sent += 1;
	  goto enqueue;

	next_feature:
	  vnet_feature_next (&next0, p0);

	drop:
	  p0->error = node->errors[error0];

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

  vlib_error_count (vm, node->node_index, ARP_ERROR_REPLIES_SENT,
		    n_replies_sent);

  return frame->n_vectors;
}



VLIB_REGISTER_NODE (arp_input_node, static) =
{
  .function = arp_input,
  .name = "arp-input",
  .vector_size = sizeof (u32),
  .n_errors = ARP_N_ERROR,
  .error_counters = arp_error_counters,
  .n_next_nodes = ARP_INPUT_N_NEXT,
  .next_nodes = {
    [ARP_INPUT_NEXT_DROP] = "error-drop",
    [ARP_INPUT_NEXT_DISABLED] = "arp-disabled",
  },
  .format_buffer = format_ethernet_arp_header,
  .format_trace = format_ethernet_arp_input_trace,
};

VLIB_REGISTER_NODE (arp_disabled_node, static) =
{
  .function = arp_disabled,
  .name = "arp-disabled",
  .vector_size = sizeof (u32),
  .n_errors = ARP_N_ERROR,
  .error_counters = arp_error_counters,
  .n_next_nodes = ARP_DISABLED_N_NEXT,
  .next_nodes = {
    [ARP_INPUT_NEXT_DROP] = "error-drop",
  },
  .format_buffer = format_ethernet_arp_header,
  .format_trace = format_ethernet_arp_input_trace,
};

VLIB_REGISTER_NODE (arp_reply_node, static) =
{
  .function = arp_reply,
  .name = "arp-reply",
  .vector_size = sizeof (u32),
  .n_errors = ARP_N_ERROR,
  .error_counters = arp_error_counters,
  .n_next_nodes = ARP_REPLY_N_NEXT,
  .next_nodes = {
    [ARP_REPLY_NEXT_DROP] = "error-drop",
    [ARP_REPLY_NEXT_REPLY_TX] = "interface-output",
  },
  .format_buffer = format_ethernet_arp_header,
  .format_trace = format_ethernet_arp_input_trace,
};

/* Built-in ARP rx feature path definition */
VNET_FEATURE_ARC_INIT (arp_feat, static) =
{
  .arc_name = "arp",
  .start_nodes = VNET_FEATURES ("arp-input"),
  .last_in_arc = "error-drop",
  .arc_index_ptr = &ethernet_arp_main.feature_arc_index,
};

VNET_FEATURE_INIT (arp_reply_feat_node, static) =
{
  .arc_name = "arp",
  .node_name = "arp-reply",
  .runs_before = VNET_FEATURES ("arp-disabled"),
};

VNET_FEATURE_INIT (arp_proxy_feat_node, static) =
{
  .arc_name = "arp",
  .node_name = "arp-proxy",
  .runs_after = VNET_FEATURES ("arp-reply"),
  .runs_before = VNET_FEATURES ("arp-disabled"),
};

VNET_FEATURE_INIT (arp_disabled_feat_node, static) =
{
  .arc_name = "arp",
  .node_name = "arp-disabled",
  .runs_before = VNET_FEATURES ("error-drop"),
};

VNET_FEATURE_INIT (arp_drop_feat_node, static) =
{
  .arc_name = "arp",
  .node_name = "error-drop",
  .runs_before = 0,	/* last feature */
};


typedef struct
{
  pg_edit_t l2_type, l3_type;
  pg_edit_t n_l2_address_bytes, n_l3_address_bytes;
  pg_edit_t opcode;
  struct
  {
    pg_edit_t mac;
    pg_edit_t ip4;
  } ip4_over_ethernet[2];
} pg_ethernet_arp_header_t;

static inline void
pg_ethernet_arp_header_init (pg_ethernet_arp_header_t * p)
{
  /* Initialize fields that are not bit fields in the IP header. */
#define _(f) pg_edit_init (&p->f, ethernet_arp_header_t, f);
  _(l2_type);
  _(l3_type);
  _(n_l2_address_bytes);
  _(n_l3_address_bytes);
  _(opcode);
  _(ip4_over_ethernet[0].mac);
  _(ip4_over_ethernet[0].ip4);
  _(ip4_over_ethernet[1].mac);
  _(ip4_over_ethernet[1].ip4);
#undef _
}

uword
unformat_pg_arp_header (unformat_input_t * input, va_list * args)
{
  pg_stream_t *s = va_arg (*args, pg_stream_t *);
  pg_ethernet_arp_header_t *p;
  u32 group_index;

  p = pg_create_edit_group (s, sizeof (p[0]), sizeof (ethernet_arp_header_t),
			    &group_index);
  pg_ethernet_arp_header_init (p);

  /* Defaults. */
  pg_edit_set_fixed (&p->l2_type, ETHERNET_ARP_HARDWARE_TYPE_ethernet);
  pg_edit_set_fixed (&p->l3_type, ETHERNET_TYPE_IP4);
  pg_edit_set_fixed (&p->n_l2_address_bytes, 6);
  pg_edit_set_fixed (&p->n_l3_address_bytes, 4);

  if (!unformat (input, "%U: %U/%U -> %U/%U",
		 unformat_pg_edit,
		 unformat_ethernet_arp_opcode_net_byte_order, &p->opcode,
		 unformat_pg_edit,
		 unformat_mac_address_t, &p->ip4_over_ethernet[0].mac,
		 unformat_pg_edit,
		 unformat_ip4_address, &p->ip4_over_ethernet[0].ip4,
		 unformat_pg_edit,
		 unformat_mac_address_t, &p->ip4_over_ethernet[1].mac,
		 unformat_pg_edit,
		 unformat_ip4_address, &p->ip4_over_ethernet[1].ip4))
    {
      /* Free up any edits we may have added. */
      pg_free_edit_group (s);
      return 0;
    }
  return 1;
}

/*
 * callback when an interface address is added or deleted
 */
static void
arp_enable_disable_interface (ip4_main_t * im,
			      uword opaque, u32 sw_if_index, u32 is_enable)
{
  ethernet_arp_main_t *am = &ethernet_arp_main;

  if (is_enable)
    arp_enable (am, sw_if_index);
  else
    arp_disable (am, sw_if_index);
}

/*
 * Remove any arp entries associated with the specified interface
 */
static clib_error_t *
vnet_arp_add_del_sw_interface (vnet_main_t * vnm, u32 sw_if_index, u32 is_add)
{
  ethernet_arp_main_t *am = &ethernet_arp_main;
  if (is_add)
    arp_disable (am, sw_if_index);
  return (NULL);
}

VNET_SW_INTERFACE_ADD_DEL_FUNCTION (vnet_arp_add_del_sw_interface);

const static ip_neighbor_vft_t arp_vft = {
  .inv_proxy4_add = arp_proxy_add,
  .inv_proxy4_del = arp_proxy_del,
  .inv_proxy4_enable = arp_proxy_enable,
  .inv_proxy4_disable = arp_proxy_disable,
};

static clib_error_t *
ethernet_arp_init (vlib_main_t * vm)
{
  ethernet_arp_main_t *am = &ethernet_arp_main;
  ip4_main_t *im = &ip4_main;
  pg_node_t *pn;

  ethernet_register_input_type (vm, ETHERNET_TYPE_ARP, arp_input_node.index);

  pn = pg_get_node (arp_input_node.index);
  pn->unformat_edit = unformat_pg_arp_header;

  am->opcode_by_name = hash_create_string (0, sizeof (uword));
#define _(o) hash_set_mem (am->opcode_by_name, #o, ETHERNET_ARP_OPCODE_##o);
  foreach_ethernet_arp_opcode;
#undef _

  /* don't trace ARP error packets */
  {
    vlib_node_runtime_t *rt =
      vlib_node_get_runtime (vm, arp_input_node.index);

    vnet_pcap_drop_trace_filter_add_del (rt->errors[ARP_ERROR_REPLIES_SENT],
					 1);
    vnet_pcap_drop_trace_filter_add_del (rt->errors[ARP_ERROR_DISABLED], 1);
    vnet_pcap_drop_trace_filter_add_del (
      rt->errors[ARP_ERROR_L2_TYPE_NOT_ETHERNET], 1);
    vnet_pcap_drop_trace_filter_add_del (rt->errors[ARP_ERROR_L3_TYPE_NOT_IP4],
					 1);
    vnet_pcap_drop_trace_filter_add_del (
      rt->errors[ARP_ERROR_L3_SRC_ADDRESS_NOT_LOCAL], 1);
    vnet_pcap_drop_trace_filter_add_del (
      rt->errors[ARP_ERROR_L3_DST_ADDRESS_NOT_LOCAL], 1);
    vnet_pcap_drop_trace_filter_add_del (
      rt->errors[ARP_ERROR_L3_DST_ADDRESS_UNSET], 1);
    vnet_pcap_drop_trace_filter_add_del (
      rt->errors[ARP_ERROR_L3_SRC_ADDRESS_IS_LOCAL], 1);
    vnet_pcap_drop_trace_filter_add_del (
      rt->errors[ARP_ERROR_L3_SRC_ADDRESS_LEARNED], 1);
    vnet_pcap_drop_trace_filter_add_del (
      rt->errors[ARP_ERROR_REPLIES_RECEIVED], 1);
    vnet_pcap_drop_trace_filter_add_del (
      rt->errors[ARP_ERROR_OPCODE_NOT_REQUEST], 1);
    vnet_pcap_drop_trace_filter_add_del (
      rt->errors[ARP_ERROR_PROXY_ARP_REPLIES_SENT], 1);
    vnet_pcap_drop_trace_filter_add_del (
      rt->errors[ARP_ERROR_L2_ADDRESS_MISMATCH], 1);
    vnet_pcap_drop_trace_filter_add_del (rt->errors[ARP_ERROR_GRATUITOUS_ARP],
					 1);
    vnet_pcap_drop_trace_filter_add_del (
      rt->errors[ARP_ERROR_INTERFACE_NO_TABLE], 1);
    vnet_pcap_drop_trace_filter_add_del (
      rt->errors[ARP_ERROR_INTERFACE_NOT_IP_ENABLED], 1);
    vnet_pcap_drop_trace_filter_add_del (
      rt->errors[ARP_ERROR_UNNUMBERED_MISMATCH], 1);
  }

  {
    ip4_enable_disable_interface_callback_t cb = {
      .function = arp_enable_disable_interface,
    };
    vec_add1 (im->enable_disable_interface_callbacks, cb);
  }

  ip_neighbor_register (AF_IP4, &arp_vft);

  return 0;
}

VLIB_INIT_FUNCTION (ethernet_arp_init) =
{
  .runs_after = VLIB_INITS("ethernet_init",
                           "ip_neighbor_init"),
};

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