/*
 * 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 = vm->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,
		       u8 with_default_routes)
{
  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);
  if (with_default_routes)
    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, 1
							  /* with_default_route */
	      ))
	    {
	      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:
 */
