/*
 * teib.h: Tunnel Endpoint Information Base
 *
 * Copyright (c) 2020 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/teib/teib.h>
#include <vnet/fib/fib_table.h>
#include <vnet/adj/adj_midchain.h>
#include <vnet/ip/ip6_ll_table.h>

typedef struct teib_key_t_
{
  ip_address_t tk_peer;
  u8 __pad[3];
  u32 tk_sw_if_index;
} __clib_packed teib_key_t;

STATIC_ASSERT_SIZEOF (teib_key_t, 24);

struct teib_entry_t_
{
  teib_key_t *te_key;
  fib_prefix_t te_nh;
  u32 te_fib_index;
};

typedef struct teib_db_t_
{
  u32 td_n_entries[N_AF];
  uword *td_db;
} teib_db_t;

static teib_db_t teib_db;
static teib_entry_t *teib_pool;
static teib_vft_t *teib_vfts;
static vlib_log_class_t teib_logger;

#define TEIB_NOTIFY(_te, _fn) {                  \
  teib_vft_t *_vft;                              \
  vec_foreach(_vft, teib_vfts) {                 \
    if (_vft->_fn) {                             \
      _vft->_fn(_te);                            \
    }                                            \
  }                                              \
}

#define TEIB_DBG(...)                           \
    vlib_log_debug (teib_logger, __VA_ARGS__);

#define TEIB_INFO(...)                          \
    vlib_log_notice (teib_logger, __VA_ARGS__);

#define TEIB_TE_DBG(_te, _fmt, _args...)                      \
  vlib_log_debug (teib_logger, "[%U]: " _fmt, format_teib_entry, _te - teib_pool, ##_args)
#define TEIB_TE_INFO(_te, _fmt, _args...)                      \
  vlib_log_notice (teib_logger, "[%U]: " _fmt, format_teib_entry, _te - teib_pool, ##_args)

u32
teib_entry_get_sw_if_index (const teib_entry_t * te)
{
  return (te->te_key->tk_sw_if_index);
}

static ip_address_family_t
teib_entry_get_af (const teib_entry_t * te)
{
  return (ip_addr_version (&te->te_key->tk_peer));
}

u32
teib_entry_get_fib_index (const teib_entry_t * te)
{
  return (te->te_fib_index);
}

const ip_address_t *
teib_entry_get_peer (const teib_entry_t * te)
{
  return (&te->te_key->tk_peer);
}

const fib_prefix_t *
teib_entry_get_nh (const teib_entry_t * te)
{
  return (&te->te_nh);
}

void
teib_entry_adj_stack (const teib_entry_t * te, adj_index_t ai)
{
  adj_midchain_delegate_stack (ai, te->te_fib_index, &te->te_nh);
}

teib_entry_t *
teib_entry_get (index_t tei)
{
  return pool_elt_at_index (teib_pool, tei);
}

teib_entry_t *
teib_entry_find (u32 sw_if_index, const ip_address_t * peer)
{
  teib_key_t nk = {
    .tk_peer = *peer,
    .tk_sw_if_index = sw_if_index,
  };
  uword *p;

  p = hash_get_mem (teib_db.td_db, &nk);

  if (NULL != p)
    return teib_entry_get (p[0]);

  return (NULL);
}

teib_entry_t *
teib_entry_find_46 (u32 sw_if_index,
		    fib_protocol_t fproto, const ip46_address_t * peer)
{
  ip_address_t ip;

  ip_address_from_46 (peer, fproto, &ip);

  return (teib_entry_find (sw_if_index, &ip));
}

static void
teib_adj_fib_add (const ip_address_t * ip, u32 sw_if_index, u32 fib_index)
{
  if (AF_IP6 == ip_addr_version (ip) &&
      ip6_address_is_link_local_unicast (&ip_addr_v6 (ip)))
    {
      ip6_ll_prefix_t pfx = {
	.ilp_addr = ip_addr_v6 (ip),
	.ilp_sw_if_index = sw_if_index,
      };
      ip6_ll_table_entry_update (&pfx, FIB_ROUTE_PATH_FLAG_NONE);
    }
  else
    {
      fib_prefix_t pfx;

      ip_address_to_fib_prefix (ip, &pfx);
      fib_table_entry_path_add (fib_index, &pfx, FIB_SOURCE_ADJ,
				FIB_ENTRY_FLAG_ATTACHED,
				fib_proto_to_dpo (pfx.fp_proto),
				&pfx.fp_addr,
				sw_if_index,
				~0, 1, NULL, FIB_ROUTE_PATH_FLAG_NONE);


      if (0 == teib_db.td_n_entries[ip_addr_version (ip)]++)
	fib_table_lock (fib_index, pfx.fp_proto, FIB_SOURCE_ADJ);
    }
}

static void
teib_adj_fib_remove (ip_address_t * ip, u32 sw_if_index, u32 fib_index)
{
  if (AF_IP6 == ip_addr_version (ip) &&
      ip6_address_is_link_local_unicast (&ip_addr_v6 (ip)))
    {
      ip6_ll_prefix_t pfx = {
	.ilp_addr = ip_addr_v6 (ip),
	.ilp_sw_if_index = sw_if_index,
      };
      ip6_ll_table_entry_delete (&pfx);
    }
  else
    {
      fib_prefix_t pfx;

      ip_address_to_fib_prefix (ip, &pfx);
      fib_table_entry_path_remove (fib_index, &pfx, FIB_SOURCE_ADJ,
				   fib_proto_to_dpo (pfx.fp_proto),
				   &pfx.fp_addr,
				   sw_if_index,
				   ~0, 1, FIB_ROUTE_PATH_FLAG_NONE);

      if (0 == --teib_db.td_n_entries[ip_addr_version (ip)])
	fib_table_unlock (fib_index, pfx.fp_proto, FIB_SOURCE_ADJ);
    }
}

int
teib_entry_add (u32 sw_if_index,
		const ip_address_t * peer,
		u32 nh_table_id, const ip_address_t * nh)
{
  fib_protocol_t nh_proto;
  teib_entry_t *te;
  u32 fib_index;
  index_t tei;

  nh_proto = (AF_IP4 == ip_addr_version (nh) ?
	      FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6);

  fib_index = fib_table_find (nh_proto, nh_table_id);

  if (~0 == fib_index)
    {
      return (VNET_API_ERROR_NO_SUCH_FIB);
    }

  te = teib_entry_find (sw_if_index, peer);

  if (NULL == te)
    {
      teib_key_t nk = {
	.tk_peer = *peer,
	.tk_sw_if_index = sw_if_index,
      };
      teib_entry_t *te;

      pool_get_zero (teib_pool, te);

      tei = te - teib_pool;
      te->te_key = clib_mem_alloc (sizeof (*te->te_key));
      clib_memcpy (te->te_key, &nk, sizeof (*te->te_key));

      ip_address_to_fib_prefix (nh, &te->te_nh);
      te->te_fib_index = fib_index;

      hash_set_mem (teib_db.td_db, te->te_key, tei);

      /* we how have a /32 in the overlay, add an adj-fib */
      teib_adj_fib_add (&te->te_key->tk_peer, sw_if_index, fib_index);

      TEIB_NOTIFY (te, nv_added);
      TEIB_TE_INFO (te, "created");
    }
  else
    {
      TEIB_TE_INFO (te, "exists");
      return (VNET_API_ERROR_ENTRY_ALREADY_EXISTS);
    }
  return 0;
}

int
teib_entry_del (u32 sw_if_index, const ip_address_t * peer)
{
  teib_entry_t *te;

  te = teib_entry_find (sw_if_index, peer);

  if (te != NULL)
    {
      TEIB_TE_INFO (te, "removed");

      u32 fib_index;

      fib_index = fib_table_get_index_for_sw_if_index
	(ip_address_family_to_fib_proto (ip_addr_version (peer)),
	 sw_if_index);

      teib_adj_fib_remove (&te->te_key->tk_peer, sw_if_index, fib_index);

      hash_unset_mem (teib_db.td_db, te->te_key);

      TEIB_NOTIFY (te, nv_deleted);

      clib_mem_free (te->te_key);
      pool_put (teib_pool, te);
    }
  else
    {
      TEIB_INFO ("no such entry: %U, %U, %U",
		 format_vnet_sw_if_index_name,
		 vnet_get_main (), sw_if_index, format_ip_address, peer);
      return (VNET_API_ERROR_NO_SUCH_ENTRY);
    }
  return 0;
}

u8 *
format_teib_entry (u8 * s, va_list * args)
{
  index_t tei = va_arg (*args, index_t);
  vnet_main_t *vnm = vnet_get_main ();
  teib_entry_t *te;

  te = teib_entry_get (tei);

  s = format (s, "[%d] ", tei);
  s = format (s, "%U:", format_vnet_sw_if_index_name,
	      vnm, te->te_key->tk_sw_if_index);
  s = format (s, "%U", format_ip_address,
	      &te->te_key->tk_peer, IP46_TYPE_ANY);
  s = format (s, " via [%d]:%U",
	      fib_table_get_table_id (te->te_fib_index, te->te_nh.fp_proto),
	      format_fib_prefix, &te->te_nh);

  return (s);
}

void
teib_walk (teib_walk_cb_t fn, void *ctx)
{
  index_t tei;

  /* *INDENT-OFF* */
  pool_foreach_index (tei, teib_pool)
   {
    fn(tei, ctx);
  }
  /* *INDENT-ON* */
}

void
teib_walk_itf (u32 sw_if_index, teib_walk_cb_t fn, void *ctx)
{
  index_t tei;

  /* *INDENT-OFF* */
  pool_foreach_index (tei, teib_pool)
   {
    if (sw_if_index == teib_entry_get_sw_if_index(teib_entry_get(tei)))
      fn(tei, ctx);
  }
  /* *INDENT-ON* */
}

static void
teib_walk_itf_proto (u32 sw_if_index,
		     ip_address_family_t af, teib_walk_cb_t fn, void *ctx)
{
  index_t tei;

  /* *INDENT-OFF* */
  pool_foreach_index (tei, teib_pool)
   {
    if (sw_if_index == teib_entry_get_sw_if_index(teib_entry_get(tei)) &&
        af == teib_entry_get_af(teib_entry_get(tei)))
      fn(tei, ctx);
  }
  /* *INDENT-ON* */
}

typedef struct teib_table_bind_ctx_t_
{
  u32 new_fib_index;
  u32 old_fib_index;
} teib_table_bind_ctx_t;

static walk_rc_t
teib_walk_table_bind (index_t tei, void *arg)
{
  teib_table_bind_ctx_t *ctx = arg;
  teib_entry_t *te;

  te = teib_entry_get (tei);

  TEIB_TE_INFO (te, "bind: %d -> %d", ctx->old_fib_index, ctx->new_fib_index);

  teib_adj_fib_remove (&te->te_key->tk_peer,
		       te->te_key->tk_sw_if_index, ctx->old_fib_index);
  teib_adj_fib_add (&te->te_key->tk_peer,
		    te->te_key->tk_sw_if_index, ctx->new_fib_index);

  return (WALK_CONTINUE);
}

static void
teib_table_bind_v4 (ip4_main_t * im,
		    uword opaque,
		    u32 sw_if_index, u32 new_fib_index, u32 old_fib_index)
{
  teib_table_bind_ctx_t ctx = {
    .old_fib_index = old_fib_index,
    .new_fib_index = new_fib_index,
  };

  teib_walk_itf_proto (sw_if_index, AF_IP4, teib_walk_table_bind, &ctx);
}

static void
teib_table_bind_v6 (ip6_main_t * im,
		    uword opaque,
		    u32 sw_if_index, u32 new_fib_index, u32 old_fib_index)
{
  teib_table_bind_ctx_t ctx = {
    .old_fib_index = old_fib_index,
    .new_fib_index = new_fib_index,
  };

  teib_walk_itf_proto (sw_if_index, AF_IP6, teib_walk_table_bind, &ctx);
}

void
teib_register (const teib_vft_t * vft)
{
  vec_add1 (teib_vfts, *vft);
}

static clib_error_t *
teib_init (vlib_main_t * vm)
{
  teib_db.td_db = hash_create_mem (0, sizeof (teib_key_t), sizeof (u32));

  ip4_table_bind_callback_t cb4 = {
    .function = teib_table_bind_v4,
  };
  vec_add1 (ip4_main.table_bind_callbacks, cb4);

  ip6_table_bind_callback_t cb6 = {
    .function = teib_table_bind_v6,
  };
  vec_add1 (ip6_main.table_bind_callbacks, cb6);

  teib_logger = vlib_log_register_class ("teib", "teib");

  return (NULL);
}

VLIB_INIT_FUNCTION (teib_init);

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