/*
 * Copyright (c) 2015 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 IPv4 and IPv6 VXLAN GPE tunnels
 *
*/
#include <vnet/vxlan-gpe/vxlan_gpe.h>
#include <vnet/fib/fib.h>
#include <vnet/ip/format.h>
#include <vnet/fib/fib_entry.h>
#include <vnet/fib/fib_table.h>
#include <vnet/mfib/mfib_table.h>
#include <vnet/adj/adj_mcast.h>
#include <vnet/interface.h>
#include <vlib/vlib.h>

/**
 * @file
 * @brief VXLAN-GPE.
 *
 * VXLAN-GPE provides the features needed to allow L2 bridge domains (BDs)
 * to span multiple servers. This is done by building an L2 overlay on
 * top of an L3 network underlay using VXLAN-GPE tunnels.
 *
 * This makes it possible for servers to be co-located in the same data
 * center or be separated geographically as long as they are reachable
 * through the underlay L3 network.
 *
 * You can refer to this kind of L2 overlay bridge domain as a VXLAN-GPE segment.
 */

vxlan_gpe_main_t vxlan_gpe_main;

/**
 * @brief Tracing function for VXLAN GPE tunnel packets
 *
 * @param *s formatting string
 * @param *args
 *
 * @return *s formatted string
 *
 */
u8 * format_vxlan_gpe_tunnel (u8 * s, va_list * args)
{
  vxlan_gpe_tunnel_t * t = va_arg (*args, vxlan_gpe_tunnel_t *);
  vxlan_gpe_main_t * ngm = &vxlan_gpe_main;

  s = format (s, "[%d] local: %U remote: %U ",
              t - ngm->tunnels,
              format_ip46_address, &t->local, IP46_TYPE_ANY,
              format_ip46_address, &t->remote, IP46_TYPE_ANY);

  s = format (s, "  vxlan VNI %d ", t->vni);

  switch (t->protocol)
    {
    case VXLAN_GPE_PROTOCOL_IP4:
      s = format (s, "next-protocol ip4");
      break;
    case VXLAN_GPE_PROTOCOL_IP6:
      s = format (s, "next-protocol ip6");
      break;
    case VXLAN_GPE_PROTOCOL_ETHERNET:
      s = format (s, "next-protocol ethernet");
      break;
    case VXLAN_GPE_PROTOCOL_NSH:
      s = format (s, "next-protocol nsh");
      break;
    default:
      s = format (s, "next-protocol unknown %d", t->protocol);
    }

  if (ip46_address_is_multicast (&t->remote))
    s = format (s, "mcast_sw_if_index %d ", t->mcast_sw_if_index);
    
  s = format (s, " fibs: (encap %d, decap %d)",
              t->encap_fib_index,
              t->decap_fib_index);

  return s;
}

/**
 * @brief Naming for VXLAN GPE tunnel
 *
 * @param *s formatting string
 * @param *args
 *
 * @return *s formatted string
 *
 */
static u8 * format_vxlan_gpe_name (u8 * s, va_list * args)
{
  u32 dev_instance = va_arg (*args, u32);
  return format (s, "vxlan_gpe_tunnel%d", dev_instance);
}

static uword dummy_interface_tx (vlib_main_t * vm,
                                 vlib_node_runtime_t * node,
                                 vlib_frame_t * frame)
{
  clib_warning ("you shouldn't be here, leaking buffers...");
  return frame->n_vectors;
}

/**
 * @brief CLI function for VXLAN GPE admin up/down
 *
 * @param *vnm
 * @param hw_if_index
 * @param flag
 *
 * @return *rc
 *
 */
static clib_error_t *
vxlan_gpe_interface_admin_up_down (vnet_main_t * vnm, u32 hw_if_index, u32 flags)
{
  u32 hw_flags = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ?
    VNET_HW_INTERFACE_FLAG_LINK_UP : 0;
  vnet_hw_interface_set_flags (vnm, hw_if_index, hw_flags);

  return 0;
}

VNET_DEVICE_CLASS (vxlan_gpe_device_class,static) = {
  .name = "VXLAN_GPE",
  .format_device_name = format_vxlan_gpe_name,
  .format_tx_trace = format_vxlan_gpe_encap_trace,
  .tx_function = dummy_interface_tx,
  .admin_up_down_function = vxlan_gpe_interface_admin_up_down,
};


/**
 * @brief Formatting function for tracing VXLAN GPE with length
 *
 * @param *s
 * @param *args
 *
 * @return *s
 *
 */
static u8 * format_vxlan_gpe_header_with_length (u8 * s, va_list * args)
{
  u32 dev_instance = va_arg (*args, u32);
  s = format (s, "unimplemented dev %u", dev_instance);
  return s;
}

VNET_HW_INTERFACE_CLASS (vxlan_gpe_hw_class) = {
  .name = "VXLAN_GPE",
  .format_header = format_vxlan_gpe_header_with_length,
  .build_rewrite = default_build_rewrite,
};

static void
vxlan_gpe_tunnel_restack_dpo(vxlan_gpe_tunnel_t * t)
{
    dpo_id_t dpo = DPO_INVALID;
    u32 encap_index = vxlan_gpe_encap_node.index;
    fib_forward_chain_type_t forw_type = ip46_address_is_ip4(&t->remote) ?
        FIB_FORW_CHAIN_TYPE_UNICAST_IP4 : FIB_FORW_CHAIN_TYPE_UNICAST_IP6;

    fib_entry_contribute_forwarding (t->fib_entry_index, forw_type, &dpo);
    dpo_stack_from_node (encap_index, &t->next_dpo, &dpo);
    dpo_reset(&dpo);
}

static vxlan_gpe_tunnel_t *
vxlan_gpe_tunnel_from_fib_node (fib_node_t *node)
{
    ASSERT(FIB_NODE_TYPE_VXLAN_GPE_TUNNEL == node->fn_type);
    return ((vxlan_gpe_tunnel_t*) (((char*)node) -
			       STRUCT_OFFSET_OF(vxlan_gpe_tunnel_t, node)));
}

/**
 * Function definition to backwalk a FIB node -
 * Here we will restack the new dpo of VXLAN_GPE DIP to encap node.
 */
static fib_node_back_walk_rc_t
vxlan_gpe_tunnel_back_walk (fib_node_t *node,
			fib_node_back_walk_ctx_t *ctx)
{
    vxlan_gpe_tunnel_restack_dpo(vxlan_gpe_tunnel_from_fib_node(node));
    return (FIB_NODE_BACK_WALK_CONTINUE);
}

/**
 * Function definition to get a FIB node from its index
 */
static fib_node_t*
vxlan_gpe_tunnel_fib_node_get (fib_node_index_t index)
{
    vxlan_gpe_tunnel_t * t;
    vxlan_gpe_main_t * ngm = &vxlan_gpe_main;

    t = pool_elt_at_index(ngm->tunnels, index);

    return (&t->node);
}

/**
 * Function definition to inform the FIB node that its last lock has gone.
 */
static void
vxlan_gpe_tunnel_last_lock_gone (fib_node_t *node)
{
    /*
     * The VXLAN_GPE tunnel is a root of the graph. As such
     * it never has children and thus is never locked.
     */
    ASSERT(0);
}

/*
 * Virtual function table registered by VXLAN_GPE tunnels
 * for participation in the FIB object graph.
 */
const static fib_node_vft_t vxlan_gpe_vft = {
    .fnv_get = vxlan_gpe_tunnel_fib_node_get,
    .fnv_last_lock = vxlan_gpe_tunnel_last_lock_gone,
    .fnv_back_walk = vxlan_gpe_tunnel_back_walk,
};

#define foreach_gpe_copy_field                  \
_(vni)                                          \
_(protocol)                                     \
_(mcast_sw_if_index)                            \
_(encap_fib_index)                              \
_(decap_fib_index)

#define foreach_copy_ipv4 {                     \
  _(local.ip4.as_u32)                           \
  _(remote.ip4.as_u32)                          \
}

#define foreach_copy_ipv6 {                     \
  _(local.ip6.as_u64[0])                        \
  _(local.ip6.as_u64[1])                        \
  _(remote.ip6.as_u64[0])                       \
  _(remote.ip6.as_u64[1])                       \
}


/**
 * @brief Calculate IPv4 VXLAN GPE rewrite header
 *
 * @param *t
 *
 * @return rc
 *
 */
int vxlan4_gpe_rewrite (vxlan_gpe_tunnel_t * t, u32 extension_size,
                        u8 protocol_override, uword encap_next_node)
{
  u8 *rw = 0;
  ip4_header_t * ip0;
  ip4_vxlan_gpe_header_t * h0;
  int len;

  len = sizeof (*h0) + extension_size;

  vec_free(t->rewrite);
  vec_validate_aligned (rw, len-1, CLIB_CACHE_LINE_BYTES);

  h0 = (ip4_vxlan_gpe_header_t *) rw;

  /* Fixed portion of the (outer) ip4 header */
  ip0 = &h0->ip4;
  ip0->ip_version_and_header_length = 0x45;
  ip0->ttl = 254;
  ip0->protocol = IP_PROTOCOL_UDP;

  /* we fix up the ip4 header length and checksum after-the-fact */
  ip0->src_address.as_u32 = t->local.ip4.as_u32;
  ip0->dst_address.as_u32 = t->remote.ip4.as_u32;
  ip0->checksum = ip4_header_checksum (ip0);

  /* UDP header, randomize src port on something, maybe? */
  h0->udp.src_port = clib_host_to_net_u16 (4790);
  h0->udp.dst_port = clib_host_to_net_u16 (UDP_DST_PORT_VXLAN_GPE);

  /* VXLAN header. Are we having fun yet? */
  h0->vxlan.flags = VXLAN_GPE_FLAGS_I | VXLAN_GPE_FLAGS_P;
  h0->vxlan.ver_res = VXLAN_GPE_VERSION;
  if (protocol_override)
  {
      h0->vxlan.protocol = protocol_override;
  }
  else
  {
      h0->vxlan.protocol = t->protocol;
  }
  t->rewrite_size = sizeof(ip4_vxlan_gpe_header_t) +  extension_size;
  h0->vxlan.vni_res = clib_host_to_net_u32 (t->vni<<8);

  t->rewrite = rw;
  t->encap_next_node = encap_next_node;
  return (0);
}

/**
 * @brief Calculate IPv6 VXLAN GPE rewrite header
 *
 * @param *t
 *
 * @return rc
 *
 */
int vxlan6_gpe_rewrite (vxlan_gpe_tunnel_t * t, u32 extension_size,
                        u8 protocol_override, uword encap_next_node)
{
  u8 *rw = 0;
  ip6_header_t * ip0;
  ip6_vxlan_gpe_header_t * h0;
  int len;

  len = sizeof (*h0) + extension_size;

  vec_free(t->rewrite);
  vec_validate_aligned (rw, len-1, CLIB_CACHE_LINE_BYTES);

  h0 = (ip6_vxlan_gpe_header_t *) rw;

  /* Fixed portion of the (outer) ip4 header */
  ip0 = &h0->ip6;
  ip0->ip_version_traffic_class_and_flow_label = clib_host_to_net_u32(6 << 28);
  ip0->hop_limit = 255;
  ip0->protocol = IP_PROTOCOL_UDP;

  ip0->src_address.as_u64[0] = t->local.ip6.as_u64[0];
  ip0->src_address.as_u64[1] = t->local.ip6.as_u64[1];
  ip0->dst_address.as_u64[0] = t->remote.ip6.as_u64[0];
  ip0->dst_address.as_u64[1] = t->remote.ip6.as_u64[1];

  /* UDP header, randomize src port on something, maybe? */
  h0->udp.src_port = clib_host_to_net_u16 (4790);
  h0->udp.dst_port = clib_host_to_net_u16 (UDP_DST_PORT_VXLAN_GPE);

  /* VXLAN header. Are we having fun yet? */
  h0->vxlan.flags = VXLAN_GPE_FLAGS_I | VXLAN_GPE_FLAGS_P;
  h0->vxlan.ver_res = VXLAN_GPE_VERSION;
  if (protocol_override)
  {
      h0->vxlan.protocol = t->protocol;
  }
  else
  {
      h0->vxlan.protocol = protocol_override;
  }
  t->rewrite_size = sizeof(ip4_vxlan_gpe_header_t) +  extension_size;
  h0->vxlan.vni_res = clib_host_to_net_u32 (t->vni<<8);

  t->rewrite = rw;
  t->encap_next_node = encap_next_node;
  return (0);
}

static void
hash_set_key_copy (uword ** h, void * key, uword v) {
	size_t ksz = hash_header(*h)->user;
        void * copy = clib_mem_alloc (ksz);
	clib_memcpy (copy, key, ksz);
	hash_set_mem (*h, copy, v);
}

static void
hash_unset_key_free (uword ** h, void * key) {
	hash_pair_t * hp = hash_get_pair_mem (*h, key);
	ASSERT (hp);
	key = uword_to_pointer (hp->key, void *);
	hash_unset_mem (*h, key);
	clib_mem_free (key);
}

static uword
vtep_addr_ref(ip46_address_t *ip)
{
	uword *vtep = ip46_address_is_ip4(ip) ?
	                 hash_get (vxlan_gpe_main.vtep4, ip->ip4.as_u32) :
	                 hash_get_mem (vxlan_gpe_main.vtep6, &ip->ip6);
	if (vtep)
		return ++(*vtep);
	ip46_address_is_ip4(ip) ?
	                 hash_set (vxlan_gpe_main.vtep4, ip->ip4.as_u32, 1) :
	                 hash_set_key_copy (&vxlan_gpe_main.vtep6, &ip->ip6, 1);
	return 1;
}

static uword
vtep_addr_unref(ip46_address_t *ip)
{
	uword *vtep = ip46_address_is_ip4(ip) ?
	                 hash_get (vxlan_gpe_main.vtep4, ip->ip4.as_u32) :
	                 hash_get_mem (vxlan_gpe_main.vtep6, &ip->ip6);
        ASSERT(vtep);
	if (--(*vtep) != 0)
		return *vtep;
	ip46_address_is_ip4(ip) ?
		hash_unset (vxlan_gpe_main.vtep4, ip->ip4.as_u32) :
		hash_unset_key_free (&vxlan_gpe_main.vtep6, &ip->ip6);
	return 0;
}

typedef CLIB_PACKED(union {
  struct {
    fib_node_index_t mfib_entry_index;
    adj_index_t mcast_adj_index;
  };
  u64 as_u64;
}) mcast_shared_t;

static inline mcast_shared_t
mcast_shared_get(ip46_address_t * ip)
{
        ASSERT(ip46_address_is_multicast(ip));
	uword * p = hash_get_mem (vxlan_gpe_main.mcast_shared, ip);
        ASSERT(p);
	return (mcast_shared_t) { .as_u64 = *p };
}

static inline void
mcast_shared_add(ip46_address_t *remote,
                 fib_node_index_t mfei,
                 adj_index_t ai)
{
    mcast_shared_t new_ep = {
        .mcast_adj_index = ai,
        .mfib_entry_index = mfei,
    };

    hash_set_key_copy (&vxlan_gpe_main.mcast_shared, remote, new_ep.as_u64);
}

static inline void
mcast_shared_remove(ip46_address_t *remote)
{
    mcast_shared_t ep = mcast_shared_get(remote);

    adj_unlock(ep.mcast_adj_index);
    mfib_table_entry_delete_index(ep.mfib_entry_index,
                                  MFIB_SOURCE_VXLAN_GPE);

    hash_unset_key_free (&vxlan_gpe_main.mcast_shared, remote);
}

static inline fib_protocol_t
fib_ip_proto(bool is_ip6)
{
  return (is_ip6) ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4;
}

/**
 * @brief Add or Del a VXLAN GPE tunnel
 *
 * @param *a
 * @param *sw_if_index
 *
 * @return rc
 *
 */
int vnet_vxlan_gpe_add_del_tunnel
(vnet_vxlan_gpe_add_del_tunnel_args_t *a, u32 * sw_if_indexp)
{
  vxlan_gpe_main_t * ngm = &vxlan_gpe_main;
  vxlan_gpe_tunnel_t *t = 0;
  vnet_main_t * vnm = ngm->vnet_main;
  vnet_hw_interface_t * hi;
  uword * p;
  u32 hw_if_index = ~0;
  u32 sw_if_index = ~0;
  int rv;
  vxlan4_gpe_tunnel_key_t key4, *key4_copy;
  vxlan6_gpe_tunnel_key_t key6, *key6_copy;
  u32 is_ip6 = a->is_ip6;

  if (!is_ip6)
  {
    key4.local = a->local.ip4.as_u32;
    key4.remote = a->remote.ip4.as_u32;
    key4.vni = clib_host_to_net_u32 (a->vni << 8);
    key4.pad = 0;

    p = hash_get_mem(ngm->vxlan4_gpe_tunnel_by_key, &key4);
  }
  else
  {
    key6.local.as_u64[0] = a->local.ip6.as_u64[0];
    key6.local.as_u64[1] = a->local.ip6.as_u64[1];
    key6.remote.as_u64[0] = a->remote.ip6.as_u64[0];
    key6.remote.as_u64[1] = a->remote.ip6.as_u64[1];
    key6.vni = clib_host_to_net_u32 (a->vni << 8);

    p = hash_get_mem(ngm->vxlan6_gpe_tunnel_by_key, &key6);
  }

  if (a->is_add)
    {
      l2input_main_t * l2im = &l2input_main;

      /* adding a tunnel: tunnel must not already exist */
      if (p)
        return VNET_API_ERROR_TUNNEL_EXIST;

      pool_get_aligned (ngm->tunnels, t, CLIB_CACHE_LINE_BYTES);
      memset (t, 0, sizeof (*t));

      /* copy from arg structure */
#define _(x) t->x = a->x;
      foreach_gpe_copy_field;
      if (!a->is_ip6) foreach_copy_ipv4
      else            foreach_copy_ipv6
#undef _

      if (!a->is_ip6) t->flags |= VXLAN_GPE_TUNNEL_IS_IPV4;

      if (!a->is_ip6) {
        rv = vxlan4_gpe_rewrite (t, 0, 0, VXLAN_GPE_ENCAP_NEXT_IP4_LOOKUP);
      } else {
        rv = vxlan6_gpe_rewrite (t, 0, 0, VXLAN_GPE_ENCAP_NEXT_IP6_LOOKUP);
      }

      if (rv)
      {
          pool_put (ngm->tunnels, t);
          return rv;
      }

      if (!is_ip6)
      {
        key4_copy = clib_mem_alloc (sizeof (*key4_copy));
        clib_memcpy (key4_copy, &key4, sizeof (*key4_copy));
        hash_set_mem (ngm->vxlan4_gpe_tunnel_by_key, key4_copy,
                      t - ngm->tunnels);
      }
      else
      {
          key6_copy = clib_mem_alloc (sizeof (*key6_copy));
          clib_memcpy (key6_copy, &key6, sizeof (*key6_copy));
          hash_set_mem (ngm->vxlan6_gpe_tunnel_by_key, key6_copy,
                        t - ngm->tunnels);
      }

      if (vec_len (ngm->free_vxlan_gpe_tunnel_hw_if_indices) > 0)
        {
	      vnet_interface_main_t * im = &vnm->interface_main;
          hw_if_index = ngm->free_vxlan_gpe_tunnel_hw_if_indices
            [vec_len (ngm->free_vxlan_gpe_tunnel_hw_if_indices)-1];
          _vec_len (ngm->free_vxlan_gpe_tunnel_hw_if_indices) -= 1;

          hi = vnet_get_hw_interface (vnm, hw_if_index);
          hi->dev_instance = t - ngm->tunnels;
          hi->hw_instance = hi->dev_instance;
	  /* clear old stats of freed tunnel before reuse */
	  sw_if_index = hi->sw_if_index;
	  vnet_interface_counter_lock(im);
	  vlib_zero_combined_counter
	    (&im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_TX], sw_if_index);
	  vlib_zero_combined_counter
	    (&im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_RX], sw_if_index);
	  vlib_zero_simple_counter
	    (&im->sw_if_counters[VNET_INTERFACE_COUNTER_DROP], sw_if_index);
	  vnet_interface_counter_unlock(im);
        }
      else
        {
          hw_if_index = vnet_register_interface
            (vnm, vxlan_gpe_device_class.index, t - ngm->tunnels,
             vxlan_gpe_hw_class.index, t - ngm->tunnels);
          hi = vnet_get_hw_interface (vnm, hw_if_index);
          hi->output_node_index = vxlan_gpe_encap_node.index;
        }

      t->hw_if_index = hw_if_index;
      t->sw_if_index = sw_if_index = hi->sw_if_index;
      vec_validate_init_empty (ngm->tunnel_index_by_sw_if_index, sw_if_index, ~0);
      ngm->tunnel_index_by_sw_if_index[sw_if_index] = t - ngm->tunnels;

      /* setup l2 input config with l2 feature and bd 0 to drop packet */
      vec_validate (l2im->configs, sw_if_index);
      l2im->configs[sw_if_index].feature_bitmap = L2INPUT_FEAT_DROP;
      l2im->configs[sw_if_index].bd_index = 0;

      vnet_sw_interface_t * si = vnet_get_sw_interface (vnm, sw_if_index);
      si->flags &= ~VNET_SW_INTERFACE_FLAG_HIDDEN;
      vnet_sw_interface_set_flags (vnm, hi->sw_if_index,
                                   VNET_SW_INTERFACE_FLAG_ADMIN_UP);
      fib_node_init(&t->node, FIB_NODE_TYPE_VXLAN_GPE_TUNNEL);
      fib_prefix_t tun_remote_pfx;
      u32 encap_index = vxlan_gpe_encap_node.index;
      vnet_flood_class_t flood_class = VNET_FLOOD_CLASS_TUNNEL_NORMAL;

      fib_prefix_from_ip46_addr(&t->remote, &tun_remote_pfx);
      if (!ip46_address_is_multicast(&t->remote))
        {
          /* Unicast tunnel -
           * 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
           */
          vtep_addr_ref(&t->local);
          t->fib_entry_index = fib_table_entry_special_add
            (t->encap_fib_index, &tun_remote_pfx, FIB_SOURCE_RR,
	     FIB_ENTRY_FLAG_NONE);
          t->sibling_index = fib_entry_child_add
            (t->fib_entry_index, FIB_NODE_TYPE_VXLAN_GPE_TUNNEL, t - ngm->tunnels);
          vxlan_gpe_tunnel_restack_dpo(t);
	}
      else
        {
 	  /* Multicast tunnel -
	   * as the same mcast group can be used for mutiple mcast tunnels
	   * with different VNIs, create the output fib adjecency only if
	   * it does not already exist
	   */
          fib_protocol_t fp = fib_ip_proto(is_ip6);

	  if (vtep_addr_ref(&t->remote) == 1)
          {
              fib_node_index_t mfei;
              adj_index_t ai;
              fib_route_path_t path = {
                  .frp_proto = fib_proto_to_dpo(fp),
                  .frp_addr = zero_addr,
                  .frp_sw_if_index = 0xffffffff,
                  .frp_fib_index = ~0,
                  .frp_weight = 0,
                  .frp_flags = FIB_ROUTE_PATH_LOCAL,
              };
              const mfib_prefix_t mpfx = {
                  .fp_proto = fp,
                  .fp_len = (is_ip6 ? 128 : 32),
                  .fp_grp_addr = tun_remote_pfx.fp_addr,
              };

              /*
               * Setup the (*,G) to receive traffic on the mcast group
               *  - the forwarding interface is for-us
               *  - the accepting interface is that from the API
               */
              mfib_table_entry_path_update(t->encap_fib_index,
                                           &mpfx,
                                           MFIB_SOURCE_VXLAN_GPE,
                                           &path,
                                           MFIB_ITF_FLAG_FORWARD);

              path.frp_sw_if_index = a->mcast_sw_if_index;
              path.frp_flags = FIB_ROUTE_PATH_FLAG_NONE;
              mfei = mfib_table_entry_path_update(t->encap_fib_index,
                                                  &mpfx,
                                                  MFIB_SOURCE_VXLAN_GPE,
                                                  &path,
                                                  MFIB_ITF_FLAG_ACCEPT);

              /*
               * Create the mcast adjacency to send traffic to the group
               */
              ai = adj_mcast_add_or_lock(fp,
                                         fib_proto_to_link(fp),
                                         a->mcast_sw_if_index);

              /*
               * create a new end-point
               */
              mcast_shared_add(&t->remote, mfei, ai);
          }

          dpo_id_t dpo = DPO_INVALID;
          mcast_shared_t ep = mcast_shared_get(&t->remote);

          /* Stack shared mcast remote mac addr rewrite on encap */
          dpo_set (&dpo, DPO_ADJACENCY_MCAST,
                   fib_proto_to_dpo(fp),
                   ep.mcast_adj_index);

          dpo_stack_from_node (encap_index, &t->next_dpo, &dpo);
          dpo_reset (&dpo);
	  flood_class = VNET_FLOOD_CLASS_TUNNEL_MASTER;
	}

      /* Set vxlan tunnel output node */
      hi->output_node_index = encap_index;

      vnet_get_sw_interface (vnet_get_main(), sw_if_index)->flood_class = flood_class;
    }
  else
    {
      /* deleting a tunnel: tunnel must exist */
      if (!p)
        return VNET_API_ERROR_NO_SUCH_ENTRY;

      t = pool_elt_at_index (ngm->tunnels, p[0]);

      sw_if_index = t->sw_if_index;
      vnet_sw_interface_set_flags (vnm, t->sw_if_index, 0 /* down */);
      vnet_sw_interface_t * si = vnet_get_sw_interface (vnm, t->sw_if_index);
      si->flags |= VNET_SW_INTERFACE_FLAG_HIDDEN;
      set_int_l2_mode(ngm->vlib_main, vnm, MODE_L3, t->sw_if_index, 0, 0, 0, 0);
      vec_add1 (ngm->free_vxlan_gpe_tunnel_hw_if_indices, t->hw_if_index);

      ngm->tunnel_index_by_sw_if_index[t->sw_if_index] = ~0;

      if (!is_ip6)
        hash_unset (ngm->vxlan4_gpe_tunnel_by_key, key4.as_u64);
      else
	hash_unset_key_free (&ngm->vxlan6_gpe_tunnel_by_key, &key6);

      if (!ip46_address_is_multicast(&t->remote))
        {
	  vtep_addr_unref(&t->local);
	  fib_entry_child_remove(t->fib_entry_index, t->sibling_index);
	  fib_table_entry_delete_index(t->fib_entry_index, FIB_SOURCE_RR);
        }
      else if (vtep_addr_unref(&t->remote) == 0)
        {
	  mcast_shared_remove(&t->remote);
        }

      fib_node_deinit(&t->node);
      vec_free (t->rewrite);
      pool_put (ngm->tunnels, t);
    }

  if (sw_if_indexp)
      *sw_if_indexp = sw_if_index;

  return 0;
}

static clib_error_t *
vxlan_gpe_add_del_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;
  u8 is_add = 1;
  ip46_address_t local, remote;
  u8 local_set = 0;
  u8 remote_set = 0;
  u8 grp_set = 0;
  u8 ipv4_set = 0;
  u8 ipv6_set = 0;
  u32 mcast_sw_if_index = ~0;
  u32 encap_fib_index = 0;
  u32 decap_fib_index = 0;
  u8 protocol = VXLAN_GPE_PROTOCOL_IP4;
  u32 vni;
  u8 vni_set = 0;
  int rv;
  u32 tmp;
  vnet_vxlan_gpe_add_del_tunnel_args_t _a, * a = &_a;
  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, "local %U",
                       unformat_ip4_address, &local.ip4))
    {
      local_set = 1;
      ipv4_set = 1;
    }
    else if (unformat (line_input, "remote %U",
                       unformat_ip4_address, &remote.ip4))
    {
      remote_set = 1;
      ipv4_set = 1;
    }
    else if (unformat (line_input, "local %U",
                       unformat_ip6_address, &local.ip6))
    {
      local_set = 1;
      ipv6_set = 1;
    }
    else if (unformat (line_input, "remote %U",
                       unformat_ip6_address, &remote.ip6))
    {
      remote_set = 1;
      ipv6_set = 1;
    }
    else if (unformat (line_input, "group %U %U",
                       unformat_ip4_address, &remote.ip4,
		       unformat_vnet_sw_interface,
		       vnet_get_main(), &mcast_sw_if_index))
      {
        grp_set = remote_set = 1;
        ipv4_set = 1;
      }
    else if (unformat (line_input, "group %U %U",
                       unformat_ip6_address, &remote.ip6,
		       unformat_vnet_sw_interface,
		       vnet_get_main(), &mcast_sw_if_index))
      {
        grp_set = remote_set = 1;
        ipv6_set = 1;
      }
    else if (unformat (line_input, "encap-vrf-id %d", &tmp))
      {
        if (ipv6_set)
          encap_fib_index = fib_table_find (FIB_PROTOCOL_IP6, tmp);
        else
          encap_fib_index = fib_table_find (FIB_PROTOCOL_IP4, tmp);

        if (encap_fib_index == ~0)
          {
            error = clib_error_return (0, "nonexistent encap fib id %d", tmp);
            goto done;
          }
      }
    else if (unformat (line_input, "decap-vrf-id %d", &tmp))
      {
        if (ipv6_set)
          decap_fib_index = fib_table_find (FIB_PROTOCOL_IP6, tmp);
        else
          decap_fib_index = fib_table_find (FIB_PROTOCOL_IP4, tmp);

        if (decap_fib_index == ~0)
          {
            error = clib_error_return (0, "nonexistent decap fib id %d", tmp);
            goto done;
          }
      }
    else if (unformat (line_input, "vni %d", &vni))
      vni_set = 1;
    else if (unformat(line_input, "next-ip4"))
      protocol = VXLAN_GPE_PROTOCOL_IP4;
    else if (unformat(line_input, "next-ip6"))
      protocol = VXLAN_GPE_PROTOCOL_IP6;
    else if (unformat(line_input, "next-ethernet"))
      protocol = VXLAN_GPE_PROTOCOL_ETHERNET;
    else if (unformat(line_input, "next-nsh"))
      protocol = VXLAN_GPE_PROTOCOL_NSH;
    else
      {
        error = clib_error_return (0, "parse error: '%U'",
                                   format_unformat_error, line_input);
        goto done;
      }
  }

  if (local_set == 0)
    {
      error = clib_error_return (0, "tunnel local address not specified");
      goto done;
    }

  if (remote_set == 0)
    {
      error = clib_error_return (0, "tunnel remote address not specified");
      goto done;
    }

  if (grp_set && !ip46_address_is_multicast(&remote))
    {
      error = clib_error_return (0, "tunnel group address not multicast");
      goto done;
    }

  if (grp_set == 0 && ip46_address_is_multicast(&remote))
    {
      error = clib_error_return (0, "remote address must be unicast");
      goto done;
    }

  if (grp_set && mcast_sw_if_index == ~0)
    {
      error = clib_error_return (0, "tunnel nonexistent multicast device");
      goto done;
    }
  if (ipv4_set && ipv6_set)
    {
      error = clib_error_return (0, "both IPv4 and IPv6 addresses specified");
      goto done;
    }

  if ((ipv4_set && memcmp(&local.ip4, &remote.ip4, sizeof(local.ip4)) == 0) ||
      (ipv6_set && memcmp(&local.ip6, &remote.ip6, sizeof(local.ip6)) == 0))
    {
      error = clib_error_return (0, "src and remote addresses are identical");
      goto done;
    }

  if (vni_set == 0)
    {
      error = clib_error_return (0, "vni not specified");
      goto done;
    }

  memset (a, 0, sizeof (*a));

  a->is_add = is_add;
  a->is_ip6 = ipv6_set;

#define _(x) a->x = x;
  foreach_gpe_copy_field;
  if (ipv4_set) foreach_copy_ipv4
  else          foreach_copy_ipv6
#undef _

  rv = vnet_vxlan_gpe_add_del_tunnel (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_INVALID_DECAP_NEXT:
      error = clib_error_return (0, "invalid decap-next...");
      goto done;

    case VNET_API_ERROR_TUNNEL_EXIST:
      error = clib_error_return (0, "tunnel already exists...");
      goto done;

    case VNET_API_ERROR_NO_SUCH_ENTRY:
      error = clib_error_return (0, "tunnel does not exist...");
      goto done;

    default:
      error = clib_error_return
        (0, "vnet_vxlan_gpe_add_del_tunnel returned %d", rv);
      goto done;
    }

done:
  unformat_free (line_input);

  return error;
}

/*?
 * Add or delete a VXLAN-GPE Tunnel.
 *
 * VXLAN-GPE provides the features needed to allow L2 bridge domains (BDs)
 * to span multiple servers. This is done by building an L2 overlay on
 * top of an L3 network underlay using VXLAN-GPE tunnels.
 *
 * This makes it possible for servers to be co-located in the same data
 * center or be separated geographically as long as they are reachable
 * through the underlay L3 network.
 *
 * You can refer to this kind of L2 overlay bridge domain as a VXLAN-GPE sengment.
 *
 * @cliexpar
 * Example of how to create a VXLAN-GPE Tunnel:
 * @cliexcmd{create vxlan-gpe tunnel local 10.0.3.1 local 10.0.3.3 vni 13 encap-vrf-id 7}
 * Example of how to delete a VXLAN Tunnel:
 * @cliexcmd{create vxlan tunnel src 10.0.3.1 remote 10.0.3.3 vni 13 del}
 ?*/
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (create_vxlan_gpe_tunnel_command, static) = {
  .path = "create vxlan-gpe tunnel",
  .short_help =
  "create vxlan-gpe tunnel local <local-addr> "
  " {remote <remote-addr>|group <mcast-addr> <intf-name>}"
  " vni <nn> [next-ip4][next-ip6][next-ethernet][next-nsh]"
  " [encap-vrf-id <nn>] [decap-vrf-id <nn>] [del]\n",
  .function = vxlan_gpe_add_del_tunnel_command_fn,
};
/* *INDENT-ON* */

/**
 * @brief CLI function for showing VXLAN GPE tunnels
 *
 * @param *vm
 * @param *input
 * @param *cmd
 *
 * @return error
 *
 */
static clib_error_t *
show_vxlan_gpe_tunnel_command_fn (vlib_main_t * vm,
                                unformat_input_t * input,
                                vlib_cli_command_t * cmd)
{
  vxlan_gpe_main_t * ngm = &vxlan_gpe_main;
  vxlan_gpe_tunnel_t * t;

  if (pool_elts (ngm->tunnels) == 0)
    vlib_cli_output (vm, "No vxlan-gpe tunnels configured.");

  pool_foreach (t, ngm->tunnels,
  ({
    vlib_cli_output (vm, "%U", format_vxlan_gpe_tunnel, t);
  }));

  return 0;
}

/*?
 * Display all the VXLAN-GPE Tunnel entries.
 *
 * @cliexpar
 * Example of how to display the VXLAN-GPE Tunnel entries:
 * @cliexstart{show vxlan-gpe tunnel}
 * [0] local 10.0.3.1 remote 10.0.3.3 vni 13 encap_fib_index 0 sw_if_index 5 decap_next l2
 * @cliexend
 ?*/
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_vxlan_gpe_tunnel_command, static) = {
    .path = "show vxlan-gpe",
    .function = show_vxlan_gpe_tunnel_command_fn,
};
/* *INDENT-ON* */

void vnet_int_vxlan_gpe_bypass_mode (u32 sw_if_index,
				 u8 is_ip6,
				 u8 is_enable)
{
  if (is_ip6)
    vnet_feature_enable_disable ("ip6-unicast", "ip6-vxlan-gpe-bypass",
				 sw_if_index, is_enable, 0, 0);
  else
    vnet_feature_enable_disable ("ip4-unicast", "ip4-vxlan-gpe-bypass",
				 sw_if_index, is_enable, 0, 0);
}


static clib_error_t *
set_ip_vxlan_gpe_bypass (u32 is_ip6,
		     unformat_input_t * input,
		     vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, * line_input = &_line_input;
  vnet_main_t * vnm = vnet_get_main();
  clib_error_t * error = 0;
  u32 sw_if_index, is_enable;

  sw_if_index = ~0;
  is_enable = 1;

  if (! unformat_user (input, unformat_line_input, line_input))
    return 0;

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat_user (line_input, unformat_vnet_sw_interface, vnm, &sw_if_index))
	  ;
      else if (unformat (line_input, "del"))
        is_enable = 0;
      else
        {
	  error = unformat_parse_error (line_input);
	  goto done;
	}
    }

  if (~0 == sw_if_index)
    {
      error = clib_error_return (0, "unknown interface `%U'",
				 format_unformat_error, line_input);
      goto done;
    }

  vnet_int_vxlan_gpe_bypass_mode (sw_if_index, is_ip6, is_enable);

 done:
  unformat_free (line_input);

  return error;
}

static clib_error_t *
set_ip4_vxlan_gpe_bypass (vlib_main_t * vm,
		      unformat_input_t * input,
		      vlib_cli_command_t * cmd)
{
  return set_ip_vxlan_gpe_bypass (0, input, cmd);
}

/*?
 * This command adds the 'ip4-vxlan-gpe-bypass' graph node for a given interface.
 * By adding the IPv4 vxlan-gpe-bypass graph node to an interface, the node checks
 *  for and validate input vxlan_gpe packet and bypass ip4-lookup, ip4-local,
 * ip4-udp-lookup nodes to speedup vxlan_gpe packet forwarding. This node will
 * cause extra overhead to for non-vxlan_gpe packets which is kept at a minimum.
 *
 * @cliexpar
 * @parblock
 * Example of graph node before ip4-vxlan-gpe-bypass is enabled:
 * @cliexstart{show vlib graph ip4-vxlan-gpe-bypass}
 *            Name                      Next                    Previous
 * ip4-vxlan-gpe-bypass                error-drop [0]
 *                                vxlan4-gpe-input [1]
 *                                 ip4-lookup [2]
 * @cliexend
 *
 * Example of how to enable ip4-vxlan-gpe-bypass on an interface:
 * @cliexcmd{set interface ip vxlan-gpe-bypass GigabitEthernet2/0/0}
 *
 * Example of graph node after ip4-vxlan-gpe-bypass is enabled:
 * @cliexstart{show vlib graph ip4-vxlan-gpe-bypass}
 *            Name                      Next                    Previous
 * ip4-vxlan-gpe-bypass                error-drop [0]               ip4-input
 *                                vxlan4-gpe-input [1]        ip4-input-no-checksum
 *                                 ip4-lookup [2]
 * @cliexend
 *
 * Example of how to display the feature enabed on an interface:
 * @cliexstart{show ip interface features GigabitEthernet2/0/0}
 * IP feature paths configured on GigabitEthernet2/0/0...
 * ...
 * ipv4 unicast:
 *   ip4-vxlan-gpe-bypass
 *   ip4-lookup
 * ...
 * @cliexend
 *
 * Example of how to disable ip4-vxlan-gpe-bypass on an interface:
 * @cliexcmd{set interface ip vxlan-gpe-bypass GigabitEthernet2/0/0 del}
 * @endparblock
?*/
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (set_interface_ip_vxlan_gpe_bypass_command, static) = {
  .path = "set interface ip vxlan-gpe-bypass",
  .function = set_ip4_vxlan_gpe_bypass,
  .short_help = "set interface ip vxlan-gpe-bypass <interface> [del]",
};
/* *INDENT-ON* */

static clib_error_t *
set_ip6_vxlan_gpe_bypass (vlib_main_t * vm,
		      unformat_input_t * input,
		      vlib_cli_command_t * cmd)
{
  return set_ip_vxlan_gpe_bypass (1, input, cmd);
}

/*?
 * This command adds the 'ip6-vxlan-gpe-bypass' graph node for a given interface.
 * By adding the IPv6 vxlan-gpe-bypass graph node to an interface, the node checks
 *  for and validate input vxlan_gpe packet and bypass ip6-lookup, ip6-local,
 * ip6-udp-lookup nodes to speedup vxlan_gpe packet forwarding. This node will
 * cause extra overhead to for non-vxlan_gpe packets which is kept at a minimum.
 *
 * @cliexpar
 * @parblock
 * Example of graph node before ip6-vxlan-gpe-bypass is enabled:
 * @cliexstart{show vlib graph ip6-vxlan-gpe-bypass}
 *            Name                      Next                    Previous
 * ip6-vxlan-gpe-bypass                error-drop [0]
 *                                vxlan6-gpe-input [1]
 *                                 ip6-lookup [2]
 * @cliexend
 *
 * Example of how to enable ip6-vxlan-gpe-bypass on an interface:
 * @cliexcmd{set interface ip6 vxlan-gpe-bypass GigabitEthernet2/0/0}
 *
 * Example of graph node after ip6-vxlan-gpe-bypass is enabled:
 * @cliexstart{show vlib graph ip6-vxlan-gpe-bypass}
 *            Name                      Next                    Previous
 * ip6-vxlan-gpe-bypass                error-drop [0]               ip6-input
 *                                vxlan6-gpe-input [1]        ip4-input-no-checksum
 *                                 ip6-lookup [2]
 * @cliexend
 *
 * Example of how to display the feature enabed on an interface:
 * @cliexstart{show ip interface features GigabitEthernet2/0/0}
 * IP feature paths configured on GigabitEthernet2/0/0...
 * ...
 * ipv6 unicast:
 *   ip6-vxlan-gpe-bypass
 *   ip6-lookup
 * ...
 * @cliexend
 *
 * Example of how to disable ip6-vxlan-gpe-bypass on an interface:
 * @cliexcmd{set interface ip6 vxlan-gpe-bypass GigabitEthernet2/0/0 del}
 * @endparblock
?*/
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (set_interface_ip6_vxlan_gpe_bypass_command, static) = {
  .path = "set interface ip6 vxlan-gpe-bypass",
  .function = set_ip6_vxlan_gpe_bypass,
  .short_help = "set interface ip vxlan-gpe-bypass <interface> [del]",
};
/* *INDENT-ON* */

/* *INDENT-OFF* */
VNET_FEATURE_INIT (ip4_vxlan_gpe_bypass, static) =
{
  .arc_name = "ip4-unicast",
  .node_name = "ip4-vxlan-gpe-bypass",
  .runs_before = VNET_FEATURES ("ip4-lookup"),
};

VNET_FEATURE_INIT (ip6_vxlan_gpe_bypass, static) =
{
  .arc_name = "ip6-unicast",
  .node_name = "ip6-vxlan-gpe-bypass",
  .runs_before = VNET_FEATURES ("ip6-lookup"),
};
/* *INDENT-ON* */

/**
 * @brief Feature init function for VXLAN GPE
 *
 * @param *vm
 *
 * @return error
 *
 */
clib_error_t *vxlan_gpe_init (vlib_main_t *vm)
{
  vxlan_gpe_main_t *ngm = &vxlan_gpe_main;

  ngm->vnet_main = vnet_get_main();
  ngm->vlib_main = vm;

  ngm->vxlan4_gpe_tunnel_by_key
    = hash_create_mem (0, sizeof(vxlan4_gpe_tunnel_key_t), sizeof (uword));

  ngm->vxlan6_gpe_tunnel_by_key
    = hash_create_mem (0, sizeof(vxlan6_gpe_tunnel_key_t), sizeof (uword));


  ngm->mcast_shared = hash_create_mem(0,
        sizeof(ip46_address_t),
	sizeof(mcast_shared_t));

  udp_register_dst_port (vm, UDP_DST_PORT_VXLAN_GPE,
                         vxlan4_gpe_input_node.index, 1 /* is_ip4 */);
  udp_register_dst_port (vm, UDP_DST_PORT_VXLAN6_GPE,
                         vxlan6_gpe_input_node.index, 0 /* is_ip4 */);

  /* Register the list of standard decap protocols supported */
  vxlan_gpe_register_decap_protocol (VXLAN_GPE_PROTOCOL_IP4,
                                     VXLAN_GPE_INPUT_NEXT_IP4_INPUT);
  vxlan_gpe_register_decap_protocol (VXLAN_GPE_PROTOCOL_IP6,
                                     VXLAN_GPE_INPUT_NEXT_IP6_INPUT);
  vxlan_gpe_register_decap_protocol (VXLAN_GPE_PROTOCOL_ETHERNET,
                                     VXLAN_GPE_INPUT_NEXT_ETHERNET_INPUT);

  fib_node_register_type(FIB_NODE_TYPE_VXLAN_GPE_TUNNEL, &vxlan_gpe_vft);

  return 0;
}

VLIB_INIT_FUNCTION(vxlan_gpe_init);

