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