/*
 * ipip_api.c - ipip api
 *
 * 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 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 <vlibmemory/api.h>
#include <vnet/api_errno.h>
#include <vnet/fib/fib_table.h>
#include <vnet/interface.h>
#include <vnet/ipip/ipip.h>
#include <vnet/vnet.h>
#include <vnet/vnet_msg_enum.h>

#define vl_typedefs		/* define message structures */
#include <vnet/vnet_all_api_h.h>
#undef vl_typedefs

#define vl_endianfun		/* define message structures */
#include <vnet/vnet_all_api_h.h>
#undef vl_endianfun

/* instantiate all the print functions we know about */
#define vl_print(handle, ...) vlib_cli_output(handle, __VA_ARGS__)
#define vl_printfun
#include <vnet/vnet_all_api_h.h>
#undef vl_printfun

#include <vlibapi/api_helper_macros.h>

#define foreach_vpe_api_msg			\
  _(IPIP_ADD_TUNNEL, ipip_add_tunnel)		\
  _(IPIP_DEL_TUNNEL, ipip_del_tunnel)		\
  _(IPIP_6RD_ADD_TUNNEL, ipip_6rd_add_tunnel)	\
  _(IPIP_6RD_DEL_TUNNEL, ipip_6rd_del_tunnel)	\
  _(IPIP_TUNNEL_DUMP, ipip_tunnel_dump)

static void
vl_api_ipip_add_tunnel_t_handler (vl_api_ipip_add_tunnel_t * mp)
{
  vl_api_ipip_add_tunnel_reply_t *rmp;
  int rv = 0;
  u32 fib_index, sw_if_index = ~0;
  ip46_address_t src = ip46_address_initializer, dst =
    ip46_address_initializer;

  /* ip addresses sent in network byte order */
  if (mp->is_ipv6)
    {
      clib_memcpy (&src.ip6, mp->src_address, 16);
      clib_memcpy (&dst.ip6, mp->dst_address, 16);
    }
  else
    {
      clib_memcpy (&src.ip4, mp->src_address, 4);
      clib_memcpy (&dst.ip4, mp->dst_address, 4);
    }

  fib_index =
    fib_table_find (fib_ip_proto (mp->is_ipv6), ntohl (mp->table_id));

  if (~0 == fib_index)
    {
      rv = VNET_API_ERROR_NO_SUCH_FIB;
    }
  else
    {
      rv = ipip_add_tunnel ((mp->is_ipv6 ?
			     IPIP_TRANSPORT_IP6 :
			     IPIP_TRANSPORT_IP4),
			    ntohl (mp->instance), &src, &dst,
			    fib_index, mp->tc_tos, &sw_if_index);
    }

  /* *INDENT-OFF* */
  REPLY_MACRO2(VL_API_IPIP_ADD_TUNNEL_REPLY,
  ({
    rmp->sw_if_index = ntohl(sw_if_index);
  }));
  /* *INDENT-ON* */
}

static void
vl_api_ipip_del_tunnel_t_handler (vl_api_ipip_del_tunnel_t * mp)
{
  vl_api_ipip_del_tunnel_reply_t *rmp;

  int rv = ipip_del_tunnel (ntohl (mp->sw_if_index));

  REPLY_MACRO (VL_API_IPIP_DEL_TUNNEL_REPLY);
}

static void
send_ipip_tunnel_details (ipip_tunnel_t * t,
			  vl_api_registration_t * reg, u32 context)
{
  vl_api_ipip_tunnel_details_t *rmp;
  bool is_ipv6 = t->transport == IPIP_TRANSPORT_IP6 ? true : false;
  fib_table_t *ft;

  rmp = vl_msg_api_alloc (sizeof (*rmp));
  clib_memset (rmp, 0, sizeof (*rmp));
  rmp->_vl_msg_id = htons (VL_API_IPIP_TUNNEL_DETAILS);
  if (is_ipv6)
    {
      clib_memcpy (rmp->src_address, &t->tunnel_src.ip6.as_u8, 16);
      clib_memcpy (rmp->dst_address, &t->tunnel_dst.ip6.as_u8, 16);
      ft = fib_table_get (t->fib_index, FIB_PROTOCOL_IP6);
      rmp->fib_index = htonl (ft->ft_table_id);
    }
  else
    {
      clib_memcpy (rmp->src_address, &t->tunnel_src.ip4.as_u8, 4);
      clib_memcpy (rmp->dst_address, &t->tunnel_dst.ip4.as_u8, 4);
      ft = fib_table_get (t->fib_index, FIB_PROTOCOL_IP4);
      rmp->fib_index = htonl (ft->ft_table_id);
    }
  rmp->instance = htonl (t->user_instance);
  rmp->sw_if_index = htonl (t->sw_if_index);
  rmp->context = context;
  rmp->is_ipv6 = is_ipv6;

  vl_api_send_msg (reg, (u8 *) rmp);
}

static void
vl_api_ipip_tunnel_dump_t_handler (vl_api_ipip_tunnel_dump_t * mp)
{
  vl_api_registration_t *reg;
  ipip_main_t *gm = &ipip_main;
  ipip_tunnel_t *t;
  u32 sw_if_index;

  reg = vl_api_client_index_to_registration (mp->client_index);
  if (!reg)
    return;

  sw_if_index = ntohl (mp->sw_if_index);

  if (sw_if_index == ~0)
    {
    /* *INDENT-OFF* */
    pool_foreach(t, gm->tunnels,
                 ({ send_ipip_tunnel_details(t, reg, mp->context); }));
    /* *INDENT-ON* */
    }
  else
    {
      t = ipip_tunnel_db_find_by_sw_if_index (sw_if_index);
      if (t)
	send_ipip_tunnel_details (t, reg, mp->context);
    }
}

static void
vl_api_ipip_6rd_add_tunnel_t_handler (vl_api_ipip_6rd_add_tunnel_t * mp)
{
  vl_api_ipip_6rd_add_tunnel_reply_t *rmp;
  u32 sixrd_tunnel_index, ip4_fib_index, ip6_fib_index;
  int rv;

  ip4_fib_index = fib_table_find (FIB_PROTOCOL_IP4, ntohl (mp->ip4_table_id));
  ip6_fib_index = fib_table_find (FIB_PROTOCOL_IP6, ntohl (mp->ip6_table_id));

  if (~0 == ip4_fib_index || ~0 == ip6_fib_index)

    {
      rv = VNET_API_ERROR_NO_SUCH_FIB;
    }
  else
    {
      rv = sixrd_add_tunnel ((ip6_address_t *) & mp->ip6_prefix,
			     mp->ip6_prefix_len,
			     (ip4_address_t *) & mp->ip4_prefix,
			     mp->ip4_prefix_len,
			     (ip4_address_t *) & mp->ip4_src,
			     mp->security_check,
			     ip4_fib_index, ip6_fib_index,
			     &sixrd_tunnel_index);
    }

  /* *INDENT-OFF* */
  REPLY_MACRO2 (VL_API_IPIP_6RD_ADD_TUNNEL_REPLY,
  ({
    rmp->sw_if_index = htonl (sixrd_tunnel_index);
  }));
  /* *INDENT-ON* */
}

static void
vl_api_ipip_6rd_del_tunnel_t_handler (vl_api_ipip_6rd_del_tunnel_t * mp)
{
  vl_api_ipip_6rd_del_tunnel_reply_t *rmp;

  int rv = sixrd_del_tunnel (ntohl (mp->sw_if_index));

  REPLY_MACRO (VL_API_IPIP_6RD_DEL_TUNNEL_REPLY);
}

/*
 * ipip_api_hookup
 * Add vpe's API message handlers to the table.
 * vlib has alread mapped shared memory and
 * added the client registration handlers.
 * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
 */
#define vl_msg_name_crc_list
#include <vnet/vnet_all_api_h.h>
#undef vl_msg_name_crc_list

static void
setup_message_id_table (api_main_t * am)
{
#define _(id, n, crc) vl_msg_api_add_msg_name_crc(am, #n "_" #crc, id);
  foreach_vl_msg_name_crc_ipip;
#undef _
}

static clib_error_t *
ipip_api_hookup (vlib_main_t * vm)
{
  api_main_t *am = &api_main;

#define _(N, n)                                                                \
  vl_msg_api_set_handlers(VL_API_##N, #n, vl_api_##n##_t_handler,              \
                          vl_noop_handler, vl_api_##n##_t_endian,              \
                          vl_api_##n##_t_print, sizeof(vl_api_##n##_t), 1);
  foreach_vpe_api_msg;
#undef _

  /*
   * Set up the (msg_name, crc, message-id) table
   */
  setup_message_id_table (am);

  return 0;
}

VLIB_API_INIT_FUNCTION (ipip_api_hookup);

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