/*
 * 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.
 */

/**
 * @file
 * @brief Common utility functions for LISP-GPE interfaces.
 *
 */

#include <vppinfra/error.h>
#include <vppinfra/hash.h>
#include <vnet/vnet.h>
#include <vnet/ip/ip.h>
#include <vnet/udp/udp.h>
#include <vnet/ethernet/ethernet.h>
#include <vnet/lisp-gpe/lisp_gpe.h>
#include <vnet/lisp-gpe/lisp_gpe_fwd_entry.h>
#include <vnet/lisp-gpe/lisp_gpe_tenant.h>
#include <vnet/lisp-gpe/lisp_gpe_adjacency.h>
#include <vnet/adj/adj.h>
#include <vnet/fib/fib_table.h>
#include <vnet/fib/ip4_fib.h>
#include <vnet/fib/ip6_fib.h>
#include <vnet/lisp-cp/lisp_cp_dpo.h>

/**
 * @brief The VLIB node arc/edge from the interface's TX node, to the L2
 * load-balanceing node. Which is where all packets go
 */
static uword l2_arc_to_lb;

#define foreach_lisp_gpe_tx_next        \
  _(DROP, "error-drop")                 \
  _(IP4_LOOKUP, "ip4-lookup")           \
  _(IP6_LOOKUP, "ip6-lookup")

typedef enum
{
#define _(sym,str) LISP_GPE_TX_NEXT_##sym,
  foreach_lisp_gpe_tx_next
#undef _
    LISP_GPE_TX_N_NEXT,
} lisp_gpe_tx_next_t;

typedef struct
{
  u32 tunnel_index;
} lisp_gpe_tx_trace_t;

u8 *
format_lisp_gpe_tx_trace (u8 * s, va_list * args)
{
  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
  lisp_gpe_tx_trace_t *t = va_arg (*args, lisp_gpe_tx_trace_t *);

  s = format (s, "LISP-GPE-TX: tunnel %d", t->tunnel_index);
  return s;
}

#define is_v4_packet(_h) ((*(u8*) _h) & 0xF0) == 0x40

/**
 * @brief LISP-GPE interface TX (encap) function.
 * @node lisp_gpe_interface_tx
 *
 * The LISP-GPE interface TX (encap) function.
 *
 * Looks up the associated tunnel based on the adjacency hit in the SD FIB
 * and if the tunnel is multihomed it uses the flow hash to determine
 * sub-tunnel, and rewrite string, to be used to encapsulate the packet.
 *
 * @param[in]   vm      vlib_main_t corresponding to the current thread.
 * @param[in]   node    vlib_node_runtime_t data for this node.
 * @param[in]   frame   vlib_frame_t whose contents should be dispatched.
 *
 * @return number of vectors in frame.
 */
static uword
lisp_gpe_interface_tx (vlib_main_t * vm, vlib_node_runtime_t * node,
		       vlib_frame_t * from_frame)
{
  u32 n_left_from, next_index, *from, *to_next;
  lisp_gpe_main_t *lgm = &lisp_gpe_main;

  from = vlib_frame_vector_args (from_frame);
  n_left_from = from_frame->n_vectors;

  next_index = node->cached_next_index;

  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)
	{
	  u32 bi0, adj_index0, next0;
	  const ip_adjacency_t *adj0;
	  const dpo_id_t *dpo0;
	  vlib_buffer_t *b0;
	  u8 is_v4_0;

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

	  b0 = vlib_get_buffer (vm, bi0);

	  /* Fixup the checksum and len fields in the LISP tunnel encap
	   * that was applied at the midchain node */
	  is_v4_0 = is_v4_packet (vlib_buffer_get_current (b0));
	  ip_udp_fixup_one (lgm->vlib_main, b0, is_v4_0);

	  /* Follow the DPO on which the midchain is stacked */
	  adj_index0 = vnet_buffer (b0)->ip.adj_index[VLIB_TX];
	  adj0 = adj_get (adj_index0);
	  dpo0 = &adj0->sub_type.midchain.next_dpo;
	  next0 = dpo0->dpoi_next_node;
	  vnet_buffer (b0)->ip.adj_index[VLIB_TX] = dpo0->dpoi_index;

	  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
	    {
	      lisp_gpe_tx_trace_t *tr = vlib_add_trace (vm, node, b0,
							sizeof (*tr));
	      tr->tunnel_index = adj_index0;
	    }
	  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
					   n_left_to_next, bi0, next0);
	}

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

  return from_frame->n_vectors;
}

static u8 *
format_lisp_gpe_name (u8 * s, va_list * args)
{
  u32 dev_instance = va_arg (*args, u32);
  return format (s, "lisp_gpe%d", dev_instance);
}

/* *INDENT-OFF* */
VNET_DEVICE_CLASS (lisp_gpe_device_class) = {
  .name = "LISP_GPE",
  .format_device_name = format_lisp_gpe_name,
  .format_tx_trace = format_lisp_gpe_tx_trace,
  .tx_function = lisp_gpe_interface_tx,
};
/* *INDENT-ON* */

u8 *
format_lisp_gpe_header_with_length (u8 * s, va_list * args)
{
  lisp_gpe_header_t *h = va_arg (*args, lisp_gpe_header_t *);
  u32 max_header_bytes = va_arg (*args, u32);
  u32 header_bytes;

  header_bytes = sizeof (h[0]);
  if (max_header_bytes != 0 && header_bytes > max_header_bytes)
    return format (s, "lisp-gpe header truncated");

  s = format (s, "flags: ");
#define _(n,v) if (h->flags & v) s = format (s, "%s ", #n);
  foreach_lisp_gpe_flag_bit;
#undef _

  s = format (s, "\n  ver_res %d res %d next_protocol %d iid %d(%x)",
	      h->ver_res, h->res, h->next_protocol,
	      clib_net_to_host_u32 (h->iid << 8),
	      clib_net_to_host_u32 (h->iid << 8));
  return s;
}

/* *INDENT-OFF* */
VNET_HW_INTERFACE_CLASS (lisp_gpe_hw_class) = {
  .name = "LISP_GPE",
  .format_header = format_lisp_gpe_header_with_length,
  .build_rewrite = lisp_gpe_build_rewrite,
  .update_adjacency = lisp_gpe_update_adjacency,
};
/* *INDENT-ON* */


typedef struct
{
  u32 dpo_index;
} l2_lisp_gpe_tx_trace_t;

static u8 *
format_l2_lisp_gpe_tx_trace (u8 * s, va_list * args)
{
  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
  l2_lisp_gpe_tx_trace_t *t = va_arg (*args, l2_lisp_gpe_tx_trace_t *);

  s = format (s, "L2-LISP-GPE-TX: load-balance %d", t->dpo_index);
  return s;
}

/**
 * @brief LISP-GPE interface TX (encap) function for L2 overlays.
 * @node l2_lisp_gpe_interface_tx
 *
 * The L2 LISP-GPE interface TX (encap) function.
 *
 * Uses bridge domain index, source and destination ethernet addresses to
 * lookup tunnel. If the tunnel is multihomed a flow has is used to determine
 * the sub-tunnel and therefore the rewrite string to be used to encapsulate
 * the packets.
 *
 * @param[in]   vm        vlib_main_t corresponding to the current thread.
 * @param[in]   node      vlib_node_runtime_t data for this node.
 * @param[in]   frame     vlib_frame_t whose contents should be dispatched.
 *
 * @return number of vectors in frame.
 */
static uword
l2_lisp_gpe_interface_tx (vlib_main_t * vm, vlib_node_runtime_t * node,
			  vlib_frame_t * from_frame)
{
  u32 n_left_from, next_index, *from, *to_next;
  lisp_gpe_main_t *lgm = &lisp_gpe_main;
  u32 thread_index = vlib_get_thread_index ();
  vlib_combined_counter_main_t *cm = &load_balance_main.lbm_to_counters;

  from = vlib_frame_vector_args (from_frame);
  n_left_from = from_frame->n_vectors;

  next_index = node->cached_next_index;

  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 *b0;
	  u32 bi0, lbi0;
	  ethernet_header_t *e0;

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

	  b0 = vlib_get_buffer (vm, bi0);
	  e0 = vlib_buffer_get_current (b0);

	  vnet_buffer (b0)->lisp.overlay_afi = LISP_AFI_MAC;

	  /* lookup dst + src mac */
	  lbi0 = lisp_l2_fib_lookup (lgm, vnet_buffer (b0)->l2.bd_index,
				     e0->src_address, e0->dst_address);
	  vnet_buffer (b0)->ip.adj_index[VLIB_TX] = lbi0;

	  vlib_increment_combined_counter (cm, thread_index, lbi0, 1,
					   vlib_buffer_length_in_chain (vm,
									b0));
	  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
	    {
	      l2_lisp_gpe_tx_trace_t *tr = vlib_add_trace (vm, node, b0,
							   sizeof (*tr));
	      tr->dpo_index = lbi0;
	    }
	  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
					   n_left_to_next, bi0, l2_arc_to_lb);
	}

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

  return from_frame->n_vectors;
}

static u8 *
format_l2_lisp_gpe_name (u8 * s, va_list * args)
{
  u32 dev_instance = va_arg (*args, u32);
  return format (s, "l2_lisp_gpe%d", dev_instance);
}

/* *INDENT-OFF* */
VNET_DEVICE_CLASS (l2_lisp_gpe_device_class,static) = {
  .name = "L2_LISP_GPE",
  .format_device_name = format_l2_lisp_gpe_name,
  .format_tx_trace = format_l2_lisp_gpe_tx_trace,
  .tx_function = l2_lisp_gpe_interface_tx,
};
/* *INDENT-ON* */

typedef struct
{
  u32 dpo_index;
} nsh_lisp_gpe_tx_trace_t;

u8 *
format_nsh_lisp_gpe_tx_trace (u8 * s, va_list * args)
{
  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
  nsh_lisp_gpe_tx_trace_t *t = va_arg (*args, nsh_lisp_gpe_tx_trace_t *);

  s = format (s, "NSH-GPE-TX: tunnel %d", t->dpo_index);
  return s;
}

/**
 * @brief LISP-GPE interface TX for NSH overlays.
 * @node nsh_lisp_gpe_interface_tx
 *
 * The NSH LISP-GPE interface TX function.
 *
 * @param[in]   vm        vlib_main_t corresponding to the current thread.
 * @param[in]   node      vlib_node_runtime_t data for this node.
 * @param[in]   frame     vlib_frame_t whose contents should be dispatched.
 *
 * @return number of vectors in frame.
 */
static uword
nsh_lisp_gpe_interface_tx (vlib_main_t * vm, vlib_node_runtime_t * node,
			   vlib_frame_t * from_frame)
{
  u32 n_left_from, next_index, *from, *to_next;
  lisp_gpe_main_t *lgm = &lisp_gpe_main;

  from = vlib_frame_vector_args (from_frame);
  n_left_from = from_frame->n_vectors;

  next_index = node->cached_next_index;

  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 *b0;
	  u32 bi0;
	  u32 *nsh0, next0;
	  const dpo_id_t *dpo0;

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

	  b0 = vlib_get_buffer (vm, bi0);
	  nsh0 = vlib_buffer_get_current (b0);

	  vnet_buffer (b0)->lisp.overlay_afi = LISP_AFI_LCAF;

	  /* lookup SPI + SI (second word of the NSH header).
	   * NB: Load balancing was done by the control plane */
	  dpo0 = lisp_nsh_fib_lookup (lgm, nsh0[1]);

	  next0 = dpo0->dpoi_next_node;
	  vnet_buffer (b0)->ip.adj_index[VLIB_TX] = dpo0->dpoi_index;

	  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
	    {
	      nsh_lisp_gpe_tx_trace_t *tr = vlib_add_trace (vm, node, b0,
							    sizeof (*tr));
	      tr->dpo_index = dpo0->dpoi_index;
	    }
	  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
					   n_left_to_next, bi0, next0);
	}

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

  return from_frame->n_vectors;
}

static u8 *
format_nsh_lisp_gpe_name (u8 * s, va_list * args)
{
  u32 dev_instance = va_arg (*args, u32);
  return format (s, "nsh_lisp_gpe%d", dev_instance);
}

/* *INDENT-OFF* */
VNET_DEVICE_CLASS (nsh_lisp_gpe_device_class,static) = {
  .name = "NSH_LISP_GPE",
  .format_device_name = format_nsh_lisp_gpe_name,
  .format_tx_trace = format_nsh_lisp_gpe_tx_trace,
  .tx_function = nsh_lisp_gpe_interface_tx,
};
/* *INDENT-ON* */

static vnet_hw_interface_t *
lisp_gpe_create_iface (lisp_gpe_main_t * lgm, u32 vni, u32 dp_table,
		       vnet_device_class_t * dev_class,
		       tunnel_lookup_t * tuns)
{
  u32 flen;
  u32 hw_if_index = ~0;
  u8 *new_name;
  vnet_hw_interface_t *hi;
  vnet_main_t *vnm = lgm->vnet_main;

  /* create hw lisp_gpeX iface if needed, otherwise reuse existing */
  flen = vec_len (lgm->free_tunnel_hw_if_indices);
  if (flen > 0)
    {
      hw_if_index = lgm->free_tunnel_hw_if_indices[flen - 1];
      _vec_len (lgm->free_tunnel_hw_if_indices) -= 1;

      hi = vnet_get_hw_interface (vnm, hw_if_index);

      /* rename interface */
      new_name = format (0, "%U", dev_class->format_device_name, vni);

      vec_add1 (new_name, 0);
      vnet_rename_interface (vnm, hw_if_index, (char *) new_name);
      vec_free (new_name);

      /* clear old stats of freed interface before reuse */
      vnet_interface_main_t *im = &vnm->interface_main;
      vnet_interface_counter_lock (im);
      vlib_zero_combined_counter (&im->combined_sw_if_counters
				  [VNET_INTERFACE_COUNTER_TX],
				  hi->sw_if_index);
      vlib_zero_combined_counter (&im->combined_sw_if_counters
				  [VNET_INTERFACE_COUNTER_RX],
				  hi->sw_if_index);
      vlib_zero_simple_counter (&im->sw_if_counters
				[VNET_INTERFACE_COUNTER_DROP],
				hi->sw_if_index);
      vnet_interface_counter_unlock (im);
    }
  else
    {
      hw_if_index = vnet_register_interface (vnm, dev_class->index, vni,
					     lisp_gpe_hw_class.index, 0);
      hi = vnet_get_hw_interface (vnm, hw_if_index);
    }

  hash_set (tuns->hw_if_index_by_dp_table, dp_table, hw_if_index);

  /* set tunnel termination: post decap, packets are tagged as having been
   * originated by lisp-gpe interface */
  hash_set (tuns->sw_if_index_by_vni, vni, hi->sw_if_index);
  hash_set (tuns->vni_by_sw_if_index, hi->sw_if_index, vni);

  return hi;
}

static void
lisp_gpe_remove_iface (lisp_gpe_main_t * lgm, u32 hi_index, u32 dp_table,
		       tunnel_lookup_t * tuns)
{
  vnet_main_t *vnm = lgm->vnet_main;
  vnet_hw_interface_t *hi;
  uword *vnip;

  hi = vnet_get_hw_interface (vnm, hi_index);

  /* disable interface */
  vnet_sw_interface_set_flags (vnm, hi->sw_if_index, 0 /* down */ );
  vnet_hw_interface_set_flags (vnm, hi->hw_if_index, 0 /* down */ );
  hash_unset (tuns->hw_if_index_by_dp_table, dp_table);
  vec_add1 (lgm->free_tunnel_hw_if_indices, hi->hw_if_index);

  /* clean tunnel termination and vni to sw_if_index binding */
  vnip = hash_get (tuns->vni_by_sw_if_index, hi->sw_if_index);
  if (0 == vnip)
    {
      clib_warning ("No vni associated to interface %d", hi->sw_if_index);
      return;
    }
  hash_unset (tuns->sw_if_index_by_vni, vnip[0]);
  hash_unset (tuns->vni_by_sw_if_index, hi->sw_if_index);
}

static void
lisp_gpe_iface_set_table (u32 sw_if_index, u32 table_id)
{
  fib_node_index_t fib_index;

  fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, table_id,
						 FIB_SOURCE_LISP);
  vec_validate (ip4_main.fib_index_by_sw_if_index, sw_if_index);
  ip4_main.fib_index_by_sw_if_index[sw_if_index] = fib_index;
  ip4_sw_interface_enable_disable (sw_if_index, 1);

  fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, table_id,
						 FIB_SOURCE_LISP);
  vec_validate (ip6_main.fib_index_by_sw_if_index, sw_if_index);
  ip6_main.fib_index_by_sw_if_index[sw_if_index] = fib_index;
  ip6_sw_interface_enable_disable (sw_if_index, 1);
}

static void
lisp_gpe_tenant_del_default_routes (u32 table_id)
{
  fib_protocol_t proto;

  FOR_EACH_FIB_IP_PROTOCOL (proto)
  {
    fib_prefix_t prefix = {
      .fp_proto = proto,
    };
    u32 fib_index;

    fib_index = fib_table_find (prefix.fp_proto, table_id);
    fib_table_entry_special_remove (fib_index, &prefix, FIB_SOURCE_LISP);
    fib_table_unlock (fib_index, prefix.fp_proto, FIB_SOURCE_LISP);
  }
}

static void
lisp_gpe_tenant_add_default_routes (u32 table_id)
{
  fib_protocol_t proto;

  FOR_EACH_FIB_IP_PROTOCOL (proto)
  {
    fib_prefix_t prefix = {
      .fp_proto = proto,
    };
    u32 fib_index;

    /*
     * Add a deafult route that results in a control plane punt DPO
     */
    fib_index = fib_table_find_or_create_and_lock (prefix.fp_proto, table_id,
						   FIB_SOURCE_LISP);
    fib_table_entry_special_dpo_add (fib_index, &prefix, FIB_SOURCE_LISP,
				     FIB_ENTRY_FLAG_EXCLUSIVE,
				     lisp_cp_dpo_get (fib_proto_to_dpo
						      (proto)));
  }
}


/**
 * @brief Add/del LISP-GPE L3 interface.
 *
 * Creates LISP-GPE interface, sets ingress arcs from lisp_gpeX_lookup,
 * installs default routes that attract all traffic with no more specific
 * routes to lgpe-ipx-lookup, set egress arcs to ipx-lookup, sets
 * the interface in the right vrf and enables it.
 *
 * @param[in]   lgm     Reference to @ref lisp_gpe_main_t.
 * @param[in]   a       Parameters to create interface.
 *
 * @return number of vectors in frame.
 */
u32
lisp_gpe_add_l3_iface (lisp_gpe_main_t * lgm, u32 vni, u32 table_id)
{
  vnet_main_t *vnm = lgm->vnet_main;
  tunnel_lookup_t *l3_ifaces = &lgm->l3_ifaces;
  vnet_hw_interface_t *hi;
  uword *hip, *si;

  hip = hash_get (l3_ifaces->hw_if_index_by_dp_table, table_id);

  if (hip)
    {
      clib_warning ("vrf %d already mapped to a vni", table_id);
      return ~0;
    }

  si = hash_get (l3_ifaces->sw_if_index_by_vni, vni);

  if (si)
    {
      clib_warning ("Interface for vni %d already exists", vni);
    }

  /* create lisp iface and populate tunnel tables */
  hi = lisp_gpe_create_iface (lgm, vni, table_id,
			      &lisp_gpe_device_class, l3_ifaces);

  /* insert default routes that point to lisp-cp lookup */
  lisp_gpe_iface_set_table (hi->sw_if_index, table_id);
  lisp_gpe_tenant_add_default_routes (table_id);

  /* enable interface */
  vnet_sw_interface_set_flags (vnm, hi->sw_if_index,
			       VNET_SW_INTERFACE_FLAG_ADMIN_UP);
  vnet_hw_interface_set_flags (vnm, hi->hw_if_index,
			       VNET_HW_INTERFACE_FLAG_LINK_UP);

  return (hi->sw_if_index);
}

void
lisp_gpe_del_l3_iface (lisp_gpe_main_t * lgm, u32 vni, u32 table_id)
{
  vnet_main_t *vnm = lgm->vnet_main;
  tunnel_lookup_t *l3_ifaces = &lgm->l3_ifaces;
  vnet_hw_interface_t *hi;
  uword *hip;

  hip = hash_get (l3_ifaces->hw_if_index_by_dp_table, table_id);

  if (hip == 0)
    {
      clib_warning ("The interface for vrf %d doesn't exist", table_id);
      return;
    }

  hi = vnet_get_hw_interface (vnm, hip[0]);

  lisp_gpe_remove_iface (lgm, hip[0], table_id, &lgm->l3_ifaces);

  /* unset default routes */
  ip4_sw_interface_enable_disable (hi->sw_if_index, 0);
  ip6_sw_interface_enable_disable (hi->sw_if_index, 0);
  lisp_gpe_tenant_del_default_routes (table_id);
}

/**
 * @brief Add/del LISP-GPE L2 interface.
 *
 * Creates LISP-GPE interface, sets it in L2 mode in the appropriate
 * bridge domain, sets egress arcs and enables it.
 *
 * @param[in]   lgm     Reference to @ref lisp_gpe_main_t.
 * @param[in]   a       Parameters to create interface.
 *
 * @return number of vectors in frame.
 */
u32
lisp_gpe_add_l2_iface (lisp_gpe_main_t * lgm, u32 vni, u32 bd_id)
{
  vnet_main_t *vnm = lgm->vnet_main;
  tunnel_lookup_t *l2_ifaces = &lgm->l2_ifaces;
  vnet_hw_interface_t *hi;
  uword *hip, *si;
  u16 bd_index;

  if (bd_id > L2_BD_ID_MAX)
    {
      clib_warning ("bridge domain ID %d exceed 16M limit", bd_id);
      return ~0;
    }

  bd_index = bd_find_or_add_bd_index (&bd_main, bd_id);
  hip = hash_get (l2_ifaces->hw_if_index_by_dp_table, bd_index);

  if (hip)
    {
      clib_warning ("bridge domain %d already mapped to a vni", bd_id);
      return ~0;
    }

  si = hash_get (l2_ifaces->sw_if_index_by_vni, vni);
  if (si)
    {
      clib_warning ("Interface for vni %d already exists", vni);
      return ~0;
    }

  /* create lisp iface and populate tunnel tables */
  hi = lisp_gpe_create_iface (lgm, vni, bd_index,
			      &l2_lisp_gpe_device_class, &lgm->l2_ifaces);

  /* enable interface */
  vnet_sw_interface_set_flags (vnm, hi->sw_if_index,
			       VNET_SW_INTERFACE_FLAG_ADMIN_UP);
  vnet_hw_interface_set_flags (vnm, hi->hw_if_index,
			       VNET_HW_INTERFACE_FLAG_LINK_UP);

  l2_arc_to_lb = vlib_node_add_named_next (vlib_get_main (),
					   hi->tx_node_index,
					   "l2-load-balance");

  /* we're ready. add iface to l2 bridge domain */
  set_int_l2_mode (lgm->vlib_main, vnm, MODE_L2_BRIDGE, hi->sw_if_index,
		   bd_index, 0, 0, 0);

  return (hi->sw_if_index);
}

/**
 * @brief Add/del LISP-GPE L2 interface.
 *
 * Creates LISP-GPE interface, sets it in L2 mode in the appropriate
 * bridge domain, sets egress arcs and enables it.
 *
 * @param[in]   lgm     Reference to @ref lisp_gpe_main_t.
 * @param[in]   a       Parameters to create interface.
 *
 * @return number of vectors in frame.
 */
void
lisp_gpe_del_l2_iface (lisp_gpe_main_t * lgm, u32 vni, u32 bd_id)
{
  tunnel_lookup_t *l2_ifaces = &lgm->l2_ifaces;
  vnet_hw_interface_t *hi;

  u32 bd_index = bd_find_index (&bd_main, bd_id);
  ASSERT (bd_index != ~0);
  uword *hip = hash_get (l2_ifaces->hw_if_index_by_dp_table, bd_index);

  if (hip == 0)
    {
      clib_warning ("The interface for bridge domain %d doesn't exist",
		    bd_id);
      return;
    }

  /* Remove interface from bridge .. by enabling L3 mode */
  hi = vnet_get_hw_interface (lgm->vnet_main, hip[0]);
  set_int_l2_mode (lgm->vlib_main, lgm->vnet_main, MODE_L3, hi->sw_if_index,
		   0, 0, 0, 0);
  lisp_gpe_remove_iface (lgm, hip[0], bd_index, &lgm->l2_ifaces);
}

/**
 * @brief Add LISP-GPE NSH interface.
 *
 * Creates LISP-GPE interface, sets it in L3 mode.
 *
 * @param[in]   lgm     Reference to @ref lisp_gpe_main_t.
 * @param[in]   a       Parameters to create interface.
 *
 * @return sw_if_index.
 */
u32
vnet_lisp_gpe_add_nsh_iface (lisp_gpe_main_t * lgm)
{
  vnet_main_t *vnm = lgm->vnet_main;
  tunnel_lookup_t *nsh_ifaces = &lgm->nsh_ifaces;
  vnet_hw_interface_t *hi;
  uword *hip, *si;

  hip = hash_get (nsh_ifaces->hw_if_index_by_dp_table, 0);

  if (hip)
    {
      clib_warning ("NSH interface 0 already exists");
      return ~0;
    }

  si = hash_get (nsh_ifaces->sw_if_index_by_vni, 0);
  if (si)
    {
      clib_warning ("NSH interface already exists");
      return ~0;
    }

  /* create lisp iface and populate tunnel tables */
  hi = lisp_gpe_create_iface (lgm, 0, 0,
			      &nsh_lisp_gpe_device_class, &lgm->nsh_ifaces);

  /* enable interface */
  vnet_sw_interface_set_flags (vnm, hi->sw_if_index,
			       VNET_SW_INTERFACE_FLAG_ADMIN_UP);
  vnet_hw_interface_set_flags (vnm, hi->hw_if_index,
			       VNET_HW_INTERFACE_FLAG_LINK_UP);

  return (hi->sw_if_index);
}

/**
 * @brief Del LISP-GPE NSH interface.
 *
 */
void
vnet_lisp_gpe_del_nsh_iface (lisp_gpe_main_t * lgm)
{
  tunnel_lookup_t *nsh_ifaces = &lgm->nsh_ifaces;
  uword *hip;

  hip = hash_get (nsh_ifaces->hw_if_index_by_dp_table, 0);

  if (hip == 0)
    {
      clib_warning ("The NSH 0 interface doesn't exist");
      return;
    }
  lisp_gpe_remove_iface (lgm, hip[0], 0, &lgm->nsh_ifaces);
}

static clib_error_t *
lisp_gpe_add_del_iface_command_fn (vlib_main_t * vm, unformat_input_t * input,
				   vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  u8 is_add = 1;
  u32 table_id, vni, bd_id;
  u8 vni_is_set = 0, vrf_is_set = 0, bd_index_is_set = 0;
  u8 nsh_iface = 0;
  clib_error_t *error = NULL;

  if (vnet_lisp_gpe_enable_disable_status () == 0)
    {
      return clib_error_return (0, "LISP is disabled");
    }

  /* Get a line of input. */
  if (!unformat_user (input, unformat_line_input, line_input))
    return 0;

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (line_input, "add"))
	is_add = 1;
      else if (unformat (line_input, "del"))
	is_add = 0;
      else if (unformat (line_input, "vrf %d", &table_id))
	{
	  vrf_is_set = 1;
	}
      else if (unformat (line_input, "vni %d", &vni))
	{
	  vni_is_set = 1;
	}
      else if (unformat (line_input, "bd %d", &bd_id))
	{
	  bd_index_is_set = 1;
	}
      else if (unformat (line_input, "nsh"))
	{
	  nsh_iface = 1;
	}
      else
	{
	  error = clib_error_return (0, "parse error: '%U'",
				     format_unformat_error, line_input);
	  goto done;
	}
    }

  if (nsh_iface)
    {
      if (is_add)
	{
	  if (~0 == vnet_lisp_gpe_add_nsh_iface (&lisp_gpe_main))
	    {
	      error = clib_error_return (0, "NSH interface not created");
	      goto done;
	    }
	}
      else
	{
	  vnet_lisp_gpe_del_nsh_iface (&lisp_gpe_main);
	}
      goto done;
    }

  if (vrf_is_set && bd_index_is_set)
    {
      error = clib_error_return
	(0, "Cannot set both vrf and brdige domain index!");
      goto done;
    }

  if (!vni_is_set)
    {
      error = clib_error_return (0, "vni must be set!");
      goto done;
    }

  if (!vrf_is_set && !bd_index_is_set)
    {
      error =
	clib_error_return (0, "vrf or bridge domain index must be set!");
      goto done;
    }

  if (bd_index_is_set)
    {
      if (is_add)
	{
	  if (~0 == lisp_gpe_tenant_l2_iface_add_or_lock (vni, bd_id))
	    {
	      error = clib_error_return (0, "L2 interface not created");
	      goto done;
	    }
	}
      else
	lisp_gpe_tenant_l2_iface_unlock (vni);
    }
  else
    {
      if (is_add)
	{
	  if (~0 == lisp_gpe_tenant_l3_iface_add_or_lock (vni, table_id))
	    {
	      error = clib_error_return (0, "L3 interface not created");
	      goto done;
	    }
	}
      else
	lisp_gpe_tenant_l3_iface_unlock (vni);
    }

done:
  unformat_free (line_input);

  return error;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (add_del_lisp_gpe_iface_command, static) = {
  .path = "gpe iface",
  .short_help = "gpe iface add/del vni <vni> vrf <vrf>",
  .function = lisp_gpe_add_del_iface_command_fn,
};
/* *INDENT-ON* */

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