/*
 * ipip.c: ipip
 *
 * Copyright (c) 2018 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 aipiped 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 <stddef.h>
#include <vnet/adj/adj_midchain.h>
#include <vnet/ipip/ipip.h>
#include <vnet/vnet.h>
#include <vnet/adj/adj_nbr.h>
#include <vnet/adj/adj_midchain.h>
#include <vnet/fib/ip4_fib.h>
#include <vnet/fib/ip6_fib.h>
#include <vnet/ip/format.h>
#include <vnet/ipip/ipip.h>
#include <vnet/teib/teib.h>
#include <vnet/tunnel/tunnel_dp.h>

ipip_main_t ipip_main;

/* Packet trace structure */
typedef struct
{
  u32 tunnel_id;
  u32 length;
  ip46_address_t src;
  ip46_address_t dst;
} ipip_tx_trace_t;

u8 *
format_ipip_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 *);
  ipip_tx_trace_t *t = va_arg (*args, ipip_tx_trace_t *);

  s =
    format (s, "IPIP: tunnel %d len %d src %U dst %U", t->tunnel_id,
	    t->length, format_ip46_address, &t->src, IP46_TYPE_ANY,
	    format_ip46_address, &t->dst, IP46_TYPE_ANY);
  return s;
}

static u8 *
ipip_build_rewrite (vnet_main_t * vnm, u32 sw_if_index,
		    vnet_link_t link_type, const void *dst_address)
{
  const ip46_address_t *dst;
  ip4_header_t *ip4;
  ip6_header_t *ip6;
  u8 *rewrite = NULL;
  ipip_tunnel_t *t;

  dst = dst_address;
  t = ipip_tunnel_db_find_by_sw_if_index (sw_if_index);

  if (!t)
    /* not one of ours */
    return (0);

  switch (t->transport)
    {
    case IPIP_TRANSPORT_IP4:
      vec_validate (rewrite, sizeof (*ip4) - 1);
      ip4 = (ip4_header_t *) rewrite;
      ip4->ip_version_and_header_length = 0x45;
      ip4->ttl = 64;
      /* fixup ip4 header length, protocol and checksum after-the-fact */
      ip4->src_address.as_u32 = t->tunnel_src.ip4.as_u32;
      ip4->dst_address.as_u32 = dst->ip4.as_u32;
      if (!(t->flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP))
	ip4_header_set_dscp (ip4, t->dscp);
      if (t->flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_SET_DF)
	ip4_header_set_df (ip4);

      switch (link_type)
	{
	case VNET_LINK_IP6:
	  ip4->protocol = IP_PROTOCOL_IPV6;
	  break;
	case VNET_LINK_IP4:
	  ip4->protocol = IP_PROTOCOL_IP_IN_IP;
	  break;
	case VNET_LINK_MPLS:
	  ip4->protocol = IP_PROTOCOL_MPLS_IN_IP;
	  break;
	default:
	  break;
	}
      ip4->checksum = ip4_header_checksum (ip4);
      break;

    case IPIP_TRANSPORT_IP6:
      vec_validate (rewrite, sizeof (*ip6) - 1);
      ip6 = (ip6_header_t *) rewrite;
      ip6->ip_version_traffic_class_and_flow_label =
	clib_host_to_net_u32 (6 << 28);
      ip6->hop_limit = 64;
      /* fixup ip6 header length and protocol after-the-fact */
      ip6->src_address.as_u64[0] = t->tunnel_src.ip6.as_u64[0];
      ip6->src_address.as_u64[1] = t->tunnel_src.ip6.as_u64[1];
      ip6->dst_address.as_u64[0] = dst->ip6.as_u64[0];
      ip6->dst_address.as_u64[1] = dst->ip6.as_u64[1];
      if (!(t->flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP))
	ip6_set_dscp_network_order (ip6, t->dscp);

      switch (link_type)
	{
	case VNET_LINK_IP6:
	  ip6->protocol = IP_PROTOCOL_IPV6;
	  break;
	case VNET_LINK_IP4:
	  ip6->protocol = IP_PROTOCOL_IP_IN_IP;
	  break;
	case VNET_LINK_MPLS:
	  ip6->protocol = IP_PROTOCOL_MPLS_IN_IP;
	  break;
	default:
	  break;
	}
      break;
    }
  return (rewrite);
}

static void
ipip64_fixup (vlib_main_t * vm, const ip_adjacency_t * adj, vlib_buffer_t * b,
	      const void *data)
{
  tunnel_encap_decap_flags_t flags;
  ip4_header_t *ip4;

  flags = pointer_to_uword (data);

  ip4 = vlib_buffer_get_current (b);
  ip4->length = clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b));
  tunnel_encap_fixup_6o4 (flags, ((ip6_header_t *) (ip4 + 1)), ip4);

  if (PREDICT_FALSE (b->flags & VNET_BUFFER_F_GSO))
    {
      vnet_buffer2 (b)->outer_l3_hdr_offset = (u8 *) ip4 - b->data;
      vnet_buffer_offload_flags_set (b, VNET_BUFFER_OFFLOAD_F_OUTER_IP_CKSUM |
					  VNET_BUFFER_OFFLOAD_F_TNL_IPIP);
    }
  else
    ip4->checksum = ip4_header_checksum (ip4);
}

static void
ipip44_fixup (vlib_main_t * vm, const ip_adjacency_t * adj, vlib_buffer_t * b,
	      const void *data)
{
  tunnel_encap_decap_flags_t flags;
  ip4_header_t *ip4;

  flags = pointer_to_uword (data);

  ip4 = vlib_buffer_get_current (b);
  ip4->length = clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b));
  tunnel_encap_fixup_4o4 (flags, ip4 + 1, ip4);

  if (PREDICT_FALSE (b->flags & VNET_BUFFER_F_GSO))
    {
      vnet_buffer2 (b)->outer_l3_hdr_offset = (u8 *) ip4 - b->data;
      vnet_buffer_offload_flags_set (b, VNET_BUFFER_OFFLOAD_F_OUTER_IP_CKSUM |
					  VNET_BUFFER_OFFLOAD_F_TNL_IPIP);
    }
  else
    ip4->checksum = ip4_header_checksum (ip4);
}

static void
ipip46_fixup (vlib_main_t * vm, const ip_adjacency_t * adj, vlib_buffer_t * b,
	      const void *data)
{
  tunnel_encap_decap_flags_t flags;
  ip6_header_t *ip6;

  flags = pointer_to_uword (data);

  /* Must set locally originated otherwise we're not allowed to
     fragment the packet later */
  b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;

  ip6 = vlib_buffer_get_current (b);
  ip6->payload_length =
    clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b) -
			  sizeof (*ip6));
  tunnel_encap_fixup_4o6 (flags, b, ((ip4_header_t *) (ip6 + 1)), ip6);

  if (PREDICT_FALSE (b->flags & VNET_BUFFER_F_GSO))
    {
      vnet_buffer2 (b)->outer_l3_hdr_offset = (u8 *) ip6 - b->data;
      vnet_buffer_offload_flags_set (b, VNET_BUFFER_OFFLOAD_F_TNL_IPIP);
    }
}

static void
ipip66_fixup (vlib_main_t * vm,
	      const ip_adjacency_t * adj, vlib_buffer_t * b, const void *data)
{
  tunnel_encap_decap_flags_t flags;
  ip6_header_t *ip6;

  flags = pointer_to_uword (data);

  /* Must set locally originated otherwise we're not allowed to
     fragment the packet later */
  b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;

  ip6 = vlib_buffer_get_current (b);
  ip6->payload_length =
    clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b) -
			  sizeof (*ip6));
  tunnel_encap_fixup_6o6 (flags, ip6 + 1, ip6);

  if (PREDICT_FALSE (b->flags & VNET_BUFFER_F_GSO))
    {
      vnet_buffer2 (b)->outer_l3_hdr_offset = (u8 *) ip6 - b->data;
      vnet_buffer_offload_flags_set (b, VNET_BUFFER_OFFLOAD_F_TNL_IPIP);
    }
}

static void
ipipm6_fixup (vlib_main_t *vm, const ip_adjacency_t *adj, vlib_buffer_t *b,
	      const void *data)
{
  tunnel_encap_decap_flags_t flags;
  ip6_header_t *ip6;

  flags = pointer_to_uword (data);

  /* Must set locally originated otherwise we're not allowed to
     fragment the packet later and we'll get an unwanted hop-limt
     decrement */
  b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;

  ip6 = vlib_buffer_get_current (b);
  ip6->payload_length =
    clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b) - sizeof (*ip6));
  tunnel_encap_fixup_mplso6 (flags, b, (mpls_unicast_header_t *) (ip6 + 1),
			     ip6);

  if (PREDICT_FALSE (b->flags & VNET_BUFFER_F_GSO))
    {
      vnet_buffer2 (b)->outer_l3_hdr_offset = (u8 *) ip6 - b->data;
      vnet_buffer_offload_flags_set (b, VNET_BUFFER_OFFLOAD_F_TNL_IPIP);
    }
}

static void
ipipm4_fixup (vlib_main_t *vm, const ip_adjacency_t *adj, vlib_buffer_t *b,
	      const void *data)
{
  tunnel_encap_decap_flags_t flags;
  ip4_header_t *ip4;

  flags = pointer_to_uword (data);

  /* Must set locally originated otherwise we'll do a TTL decrement
   * during ip4-rewrite */
  b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;

  ip4 = vlib_buffer_get_current (b);
  ip4->length =
    clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b) - sizeof (*ip4));
  tunnel_encap_fixup_mplso4 (flags, (mpls_unicast_header_t *) (ip4 + 1), ip4);

  if (PREDICT_FALSE (b->flags & VNET_BUFFER_F_GSO))
    {
      vnet_buffer2 (b)->outer_l3_hdr_offset = (u8 *) ip4 - b->data;
      vnet_buffer_offload_flags_set (b, VNET_BUFFER_OFFLOAD_F_OUTER_IP_CKSUM |
					  VNET_BUFFER_OFFLOAD_F_TNL_IPIP);
    }
  else
    ip4->checksum = ip4_header_checksum (ip4);
}

static void
ipip_tunnel_stack (adj_index_t ai)
{
  ip_adjacency_t *adj;
  ipip_tunnel_t *t;
  u32 sw_if_index;

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

  t = ipip_tunnel_db_find_by_sw_if_index (sw_if_index);
  if (!t)
    return;

  if ((vnet_hw_interface_get_flags (vnet_get_main (), t->hw_if_index) &
       VNET_HW_INTERFACE_FLAG_LINK_UP) == 0)
    {
      adj_midchain_delegate_unstack (ai);
    }
  else
    {
      fib_prefix_t dst = {
        .fp_len = t->transport == IPIP_TRANSPORT_IP6 ? 128 : 32,
        .fp_proto = (t->transport == IPIP_TRANSPORT_IP6 ?
                     FIB_PROTOCOL_IP6 :
                     FIB_PROTOCOL_IP4),
        .fp_addr = t->tunnel_dst
      };

      adj_midchain_delegate_stack (ai, t->fib_index, &dst);
    }
}

static adj_walk_rc_t
ipip_adj_walk_cb (adj_index_t ai, void *ctx)
{
  ipip_tunnel_stack (ai);

  return (ADJ_WALK_RC_CONTINUE);
}

static void
ipip_tunnel_restack (ipip_tunnel_t * gt)
{
  fib_protocol_t proto;

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

static adj_midchain_fixup_t
ipip_get_fixup (const ipip_tunnel_t * t, vnet_link_t lt, adj_flags_t * aflags)
{
  if (t->transport == IPIP_TRANSPORT_IP6 && lt == VNET_LINK_IP6)
    return (ipip66_fixup);
  if (t->transport == IPIP_TRANSPORT_IP6 && lt == VNET_LINK_IP4)
    return (ipip46_fixup);
  if (t->transport == IPIP_TRANSPORT_IP6 && lt == VNET_LINK_MPLS)
    return (ipipm6_fixup);
  if (t->transport == IPIP_TRANSPORT_IP4 && lt == VNET_LINK_IP6)
    return (ipip64_fixup);
  if (t->transport == IPIP_TRANSPORT_IP4 && lt == VNET_LINK_MPLS)
    return (ipipm4_fixup);
  if (t->transport == IPIP_TRANSPORT_IP4 && lt == VNET_LINK_IP4)
    {
      *aflags = *aflags | ADJ_FLAG_MIDCHAIN_FIXUP_IP4O4_HDR;
      return (ipip44_fixup);
    }

  ASSERT (0);
  return (ipip44_fixup);
}

void
ipip_update_adj (vnet_main_t * vnm, u32 sw_if_index, adj_index_t ai)
{
  adj_midchain_fixup_t fixup;
  ipip_tunnel_t *t;
  adj_flags_t af;

  af = ADJ_FLAG_NONE;
  t = ipip_tunnel_db_find_by_sw_if_index (sw_if_index);
  if (!t)
    return;

  /*
   * the user has not requested that the load-balancing be based on
   * a flow hash of the inner packet. so use the stacking to choose
   * a path.
   */
  if (!(t->flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_INNER_HASH))
    af |= ADJ_FLAG_MIDCHAIN_IP_STACK;

  fixup = ipip_get_fixup (t, adj_get_link_type (ai), &af);
  adj_nbr_midchain_update_rewrite
    (ai, fixup,
     uword_to_pointer (t->flags, void *), af,
     ipip_build_rewrite (vnm, sw_if_index,
			 adj_get_link_type (ai), &t->tunnel_dst));
  ipip_tunnel_stack (ai);
}

typedef struct mipip_walk_ctx_t_
{
  const ipip_tunnel_t *t;
  const teib_entry_t *ne;
} mipip_walk_ctx_t;

static adj_walk_rc_t
mipip_mk_complete_walk (adj_index_t ai, void *data)
{
  adj_midchain_fixup_t fixup;
  mipip_walk_ctx_t *ctx = data;
  adj_flags_t af;

  af = ADJ_FLAG_NONE;
  fixup = ipip_get_fixup (ctx->t, adj_get_link_type (ai), &af);

  /*
   * the user has not requested that the load-balancing be based on
   * a flow hash of the inner packet. so use the stacking to choose
   * a path.
   */
  if (!(ctx->t->flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_INNER_HASH))
    af |= ADJ_FLAG_MIDCHAIN_IP_STACK;

  adj_nbr_midchain_update_rewrite
    (ai, fixup,
     uword_to_pointer (ctx->t->flags, void *),
     af, ipip_build_rewrite (vnet_get_main (),
			     ctx->t->sw_if_index,
			     adj_get_link_type (ai),
			     &teib_entry_get_nh (ctx->ne)->fp_addr));

  teib_entry_adj_stack (ctx->ne, ai);

  return (ADJ_WALK_RC_CONTINUE);
}

static adj_walk_rc_t
mipip_mk_incomplete_walk (adj_index_t ai, void *data)
{
  adj_midchain_fixup_t fixup;
  ipip_tunnel_t *t = data;
  adj_flags_t af;

  af = ADJ_FLAG_NONE;
  fixup = ipip_get_fixup (t, adj_get_link_type (ai), &af);

  adj_nbr_midchain_update_rewrite (ai, fixup, NULL, ADJ_FLAG_NONE, NULL);

  adj_midchain_delegate_unstack (ai);

  return (ADJ_WALK_RC_CONTINUE);
}

void
mipip_update_adj (vnet_main_t * vnm, u32 sw_if_index, adj_index_t ai)
{
  ipip_main_t *gm = &ipip_main;
  adj_midchain_fixup_t fixup;
  ip_adjacency_t *adj;
  teib_entry_t *ne;
  ipip_tunnel_t *t;
  adj_flags_t af;
  u32 ti;

  af = ADJ_FLAG_NONE;
  adj = adj_get (ai);
  ti = gm->tunnel_index_by_sw_if_index[sw_if_index];
  t = pool_elt_at_index (gm->tunnels, ti);

  ne = teib_entry_find_46 (sw_if_index,
			   adj->ia_nh_proto, &adj->sub_type.nbr.next_hop);

  if (NULL == ne)
    {
      // no TEIB entry to provide the next-hop
      fixup = ipip_get_fixup (t, adj_get_link_type (ai), &af);
      adj_nbr_midchain_update_rewrite
	(ai, fixup, uword_to_pointer (t->flags, void *), ADJ_FLAG_NONE, NULL);
      return;
    }

  mipip_walk_ctx_t ctx = {
    .t = t,
    .ne = ne
  };
  adj_nbr_walk_nh (sw_if_index,
		   adj->ia_nh_proto,
		   &adj->sub_type.nbr.next_hop, mipip_mk_complete_walk, &ctx);
}

static u8 *
format_ipip_tunnel_name (u8 * s, va_list * args)
{
  u32 dev_instance = va_arg (*args, u32);
  ipip_main_t *gm = &ipip_main;
  ipip_tunnel_t *t;

  if (dev_instance >= vec_len (gm->tunnels))
    return format (s, "<improperly-referenced>");

  t = pool_elt_at_index (gm->tunnels, dev_instance);
  return format (s, "ipip%d", t->user_instance);
}

static u8 *
format_ipip_device (u8 * s, va_list * args)
{
  u32 dev_instance = va_arg (*args, u32);
  CLIB_UNUSED (int verbose) = va_arg (*args, int);

  s = format (s, "IPIP tunnel: id %d\n", dev_instance);
  return s;
}

static clib_error_t *
ipip_interface_admin_up_down (vnet_main_t * vnm, u32 hw_if_index, u32 flags)
{
  vnet_hw_interface_t *hi;
  ipip_tunnel_t *t;

  hi = vnet_get_hw_interface (vnm, hw_if_index);

  t = ipip_tunnel_db_find_by_sw_if_index (hi->sw_if_index);
  if (!t)
    return 0;

  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 */ );

  ipip_tunnel_restack (t);

  return /* no error */ 0;
}

static int
ipip_tunnel_desc (u32 sw_if_index,
		  ip46_address_t * src, ip46_address_t * dst, u8 * is_l2)
{
  ipip_tunnel_t *t;

  t = ipip_tunnel_db_find_by_sw_if_index (sw_if_index);
  if (!t)
    return -1;

  *src = t->tunnel_src;
  *dst = t->tunnel_dst;
  *is_l2 = 0;

  return (0);
}

VNET_DEVICE_CLASS(ipip_device_class) = {
    .name = "IPIP tunnel device",
    .format_device_name = format_ipip_tunnel_name,
    .format_device = format_ipip_device,
    .format_tx_trace = format_ipip_tx_trace,
    .admin_up_down_function = ipip_interface_admin_up_down,
    .ip_tun_desc = ipip_tunnel_desc,
#ifdef SOON
    .clear counter = 0;
#endif
};

VNET_HW_INTERFACE_CLASS(ipip_hw_interface_class) = {
    .name = "IPIP",
    //.format_header = format_ipip_header_with_length,
    //.unformat_header = unformat_ipip_header,
    .build_rewrite = ipip_build_rewrite,
    .update_adjacency = ipip_update_adj,
    .flags = VNET_HW_INTERFACE_CLASS_FLAG_P2P,
};

VNET_HW_INTERFACE_CLASS(mipip_hw_interface_class) = {
    .name = "mIPIP",
    //.format_header = format_ipip_header_with_length,
    //.unformat_header = unformat_ipip_header,
    .build_rewrite = ipip_build_rewrite,
    .update_adjacency = mipip_update_adj,
    .flags = VNET_HW_INTERFACE_CLASS_FLAG_NBMA,
};

ipip_tunnel_t *
ipip_tunnel_db_find (const ipip_tunnel_key_t * key)
{
  ipip_main_t *gm = &ipip_main;
  uword *p;

  p = hash_get_mem (gm->tunnel_by_key, key);
  if (!p)
    return (NULL);
  return (pool_elt_at_index (gm->tunnels, p[0]));
}

ipip_tunnel_t *
ipip_tunnel_db_find_by_sw_if_index (u32 sw_if_index)
{
  ipip_main_t *gm = &ipip_main;
  if (vec_len (gm->tunnel_index_by_sw_if_index) <= sw_if_index)
    return NULL;
  u32 ti = gm->tunnel_index_by_sw_if_index[sw_if_index];
  if (ti == ~0)
    return NULL;
  return pool_elt_at_index (gm->tunnels, ti);
}

void
ipip_tunnel_db_add (ipip_tunnel_t * t, const ipip_tunnel_key_t * key)
{
  ipip_main_t *gm = &ipip_main;

  hash_set_mem_alloc (&gm->tunnel_by_key, key, t->dev_instance);
}

void
ipip_tunnel_db_remove (ipip_tunnel_t * t, const ipip_tunnel_key_t * key)
{
  ipip_main_t *gm = &ipip_main;

  hash_unset_mem_free (&gm->tunnel_by_key, key);
}

void
ipip_mk_key_i (ipip_transport_t transport,
	       ipip_mode_t mode,
	       const ip46_address_t * src,
	       const ip46_address_t * dst,
	       u32 fib_index, ipip_tunnel_key_t * key)
{
  key->transport = transport;
  key->mode = mode;
  key->src = *src;
  key->dst = *dst;
  key->fib_index = fib_index;
  key->__pad = 0;;
}

void
ipip_mk_key (const ipip_tunnel_t * t, ipip_tunnel_key_t * key)
{
  ipip_mk_key_i (t->transport, t->mode,
		 &t->tunnel_src, &t->tunnel_dst, t->fib_index, key);
}

static void
ipip_teib_mk_key (const ipip_tunnel_t * t,
		  const teib_entry_t * ne, ipip_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 */
  ipip_mk_key_i (t->transport, IPIP_MODE_P2P,
		 &t->tunnel_src, &nh->fp_addr,
		 teib_entry_get_fib_index (ne), key);
}

static void
ipip_teib_entry_added (const teib_entry_t * ne)
{
  ipip_main_t *gm = &ipip_main;
  const ip_address_t *nh;
  ipip_tunnel_key_t key;
  ipip_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);

  ipip_teib_mk_key (t, ne, &key);
  ipip_tunnel_db_add (t, &key);

  // update the rewrites for each of the adjacencies for this next-hop
  mipip_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),
		   (AF_IP4 == ip_addr_version (nh) ?
		    FIB_PROTOCOL_IP4 :
		    FIB_PROTOCOL_IP6),
		   &ip_addr_46 (nh), mipip_mk_complete_walk, &ctx);
}

static void
ipip_teib_entry_deleted (const teib_entry_t * ne)
{
  ipip_main_t *gm = &ipip_main;
  const ip_address_t *nh;
  ipip_tunnel_key_t key;
  ipip_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);

  ipip_teib_mk_key (t, ne, &key);
  ipip_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),
		   (AF_IP4 == ip_addr_version (nh) ?
		    FIB_PROTOCOL_IP4 :
		    FIB_PROTOCOL_IP6),
		   &ip_addr_46 (nh), mipip_mk_incomplete_walk, t);
}

static walk_rc_t
ipip_tunnel_delete_teib_walk (index_t nei, void *ctx)
{
  ipip_tunnel_t *t = ctx;
  ipip_tunnel_key_t key;

  ipip_teib_mk_key (t, teib_entry_get (nei), &key);
  ipip_tunnel_db_remove (t, &key);

  return (WALK_CONTINUE);
}

static walk_rc_t
ipip_tunnel_add_teib_walk (index_t nei, void *ctx)
{
  ipip_tunnel_t *t = ctx;
  ipip_tunnel_key_t key;

  ipip_teib_mk_key (t, teib_entry_get (nei), &key);
  ipip_tunnel_db_add (t, &key);

  return (WALK_CONTINUE);
}

int
ipip_add_tunnel (ipip_transport_t transport,
		 u32 instance, ip46_address_t * src, ip46_address_t * dst,
		 u32 fib_index, tunnel_encap_decap_flags_t flags,
		 ip_dscp_t dscp, tunnel_mode_t tmode, u32 * sw_if_indexp)
{
  ipip_main_t *gm = &ipip_main;
  vnet_main_t *vnm = gm->vnet_main;
  ipip_tunnel_t *t;
  vnet_hw_interface_t *hi;
  u32 hw_if_index, sw_if_index;
  ipip_tunnel_key_t key;
  ipip_mode_t mode;

  if (tmode == TUNNEL_MODE_MP && !ip46_address_is_zero (dst))
    return (VNET_API_ERROR_INVALID_DST_ADDRESS);

  mode = (tmode == TUNNEL_MODE_P2P ? IPIP_MODE_P2P : IPIP_MODE_P2MP);
  ipip_mk_key_i (transport, mode, src, dst, fib_index, &key);

  t = ipip_tunnel_db_find (&key);
  if (t)
    {
      if (sw_if_indexp)
	sw_if_indexp[0] = t->sw_if_index;
      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 = 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 */

  hw_if_index = vnet_register_interface (vnm, ipip_device_class.index, t_idx,
					 (mode == IPIP_MODE_P2P ?
					  ipip_hw_interface_class.index :
					  mipip_hw_interface_class.index),
					 t_idx);

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

  t->mode = mode;
  t->hw_if_index = hw_if_index;
  t->fib_index = fib_index;
  t->sw_if_index = sw_if_index;
  t->dscp = dscp;
  t->flags = flags;
  t->transport = transport;

  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 (t->transport == IPIP_TRANSPORT_IP4)
    hi->frame_overhead = sizeof (ip4_header_t);
  else
    hi->frame_overhead = sizeof (ip6_header_t);

  hi->min_frame_size = hi->frame_overhead + 64;

  /* Standard default ipip MTU. */
  vnet_sw_interface_set_mtu (vnm, sw_if_index, 9000);
  vnet_set_interface_l3_output_node (gm->vlib_main, sw_if_index,
				     (u8 *) "tunnel-output");

  t->tunnel_src = *src;
  t->tunnel_dst = *dst;

  ipip_tunnel_db_add (t, &key);

  if (t->mode == IPIP_MODE_P2MP)
    teib_walk_itf (t->sw_if_index, ipip_tunnel_add_teib_walk, t);

  if (sw_if_indexp)
    *sw_if_indexp = sw_if_index;

  if (t->transport == IPIP_TRANSPORT_IP6 && !gm->ip6_protocol_registered)
    {
      ip6_register_protocol (IP_PROTOCOL_IP_IN_IP, ipip6_input_node.index);
      ip6_register_protocol (IP_PROTOCOL_MPLS_IN_IP, ipip6_input_node.index);
      ip6_register_protocol (IP_PROTOCOL_IPV6, ipip6_input_node.index);
      gm->ip6_protocol_registered = true;
    }
  else if (t->transport == IPIP_TRANSPORT_IP4 && !gm->ip4_protocol_registered)
    {
      ip4_register_protocol (IP_PROTOCOL_IP_IN_IP, ipip4_input_node.index);
      ip4_register_protocol (IP_PROTOCOL_MPLS_IN_IP, ipip4_input_node.index);
      ip4_register_protocol (IP_PROTOCOL_IPV6, ipip4_input_node.index);
      gm->ip4_protocol_registered = true;
    }
  return 0;
}

int
ipip_del_tunnel (u32 sw_if_index)
{
  ipip_main_t *gm = &ipip_main;
  vnet_main_t *vnm = gm->vnet_main;
  ipip_tunnel_t *t;
  ipip_tunnel_key_t key;

  t = ipip_tunnel_db_find_by_sw_if_index (sw_if_index);
  if (t == NULL)
    return VNET_API_ERROR_NO_SUCH_ENTRY;

  if (t->mode == IPIP_MODE_P2MP)
    teib_walk_itf (t->sw_if_index, ipip_tunnel_delete_teib_walk, t);

  vnet_sw_interface_set_flags (vnm, sw_if_index, 0 /* down */ );
  vnet_reset_interface_l3_output_node (gm->vlib_main, t->sw_if_index);
  gm->tunnel_index_by_sw_if_index[sw_if_index] = ~0;
  vnet_delete_hw_interface (vnm, t->hw_if_index);
  hash_unset (gm->instance_used, t->user_instance);

  ipip_mk_key (t, &key);
  ipip_tunnel_db_remove (t, &key);
  pool_put (gm->tunnels, t);

  return 0;
}

const static teib_vft_t ipip_teib_vft = {
  .nv_added = ipip_teib_entry_added,
  .nv_deleted = ipip_teib_entry_deleted,
};

static clib_error_t *
ipip_init (vlib_main_t * vm)
{
  ipip_main_t *gm = &ipip_main;

  clib_memset (gm, 0, sizeof (gm[0]));
  gm->vlib_main = vm;
  gm->vnet_main = vnet_get_main ();
  gm->tunnel_by_key =
    hash_create_mem (0, sizeof (ipip_tunnel_key_t), sizeof (uword));

  teib_register (&ipip_teib_vft);

  return 0;
}

VLIB_INIT_FUNCTION (ipip_init);

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