/*
 * gre_interface.c: gre interfaces
 *
 * Copyright (c) 2012 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 <vnet/pg/pg.h>
#include <vnet/gre/gre.h>
#include <vnet/ip/format.h>
#include <vnet/fib/ip4_fib.h>
#include <vnet/fib/ip6_fib.h>
#include <vnet/adj/adj_midchain.h>
#include <vnet/adj/adj_nbr.h>
#include <vnet/mpls/mpls.h>
#include <vnet/l2/l2_input.h>
#include <vnet/teib/teib.h>

u8 *
format_gre_tunnel_type (u8 * s, va_list * args)
{
  gre_tunnel_type_t type = va_arg (*args, int);

  switch (type)
    {
#define _(n, v) case GRE_TUNNEL_TYPE_##n:       \
      s = format (s, "%s", v);                  \
      break;
      foreach_gre_tunnel_type
#undef _
    }

  return (s);
}

static u8 *
format_gre_tunnel (u8 * s, va_list * args)
{
  gre_tunnel_t *t = va_arg (*args, gre_tunnel_t *);

  s = format (s, "[%d] instance %d src %U dst %U fib-idx %d sw-if-idx %d ",
	      t->dev_instance, t->user_instance,
	      format_ip46_address, &t->tunnel_src, IP46_TYPE_ANY,
	      format_ip46_address, &t->tunnel_dst.fp_addr, IP46_TYPE_ANY,
	      t->outer_fib_index, t->sw_if_index);

  s = format (s, "payload %U ", format_gre_tunnel_type, t->type);
  s = format (s, "%U ", format_tunnel_mode, t->mode);

  if (t->type == GRE_TUNNEL_TYPE_ERSPAN)
    s = format (s, "session %d ", t->session_id);

  if (t->type != GRE_TUNNEL_TYPE_L3)
    s = format (s, "l2-adj-idx %d ", t->l2_adj_index);

  return s;
}

static gre_tunnel_t *
gre_tunnel_db_find (const vnet_gre_tunnel_add_del_args_t * a,
		    u32 outer_fib_index, gre_tunnel_key_t * key)
{
  gre_main_t *gm = &gre_main;
  uword *p;

  if (!a->is_ipv6)
    {
      gre_mk_key4 (a->src.ip4, a->dst.ip4, outer_fib_index,
		   a->type, a->mode, a->session_id, &key->gtk_v4);
      p = hash_get_mem (gm->tunnel_by_key4, &key->gtk_v4);
    }
  else
    {
      gre_mk_key6 (&a->src.ip6, &a->dst.ip6, outer_fib_index,
		   a->type, a->mode, a->session_id, &key->gtk_v6);
      p = hash_get_mem (gm->tunnel_by_key6, &key->gtk_v6);
    }

  if (NULL == p)
    return (NULL);

  return (pool_elt_at_index (gm->tunnels, p[0]));
}

static void
gre_tunnel_db_add (gre_tunnel_t * t, gre_tunnel_key_t * key)
{
  gre_main_t *gm = &gre_main;

  if (t->tunnel_dst.fp_proto == FIB_PROTOCOL_IP6)
    {
      hash_set_mem_alloc (&gm->tunnel_by_key6, &key->gtk_v6, t->dev_instance);
    }
  else
    {
      hash_set_mem_alloc (&gm->tunnel_by_key4, &key->gtk_v4, t->dev_instance);
    }
}

static void
gre_tunnel_db_remove (gre_tunnel_t * t, gre_tunnel_key_t * key)
{
  gre_main_t *gm = &gre_main;

  if (t->tunnel_dst.fp_proto == FIB_PROTOCOL_IP6)
    {
      hash_unset_mem_free (&gm->tunnel_by_key6, &key->gtk_v6);
    }
  else
    {
      hash_unset_mem_free (&gm->tunnel_by_key4, &key->gtk_v4);
    }
}

/**
 * gre_tunnel_stack
 *
 * 'stack' (resolve the recursion for) the tunnel's midchain adjacency
 */
void
gre_tunnel_stack (adj_index_t ai)
{
  gre_main_t *gm = &gre_main;
  ip_adjacency_t *adj;
  gre_tunnel_t *gt;
  u32 sw_if_index;

  adj = adj_get (ai);
  sw_if_index = adj->rewrite_header.sw_if_index;

  if ((vec_len (gm->tunnel_index_by_sw_if_index) <= sw_if_index) ||
      (~0 == gm->tunnel_index_by_sw_if_index[sw_if_index]))
    return;

  gt = pool_elt_at_index (gm->tunnels,
			  gm->tunnel_index_by_sw_if_index[sw_if_index]);

  if ((vnet_hw_interface_get_flags (vnet_get_main (), gt->hw_if_index) &
       VNET_HW_INTERFACE_FLAG_LINK_UP) == 0)
    {
      adj_midchain_delegate_unstack (ai);
    }
  else
    {
      adj_midchain_delegate_stack (ai, gt->outer_fib_index, &gt->tunnel_dst);
    }
}

/**
 * @brief Call back when restacking all adjacencies on a GRE interface
 */
static adj_walk_rc_t
gre_adj_walk_cb (adj_index_t ai, void *ctx)
{
  gre_tunnel_stack (ai);

  return (ADJ_WALK_RC_CONTINUE);
}

static void
gre_tunnel_restack (gre_tunnel_t * gt)
{
  fib_protocol_t proto;

  /*
   * walk all the adjacencies on th GRE interface and restack them
   */
  FOR_EACH_FIB_IP_PROTOCOL (proto)
  {
    adj_nbr_walk (gt->sw_if_index, proto, gre_adj_walk_cb, NULL);
  }
}

static void
gre_teib_mk_key (const gre_tunnel_t * t,
		 const teib_entry_t * ne, gre_tunnel_key_t * key)
{
  const fib_prefix_t *nh;

  nh = teib_entry_get_nh (ne);

  /* construct the key using mode P2P so it can be found in the DP */
  if (FIB_PROTOCOL_IP4 == nh->fp_proto)
    gre_mk_key4 (t->tunnel_src.ip4,
		 nh->fp_addr.ip4,
		 teib_entry_get_fib_index (ne),
		 t->type, TUNNEL_MODE_P2P, 0, &key->gtk_v4);
  else
    gre_mk_key6 (&t->tunnel_src.ip6,
		 &nh->fp_addr.ip6,
		 teib_entry_get_fib_index (ne),
		 t->type, TUNNEL_MODE_P2P, 0, &key->gtk_v6);
}

/**
 * An NHRP entry has been added
 */
static void
gre_teib_entry_added (const teib_entry_t * ne)
{
  gre_main_t *gm = &gre_main;
  const ip46_address_t *nh;
  gre_tunnel_key_t key;
  gre_tunnel_t *t;
  u32 sw_if_index;
  u32 t_idx;

  sw_if_index = teib_entry_get_sw_if_index (ne);
  if (vec_len (gm->tunnel_index_by_sw_if_index) < sw_if_index)
    return;

  t_idx = gm->tunnel_index_by_sw_if_index[sw_if_index];

  if (INDEX_INVALID == t_idx)
    return;

  /* entry has been added on an interface for which there is a GRE tunnel */
  t = pool_elt_at_index (gm->tunnels, t_idx);

  if (t->mode != TUNNEL_MODE_MP)
    return;

  /* the next-hop (underlay) of the NHRP entry will form part of the key for
   * ingress lookup to match packets to this interface */
  gre_teib_mk_key (t, ne, &key);
  gre_tunnel_db_add (t, &key);

  /* update the rewrites for each of the adjacencies for this peer (overlay)
   * using  the next-hop (underlay) */
  mgre_walk_ctx_t ctx = {
    .t = t,
    .ne = ne
  };
  nh = teib_entry_get_peer (ne);
  adj_nbr_walk_nh (teib_entry_get_sw_if_index (ne),
		   (ip46_address_is_ip4 (nh) ?
		    FIB_PROTOCOL_IP4 :
		    FIB_PROTOCOL_IP6), nh, mgre_mk_complete_walk, &ctx);
}

static void
gre_teib_entry_deleted (const teib_entry_t * ne)
{
  gre_main_t *gm = &gre_main;
  const ip46_address_t *nh;
  gre_tunnel_key_t key;
  gre_tunnel_t *t;
  u32 sw_if_index;
  u32 t_idx;

  sw_if_index = teib_entry_get_sw_if_index (ne);
  if (vec_len (gm->tunnel_index_by_sw_if_index) < sw_if_index)
    return;

  t_idx = gm->tunnel_index_by_sw_if_index[sw_if_index];

  if (INDEX_INVALID == t_idx)
    return;

  t = pool_elt_at_index (gm->tunnels, t_idx);

  /* remove the next-hop as an ingress lookup key */
  gre_teib_mk_key (t, ne, &key);
  gre_tunnel_db_remove (t, &key);

  nh = teib_entry_get_peer (ne);

  /* make all the adjacencies incomplete */
  adj_nbr_walk_nh (teib_entry_get_sw_if_index (ne),
		   (ip46_address_is_ip4 (nh) ?
		    FIB_PROTOCOL_IP4 :
		    FIB_PROTOCOL_IP6), nh, mgre_mk_incomplete_walk, t);
}

static walk_rc_t
gre_tunnel_delete_teib_walk (index_t nei, void *ctx)
{
  gre_tunnel_t *t = ctx;
  gre_tunnel_key_t key;

  gre_teib_mk_key (t, teib_entry_get (nei), &key);
  gre_tunnel_db_remove (t, &key);

  return (WALK_CONTINUE);
}

static walk_rc_t
gre_tunnel_add_teib_walk (index_t nei, void *ctx)
{
  gre_tunnel_t *t = ctx;
  gre_tunnel_key_t key;

  gre_teib_mk_key (t, teib_entry_get (nei), &key);
  gre_tunnel_db_add (t, &key);

  return (WALK_CONTINUE);
}

static int
vnet_gre_tunnel_add (vnet_gre_tunnel_add_del_args_t * a,
		     u32 outer_fib_index, u32 * sw_if_indexp)
{
  gre_main_t *gm = &gre_main;
  vnet_main_t *vnm = gm->vnet_main;
  ip4_main_t *im4 = &ip4_main;
  ip6_main_t *im6 = &ip6_main;
  gre_tunnel_t *t;
  vnet_hw_interface_t *hi;
  u32 hw_if_index, sw_if_index;
  clib_error_t *error;
  u8 is_ipv6 = a->is_ipv6;
  gre_tunnel_key_t key;

  t = gre_tunnel_db_find (a, outer_fib_index, &key);
  if (NULL != t)
    return VNET_API_ERROR_IF_ALREADY_EXISTS;

  pool_get_aligned (gm->tunnels, t, CLIB_CACHE_LINE_BYTES);
  clib_memset (t, 0, sizeof (*t));

  /* Reconcile the real dev_instance and a possible requested instance */
  u32 t_idx = t - gm->tunnels;	/* tunnel index (or instance) */
  u32 u_idx = a->instance;	/* user specified instance */
  if (u_idx == ~0)
    u_idx = t_idx;
  if (hash_get (gm->instance_used, u_idx))
    {
      pool_put (gm->tunnels, t);
      return VNET_API_ERROR_INSTANCE_IN_USE;
    }
  hash_set (gm->instance_used, u_idx, 1);

  t->dev_instance = t_idx;	/* actual */
  t->user_instance = u_idx;	/* name */

  t->type = a->type;
  t->mode = a->mode;
  t->flags = a->flags;
  if (t->type == GRE_TUNNEL_TYPE_ERSPAN)
    t->session_id = a->session_id;

  if (t->type == GRE_TUNNEL_TYPE_L3)
    {
      if (t->mode == TUNNEL_MODE_P2P)
	hw_if_index =
	  vnet_register_interface (vnm, gre_device_class.index, t_idx,
				   gre_hw_interface_class.index, t_idx);
      else
	hw_if_index =
	  vnet_register_interface (vnm, gre_device_class.index, t_idx,
				   mgre_hw_interface_class.index, t_idx);
    }
  else
    {
      /* Default MAC address (d00b:eed0:0000 + sw_if_index) */
      u8 address[6] =
	{ 0xd0, 0x0b, 0xee, 0xd0, (u8) (t_idx >> 8), (u8) t_idx };
      error =
	ethernet_register_interface (vnm, gre_device_class.index, t_idx,
				     address, &hw_if_index, 0);
      if (error)
	{
	  clib_error_report (error);
	  return VNET_API_ERROR_INVALID_REGISTRATION;
	}
    }

  /* Set GRE tunnel interface output node (not used for L3 payload) */
  if (GRE_TUNNEL_TYPE_ERSPAN == t->type)
    vnet_set_interface_output_node (vnm, hw_if_index,
				    gre_erspan_encap_node.index);
  else
    vnet_set_interface_output_node (vnm, hw_if_index,
				    gre_teb_encap_node.index);

  hi = vnet_get_hw_interface (vnm, hw_if_index);
  sw_if_index = hi->sw_if_index;

  t->hw_if_index = hw_if_index;
  t->outer_fib_index = outer_fib_index;
  t->sw_if_index = sw_if_index;
  t->l2_adj_index = ADJ_INDEX_INVALID;

  vec_validate_init_empty (gm->tunnel_index_by_sw_if_index, sw_if_index, ~0);
  gm->tunnel_index_by_sw_if_index[sw_if_index] = t_idx;

  if (!is_ipv6)
    {
      vec_validate (im4->fib_index_by_sw_if_index, sw_if_index);
      hi->min_packet_bytes =
	64 + sizeof (gre_header_t) + sizeof (ip4_header_t);
    }
  else
    {
      vec_validate (im6->fib_index_by_sw_if_index, sw_if_index);
      hi->min_packet_bytes =
	64 + sizeof (gre_header_t) + sizeof (ip6_header_t);
    }

  /* Standard default gre MTU. */
  vnet_sw_interface_set_mtu (vnm, sw_if_index, 9000);

  /*
   * source the FIB entry for the tunnel's destination
   * and become a child thereof. The tunnel will then get poked
   * when the forwarding for the entry updates, and the tunnel can
   * re-stack accordingly
   */

  clib_memcpy (&t->tunnel_src, &a->src, sizeof (t->tunnel_src));
  t->tunnel_dst.fp_len = !is_ipv6 ? 32 : 128;
  t->tunnel_dst.fp_proto = !is_ipv6 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6;
  t->tunnel_dst.fp_addr = a->dst;

  gre_tunnel_db_add (t, &key);

  if (t->mode == TUNNEL_MODE_MP)
    teib_walk_itf (t->sw_if_index, gre_tunnel_add_teib_walk, t);

  if (t->type == GRE_TUNNEL_TYPE_ERSPAN)
    {
      gre_sn_key_t skey;
      gre_sn_t *gre_sn;

      gre_mk_sn_key (t, &skey);
      gre_sn = (gre_sn_t *) hash_get_mem (gm->seq_num_by_key, &skey);
      if (gre_sn != NULL)
	{
	  gre_sn->ref_count++;
	  t->gre_sn = gre_sn;
	}
      else
	{
	  gre_sn = clib_mem_alloc (sizeof (gre_sn_t));
	  gre_sn->seq_num = 0;
	  gre_sn->ref_count = 1;
	  t->gre_sn = gre_sn;
	  hash_set_mem_alloc (&gm->seq_num_by_key, &skey, (uword) gre_sn);
	}
    }

  if (t->type != GRE_TUNNEL_TYPE_L3)
    {
      t->l2_adj_index = adj_nbr_add_or_lock
	(t->tunnel_dst.fp_proto, VNET_LINK_ETHERNET, &zero_addr, sw_if_index);
      gre_update_adj (vnm, t->sw_if_index, t->l2_adj_index);
    }

  if (sw_if_indexp)
    *sw_if_indexp = sw_if_index;

  /* register gre46-input nodes */
  ip4_register_protocol (IP_PROTOCOL_GRE, gre4_input_node.index);
  ip6_register_protocol (IP_PROTOCOL_GRE, gre6_input_node.index);

  return 0;
}

static int
vnet_gre_tunnel_delete (vnet_gre_tunnel_add_del_args_t * a,
			u32 outer_fib_index, u32 * sw_if_indexp)
{
  gre_main_t *gm = &gre_main;
  vnet_main_t *vnm = gm->vnet_main;
  gre_tunnel_t *t;
  gre_tunnel_key_t key;
  u32 sw_if_index;

  t = gre_tunnel_db_find (a, outer_fib_index, &key);
  if (NULL == t)
    return VNET_API_ERROR_NO_SUCH_ENTRY;

  if (t->mode == TUNNEL_MODE_MP)
    teib_walk_itf (t->sw_if_index, gre_tunnel_delete_teib_walk, t);

  sw_if_index = t->sw_if_index;
  vnet_sw_interface_set_flags (vnm, sw_if_index, 0 /* down */ );

  /* make sure tunnel is removed from l2 bd or xconnect */
  set_int_l2_mode (gm->vlib_main, vnm, MODE_L3, sw_if_index, 0,
		   L2_BD_PORT_TYPE_NORMAL, 0, 0);
  gm->tunnel_index_by_sw_if_index[sw_if_index] = ~0;

  if (t->type == GRE_TUNNEL_TYPE_L3)
    vnet_delete_hw_interface (vnm, t->hw_if_index);
  else
    ethernet_delete_interface (vnm, t->hw_if_index);

  if (t->l2_adj_index != ADJ_INDEX_INVALID)
    {
      adj_midchain_delegate_unstack (t->l2_adj_index);
      adj_unlock (t->l2_adj_index);
    }

  ASSERT ((t->type != GRE_TUNNEL_TYPE_ERSPAN) || (t->gre_sn != NULL));
  if ((t->type == GRE_TUNNEL_TYPE_ERSPAN) && (t->gre_sn->ref_count-- == 1))
    {
      gre_sn_key_t skey;
      gre_mk_sn_key (t, &skey);
      hash_unset_mem_free (&gm->seq_num_by_key, &skey);
      clib_mem_free (t->gre_sn);
    }

  hash_unset (gm->instance_used, t->user_instance);
  gre_tunnel_db_remove (t, &key);
  pool_put (gm->tunnels, t);

  if (sw_if_indexp)
    *sw_if_indexp = sw_if_index;

  return 0;
}

int
vnet_gre_tunnel_add_del (vnet_gre_tunnel_add_del_args_t * a,
			 u32 * sw_if_indexp)
{
  u32 outer_fib_index;

  if (!a->is_ipv6)
    outer_fib_index = ip4_fib_index_from_table_id (a->outer_table_id);
  else
    outer_fib_index = ip6_fib_index_from_table_id (a->outer_table_id);

  if (~0 == outer_fib_index)
    return VNET_API_ERROR_NO_SUCH_FIB;

  if (a->session_id > GTK_SESSION_ID_MAX)
    return VNET_API_ERROR_INVALID_SESSION_ID;

  if (a->mode == TUNNEL_MODE_MP && !ip46_address_is_zero (&a->dst))
    return (VNET_API_ERROR_INVALID_DST_ADDRESS);

  if (a->is_add)
    return (vnet_gre_tunnel_add (a, outer_fib_index, sw_if_indexp));
  else
    return (vnet_gre_tunnel_delete (a, outer_fib_index, sw_if_indexp));
}

clib_error_t *
gre_interface_admin_up_down (vnet_main_t * vnm, u32 hw_if_index, u32 flags)
{
  gre_main_t *gm = &gre_main;
  vnet_hw_interface_t *hi;
  gre_tunnel_t *t;
  u32 ti;

  hi = vnet_get_hw_interface (vnm, hw_if_index);

  if (NULL == gm->tunnel_index_by_sw_if_index ||
      hi->sw_if_index >= vec_len (gm->tunnel_index_by_sw_if_index))
    return (NULL);

  ti = gm->tunnel_index_by_sw_if_index[hi->sw_if_index];

  if (~0 == ti)
    /* not one of ours */
    return (NULL);

  t = pool_elt_at_index (gm->tunnels, ti);

  if (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP)
    vnet_hw_interface_set_flags (vnm, hw_if_index,
				 VNET_HW_INTERFACE_FLAG_LINK_UP);
  else
    vnet_hw_interface_set_flags (vnm, hw_if_index, 0 /* down */ );

  gre_tunnel_restack (t);

  return /* no error */ 0;
}

static clib_error_t *
create_gre_tunnel_command_fn (vlib_main_t * vm,
			      unformat_input_t * input,
			      vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  vnet_gre_tunnel_add_del_args_t _a, *a = &_a;
  ip46_address_t src = ip46_address_initializer, dst =
    ip46_address_initializer;
  u32 instance = ~0;
  u32 outer_table_id = 0;
  gre_tunnel_type_t t_type = GRE_TUNNEL_TYPE_L3;
  tunnel_mode_t t_mode = TUNNEL_MODE_P2P;
  u32 session_id = 0;
  int rv;
  u8 is_add = 1;
  u32 sw_if_index;
  clib_error_t *error = NULL;

  /* 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, "del"))
	is_add = 0;
      else if (unformat (line_input, "instance %d", &instance))
	;
      else if (unformat (line_input, "src %U", unformat_ip46_address, &src))
	;
      else if (unformat (line_input, "dst %U", unformat_ip46_address, &dst))
	;
      else if (unformat (line_input, "outer-table-id %d", &outer_table_id))
	;
      else if (unformat (line_input, "multipoint"))
	t_mode = TUNNEL_MODE_MP;
      else if (unformat (line_input, "teb"))
	t_type = GRE_TUNNEL_TYPE_TEB;
      else if (unformat (line_input, "erspan %d", &session_id))
	t_type = GRE_TUNNEL_TYPE_ERSPAN;
      else
	{
	  error = clib_error_return (0, "unknown input `%U'",
				     format_unformat_error, line_input);
	  goto done;
	}
    }

  if (ip46_address_is_equal (&src, &dst))
    {
      error = clib_error_return (0, "src and dst are identical");
      goto done;
    }

  if (t_mode != TUNNEL_MODE_MP && ip46_address_is_zero (&dst))
    {
      error = clib_error_return (0, "destination address not specified");
      goto done;
    }

  if (ip46_address_is_zero (&src))
    {
      error = clib_error_return (0, "source address not specified");
      goto done;
    }

  if (ip46_address_is_ip4 (&src) != ip46_address_is_ip4 (&dst))
    {
      error =
	clib_error_return (0, "src and dst address must be the same AF");
      goto done;
    }

  clib_memset (a, 0, sizeof (*a));
  a->is_add = is_add;
  a->outer_table_id = outer_table_id;
  a->type = t_type;
  a->mode = t_mode;
  a->session_id = session_id;
  a->is_ipv6 = !ip46_address_is_ip4 (&src);
  a->instance = instance;
  clib_memcpy (&a->src, &src, sizeof (a->src));
  clib_memcpy (&a->dst, &dst, sizeof (a->dst));

  rv = vnet_gre_tunnel_add_del (a, &sw_if_index);

  switch (rv)
    {
    case 0:
      vlib_cli_output (vm, "%U\n", format_vnet_sw_if_index_name,
		       vnet_get_main (), sw_if_index);
      break;
    case VNET_API_ERROR_IF_ALREADY_EXISTS:
      error = clib_error_return (0, "GRE tunnel already exists...");
      goto done;
    case VNET_API_ERROR_NO_SUCH_FIB:
      error = clib_error_return (0, "outer table ID %d doesn't exist\n",
				 outer_table_id);
      goto done;
    case VNET_API_ERROR_NO_SUCH_ENTRY:
      error = clib_error_return (0, "GRE tunnel doesn't exist");
      goto done;
    case VNET_API_ERROR_INVALID_SESSION_ID:
      error = clib_error_return (0, "session ID %d out of range\n",
				 session_id);
      goto done;
    case VNET_API_ERROR_INSTANCE_IN_USE:
      error = clib_error_return (0, "Instance is in use");
      goto done;
    default:
      error =
	clib_error_return (0, "vnet_gre_tunnel_add_del returned %d", rv);
      goto done;
    }

done:
  unformat_free (line_input);

  return error;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (create_gre_tunnel_command, static) = {
  .path = "create gre tunnel",
  .short_help = "create gre tunnel src <addr> dst <addr> [instance <n>] "
                "[outer-fib-id <fib>] [teb | erspan <session-id>] [del]",
  .function = create_gre_tunnel_command_fn,
};
/* *INDENT-ON* */

static clib_error_t *
show_gre_tunnel_command_fn (vlib_main_t * vm,
			    unformat_input_t * input,
			    vlib_cli_command_t * cmd)
{
  gre_main_t *gm = &gre_main;
  gre_tunnel_t *t;
  u32 ti = ~0;

  if (pool_elts (gm->tunnels) == 0)
    vlib_cli_output (vm, "No GRE tunnels configured...");

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "%d", &ti))
	;
      else
	break;
    }

  if (~0 == ti)
    {
      /* *INDENT-OFF* */
      pool_foreach (t, gm->tunnels,
      ({
          vlib_cli_output (vm, "%U", format_gre_tunnel, t);
      }));
      /* *INDENT-ON* */
    }
  else
    {
      t = pool_elt_at_index (gm->tunnels, ti);

      vlib_cli_output (vm, "%U", format_gre_tunnel, t);
    }

  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_gre_tunnel_command, static) = {
    .path = "show gre tunnel",
    .function = show_gre_tunnel_command_fn,
};
/* *INDENT-ON* */

const static teib_vft_t gre_teib_vft = {
  .nv_added = gre_teib_entry_added,
  .nv_deleted = gre_teib_entry_deleted,
};

/* force inclusion from application's main.c */
clib_error_t *
gre_interface_init (vlib_main_t * vm)
{
  teib_register (&gre_teib_vft);

  return (NULL);
}

VLIB_INIT_FUNCTION (gre_interface_init);

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