/*
 *------------------------------------------------------------------
 * ip_api.c - vnet ip api
 *
 * Copyright (c) 2016 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/vnet.h>
#include <vlibmemory/api.h>

#include <vnet/interface.h>
#include <vnet/api_errno.h>
#include <vnet/ethernet/ethernet.h>
#include <vnet/ethernet/ethernet_types_api.h>
#include <vnet/ip/ip.h>
#include <vnet/ip/ip_neighbor.h>
#include <vnet/ip/ip_types_api.h>
#include <vnet/ip/ip6_neighbor.h>
#include <vnet/ip/ip_punt_drop.h>
#include <vnet/ip/ip_types_api.h>
#include <vnet/fib/fib_table.h>
#include <vnet/fib/fib_api.h>
#include <vnet/ethernet/arp_packet.h>
#include <vnet/mfib/ip6_mfib.h>
#include <vnet/mfib/ip4_mfib.h>
#include <vnet/mfib/mfib_signal.h>
#include <vnet/mfib/mfib_entry.h>
#include <vnet/mfib/mfib_api.h>
#include <vnet/ip/ip_source_and_port_range_check.h>
#include <vnet/fib/ip4_fib.h>
#include <vnet/fib/ip6_fib.h>
#include <vnet/fib/fib_path_list.h>
#include <vnet/ip/ip6_hop_by_hop.h>
#include <vnet/ip/reass/ip4_sv_reass.h>
#include <vnet/ip/reass/ip4_full_reass.h>
#include <vnet/ip/reass/ip6_sv_reass.h>
#include <vnet/ip/reass/ip6_full_reass.h>
#include <vnet/ethernet/arp.h>
#include <vnet/ip/ip_types_api.h>

#include <vnet/vnet_msg_enum.h>

#define vl_typedefs		/* define message structures */
#include <vnet/vnet_all_api_h.h>
#undef vl_typedefs

#define vl_endianfun		/* define message structures */
#include <vnet/vnet_all_api_h.h>
#undef vl_endianfun

/* instantiate all the print functions we know about */
#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
#define vl_printfun
#include <vnet/vnet_all_api_h.h>
#undef vl_printfun

#include <vlibapi/api_helper_macros.h>

#include <vnet/format_fns.h>

#define foreach_ip_api_msg                                              \
_(IP_TABLE_DUMP, ip_table_dump)                                         \
_(IP_ROUTE_DUMP, ip_route_dump)                                         \
_(IP_MTABLE_DUMP, ip_mtable_dump)                                       \
_(IP_MROUTE_DUMP, ip_mroute_dump)                                       \
_(IP_NEIGHBOR_DUMP, ip_neighbor_dump)                                   \
_(IP_MROUTE_ADD_DEL, ip_mroute_add_del)                                 \
_(MFIB_SIGNAL_DUMP, mfib_signal_dump)                                   \
_(IP_ADDRESS_DUMP, ip_address_dump)                                     \
_(IP_UNNUMBERED_DUMP, ip_unnumbered_dump)                               \
_(IP_DUMP, ip_dump)                                                     \
_(IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del)                             \
_(SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit)			\
_(IP_PROBE_NEIGHBOR, ip_probe_neighbor)      			        \
_(IP_SCAN_NEIGHBOR_ENABLE_DISABLE, ip_scan_neighbor_enable_disable)     \
_(WANT_IP4_ARP_EVENTS, want_ip4_arp_events)                             \
_(WANT_IP6_ND_EVENTS, want_ip6_nd_events)                               \
_(WANT_IP6_RA_EVENTS, want_ip6_ra_events)                               \
_(PROXY_ARP_ADD_DEL, proxy_arp_add_del)                                 \
_(PROXY_ARP_DUMP, proxy_arp_dump)                                       \
_(PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable)       \
 _(PROXY_ARP_INTFC_DUMP, proxy_arp_intfc_dump)                          \
_(RESET_FIB, reset_fib)							\
_(IP_ROUTE_ADD_DEL, ip_route_add_del)                                   \
_(IP_TABLE_ADD_DEL, ip_table_add_del)                                   \
_(IP_PUNT_POLICE, ip_punt_police)                                       \
_(IP_PUNT_REDIRECT, ip_punt_redirect)                                   \
_(SET_IP_FLOW_HASH,set_ip_flow_hash)                                    \
_(SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config)           \
_(SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix)           \
_(IP6ND_PROXY_ADD_DEL, ip6nd_proxy_add_del)                             \
_(IP6ND_PROXY_DUMP, ip6nd_proxy_dump)                                   \
_(IP6ND_SEND_ROUTER_SOLICITATION, ip6nd_send_router_solicitation)       \
_(SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable )    \
_(IP_CONTAINER_PROXY_ADD_DEL, ip_container_proxy_add_del)               \
_(IP_CONTAINER_PROXY_DUMP, ip_container_proxy_dump)                     \
_(IOAM_ENABLE, ioam_enable)                                             \
_(IOAM_DISABLE, ioam_disable)                                           \
_(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,                               \
  ip_source_and_port_range_check_add_del)                               \
_(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,                     \
  ip_source_and_port_range_check_interface_add_del)                     \
_(IP_SOURCE_CHECK_INTERFACE_ADD_DEL,                                    \
  ip_source_check_interface_add_del)                                    \
_(IP_REASSEMBLY_SET, ip_reassembly_set)                                 \
_(IP_REASSEMBLY_GET, ip_reassembly_get)                                 \
_(IP_REASSEMBLY_ENABLE_DISABLE, ip_reassembly_enable_disable)           \
_(IP_PUNT_REDIRECT_DUMP, ip_punt_redirect_dump)


static vl_api_ip_neighbor_flags_t
ip_neighbor_flags_encode (ip_neighbor_flags_t f)
{
  vl_api_ip_neighbor_flags_t v = IP_API_NEIGHBOR_FLAG_NONE;

  if (f & IP_NEIGHBOR_FLAG_STATIC)
    v |= IP_API_NEIGHBOR_FLAG_STATIC;
  if (f & IP_NEIGHBOR_FLAG_NO_FIB_ENTRY)
    v |= IP_API_NEIGHBOR_FLAG_NO_FIB_ENTRY;

  return (clib_host_to_net_u32 (v));
}

static void
send_ip_neighbor_details (u32 sw_if_index,
			  const ip46_address_t * ip_address,
			  const mac_address_t * mac,
			  ip_neighbor_flags_t flags,
			  vl_api_registration_t * reg, u32 context)
{
  vl_api_ip_neighbor_details_t *mp;

  mp = vl_msg_api_alloc (sizeof (*mp));
  clib_memset (mp, 0, sizeof (*mp));
  mp->_vl_msg_id = ntohs (VL_API_IP_NEIGHBOR_DETAILS);
  mp->context = context;
  mp->neighbor.sw_if_index = htonl (sw_if_index);
  mp->neighbor.flags = ip_neighbor_flags_encode (flags);

  ip_address_encode (ip_address, IP46_TYPE_ANY, &mp->neighbor.ip_address);
  mac_address_encode (mac, mp->neighbor.mac_address);

  vl_api_send_msg (reg, (u8 *) mp);
}

static void
vl_api_ip_neighbor_dump_t_handler (vl_api_ip_neighbor_dump_t * mp)
{
  vl_api_registration_t *reg;

  reg = vl_api_client_index_to_registration (mp->client_index);
  if (!reg)
    return;

  u32 sw_if_index = ntohl (mp->sw_if_index);

  if (mp->is_ipv6)
    {
      ip6_neighbor_t *n, *ns;

      ns = ip6_neighbors_entries (sw_if_index);
      /* *INDENT-OFF* */
      vec_foreach (n, ns)
      {
        ip46_address_t nh = {
          .ip6 = {
            .as_u64[0] = n->key.ip6_address.as_u64[0],
            .as_u64[1] = n->key.ip6_address.as_u64[1],
          },
        };
        send_ip_neighbor_details (n->key.sw_if_index, &nh,
                                  &n->mac, n->flags,
                                  reg, mp->context);
      }
      /* *INDENT-ON* */
      vec_free (ns);
    }
  else
    {
      ethernet_arp_ip4_entry_t *n, *ns;

      ns = ip4_neighbor_entries (sw_if_index);
      /* *INDENT-OFF* */
      vec_foreach (n, ns)
      {
        ip46_address_t nh = {
          .ip4 = {
            .as_u32 = n->ip4_address.as_u32,
          },
        };

        send_ip_neighbor_details (n->sw_if_index, &nh,
                                  &n->mac, n->flags,
                                  reg, mp->context);
      }
      /* *INDENT-ON* */
      vec_free (ns);
    }
}

static void
send_ip_table_details (vpe_api_main_t * am,
		       vl_api_registration_t * reg,
		       u32 context, const fib_table_t * table)
{
  vl_api_ip_table_details_t *mp;

  mp = vl_msg_api_alloc (sizeof (*mp));
  if (!mp)
    return;
  clib_memset (mp, 0, sizeof (*mp));
  mp->_vl_msg_id = ntohs (VL_API_IP_TABLE_DETAILS);
  mp->context = context;

  mp->table.is_ip6 = (table->ft_proto == FIB_PROTOCOL_IP6);
  mp->table.table_id = htonl (table->ft_table_id);
  memcpy (mp->table.name, table->ft_desc,
	  clib_min (vec_len (table->ft_desc), sizeof (mp->table.name)));

  vl_api_send_msg (reg, (u8 *) mp);
}

static void
vl_api_ip_table_dump_t_handler (vl_api_ip_table_dump_t * mp)
{
  vpe_api_main_t *am = &vpe_api_main;
  vl_api_registration_t *reg;
  fib_table_t *fib_table;

  reg = vl_api_client_index_to_registration (mp->client_index);
  if (!reg)
    return;

  /* *INDENT-OFF* */
  pool_foreach (fib_table, ip4_main.fibs,
  ({
    send_ip_table_details(am, reg, mp->context, fib_table);
  }));
  pool_foreach (fib_table, ip6_main.fibs,
  ({
    /* don't send link locals */
    if (fib_table->ft_flags & FIB_TABLE_FLAG_IP6_LL)
      continue;
    send_ip_table_details(am, reg, mp->context, fib_table);
  }));
  /* *INDENT-ON* */
}

typedef struct vl_api_ip_fib_dump_walk_ctx_t_
{
  fib_node_index_t *feis;
} vl_api_ip_fib_dump_walk_ctx_t;

static fib_table_walk_rc_t
vl_api_ip_fib_dump_walk (fib_node_index_t fei, void *arg)
{
  vl_api_ip_fib_dump_walk_ctx_t *ctx = arg;

  vec_add1 (ctx->feis, fei);

  return (FIB_TABLE_WALK_CONTINUE);
}

static void
send_ip_route_details (vpe_api_main_t * am,
		       vl_api_registration_t * reg,
		       u32 context, fib_node_index_t fib_entry_index)
{
  fib_route_path_t *rpaths, *rpath;
  vl_api_ip_route_details_t *mp;
  const fib_prefix_t *pfx;
  vl_api_fib_path_t *fp;
  int path_count;

  rpaths = NULL;
  pfx = fib_entry_get_prefix (fib_entry_index);
  rpaths = fib_entry_encode (fib_entry_index);

  path_count = vec_len (rpaths);
  mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp));
  if (!mp)
    return;
  clib_memset (mp, 0, sizeof (*mp));
  mp->_vl_msg_id = ntohs (VL_API_IP_ROUTE_DETAILS);
  mp->context = context;

  ip_prefix_encode (pfx, &mp->route.prefix);
  mp->route.table_id =
    htonl (fib_table_get_table_id
	   (fib_entry_get_fib_index (fib_entry_index), pfx->fp_proto));
  mp->route.n_paths = path_count;
  mp->route.stats_index =
    htonl (fib_table_entry_get_stats_index
	   (fib_entry_get_fib_index (fib_entry_index), pfx));

  fp = mp->route.paths;
  vec_foreach (rpath, rpaths)
  {
    fib_api_path_encode (rpath, fp);
    fp++;
  }

  vl_api_send_msg (reg, (u8 *) mp);
}

typedef struct apt_ip6_fib_show_ctx_t_
{
  fib_node_index_t *entries;
} api_ip6_fib_show_ctx_t;

static void
vl_api_ip_route_dump_t_handler (vl_api_ip_route_dump_t * mp)
{
  vpe_api_main_t *am = &vpe_api_main;
  fib_node_index_t *fib_entry_index;
  vl_api_registration_t *reg;
  fib_protocol_t fproto;
  u32 fib_index;

  reg = vl_api_client_index_to_registration (mp->client_index);
  if (!reg)
    return;

  vl_api_ip_fib_dump_walk_ctx_t ctx = {
    .feis = NULL,
  };

  fproto = (mp->table.is_ip6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4);
  fib_index = fib_table_find (fproto, ntohl (mp->table.table_id));

  if (INDEX_INVALID == fib_index)
    return;

  fib_table_walk (fib_index, fproto, vl_api_ip_fib_dump_walk, &ctx);

  vec_foreach (fib_entry_index, ctx.feis)
  {
    send_ip_route_details (am, reg, mp->context, *fib_entry_index);
  }

  vec_free (ctx.feis);
}

static void
send_ip_mtable_details (vl_api_registration_t * reg,
			u32 context, const mfib_table_t * mfib_table)
{
  vl_api_ip_mtable_details_t *mp;

  mp = vl_msg_api_alloc (sizeof (*mp));
  if (!mp)
    return;
  memset (mp, 0, sizeof (*mp));
  mp->_vl_msg_id = ntohs (VL_API_IP_MTABLE_DETAILS);
  mp->context = context;

  mp->table.table_id = htonl (mfib_table->mft_table_id);
  mp->table.is_ip6 = (FIB_PROTOCOL_IP6 == mfib_table->mft_proto);

  vl_api_send_msg (reg, (u8 *) mp);
}

static void
vl_api_ip_mtable_dump_t_handler (vl_api_ip_mtable_dump_t * mp)
{
  vl_api_registration_t *reg;
  mfib_table_t *mfib_table;

  reg = vl_api_client_index_to_registration (mp->client_index);
  if (!reg)
    return;

  /* *INDENT-OFF* */
  pool_foreach (mfib_table, ip4_main.mfibs,
  ({
      send_ip_mtable_details (reg, mp->context, mfib_table);
  }));
  pool_foreach (mfib_table, ip6_main.mfibs,
  ({
      send_ip_mtable_details (reg, mp->context, mfib_table);
  }));
  /* *INDENT-ON* */
}

typedef struct vl_api_ip_mfib_dump_ctx_t_
{
  fib_node_index_t *entries;
} vl_api_ip_mfib_dump_ctx_t;

static int
mfib_route_dump_walk (fib_node_index_t fei, void *arg)
{
  vl_api_ip_mfib_dump_ctx_t *ctx = arg;

  vec_add1 (ctx->entries, fei);

  return (0);
}

static void
send_ip_mroute_details (vpe_api_main_t * am,
			vl_api_registration_t * reg,
			u32 context, fib_node_index_t mfib_entry_index)
{
  fib_route_path_t *rpaths, *rpath;
  vl_api_ip_mroute_details_t *mp;
  const mfib_prefix_t *pfx;
  vl_api_mfib_path_t *fp;
  int path_count;

  rpaths = NULL;
  pfx = mfib_entry_get_prefix (mfib_entry_index);
  rpaths = mfib_entry_encode (mfib_entry_index);

  path_count = vec_len (rpaths);
  mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp));
  if (!mp)
    return;
  clib_memset (mp, 0, sizeof (*mp));
  mp->_vl_msg_id = ntohs (VL_API_IP_MROUTE_DETAILS);
  mp->context = context;

  ip_mprefix_encode (pfx, &mp->route.prefix);
  mp->route.table_id =
    htonl (mfib_table_get_table_id
	   (mfib_entry_get_fib_index (mfib_entry_index), pfx->fp_proto));
  mp->route.n_paths = htonl (path_count);
  fp = mp->route.paths;
  vec_foreach (rpath, rpaths)
  {
    mfib_api_path_encode (rpath, fp);
    fp++;
  }

  vl_api_send_msg (reg, (u8 *) mp);
  vec_free (rpaths);
}

static void
vl_api_ip_mroute_dump_t_handler (vl_api_ip_mroute_dump_t * mp)
{
  vpe_api_main_t *am = &vpe_api_main;
  vl_api_registration_t *reg;
  fib_node_index_t *mfeip;
  fib_protocol_t fproto;
  u32 fib_index;

  vl_api_ip_mfib_dump_ctx_t ctx = {
    .entries = NULL,
  };

  reg = vl_api_client_index_to_registration (mp->client_index);
  if (!reg)
    return;

  fproto = fib_ip_proto (mp->table.is_ip6);
  fib_index = mfib_table_find (fproto, ntohl (mp->table.table_id));

  if (INDEX_INVALID == fib_index)
    return;

  mfib_table_walk (fib_index, fproto, mfib_route_dump_walk, &ctx);

  vec_sort_with_function (ctx.entries, mfib_entry_cmp_for_sort);

  vec_foreach (mfeip, ctx.entries)
  {
    send_ip_mroute_details (am, reg, mp->context, *mfeip);
  }

  vec_free (ctx.entries);
}

static void
vl_api_ip_punt_police_t_handler (vl_api_ip_punt_police_t * mp,
				 vlib_main_t * vm)
{
  vl_api_ip_punt_police_reply_t *rmp;
  int rv = 0;

  if (mp->is_ip6)
    ip6_punt_policer_add_del (mp->is_add, ntohl (mp->policer_index));
  else
    ip4_punt_policer_add_del (mp->is_add, ntohl (mp->policer_index));

  REPLY_MACRO (VL_API_IP_PUNT_POLICE_REPLY);
}

static void
vl_api_ip_punt_redirect_t_handler (vl_api_ip_punt_redirect_t * mp,
				   vlib_main_t * vm)
{
  vl_api_ip_punt_redirect_reply_t *rmp;
  int rv = 0;
  ip46_type_t ipv;
  ip46_address_t nh;

  if (!vnet_sw_if_index_is_api_valid (ntohl (mp->punt.tx_sw_if_index)))
    goto bad_sw_if_index;

  ipv = ip_address_decode (&mp->punt.nh, &nh);
  if (mp->is_add)
    {
      if (ipv == IP46_TYPE_IP6)
	{
	  ip6_punt_redirect_add (ntohl (mp->punt.rx_sw_if_index),
				 ntohl (mp->punt.tx_sw_if_index), &nh);
	}
      else if (ipv == IP46_TYPE_IP4)
	{
	  ip4_punt_redirect_add (ntohl (mp->punt.rx_sw_if_index),
				 ntohl (mp->punt.tx_sw_if_index), &nh);
	}
    }
  else
    {
      if (ipv == IP46_TYPE_IP6)
	{
	  ip6_punt_redirect_del (ntohl (mp->punt.rx_sw_if_index));
	}
      else if (ipv == IP46_TYPE_IP4)
	{
	  ip4_punt_redirect_del (ntohl (mp->punt.rx_sw_if_index));
	}
    }

  BAD_SW_IF_INDEX_LABEL;

  REPLY_MACRO (VL_API_IP_PUNT_REDIRECT_REPLY);
}

static ip_neighbor_flags_t
ip_neighbor_flags_decode (vl_api_ip_neighbor_flags_t v)
{
  ip_neighbor_flags_t f = IP_NEIGHBOR_FLAG_NONE;

  v = clib_net_to_host_u32 (v);

  if (v & IP_API_NEIGHBOR_FLAG_STATIC)
    f |= IP_NEIGHBOR_FLAG_STATIC;
  if (v & IP_API_NEIGHBOR_FLAG_NO_FIB_ENTRY)
    f |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;

  return (f);
}

static void
vl_api_ip_neighbor_add_del_t_handler (vl_api_ip_neighbor_add_del_t * mp,
				      vlib_main_t * vm)
{
  vl_api_ip_neighbor_add_del_reply_t *rmp;
  ip_neighbor_flags_t flags;
  u32 stats_index = ~0;
  ip46_address_t ip;
  mac_address_t mac;
  ip46_type_t type;
  int rv;

  VALIDATE_SW_IF_INDEX ((&mp->neighbor));

  flags = ip_neighbor_flags_decode (mp->neighbor.flags);
  type = ip_address_decode (&mp->neighbor.ip_address, &ip);
  mac_address_decode (mp->neighbor.mac_address, &mac);

  /*
   * there's no validation here of the ND/ARP entry being added.
   * The expectation is that the FIB will ensure that nothing bad
   * will come of adding bogus entries.
   */
  if (mp->is_add)
    rv = ip_neighbor_add (&ip, type, &mac,
			  ntohl (mp->neighbor.sw_if_index),
			  flags, &stats_index);
  else
    rv = ip_neighbor_del (&ip, type, ntohl (mp->neighbor.sw_if_index));

  BAD_SW_IF_INDEX_LABEL;

  /* *INDENT-OFF* */
  REPLY_MACRO2 (VL_API_IP_NEIGHBOR_ADD_DEL_REPLY,
  ({
    rmp->stats_index = htonl (stats_index);
  }));
  /* *INDENT-ON* */
}

void
ip_table_delete (fib_protocol_t fproto, u32 table_id, u8 is_api)
{
  u32 fib_index, mfib_index;

  /*
   * ignore action on the default table - this is always present
   * and cannot be added nor deleted from the API
   */
  if (0 != table_id)
    {
      /*
       * The API holds only one lock on the table.
       * i.e. it can be added many times via the API but needs to be
       * deleted only once.
       * The FIB index for unicast and multicast is not necessarily the
       * same, since internal VPP systesm (like LISP and SR) create
       * their own unicast tables.
       */
      fib_index = fib_table_find (fproto, table_id);
      mfib_index = mfib_table_find (fproto, table_id);

      if (~0 != fib_index)
	{
	  fib_table_unlock (fib_index, fproto,
			    (is_api ? FIB_SOURCE_API : FIB_SOURCE_CLI));
	}
      if (~0 != mfib_index)
	{
	  mfib_table_unlock (mfib_index, fproto,
			     (is_api ? MFIB_SOURCE_API : MFIB_SOURCE_CLI));
	}
    }
}

void
vl_api_ip_table_add_del_t_handler (vl_api_ip_table_add_del_t * mp)
{
  vl_api_ip_table_add_del_reply_t *rmp;
  fib_protocol_t fproto = (mp->table.is_ip6 ?
			   FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4);
  u32 table_id = ntohl (mp->table.table_id);
  int rv = 0;

  if (mp->is_add)
    {
      ip_table_create (fproto, table_id, 1, mp->table.name);
    }
  else
    {
      ip_table_delete (fproto, table_id, 1);
    }

  REPLY_MACRO (VL_API_IP_TABLE_ADD_DEL_REPLY);
}

static int
ip_route_add_del_t_handler (vl_api_ip_route_add_del_t * mp, u32 * stats_index)
{
  fib_route_path_t *rpaths = NULL, *rpath;
  fib_entry_flag_t entry_flags;
  vl_api_fib_path_t *apath;
  fib_prefix_t pfx;
  u32 fib_index;
  int rv, ii;

  entry_flags = FIB_ENTRY_FLAG_NONE;
  ip_prefix_decode (&mp->route.prefix, &pfx);

  rv = fib_api_table_id_decode (pfx.fp_proto,
				ntohl (mp->route.table_id), &fib_index);
  if (0 != rv)
    goto out;

  if (0 != mp->route.n_paths)
    vec_validate (rpaths, mp->route.n_paths - 1);

  for (ii = 0; ii < mp->route.n_paths; ii++)
    {
      apath = &mp->route.paths[ii];
      rpath = &rpaths[ii];

      rv = fib_api_path_decode (apath, rpath);

      if ((rpath->frp_flags & FIB_ROUTE_PATH_LOCAL) &&
	  (~0 == rpath->frp_sw_if_index))
	entry_flags |= (FIB_ENTRY_FLAG_CONNECTED | FIB_ENTRY_FLAG_LOCAL);

      if (0 != rv)
	goto out;
    }

  rv = fib_api_route_add_del (mp->is_add,
			      mp->is_multipath,
			      fib_index, &pfx, entry_flags, rpaths);

  if (mp->is_add && 0 == rv)
    *stats_index = fib_table_entry_get_stats_index (fib_index, &pfx);

out:
  vec_free (rpaths);

  return (rv);
}

void
vl_api_ip_route_add_del_t_handler (vl_api_ip_route_add_del_t * mp)
{
  vl_api_ip_route_add_del_reply_t *rmp;
  u32 stats_index = ~0;
  int rv;

  rv = ip_route_add_del_t_handler (mp, &stats_index);

  /* *INDENT-OFF* */
  REPLY_MACRO2 (VL_API_IP_ROUTE_ADD_DEL_REPLY,
  ({
    rmp->stats_index = htonl (stats_index);
  }))
  /* *INDENT-ON* */
}

void
ip_table_create (fib_protocol_t fproto,
		 u32 table_id, u8 is_api, const u8 * name)
{
  u32 fib_index, mfib_index;

  /*
   * ignore action on the default table - this is always present
   * and cannot be added nor deleted from the API
   */
  if (0 != table_id)
    {
      /*
       * The API holds only one lock on the table.
       * i.e. it can be added many times via the API but needs to be
       * deleted only once.
       * The FIB index for unicast and multicast is not necessarily the
       * same, since internal VPP systesm (like LISP and SR) create
       * their own unicast tables.
       */
      fib_index = fib_table_find (fproto, table_id);
      mfib_index = mfib_table_find (fproto, table_id);

      if (~0 == fib_index)
	{
	  fib_table_find_or_create_and_lock_w_name (fproto, table_id,
						    (is_api ?
						     FIB_SOURCE_API :
						     FIB_SOURCE_CLI), name);
	}
      if (~0 == mfib_index)
	{
	  mfib_table_find_or_create_and_lock_w_name (fproto, table_id,
						     (is_api ?
						      MFIB_SOURCE_API :
						      MFIB_SOURCE_CLI), name);
	}
    }
}

static u32
mroute_add_del_handler (u8 is_add,
			u8 is_multipath,
			u32 fib_index,
			const mfib_prefix_t * prefix,
			u32 entry_flags,
			u32 rpf_id, fib_route_path_t * rpaths)
{
  u32 mfib_entry_index = ~0;

  if (0 == vec_len (rpaths))
    {
      mfib_entry_index = mfib_table_entry_update (fib_index, prefix,
						  MFIB_SOURCE_API,
						  rpf_id, entry_flags);
    }
  else
    {
      if (is_add)
	{
	  mfib_entry_index =
	    mfib_table_entry_paths_update (fib_index, prefix,
					   MFIB_SOURCE_API, rpaths);
	}
      else
	{
	  mfib_table_entry_paths_remove (fib_index, prefix,
					 MFIB_SOURCE_API, rpaths);
	}
    }

  return (mfib_entry_index);
}

static int
api_mroute_add_del_t_handler (vl_api_ip_mroute_add_del_t * mp,
			      u32 * stats_index)
{
  fib_route_path_t *rpath, *rpaths = NULL;
  fib_node_index_t mfib_entry_index;
  mfib_prefix_t pfx;
  u32 fib_index;
  int rv;
  u16 ii;

  ip_mprefix_decode (&mp->route.prefix, &pfx);

  rv = mfib_api_table_id_decode (pfx.fp_proto,
				 ntohl (mp->route.table_id), &fib_index);
  if (0 != rv)
    goto out;

  vec_validate (rpaths, mp->route.n_paths - 1);

  for (ii = 0; ii < mp->route.n_paths; ii++)
    {
      rpath = &rpaths[ii];

      rv = mfib_api_path_decode (&mp->route.paths[ii], rpath);

      if (0 != rv)
	goto out;
    }

  mfib_entry_index = mroute_add_del_handler (mp->is_add,
					     mp->is_add,
					     fib_index, &pfx,
					     ntohl (mp->route.entry_flags),
					     ntohl (mp->route.rpf_id),
					     rpaths);

  if (~0 != mfib_entry_index)
    *stats_index = mfib_entry_get_stats_index (mfib_entry_index);

out:
  return (rv);
}

void
vl_api_ip_mroute_add_del_t_handler (vl_api_ip_mroute_add_del_t * mp)
{
  vl_api_ip_mroute_add_del_reply_t *rmp;
  u32 stats_index = ~0;
  int rv;

  rv = api_mroute_add_del_t_handler (mp, &stats_index);

  /* *INDENT-OFF* */
  REPLY_MACRO2 (VL_API_IP_MROUTE_ADD_DEL_REPLY,
  ({
    rmp->stats_index = htonl (stats_index);
  }));
  /* *INDENT-ON* */
}

static void
send_ip_details (vpe_api_main_t * am,
		 vl_api_registration_t * reg, u32 sw_if_index, u8 is_ipv6,
		 u32 context)
{
  vl_api_ip_details_t *mp;

  mp = vl_msg_api_alloc (sizeof (*mp));
  clib_memset (mp, 0, sizeof (*mp));
  mp->_vl_msg_id = ntohs (VL_API_IP_DETAILS);

  mp->sw_if_index = ntohl (sw_if_index);
  mp->is_ipv6 = is_ipv6;
  mp->context = context;

  vl_api_send_msg (reg, (u8 *) mp);
}

static void
send_ip_address_details (vpe_api_main_t * am,
			 vl_api_registration_t * reg,
			 const fib_prefix_t * pfx,
			 u32 sw_if_index, u32 context)
{
  vl_api_ip_address_details_t *mp;

  mp = vl_msg_api_alloc (sizeof (*mp));
  clib_memset (mp, 0, sizeof (*mp));
  mp->_vl_msg_id = ntohs (VL_API_IP_ADDRESS_DETAILS);

  ip_prefix_encode (pfx, &mp->prefix);
  mp->context = context;
  mp->sw_if_index = htonl (sw_if_index);

  vl_api_send_msg (reg, (u8 *) mp);
}

static void
vl_api_ip_address_dump_t_handler (vl_api_ip_address_dump_t * mp)
{
  vpe_api_main_t *am = &vpe_api_main;
  vl_api_registration_t *reg;
  ip6_main_t *im6 = &ip6_main;
  ip4_main_t *im4 = &ip4_main;
  ip_lookup_main_t *lm6 = &im6->lookup_main;
  ip_lookup_main_t *lm4 = &im4->lookup_main;
  ip_interface_address_t *ia = 0;
  u32 sw_if_index = ~0;
  int rv __attribute__ ((unused)) = 0;

  VALIDATE_SW_IF_INDEX (mp);

  sw_if_index = ntohl (mp->sw_if_index);

  reg = vl_api_client_index_to_registration (mp->client_index);
  if (!reg)
    return;

  if (mp->is_ipv6)
    {
      /* *INDENT-OFF* */
      /* Do not send subnet details of the IP-interface for
       * unnumbered interfaces. otherwise listening clients
       * will be confused that the subnet is applied on more
       * than one interface */
      foreach_ip_interface_address (lm6, ia, sw_if_index, 0,
      ({
        fib_prefix_t pfx = {
          .fp_addr.ip6 = *(ip6_address_t *)ip_interface_address_get_address (lm6, ia),
          .fp_len = ia->address_length,
          .fp_proto = FIB_PROTOCOL_IP6,
        };
        send_ip_address_details(am, reg, &pfx, sw_if_index, mp->context);
      }));
      /* *INDENT-ON* */
    }
  else
    {
      /* *INDENT-OFF* */
      foreach_ip_interface_address (lm4, ia, sw_if_index, 0,
      ({
        fib_prefix_t pfx = {
          .fp_addr.ip4 = *(ip4_address_t *)ip_interface_address_get_address (lm4, ia),
          .fp_len = ia->address_length,
          .fp_proto = FIB_PROTOCOL_IP4,
        };

        send_ip_address_details(am, reg, &pfx, sw_if_index, mp->context);
      }));
      /* *INDENT-ON* */
    }

  BAD_SW_IF_INDEX_LABEL;
}

static void
send_ip_unnumbered_details (vpe_api_main_t * am,
			    vl_api_registration_t * reg,
			    u32 sw_if_index, u32 ip_sw_if_index, u32 context)
{
  vl_api_ip_unnumbered_details_t *mp;

  mp = vl_msg_api_alloc (sizeof (*mp));
  clib_memset (mp, 0, sizeof (*mp));
  mp->_vl_msg_id = ntohs (VL_API_IP_UNNUMBERED_DETAILS);

  mp->context = context;
  mp->sw_if_index = htonl (sw_if_index);
  mp->ip_sw_if_index = htonl (ip_sw_if_index);

  vl_api_send_msg (reg, (u8 *) mp);
}

static void
vl_api_ip_unnumbered_dump_t_handler (vl_api_ip_unnumbered_dump_t * mp)
{
  vnet_main_t *vnm = vnet_get_main ();
  vnet_interface_main_t *im = &vnm->interface_main;
  int rv __attribute__ ((unused)) = 0;
  vpe_api_main_t *am = &vpe_api_main;
  vl_api_registration_t *reg;
  vnet_sw_interface_t *si;
  u32 sw_if_index;

  sw_if_index = ntohl (mp->sw_if_index);

  reg = vl_api_client_index_to_registration (mp->client_index);
  if (!reg)
    return;

  if (~0 != sw_if_index)
    {
      VALIDATE_SW_IF_INDEX (mp);

      si = vnet_get_sw_interface (vnm, ntohl (mp->sw_if_index));

      if (!(si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED))
	{
	  send_ip_unnumbered_details (am, reg,
				      sw_if_index,
				      si->unnumbered_sw_if_index,
				      mp->context);
	}
    }
  else
    {
      /* *INDENT-OFF* */
      pool_foreach (si, im->sw_interfaces,
      ({
        if ((si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED))
          {
            send_ip_unnumbered_details(am, reg,
                                       si->sw_if_index,
                                       si->unnumbered_sw_if_index,
                                       mp->context);
          }
      }));
      /* *INDENT-ON* */
    }

  BAD_SW_IF_INDEX_LABEL;
}

static void
vl_api_ip_dump_t_handler (vl_api_ip_dump_t * mp)
{
  vpe_api_main_t *am = &vpe_api_main;
  vnet_main_t *vnm = vnet_get_main ();
  vlib_main_t *vm = vlib_get_main ();
  vnet_interface_main_t *im = &vnm->interface_main;
  vl_api_registration_t *reg;
  vnet_sw_interface_t *si, *sorted_sis;
  u32 sw_if_index = ~0;

  reg = vl_api_client_index_to_registration (mp->client_index);
  if (!reg)
    return;

  /* Gather interfaces. */
  sorted_sis = vec_new (vnet_sw_interface_t, pool_elts (im->sw_interfaces));
  _vec_len (sorted_sis) = 0;
  /* *INDENT-OFF* */
  pool_foreach (si, im->sw_interfaces,
  ({
    vec_add1 (sorted_sis, si[0]);
  }));
  /* *INDENT-ON* */

  vec_foreach (si, sorted_sis)
  {
    if (!(si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED))
      {
	if (mp->is_ipv6 && !ip6_interface_enabled (vm, si->sw_if_index))
	  {
	    continue;
	  }
	sw_if_index = si->sw_if_index;
	send_ip_details (am, reg, sw_if_index, mp->is_ipv6, mp->context);
      }
  }

  vec_free (sorted_sis);
}

static void
set_ip6_flow_hash (vl_api_set_ip_flow_hash_t * mp)
{
  vl_api_set_ip_flow_hash_reply_t *rmp;
  int rv;
  u32 table_id;
  flow_hash_config_t flow_hash_config = 0;

  table_id = ntohl (mp->vrf_id);

#define _(a,b) if (mp->a) flow_hash_config |= b;
  foreach_flow_hash_bit;
#undef _

  rv = vnet_set_ip6_flow_hash (table_id, flow_hash_config);

  REPLY_MACRO (VL_API_SET_IP_FLOW_HASH_REPLY);
}

static void
set_ip4_flow_hash (vl_api_set_ip_flow_hash_t * mp)
{
  vl_api_set_ip_flow_hash_reply_t *rmp;
  int rv;
  u32 table_id;
  flow_hash_config_t flow_hash_config = 0;

  table_id = ntohl (mp->vrf_id);

#define _(a,b) if (mp->a) flow_hash_config |= b;
  foreach_flow_hash_bit;
#undef _

  rv = vnet_set_ip4_flow_hash (table_id, flow_hash_config);

  REPLY_MACRO (VL_API_SET_IP_FLOW_HASH_REPLY);
}


static void
vl_api_set_ip_flow_hash_t_handler (vl_api_set_ip_flow_hash_t * mp)
{
  if (mp->is_ipv6 == 0)
    set_ip4_flow_hash (mp);
  else
    set_ip6_flow_hash (mp);
}

static void
  vl_api_sw_interface_ip6nd_ra_config_t_handler
  (vl_api_sw_interface_ip6nd_ra_config_t * mp)
{
  vl_api_sw_interface_ip6nd_ra_config_reply_t *rmp;
  vlib_main_t *vm = vlib_get_main ();
  int rv = 0;
  u8 is_no, suppress, managed, other, ll_option, send_unicast, cease,
    default_router;

  is_no = mp->is_no == 1;
  suppress = mp->suppress == 1;
  managed = mp->managed == 1;
  other = mp->other == 1;
  ll_option = mp->ll_option == 1;
  send_unicast = mp->send_unicast == 1;
  cease = mp->cease == 1;
  default_router = mp->default_router == 1;

  VALIDATE_SW_IF_INDEX (mp);

  rv = ip6_neighbor_ra_config (vm, ntohl (mp->sw_if_index),
			       suppress, managed, other,
			       ll_option, send_unicast, cease,
			       default_router, ntohl (mp->lifetime),
			       ntohl (mp->initial_count),
			       ntohl (mp->initial_interval),
			       ntohl (mp->max_interval),
			       ntohl (mp->min_interval), is_no);

  BAD_SW_IF_INDEX_LABEL;

  REPLY_MACRO (VL_API_SW_INTERFACE_IP6ND_RA_CONFIG_REPLY);
}

static void
  vl_api_sw_interface_ip6nd_ra_prefix_t_handler
  (vl_api_sw_interface_ip6nd_ra_prefix_t * mp)
{
  vlib_main_t *vm = vlib_get_main ();
  vl_api_sw_interface_ip6nd_ra_prefix_reply_t *rmp;
  fib_prefix_t pfx;
  int rv = 0;
  u8 is_no, use_default, no_advertise, off_link, no_autoconfig, no_onlink;

  VALIDATE_SW_IF_INDEX (mp);

  ip_prefix_decode (&mp->prefix, &pfx);
  is_no = mp->is_no == 1;
  use_default = mp->use_default == 1;
  no_advertise = mp->no_advertise == 1;
  off_link = mp->off_link == 1;
  no_autoconfig = mp->no_autoconfig == 1;
  no_onlink = mp->no_onlink == 1;

  rv = ip6_neighbor_ra_prefix (vm, ntohl (mp->sw_if_index),
			       &pfx.fp_addr.ip6,
			       pfx.fp_len, use_default,
			       ntohl (mp->val_lifetime),
			       ntohl (mp->pref_lifetime), no_advertise,
			       off_link, no_autoconfig, no_onlink, is_no);

  BAD_SW_IF_INDEX_LABEL;
  REPLY_MACRO (VL_API_SW_INTERFACE_IP6ND_RA_PREFIX_REPLY);
}

static void
send_ip6nd_proxy_details (vl_api_registration_t * reg,
			  u32 context,
			  const ip46_address_t * addr, u32 sw_if_index)
{
  vl_api_ip6nd_proxy_details_t *mp;

  mp = vl_msg_api_alloc (sizeof (*mp));
  clib_memset (mp, 0, sizeof (*mp));
  mp->_vl_msg_id = ntohs (VL_API_IP6ND_PROXY_DETAILS);
  mp->context = context;
  mp->sw_if_index = htonl (sw_if_index);

  ip6_address_encode (&addr->ip6, mp->ip);

  vl_api_send_msg (reg, (u8 *) mp);
}

typedef struct api_ip6nd_proxy_fib_table_walk_ctx_t_
{
  u32 *indices;
} api_ip6nd_proxy_fib_table_walk_ctx_t;

static fib_table_walk_rc_t
api_ip6nd_proxy_fib_table_walk (fib_node_index_t fei, void *arg)
{
  api_ip6nd_proxy_fib_table_walk_ctx_t *ctx = arg;

  if (fib_entry_is_sourced (fei, FIB_SOURCE_IP6_ND_PROXY))
    {
      vec_add1 (ctx->indices, fei);
    }

  return (FIB_TABLE_WALK_CONTINUE);
}

static void
vl_api_ip6nd_proxy_dump_t_handler (vl_api_ip6nd_proxy_dump_t * mp)
{
  ip6_main_t *im6 = &ip6_main;
  fib_table_t *fib_table;
  api_ip6nd_proxy_fib_table_walk_ctx_t ctx = {
    .indices = NULL,
  };
  fib_node_index_t *feip;
  const fib_prefix_t *pfx;
  vl_api_registration_t *reg;

  reg = vl_api_client_index_to_registration (mp->client_index);
  if (!reg)
    return;

  /* *INDENT-OFF* */
  pool_foreach (fib_table, im6->fibs,
  ({
    fib_table_walk(fib_table->ft_index,
                   FIB_PROTOCOL_IP6,
                   api_ip6nd_proxy_fib_table_walk,
                   &ctx);
  }));
  /* *INDENT-ON* */

  vec_sort_with_function (ctx.indices, fib_entry_cmp_for_sort);

  vec_foreach (feip, ctx.indices)
  {
    pfx = fib_entry_get_prefix (*feip);

    send_ip6nd_proxy_details (reg,
			      mp->context,
			      &pfx->fp_addr,
			      fib_entry_get_resolving_interface (*feip));
  }

  vec_free (ctx.indices);
}

static void
vl_api_ip6nd_proxy_add_del_t_handler (vl_api_ip6nd_proxy_add_del_t * mp)
{
  vl_api_ip6nd_proxy_add_del_reply_t *rmp;
  ip6_address_t ip6;
  int rv = 0;

  VALIDATE_SW_IF_INDEX (mp);

  ip6_address_decode (mp->ip, &ip6);
  rv = ip6_neighbor_proxy_add_del (ntohl (mp->sw_if_index), &ip6, mp->is_del);

  BAD_SW_IF_INDEX_LABEL;
  REPLY_MACRO (VL_API_IP6ND_PROXY_ADD_DEL_REPLY);
}

static void
  vl_api_ip6nd_send_router_solicitation_t_handler
  (vl_api_ip6nd_send_router_solicitation_t * mp)
{
  vl_api_ip6nd_send_router_solicitation_reply_t *rmp;
  icmp6_send_router_solicitation_params_t params;
  vlib_main_t *vm = vlib_get_main ();
  int rv = 0;

  VALIDATE_SW_IF_INDEX (mp);

  BAD_SW_IF_INDEX_LABEL;
  REPLY_MACRO (VL_API_IP6ND_SEND_ROUTER_SOLICITATION_REPLY);

  if (rv != 0)
    return;

  params.irt = ntohl (mp->irt);
  params.mrt = ntohl (mp->mrt);
  params.mrc = ntohl (mp->mrc);
  params.mrd = ntohl (mp->mrd);

  icmp6_send_router_solicitation (vm, ntohl (mp->sw_if_index), mp->stop,
				  &params);
}

static void
  vl_api_sw_interface_ip6_enable_disable_t_handler
  (vl_api_sw_interface_ip6_enable_disable_t * mp)
{
  vlib_main_t *vm = vlib_get_main ();
  vl_api_sw_interface_ip6_enable_disable_reply_t *rmp;
  vnet_main_t *vnm = vnet_get_main ();
  int rv = 0;
  clib_error_t *error;

  vnm->api_errno = 0;

  VALIDATE_SW_IF_INDEX (mp);

  error =
    (mp->enable == 1) ? enable_ip6_interface (vm,
					      ntohl (mp->sw_if_index)) :
    disable_ip6_interface (vm, ntohl (mp->sw_if_index));

  if (error)
    {
      clib_error_report (error);
      rv = VNET_API_ERROR_UNSPECIFIED;
    }
  else
    {
      rv = vnm->api_errno;
    }

  BAD_SW_IF_INDEX_LABEL;

  REPLY_MACRO (VL_API_SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY);
}

void
vl_mfib_signal_send_one (vl_api_registration_t * reg,
			 u32 context, const mfib_signal_t * mfs)
{
  vl_api_mfib_signal_details_t *mp;
  const mfib_prefix_t *prefix;
  mfib_table_t *mfib;
  mfib_itf_t *mfi;

  mp = vl_msg_api_alloc (sizeof (*mp));

  clib_memset (mp, 0, sizeof (*mp));
  mp->_vl_msg_id = ntohs (VL_API_MFIB_SIGNAL_DETAILS);
  mp->context = context;

  mfi = mfib_itf_get (mfs->mfs_itf);
  prefix = mfib_entry_get_prefix (mfs->mfs_entry);
  mfib = mfib_table_get (mfib_entry_get_fib_index (mfs->mfs_entry),
			 prefix->fp_proto);
  mp->table_id = ntohl (mfib->mft_table_id);
  mp->sw_if_index = ntohl (mfi->mfi_sw_if_index);

  ip_mprefix_encode (prefix, &mp->prefix);

  if (0 != mfs->mfs_buffer_len)
    {
      mp->ip_packet_len = ntohs (mfs->mfs_buffer_len);

      memcpy (mp->ip_packet_data, mfs->mfs_buffer, mfs->mfs_buffer_len);
    }
  else
    {
      mp->ip_packet_len = 0;
    }

  vl_api_send_msg (reg, (u8 *) mp);
}

static void
vl_api_mfib_signal_dump_t_handler (vl_api_mfib_signal_dump_t * mp)
{
  vl_api_registration_t *reg;

  reg = vl_api_client_index_to_registration (mp->client_index);
  if (!reg)
    return;

  while (vl_api_can_send_msg (reg) && mfib_signal_send_one (reg, mp->context))
    ;
}

static void
  vl_api_ip_container_proxy_add_del_t_handler
  (vl_api_ip_container_proxy_add_del_t * mp)
{
  vl_api_ip_container_proxy_add_del_reply_t *rmp;
  vnet_ip_container_proxy_args_t args;
  int rv = 0;
  clib_error_t *error;

  clib_memset (&args, 0, sizeof (args));

  ip_prefix_decode (&mp->pfx, &args.prefix);

  args.sw_if_index = clib_net_to_host_u32 (mp->sw_if_index);
  args.is_add = mp->is_add;
  if ((error = vnet_ip_container_proxy_add_del (&args)))
    {
      rv = clib_error_get_code (error);
      clib_error_report (error);
    }

  REPLY_MACRO (VL_API_IP_CONTAINER_PROXY_ADD_DEL_REPLY);
}

typedef struct ip_container_proxy_walk_ctx_t_
{
  vl_api_registration_t *reg;
  u32 context;
} ip_container_proxy_walk_ctx_t;

static int
ip_container_proxy_send_details (const fib_prefix_t * pfx, u32 sw_if_index,
				 void *args)
{
  vl_api_ip_container_proxy_details_t *mp;
  ip_container_proxy_walk_ctx_t *ctx = args;

  mp = vl_msg_api_alloc (sizeof (*mp));
  if (!mp)
    return 1;

  clib_memset (mp, 0, sizeof (*mp));
  mp->_vl_msg_id = ntohs (VL_API_IP_CONTAINER_PROXY_DETAILS);
  mp->context = ctx->context;

  mp->sw_if_index = ntohl (sw_if_index);
  ip_prefix_encode (pfx, &mp->prefix);

  vl_api_send_msg (ctx->reg, (u8 *) mp);

  return 1;
}

static void
vl_api_ip_container_proxy_dump_t_handler (vl_api_ip_container_proxy_dump_t *
					  mp)
{
  vl_api_registration_t *reg;

  reg = vl_api_client_index_to_registration (mp->client_index);
  if (!reg)
    return;

  ip_container_proxy_walk_ctx_t ctx = {
    .context = mp->context,
    .reg = reg,
  };

  ip_container_proxy_walk (ip_container_proxy_send_details, &ctx);
}

static void
vl_api_ioam_enable_t_handler (vl_api_ioam_enable_t * mp)
{
  int rv = 0;
  vl_api_ioam_enable_reply_t *rmp;
  clib_error_t *error;

  /* Ignoring the profile id as currently a single profile
   * is supported */
  error = ip6_ioam_enable (mp->trace_enable, mp->pot_enable,
			   mp->seqno, mp->analyse);
  if (error)
    {
      clib_error_report (error);
      rv = clib_error_get_code (error);
    }

  REPLY_MACRO (VL_API_IOAM_ENABLE_REPLY);
}

static void
vl_api_ioam_disable_t_handler (vl_api_ioam_disable_t * mp)
{
  int rv = 0;
  vl_api_ioam_disable_reply_t *rmp;
  clib_error_t *error;

  error = clear_ioam_rewrite_fn ();
  if (error)
    {
      clib_error_report (error);
      rv = clib_error_get_code (error);
    }

  REPLY_MACRO (VL_API_IOAM_DISABLE_REPLY);
}

static void
  vl_api_ip_source_and_port_range_check_add_del_t_handler
  (vl_api_ip_source_and_port_range_check_add_del_t * mp)
{
  vl_api_ip_source_and_port_range_check_add_del_reply_t *rmp;
  int rv = 0;

  u8 is_add = mp->is_add;
  fib_prefix_t pfx;
  u16 *low_ports = 0;
  u16 *high_ports = 0;
  u32 vrf_id;
  u16 tmp_low, tmp_high;
  u8 num_ranges;
  int i;

  ip_prefix_decode (&mp->prefix, &pfx);

  // Validate port range
  num_ranges = mp->number_of_ranges;
  if (num_ranges > 32)
    {				// This is size of array in VPE.API
      rv = VNET_API_ERROR_EXCEEDED_NUMBER_OF_RANGES_CAPACITY;
      goto reply;
    }

  vec_reset_length (low_ports);
  vec_reset_length (high_ports);

  for (i = 0; i < num_ranges; i++)
    {
      tmp_low = mp->low_ports[i];
      tmp_high = mp->high_ports[i];
      // If tmp_low <= tmp_high then only need to check tmp_low = 0
      // If tmp_low <= tmp_high then only need to check tmp_high > 65535
      if (tmp_low > tmp_high || tmp_low == 0 || tmp_high > 65535)
	{
	  rv = VNET_API_ERROR_INVALID_VALUE;
	  goto reply;
	}
      vec_add1 (low_ports, tmp_low);
      vec_add1 (high_ports, tmp_high + 1);
    }

  vrf_id = ntohl (mp->vrf_id);

  if (vrf_id < 1)
    {
      rv = VNET_API_ERROR_INVALID_VALUE;
      goto reply;
    }


  if (FIB_PROTOCOL_IP6 == pfx.fp_proto)
    {
      rv = ip6_source_and_port_range_check_add_del (&pfx.fp_addr.ip6,
						    pfx.fp_len,
						    vrf_id,
						    low_ports,
						    high_ports, is_add);
    }
  else
    {
      rv = ip4_source_and_port_range_check_add_del (&pfx.fp_addr.ip4,
						    pfx.fp_len,
						    vrf_id,
						    low_ports,
						    high_ports, is_add);
    }

reply:
  vec_free (low_ports);
  vec_free (high_ports);
  REPLY_MACRO (VL_API_IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY);
}

static void
  vl_api_ip_source_and_port_range_check_interface_add_del_t_handler
  (vl_api_ip_source_and_port_range_check_interface_add_del_t * mp)
{
  vlib_main_t *vm = vlib_get_main ();
  vl_api_ip_source_and_port_range_check_interface_add_del_reply_t *rmp;
  ip4_main_t *im = &ip4_main;
  int rv;
  u32 sw_if_index;
  u32 fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS];
  u32 vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS];
  uword *p = 0;
  int i;

  vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_OUT] =
    ntohl (mp->tcp_out_vrf_id);
  vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_OUT] =
    ntohl (mp->udp_out_vrf_id);
  vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_IN] =
    ntohl (mp->tcp_in_vrf_id);
  vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_IN] =
    ntohl (mp->udp_in_vrf_id);


  for (i = 0; i < IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS; i++)
    {
      if (vrf_id[i] != 0 && vrf_id[i] != ~0)
	{
	  p = hash_get (im->fib_index_by_table_id, vrf_id[i]);

	  if (p == 0)
	    {
	      rv = VNET_API_ERROR_INVALID_VALUE;
	      goto reply;
	    }

	  fib_index[i] = p[0];
	}
      else
	fib_index[i] = ~0;
    }
  sw_if_index = ntohl (mp->sw_if_index);

  VALIDATE_SW_IF_INDEX (mp);

  rv =
    set_ip_source_and_port_range_check (vm, fib_index, sw_if_index,
					mp->is_add);

  BAD_SW_IF_INDEX_LABEL;
reply:

  REPLY_MACRO (VL_API_IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY);
}

typedef union
{
  u32 fib_index;
} ip4_source_check_config_t;

static void
  vl_api_ip_source_check_interface_add_del_t_handler
  (vl_api_ip_source_check_interface_add_del_t * mp)
{
  vl_api_ip_source_check_interface_add_del_reply_t *rmp;
  int rv;
  u32 sw_if_index = ntohl (mp->sw_if_index);
  u8 is_add = mp->is_add;
  char *feature_name =
    mp->loose ? "ip4-source-check-via-any" : "ip4-source-check-via-rx";

  ip4_source_check_config_t config;

  VALIDATE_SW_IF_INDEX (mp);

  config.fib_index =
    fib_table_get_index_for_sw_if_index (FIB_PROTOCOL_IP4, sw_if_index);
  rv =
    vnet_feature_enable_disable ("ip4-unicast", feature_name, sw_if_index,
				 is_add, &config, sizeof (config));
  BAD_SW_IF_INDEX_LABEL;

  REPLY_MACRO (VL_API_IP_SOURCE_CHECK_INTERFACE_ADD_DEL_REPLY);
}

#define IP4_ARP_EVENT 3
#define IP6_ND_EVENT 4

static vlib_node_registration_t ip_resolver_process_node;

static int
arp_change_delete_callback (u32 pool_index,
			    const mac_address_t * mac,
			    u32 sw_if_index, const ip4_address_t * address)
{
  vpe_api_main_t *am = &vpe_api_main;

  if (pool_is_free_index (am->arp_events, pool_index))
    return 1;

  pool_put_index (am->arp_events, pool_index);
  return 0;
}

static void
handle_ip4_arp_event (u32 pool_index)
{
  vpe_api_main_t *vam = &vpe_api_main;
  vnet_main_t *vnm = vam->vnet_main;
  vlib_main_t *vm = vam->vlib_main;
  vl_api_ip4_arp_event_t *event;
  vl_api_ip4_arp_event_t *mp;
  vl_api_registration_t *reg;

  /* Client can cancel, die, etc. */
  if (pool_is_free_index (vam->arp_events, pool_index))
    return;

  event = pool_elt_at_index (vam->arp_events, pool_index);

  reg = vl_api_client_index_to_registration (event->client_index);
  if (!reg)
    {
      (void) vnet_add_del_ip4_arp_change_event
	(vnm, arp_change_delete_callback,
	 event->pid, event->ip,
	 ip_resolver_process_node.index, IP4_ARP_EVENT,
	 ~0 /* pool index, notused */ , 0 /* is_add */ );
      return;
    }

  if (vl_api_can_send_msg (reg))
    {
      mp = vl_msg_api_alloc (sizeof (*mp));
      clib_memcpy (mp, event, sizeof (*mp));
      vl_api_send_msg (reg, (u8 *) mp);
    }
  else
    {
      static f64 last_time;
      /*
       * Throttle syslog msgs.
       * It's pretty tempting to just revoke the registration...
       */
      if (vlib_time_now (vm) > last_time + 10.0)
	{
	  clib_warning ("arp event for %U to pid %d: queue stuffed!",
			format_ip4_address, event->ip, event->pid);
	  last_time = vlib_time_now (vm);
	}
    }
}

static int
nd_change_delete_callback (u32 pool_index,
			   const mac_address_t * mac,
			   u32 sw_if_index, const ip6_address_t * addr)
{
  vpe_api_main_t *am = &vpe_api_main;

  if (pool_is_free_index (am->nd_events, pool_index))
    return 1;

  pool_put_index (am->nd_events, pool_index);
  return 0;
}

static void
handle_ip6_nd_event (u32 pool_index)
{
  vpe_api_main_t *vam = &vpe_api_main;
  vnet_main_t *vnm = vam->vnet_main;
  vlib_main_t *vm = vam->vlib_main;
  vl_api_ip6_nd_event_t *event;
  vl_api_ip6_nd_event_t *mp;
  vl_api_registration_t *reg;

  /* Client can cancel, die, etc. */
  if (pool_is_free_index (vam->nd_events, pool_index))
    return;

  event = pool_elt_at_index (vam->nd_events, pool_index);

  reg = vl_api_client_index_to_registration (event->client_index);
  if (!reg)
    {
      (void) vnet_add_del_ip6_nd_change_event
	(vnm, nd_change_delete_callback,
	 event->pid, event->ip,
	 ip_resolver_process_node.index, IP6_ND_EVENT,
	 ~0 /* pool index, notused */ , 0 /* is_add */ );
      return;
    }

  if (vl_api_can_send_msg (reg))
    {
      mp = vl_msg_api_alloc (sizeof (*mp));
      clib_memcpy (mp, event, sizeof (*mp));
      vl_api_send_msg (reg, (u8 *) mp);
    }
  else
    {
      static f64 last_time;
      /*
       * Throttle syslog msgs.
       * It's pretty tempting to just revoke the registration...
       */
      if (vlib_time_now (vm) > last_time + 10.0)
	{
	  clib_warning ("ip6 nd event for %U to pid %d: queue stuffed!",
			format_ip6_address, event->ip, event->pid);
	  last_time = vlib_time_now (vm);
	}
    }
}

static uword
resolver_process (vlib_main_t * vm,
		  vlib_node_runtime_t * rt, vlib_frame_t * f)
{
  volatile f64 timeout = 100.0;
  volatile uword *event_data = 0;

  while (1)
    {
      vlib_process_wait_for_event_or_clock (vm, timeout);

      uword event_type =
	vlib_process_get_events (vm, (uword **) & event_data);

      int i;
      switch (event_type)
	{
	case IP4_ARP_EVENT:
	  for (i = 0; i < vec_len (event_data); i++)
	    handle_ip4_arp_event (event_data[i]);
	  break;

	case IP6_ND_EVENT:
	  for (i = 0; i < vec_len (event_data); i++)
	    handle_ip6_nd_event (event_data[i]);
	  break;

	case ~0:		/* timeout */
	  break;
	}

      vec_reset_length (event_data);
    }
  return 0;			/* or not */
}

/* *INDENT-OFF* */
VLIB_REGISTER_NODE (ip_resolver_process_node,static) = {
  .function = resolver_process,
  .type = VLIB_NODE_TYPE_PROCESS,
  .name = "ip-route-resolver-process",
};
/* *INDENT-ON* */

static int
nd_change_data_callback (u32 pool_index, const mac_address_t * new_mac,
			 u32 sw_if_index, const ip6_address_t * address)
{
  vpe_api_main_t *am = &vpe_api_main;
  vl_api_ip6_nd_event_t *event;

  if (pool_is_free_index (am->nd_events, pool_index))
    return 1;

  event = pool_elt_at_index (am->nd_events, pool_index);
  if (ethernet_mac_address_equal (event->mac, new_mac->bytes) &&
      sw_if_index == ntohl (event->sw_if_index))
    {
      return 1;
    }

  mac_address_encode (new_mac, event->mac);
  event->sw_if_index = htonl (sw_if_index);
  return 0;
}

static vlib_node_registration_t wc_arp_process_node;

enum
{ WC_ARP_REPORT, WC_ND_REPORT, RA_REPORT, REPORT_MAX };

static uword
wc_arp_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
{
  /* These cross the longjmp boundary (vlib_process_wait_for_event)
   * and need to be volatile - to prevent them from being optimized into
   * a register - which could change during suspension */

  volatile wc_arp_report_t arp_prev = { 0 };
  volatile wc_nd_report_t nd_prev = { 0 };
  volatile f64 last_arp = vlib_time_now (vm);
  volatile f64 last_nd = vlib_time_now (vm);

  while (1)
    {
      vlib_process_wait_for_event (vm);
      uword event_type = WC_ARP_REPORT;
      void *event_data = vlib_process_get_event_data (vm, &event_type);

      f64 now = vlib_time_now (vm);
      int i;
      if (event_type == WC_ARP_REPORT)
	{
	  wc_arp_report_t *arp_events = event_data;
	  for (i = 0; i < vec_len (arp_events); i++)
	    {
	      /* discard dup event - cast away volatile */
	      if (arp_prev.ip.as_u32 == arp_events[i].ip.as_u32 &&
		  mac_address_equal ((const mac_address_t *) &arp_prev.mac,
				     &arp_events[i].mac) &&
		  arp_prev.sw_if_index == arp_events[i].sw_if_index &&
		  (now - last_arp) < 10.0)
		{
		  continue;
		}
	      arp_prev = arp_events[i];
	      last_arp = now;
	      vpe_client_registration_t *reg;
            /* *INDENT-OFF* */
            pool_foreach(reg, vpe_api_main.wc_ip4_arp_events_registrations,
            ({
	      vl_api_registration_t *vl_reg;
              vl_reg = vl_api_client_index_to_registration (reg->client_index);
              ASSERT (vl_reg != NULL);
	      if (reg && vl_api_can_send_msg (vl_reg))
	        {
	          vl_api_ip4_arp_event_t * event = vl_msg_api_alloc (sizeof *event);
	          clib_memset (event, 0, sizeof *event);
	          event->_vl_msg_id = htons (VL_API_IP4_ARP_EVENT);
	          event->client_index = reg->client_index;
	          event->pid = reg->client_pid;
	          event->mac_ip = 1;
	          ip4_address_encode(&arp_events[i].ip, event->ip);
	          event->sw_if_index = htonl(arp_events[i].sw_if_index);
	          mac_address_encode(&arp_events[i].mac, event->mac);
	          vl_api_send_msg (vl_reg, (u8 *) event);
	        }
            }));
            /* *INDENT-ON* */
	    }
	}
      else if (event_type == WC_ND_REPORT)
	{
	  wc_nd_report_t *nd_events = event_data;
	  for (i = 0; i < vec_len (nd_events); i++)
	    {
	      /* discard dup event - cast away volatile */
	      if (ip6_address_is_equal ((const ip6_address_t *) &nd_prev.ip6,
					&nd_events[i].ip6)
		  && mac_address_equal ((const mac_address_t *) &nd_prev.mac,
					&nd_events[i].mac)
		  && nd_prev.sw_if_index == nd_events[i].sw_if_index
		  && (now - last_nd) < 10.0)
		{
		  continue;
		}
	      nd_prev = nd_events[i];
	      last_nd = now;
	      vpe_client_registration_t *reg;
              /* *INDENT-OFF* */
              pool_foreach(reg, vpe_api_main.wc_ip6_nd_events_registrations,
              ({
	        vl_api_registration_t *vl_reg;
                vl_reg = vl_api_client_index_to_registration (reg->client_index);
	        if (vl_reg && vl_api_can_send_msg (vl_reg))
	          {
	            vl_api_ip6_nd_event_t * event = vl_msg_api_alloc (sizeof *event);
	            clib_memset (event, 0, sizeof *event);
	            event->_vl_msg_id = htons (VL_API_IP6_ND_EVENT);
	            event->client_index = reg->client_index;
	            event->pid = reg->client_pid;
	            event->mac_ip = 1;
	            ip6_address_encode(&nd_events[i].ip6, event->ip);
	            event->sw_if_index = htonl(nd_events[i].sw_if_index);
	            mac_address_encode(&nd_events[i].mac, event->mac);
	            vl_api_send_msg (vl_reg, (u8 *) event);
	          }
              }));
            /* *INDENT-ON* */
	    }
	}
      else if (event_type == RA_REPORT)
	{
	  ra_report_t *ra_events = event_data;
	  for (i = 0; i < vec_len (ra_events); i++)
	    {
	      ip6_neighbor_public_main_t *npm = &ip6_neighbor_public_main;
	      call_ip6_neighbor_callbacks (&ra_events[i],
					   npm->ra_report_functions);

	      vpe_client_registration_t *reg;
              /* *INDENT-OFF* */
              pool_foreach(reg, vpe_api_main.ip6_ra_events_registrations,
              ({
		vl_api_registration_t *vl_reg;
		vl_reg =
		  vl_api_client_index_to_registration (reg->client_index);
		if (vl_reg && vl_api_can_send_msg (vl_reg))
		  {
		    u32 event_size =
		      sizeof (vl_api_ip6_ra_event_t) +
		      vec_len (ra_events[i].prefixes) *
		      sizeof (vl_api_ip6_ra_prefix_info_t);
		    vl_api_ip6_ra_event_t *event =
		      vl_msg_api_alloc (event_size);
		    clib_memset (event, 0, event_size);
		    event->_vl_msg_id = htons (VL_API_IP6_RA_EVENT);
		    event->client_index = reg->client_index;
		    event->pid = reg->client_pid;

		    event->sw_if_index = clib_host_to_net_u32 (ra_events[i].sw_if_index);

		    ip6_address_encode (&ra_events[i].router_address,
                                        event->router_addr);

		    event->current_hop_limit = ra_events[i].current_hop_limit;
		    event->flags = ra_events[i].flags;
		    event->router_lifetime_in_sec =
		      clib_host_to_net_u16 (ra_events
					    [i].router_lifetime_in_sec);
		    event->neighbor_reachable_time_in_msec =
		      clib_host_to_net_u32 (ra_events
					    [i].neighbor_reachable_time_in_msec);
		    event->time_in_msec_between_retransmitted_neighbor_solicitations
		      =
		      clib_host_to_net_u32 (ra_events
					    [i].time_in_msec_between_retransmitted_neighbor_solicitations);

		    event->n_prefixes =
		      clib_host_to_net_u32 (vec_len (ra_events[i].prefixes));
		    vl_api_ip6_ra_prefix_info_t *prefix =
		      (typeof (prefix)) event->prefixes;
		    u32 j;
		    for (j = 0; j < vec_len (ra_events[i].prefixes); j++)
		      {
			ra_report_prefix_info_t *info =
			  &ra_events[i].prefixes[j];
			ip_prefix_encode(&info->prefix, &prefix->prefix);
			prefix->flags = info->flags;
			prefix->valid_time =
			  clib_host_to_net_u32 (info->valid_time);
			prefix->preferred_time =
			  clib_host_to_net_u32 (info->preferred_time);
			prefix++;
		      }

		    vl_api_send_msg (vl_reg, (u8 *) event);
		  }
              }));
              /* *INDENT-ON* */
	      vec_free (ra_events[i].prefixes);
	    }
	}
      vlib_process_put_event_data (vm, event_data);
    }

  return 0;
}

/* *INDENT-OFF* */
VLIB_REGISTER_NODE (wc_arp_process_node,static) = {
  .function = wc_arp_process,
  .type = VLIB_NODE_TYPE_PROCESS,
  .name = "wildcard-ip4-arp-publisher-process",
};
/* *INDENT-ON* */

static int
arp_change_data_callback (u32 pool_index,
			  const mac_address_t * mac,
			  u32 sw_if_index, const ip4_address_t * address)
{
  vpe_api_main_t *am = &vpe_api_main;
  vl_api_ip4_arp_event_t *event;

  if (pool_is_free_index (am->arp_events, pool_index))
    return 1;

  event = pool_elt_at_index (am->arp_events, pool_index);
  if (ethernet_mac_address_equal (event->mac, mac->bytes) &&
      sw_if_index == ntohl (event->sw_if_index))
    {
      return 1;
    }

  mac_address_encode (mac, event->mac);
  event->sw_if_index = htonl (sw_if_index);
  return 0;
}

static void
vl_api_want_ip4_arp_events_t_handler (vl_api_want_ip4_arp_events_t * mp)
{
  vpe_api_main_t *am = &vpe_api_main;
  vnet_main_t *vnm = vnet_get_main ();
  vl_api_want_ip4_arp_events_reply_t *rmp;
  ip4_address_t ip;
  int rv = 0;

  ip4_address_decode (mp->ip, &ip);

  if (ip.as_u32 == 0)
    {
      uword *p =
	hash_get (am->wc_ip4_arp_events_registration_hash, mp->client_index);
      vpe_client_registration_t *rp;
      if (p)
	{
	  if (mp->enable_disable)
	    {
	      clib_warning ("pid %d: already enabled...", mp->pid);
	      rv = VNET_API_ERROR_INVALID_REGISTRATION;
	      goto reply;
	    }
	  else
	    {
	      rp =
		pool_elt_at_index (am->wc_ip4_arp_events_registrations, p[0]);
	      pool_put (am->wc_ip4_arp_events_registrations, rp);
	      hash_unset (am->wc_ip4_arp_events_registration_hash,
			  mp->client_index);
	      if (pool_elts (am->wc_ip4_arp_events_registrations) == 0)
		wc_arp_set_publisher_node (~0, REPORT_MAX);
	      goto reply;
	    }
	}
      if (mp->enable_disable == 0)
	{
	  clib_warning ("pid %d: already disabled...", mp->pid);
	  rv = VNET_API_ERROR_INVALID_REGISTRATION;
	  goto reply;
	}
      pool_get (am->wc_ip4_arp_events_registrations, rp);
      rp->client_index = mp->client_index;
      rp->client_pid = mp->pid;
      hash_set (am->wc_ip4_arp_events_registration_hash, rp->client_index,
		rp - am->wc_ip4_arp_events_registrations);
      wc_arp_set_publisher_node (wc_arp_process_node.index, WC_ARP_REPORT);
      goto reply;
    }

  if (mp->enable_disable)
    {
      vl_api_ip4_arp_event_t *event;
      pool_get (am->arp_events, event);
      rv = vnet_add_del_ip4_arp_change_event
	(vnm, arp_change_data_callback,
	 mp->pid, mp->ip /* addr, in net byte order */ ,
	 ip_resolver_process_node.index,
	 IP4_ARP_EVENT, event - am->arp_events, 1 /* is_add */ );

      if (rv)
	{
	  pool_put (am->arp_events, event);
	  goto reply;
	}
      clib_memset (event, 0, sizeof (*event));

      /* Python API expects events to have no context */
      event->_vl_msg_id = htons (VL_API_IP4_ARP_EVENT);
      event->client_index = mp->client_index;
      memcpy (event->ip, mp->ip, 4);
      event->pid = mp->pid;
      if (ip.as_u32 == 0)
	event->mac_ip = 1;
    }
  else
    {
      rv = vnet_add_del_ip4_arp_change_event
	(vnm, arp_change_delete_callback,
	 mp->pid, mp->ip /* addr, in net byte order */ ,
	 ip_resolver_process_node.index,
	 IP4_ARP_EVENT, ~0 /* pool index */ , 0 /* is_add */ );
    }
reply:
  REPLY_MACRO (VL_API_WANT_IP4_ARP_EVENTS_REPLY);
}

static clib_error_t *
want_ip4_arp_events_reaper (u32 client_index)
{
  vpe_client_registration_t *rp;
  vl_api_ip4_arp_event_t *event;
  u32 *to_delete, *event_id;
  vpe_api_main_t *am;
  vnet_main_t *vnm;
  uword *p;

  am = &vpe_api_main;
  vnm = vnet_get_main ();
  to_delete = NULL;

  /* clear out all of its pending resolutions */
  /* *INDENT-OFF* */
  pool_foreach(event, am->arp_events,
  ({
    if (event->client_index == client_index)
      {
        vec_add1(to_delete, event - am->arp_events);
      }
  }));
  /* *INDENT-ON* */

  vec_foreach (event_id, to_delete)
  {
    event = pool_elt_at_index (am->arp_events, *event_id);
    vnet_add_del_ip4_arp_change_event
      (vnm, arp_change_delete_callback,
       event->pid, event->ip,
       ip_resolver_process_node.index, IP4_ARP_EVENT,
       ~0 /* pool index, notused */ , 0 /* is_add */ );
  }
  vec_free (to_delete);

  /* remove from the registration hash */
  p = hash_get (am->wc_ip4_arp_events_registration_hash, client_index);

  if (p)
    {
      rp = pool_elt_at_index (am->wc_ip4_arp_events_registrations, p[0]);
      pool_put (am->wc_ip4_arp_events_registrations, rp);
      hash_unset (am->wc_ip4_arp_events_registration_hash, client_index);
      if (pool_elts (am->wc_ip4_arp_events_registrations) == 0)
	wc_arp_set_publisher_node (~0, REPORT_MAX);
    }
  return (NULL);
}

VL_MSG_API_REAPER_FUNCTION (want_ip4_arp_events_reaper);

static void
vl_api_want_ip6_nd_events_t_handler (vl_api_want_ip6_nd_events_t * mp)
{
  vpe_api_main_t *am = &vpe_api_main;
  vnet_main_t *vnm = vnet_get_main ();
  vl_api_want_ip6_nd_events_reply_t *rmp;
  ip6_address_t ip6;
  int rv = 0;

  ip6_address_decode (mp->ip, &ip6);

  if (ip6_address_is_zero (&ip6))
    {
      uword *p =
	hash_get (am->wc_ip6_nd_events_registration_hash, mp->client_index);
      vpe_client_registration_t *rp;
      if (p)
	{
	  if (mp->enable_disable)
	    {
	      clib_warning ("pid %d: already enabled...", mp->pid);
	      rv = VNET_API_ERROR_INVALID_REGISTRATION;
	      goto reply;
	    }
	  else
	    {
	      rp =
		pool_elt_at_index (am->wc_ip6_nd_events_registrations, p[0]);
	      pool_put (am->wc_ip6_nd_events_registrations, rp);
	      hash_unset (am->wc_ip6_nd_events_registration_hash,
			  mp->client_index);
	      if (pool_elts (am->wc_ip6_nd_events_registrations) == 0)
		wc_nd_set_publisher_node (~0, REPORT_MAX);
	      goto reply;
	    }
	}
      if (mp->enable_disable == 0)
	{
	  clib_warning ("pid %d: already disabled...", mp->pid);
	  rv = VNET_API_ERROR_INVALID_REGISTRATION;
	  goto reply;
	}
      pool_get (am->wc_ip6_nd_events_registrations, rp);
      rp->client_index = mp->client_index;
      rp->client_pid = mp->pid;
      hash_set (am->wc_ip6_nd_events_registration_hash, rp->client_index,
		rp - am->wc_ip6_nd_events_registrations);
      wc_nd_set_publisher_node (wc_arp_process_node.index, WC_ND_REPORT);
      goto reply;
    }

  if (mp->enable_disable)
    {
      vl_api_ip6_nd_event_t *event;
      pool_get (am->nd_events, event);

      rv = vnet_add_del_ip6_nd_change_event
	(vnm, nd_change_data_callback,
	 mp->pid, &ip6,
	 ip_resolver_process_node.index,
	 IP6_ND_EVENT, event - am->nd_events, 1 /* is_add */ );

      if (rv)
	{
	  pool_put (am->nd_events, event);
	  goto reply;
	}
      clib_memset (event, 0, sizeof (*event));

      event->_vl_msg_id = ntohs (VL_API_IP6_ND_EVENT);
      event->client_index = mp->client_index;
      ip6_address_encode (&ip6, event->ip);
      event->pid = mp->pid;
    }
  else
    {
      rv = vnet_add_del_ip6_nd_change_event
	(vnm, nd_change_delete_callback,
	 mp->pid, &ip6 /* addr, in net byte order */ ,
	 ip_resolver_process_node.index,
	 IP6_ND_EVENT, ~0 /* pool index */ , 0 /* is_add */ );
    }
reply:
  REPLY_MACRO (VL_API_WANT_IP6_ND_EVENTS_REPLY);
}

static clib_error_t *
want_ip6_nd_events_reaper (u32 client_index)
{

  vpe_client_registration_t *rp;
  vl_api_ip6_nd_event_t *event;
  u32 *to_delete, *event_id;
  vpe_api_main_t *am;
  vnet_main_t *vnm;
  uword *p;

  am = &vpe_api_main;
  vnm = vnet_get_main ();
  to_delete = NULL;

  /* clear out all of its pending resolutions */
  /* *INDENT-OFF* */
  pool_foreach(event, am->nd_events,
  ({
    if (event->client_index == client_index)
      {
        vec_add1(to_delete, event - am->nd_events);
      }
  }));
  /* *INDENT-ON* */

  vec_foreach (event_id, to_delete)
  {
    event = pool_elt_at_index (am->nd_events, *event_id);
    vnet_add_del_ip6_nd_change_event
      (vnm, nd_change_delete_callback,
       event->pid, event->ip,
       ip_resolver_process_node.index, IP6_ND_EVENT,
       ~0 /* pool index, notused */ , 0 /* is_add */ );
  }
  vec_free (to_delete);

  /* remove from the registration hash */
  p = hash_get (am->wc_ip6_nd_events_registration_hash, client_index);

  if (p)
    {
      rp = pool_elt_at_index (am->wc_ip6_nd_events_registrations, p[0]);
      pool_put (am->wc_ip6_nd_events_registrations, rp);
      hash_unset (am->wc_ip6_nd_events_registration_hash, client_index);
      if (pool_elts (am->wc_ip6_nd_events_registrations) == 0)
	wc_nd_set_publisher_node (~0, REPORT_MAX);
    }
  return (NULL);
}

VL_MSG_API_REAPER_FUNCTION (want_ip6_nd_events_reaper);

static void
vl_api_want_ip6_ra_events_t_handler (vl_api_want_ip6_ra_events_t * mp)
{
  vpe_api_main_t *am = &vpe_api_main;
  vl_api_want_ip6_ra_events_reply_t *rmp;
  int rv = 0;

  uword *p = hash_get (am->ip6_ra_events_registration_hash, mp->client_index);
  vpe_client_registration_t *rp;
  if (p)
    {
      if (mp->enable_disable)
	{
	  clib_warning ("pid %d: already enabled...", ntohl (mp->pid));
	  rv = VNET_API_ERROR_INVALID_REGISTRATION;
	  goto reply;
	}
      else
	{
	  rp = pool_elt_at_index (am->ip6_ra_events_registrations, p[0]);
	  pool_put (am->ip6_ra_events_registrations, rp);
	  hash_unset (am->ip6_ra_events_registration_hash, mp->client_index);
	  goto reply;
	}
    }
  if (mp->enable_disable == 0)
    {
      clib_warning ("pid %d: already disabled...", ntohl (mp->pid));
      rv = VNET_API_ERROR_INVALID_REGISTRATION;
      goto reply;
    }
  pool_get (am->ip6_ra_events_registrations, rp);
  rp->client_index = mp->client_index;
  rp->client_pid = ntohl (mp->pid);
  hash_set (am->ip6_ra_events_registration_hash, rp->client_index,
	    rp - am->ip6_ra_events_registrations);

reply:
  REPLY_MACRO (VL_API_WANT_IP6_RA_EVENTS_REPLY);
}

static clib_error_t *
want_ip6_ra_events_reaper (u32 client_index)
{
  vpe_api_main_t *am = &vpe_api_main;
  vpe_client_registration_t *rp;
  uword *p;

  p = hash_get (am->ip6_ra_events_registration_hash, client_index);

  if (p)
    {
      rp = pool_elt_at_index (am->ip6_ra_events_registrations, p[0]);
      pool_put (am->ip6_ra_events_registrations, rp);
      hash_unset (am->ip6_ra_events_registration_hash, client_index);
    }
  return (NULL);
}

VL_MSG_API_REAPER_FUNCTION (want_ip6_ra_events_reaper);

static void
vl_api_proxy_arp_add_del_t_handler (vl_api_proxy_arp_add_del_t * mp)
{
  vl_api_proxy_arp_add_del_reply_t *rmp;
  ip4_address_t lo, hi;
  u32 fib_index;
  int rv;

  fib_index = fib_table_find (FIB_PROTOCOL_IP4, ntohl (mp->proxy.table_id));

  if (~0 == fib_index)
    {
      rv = VNET_API_ERROR_NO_SUCH_FIB;
      goto out;
    }

  ip4_address_decode (mp->proxy.low, &lo);
  ip4_address_decode (mp->proxy.hi, &hi);

  rv = vnet_proxy_arp_add_del (&lo, &hi, fib_index, mp->is_add == 0);

out:
  REPLY_MACRO (VL_API_PROXY_ARP_ADD_DEL_REPLY);
}

typedef struct proxy_arp_walk_ctx_t_
{
  vl_api_registration_t *reg;
  u32 context;
} proxy_arp_walk_ctx_t;

static walk_rc_t
send_proxy_arp_details (const ip4_address_t * lo_addr,
			const ip4_address_t * hi_addr,
			u32 fib_index, void *data)
{
  vl_api_proxy_arp_details_t *mp;
  proxy_arp_walk_ctx_t *ctx;

  ctx = data;

  mp = vl_msg_api_alloc (sizeof (*mp));
  clib_memset (mp, 0, sizeof (*mp));
  mp->_vl_msg_id = ntohs (VL_API_PROXY_ARP_DETAILS);
  mp->context = ctx->context;
  mp->proxy.table_id = htonl (fib_index);

  ip4_address_encode (lo_addr, mp->proxy.low);
  ip4_address_encode (hi_addr, mp->proxy.hi);

  vl_api_send_msg (ctx->reg, (u8 *) mp);

  return (WALK_CONTINUE);
}

static void
vl_api_proxy_arp_dump_t_handler (vl_api_proxy_arp_dump_t * mp)
{
  vl_api_registration_t *reg;

  reg = vl_api_client_index_to_registration (mp->client_index);
  if (!reg)
    return;

  proxy_arp_walk_ctx_t wctx = {
    .reg = reg,
    .context = mp->context,
  };

  proxy_arp_walk (send_proxy_arp_details, &wctx);
}

static walk_rc_t
send_proxy_arp_intfc_details (u32 sw_if_index, void *data)
{
  vl_api_proxy_arp_intfc_details_t *mp;
  proxy_arp_walk_ctx_t *ctx;

  ctx = data;

  mp = vl_msg_api_alloc (sizeof (*mp));
  clib_memset (mp, 0, sizeof (*mp));
  mp->_vl_msg_id = ntohs (VL_API_PROXY_ARP_INTFC_DETAILS);
  mp->context = ctx->context;
  mp->sw_if_index = htonl (sw_if_index);

  vl_api_send_msg (ctx->reg, (u8 *) mp);

  return (WALK_CONTINUE);
}

static void
vl_api_proxy_arp_intfc_dump_t_handler (vl_api_proxy_arp_intfc_dump_t * mp)
{
  vl_api_registration_t *reg;

  reg = vl_api_client_index_to_registration (mp->client_index);
  if (!reg)
    return;

  proxy_arp_walk_ctx_t wctx = {
    .reg = reg,
    .context = mp->context,
  };

  proxy_arp_intfc_walk (send_proxy_arp_intfc_details, &wctx);
}

static void
  vl_api_proxy_arp_intfc_enable_disable_t_handler
  (vl_api_proxy_arp_intfc_enable_disable_t * mp)
{
  int rv = 0;
  vnet_main_t *vnm = vnet_get_main ();
  vl_api_proxy_arp_intfc_enable_disable_reply_t *rmp;

  VALIDATE_SW_IF_INDEX (mp);

  rv = vnet_proxy_arp_enable_disable (vnm,
				      ntohl (mp->sw_if_index),
				      mp->enable_disable);

  BAD_SW_IF_INDEX_LABEL;

  REPLY_MACRO (VL_API_PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY);
}

static void
vl_api_ip_probe_neighbor_t_handler (vl_api_ip_probe_neighbor_t * mp)
{
  int rv = 0;
  vlib_main_t *vm = vlib_get_main ();
  vl_api_ip_probe_neighbor_reply_t *rmp;
  clib_error_t *error;
  ip46_address_t dst;
  ip46_type_t itype;

  VALIDATE_SW_IF_INDEX (mp);

  u32 sw_if_index = ntohl (mp->sw_if_index);
  itype = ip_address_decode (&mp->dst, &dst);

  if (IP46_TYPE_IP6 == itype)
    error = ip6_probe_neighbor (vm, &dst.ip6, sw_if_index, 0);
  else
    error = ip4_probe_neighbor (vm, &dst.ip4, sw_if_index, 0);

  if (error)
    {
      clib_error_report (error);
      rv = clib_error_get_code (error);
    }

  BAD_SW_IF_INDEX_LABEL;

  REPLY_MACRO (VL_API_IP_PROBE_NEIGHBOR_REPLY);
}

static void
  vl_api_ip_scan_neighbor_enable_disable_t_handler
  (vl_api_ip_scan_neighbor_enable_disable_t * mp)
{
  int rv = 0;
  vl_api_ip_scan_neighbor_enable_disable_reply_t *rmp;
  ip_neighbor_scan_arg_t arg;

  arg.mode = mp->mode;
  arg.scan_interval = mp->scan_interval;
  arg.max_proc_time = mp->max_proc_time;
  arg.max_update = mp->max_update;
  arg.scan_int_delay = mp->scan_int_delay;
  arg.stale_threshold = mp->stale_threshold;
  ip_neighbor_scan_enable_disable (&arg);

  REPLY_MACRO (VL_API_IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY);
}

static int
ip4_reset_fib_t_handler (vl_api_reset_fib_t * mp)
{
  vnet_main_t *vnm = vnet_get_main ();
  vnet_interface_main_t *im = &vnm->interface_main;
  ip4_main_t *im4 = &ip4_main;
  static u32 *sw_if_indices_to_shut;
  fib_table_t *fib_table;
  ip4_fib_t *fib;
  u32 sw_if_index;
  int i;
  int rv = VNET_API_ERROR_NO_SUCH_FIB;
  u32 target_fib_id = ntohl (mp->vrf_id);

  /* *INDENT-OFF* */
  pool_foreach (fib_table, im4->fibs,
  ({
    vnet_sw_interface_t * si;

    fib = pool_elt_at_index (im4->v4_fibs, fib_table->ft_index);

    if (fib->table_id != target_fib_id)
      continue;

    /* remove any mpls encap/decap labels */
    mpls_fib_reset_labels (fib->table_id);

    /* remove any proxy arps in this fib */
    vnet_proxy_arp_fib_reset (fib->table_id);

    /* Set the flow hash for this fib to the default */
    vnet_set_ip4_flow_hash (fib->table_id, IP_FLOW_HASH_DEFAULT);

    vec_reset_length (sw_if_indices_to_shut);

    /* Shut down interfaces in this FIB / clean out intfc routes */
    pool_foreach (si, im->sw_interfaces,
    ({
      u32 sw_if_index = si->sw_if_index;

      if (sw_if_index < vec_len (im4->fib_index_by_sw_if_index)
          && (im4->fib_index_by_sw_if_index[si->sw_if_index] ==
              fib->index))
        vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
    }));

    for (i = 0; i < vec_len (sw_if_indices_to_shut); i++) {
      sw_if_index = sw_if_indices_to_shut[i];

      u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
      flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
      vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
    }

    fib_table_flush(fib->index, FIB_PROTOCOL_IP4, FIB_SOURCE_API);

    rv = 0;
    break;
    })); /* pool_foreach (fib) */
    /* *INDENT-ON* */

  return rv;
}

static int
ip6_reset_fib_t_handler (vl_api_reset_fib_t * mp)
{
  vnet_main_t *vnm = vnet_get_main ();
  vnet_interface_main_t *im = &vnm->interface_main;
  ip6_main_t *im6 = &ip6_main;
  static u32 *sw_if_indices_to_shut;
  fib_table_t *fib_table;
  ip6_fib_t *fib;
  u32 sw_if_index;
  int i;
  int rv = VNET_API_ERROR_NO_SUCH_FIB;
  u32 target_fib_id = ntohl (mp->vrf_id);

  /* *INDENT-OFF* */
  pool_foreach (fib_table, im6->fibs,
  ({
    vnet_sw_interface_t * si;

    fib = pool_elt_at_index (im6->v6_fibs, fib_table->ft_index);

    if (fib->table_id != target_fib_id)
      continue;

    vec_reset_length (sw_if_indices_to_shut);

    /* Set the flow hash for this fib to the default */
    vnet_set_ip6_flow_hash (fib->table_id, IP_FLOW_HASH_DEFAULT);

    /* Shut down interfaces in this FIB / clean out intfc routes */
    pool_foreach (si, im->sw_interfaces,
    ({
      if (im6->fib_index_by_sw_if_index[si->sw_if_index] ==
          fib->index)
        vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
    }));

    for (i = 0; i < vec_len (sw_if_indices_to_shut); i++) {
      sw_if_index = sw_if_indices_to_shut[i];

      u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
      flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
      vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
    }

    fib_table_flush(fib->index, FIB_PROTOCOL_IP6, FIB_SOURCE_API);

    rv = 0;
    break;
  })); /* pool_foreach (fib) */
  /* *INDENT-ON* */

  return rv;
}

static void
vl_api_reset_fib_t_handler (vl_api_reset_fib_t * mp)
{
  int rv;
  vl_api_reset_fib_reply_t *rmp;

  if (mp->is_ipv6)
    rv = ip6_reset_fib_t_handler (mp);
  else
    rv = ip4_reset_fib_t_handler (mp);

  REPLY_MACRO (VL_API_RESET_FIB_REPLY);
}

static void
vl_api_set_arp_neighbor_limit_t_handler (vl_api_set_arp_neighbor_limit_t * mp)
{
  int rv;
  vl_api_set_arp_neighbor_limit_reply_t *rmp;
  vnet_main_t *vnm = vnet_get_main ();
  clib_error_t *error;

  vnm->api_errno = 0;

  if (mp->is_ipv6)
    error = ip6_set_neighbor_limit (ntohl (mp->arp_neighbor_limit));
  else
    error = ip4_set_arp_limit (ntohl (mp->arp_neighbor_limit));

  if (error)
    {
      clib_error_report (error);
      rv = VNET_API_ERROR_UNSPECIFIED;
    }
  else
    {
      rv = vnm->api_errno;
    }

  REPLY_MACRO (VL_API_SET_ARP_NEIGHBOR_LIMIT_REPLY);
}

void
vl_api_ip_reassembly_set_t_handler (vl_api_ip_reassembly_set_t * mp)
{
  vl_api_ip_reassembly_set_reply_t *rmp;
  int rv = 0;
  switch ((vl_api_ip_reass_type_t) clib_net_to_host_u32 (mp->type))
    {
    case IP_REASS_TYPE_FULL:
      if (mp->is_ip6)
	{
	  rv = ip6_full_reass_set (clib_net_to_host_u32 (mp->timeout_ms),
				   clib_net_to_host_u32
				   (mp->max_reassemblies),
				   clib_net_to_host_u32
				   (mp->max_reassembly_length),
				   clib_net_to_host_u32
				   (mp->expire_walk_interval_ms));
	}
      else
	{
	  rv = ip4_full_reass_set (clib_net_to_host_u32 (mp->timeout_ms),
				   clib_net_to_host_u32
				   (mp->max_reassemblies),
				   clib_net_to_host_u32
				   (mp->max_reassembly_length),
				   clib_net_to_host_u32
				   (mp->expire_walk_interval_ms));
	}
      break;
    case IP_REASS_TYPE_SHALLOW_VIRTUAL:
      if (mp->is_ip6)
	{
	  rv =
	    ip6_sv_reass_set (clib_net_to_host_u32 (mp->timeout_ms),
			      clib_net_to_host_u32 (mp->max_reassemblies),
			      clib_net_to_host_u32
			      (mp->max_reassembly_length),
			      clib_net_to_host_u32
			      (mp->expire_walk_interval_ms));
	}
      else
	{
	  rv = ip4_sv_reass_set (clib_net_to_host_u32 (mp->timeout_ms),
				 clib_net_to_host_u32 (mp->max_reassemblies),
				 clib_net_to_host_u32
				 (mp->max_reassembly_length),
				 clib_net_to_host_u32
				 (mp->expire_walk_interval_ms));
	}
      break;
    }

  REPLY_MACRO (VL_API_IP_REASSEMBLY_SET_REPLY);
}

void
vl_api_ip_reassembly_get_t_handler (vl_api_ip_reassembly_get_t * mp)
{
  vl_api_registration_t *rp;

  rp = vl_api_client_index_to_registration (mp->client_index);
  if (rp == 0)
    return;

  vl_api_ip_reassembly_get_reply_t *rmp = vl_msg_api_alloc (sizeof (*rmp));
  clib_memset (rmp, 0, sizeof (*rmp));
  rmp->_vl_msg_id = ntohs (VL_API_IP_REASSEMBLY_GET_REPLY);
  rmp->context = mp->context;
  rmp->retval = 0;
  u32 timeout_ms;
  u32 max_reassemblies;
  u32 max_reassembly_length;
  u32 expire_walk_interval_ms;
  switch ((vl_api_ip_reass_type_t) clib_net_to_host_u32 (mp->type))
    {
    case IP_REASS_TYPE_FULL:
      if (mp->is_ip6)
	{
	  rmp->is_ip6 = 1;
	  ip6_full_reass_get (&timeout_ms, &max_reassemblies,
			      &max_reassembly_length,
			      &expire_walk_interval_ms);
	}
      else
	{
	  rmp->is_ip6 = 0;
	  ip4_full_reass_get (&timeout_ms, &max_reassemblies,
			      &max_reassembly_length,
			      &expire_walk_interval_ms);
	}
      break;
    case IP_REASS_TYPE_SHALLOW_VIRTUAL:
      if (mp->is_ip6)
	{
	  rmp->is_ip6 = 1;
	  ip6_sv_reass_get (&timeout_ms, &max_reassemblies,
			    &max_reassembly_length, &expire_walk_interval_ms);
	}
      else
	{
	  rmp->is_ip6 = 0;
	  ip4_sv_reass_get (&timeout_ms, &max_reassemblies,
			    &max_reassembly_length, &expire_walk_interval_ms);
	}
      break;
    }
  rmp->timeout_ms = clib_host_to_net_u32 (rmp->timeout_ms);
  rmp->max_reassemblies = clib_host_to_net_u32 (rmp->max_reassemblies);
  rmp->expire_walk_interval_ms =
    clib_host_to_net_u32 (rmp->expire_walk_interval_ms);
  vl_api_send_msg (rp, (u8 *) rmp);
}

void
  vl_api_ip_reassembly_enable_disable_t_handler
  (vl_api_ip_reassembly_enable_disable_t * mp)
{
  vl_api_ip_reassembly_enable_disable_reply_t *rmp;
  int rv = 0;
  switch ((vl_api_ip_reass_type_t) clib_net_to_host_u32 (mp->type))
    {
    case IP_REASS_TYPE_FULL:
      rv =
	ip4_full_reass_enable_disable (clib_net_to_host_u32 (mp->sw_if_index),
				       mp->enable_ip4);
      if (0 == rv)
	rv =
	  ip6_full_reass_enable_disable (clib_net_to_host_u32
					 (mp->sw_if_index), mp->enable_ip6);
      break;
    case IP_REASS_TYPE_SHALLOW_VIRTUAL:
      rv =
	ip4_sv_reass_enable_disable (clib_net_to_host_u32 (mp->sw_if_index),
				     mp->enable_ip4);
      if (0 == rv)
	{
	  rv =
	    ip6_sv_reass_enable_disable (clib_net_to_host_u32
					 (mp->sw_if_index), mp->enable_ip6);
	}
      break;
    }

  REPLY_MACRO (VL_API_IP_REASSEMBLY_ENABLE_DISABLE_REPLY);
}

typedef struct ip_punt_redirect_walk_ctx_t_
{
  vl_api_registration_t *reg;
  u32 context;
} ip_punt_redirect_walk_ctx_t;

static walk_rc_t
send_ip_punt_redirect_details (u32 rx_sw_if_index,
			       const ip_punt_redirect_rx_t * ipr, void *arg)
{
  ip_punt_redirect_walk_ctx_t *ctx = arg;
  vl_api_ip_punt_redirect_details_t *mp;
  fib_path_encode_ctx_t path_ctx = {
    .rpaths = NULL,
  };

  mp = vl_msg_api_alloc (sizeof (*mp));
  if (!mp)
    return (WALK_STOP);;

  clib_memset (mp, 0, sizeof (*mp));
  mp->_vl_msg_id = ntohs (VL_API_IP_PUNT_REDIRECT_DETAILS);
  mp->context = ctx->context;

  fib_path_list_walk_w_ext (ipr->pl, NULL, fib_path_encode, &path_ctx);

  mp->punt.rx_sw_if_index = htonl (rx_sw_if_index);
  mp->punt.tx_sw_if_index = htonl (path_ctx.rpaths[0].frp_sw_if_index);

  ip_address_encode (&path_ctx.rpaths[0].frp_addr,
		     fib_proto_to_ip46 (ipr->fproto), &mp->punt.nh);

  vl_api_send_msg (ctx->reg, (u8 *) mp);

  vec_free (path_ctx.rpaths);

  return (WALK_CONTINUE);
}

static void
vl_api_ip_punt_redirect_dump_t_handler (vl_api_ip_punt_redirect_dump_t * mp)
{
  vl_api_registration_t *reg;
  fib_protocol_t fproto;

  reg = vl_api_client_index_to_registration (mp->client_index);
  if (!reg)
    return;

  fproto = mp->is_ipv6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4;

  ip_punt_redirect_walk_ctx_t ctx = {
    .reg = reg,
    .context = mp->context,
  };

  if (~0 != mp->sw_if_index)
    {
      u32 rx_sw_if_index;
      index_t pri;

      rx_sw_if_index = ntohl (mp->sw_if_index);
      pri = ip_punt_redirect_find (fproto, rx_sw_if_index);

      if (INDEX_INVALID == pri)
	return;

      send_ip_punt_redirect_details (rx_sw_if_index,
				     ip_punt_redirect_get (pri), &ctx);
    }
  else
    ip_punt_redirect_walk (fproto, send_ip_punt_redirect_details, &ctx);
}

#define vl_msg_name_crc_list
#include <vnet/ip/ip.api.h>
#undef vl_msg_name_crc_list

static void
setup_message_id_table (api_main_t * am)
{
#define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
  foreach_vl_msg_name_crc_ip;
#undef _
}

static clib_error_t *
ip_api_hookup (vlib_main_t * vm)
{
  api_main_t *am = &api_main;

#define _(N,n)                                                  \
    vl_msg_api_set_handlers(VL_API_##N, #n,                     \
                           vl_api_##n##_t_handler,              \
                           vl_noop_handler,                     \
                           vl_api_##n##_t_endian,               \
                           vl_api_##n##_t_print,                \
                           sizeof(vl_api_##n##_t), 1);
  foreach_ip_api_msg;
#undef _

  /*
   * Mark the route add/del API as MP safe
   */
  am->is_mp_safe[VL_API_IP_ROUTE_ADD_DEL] = 1;
  am->is_mp_safe[VL_API_IP_ROUTE_ADD_DEL_REPLY] = 1;

  /*
   * Set up the (msg_name, crc, message-id) table
   */
  setup_message_id_table (am);

  ra_set_publisher_node (wc_arp_process_node.index, RA_REPORT);

  return 0;
}

VLIB_API_INIT_FUNCTION (ip_api_hookup);

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