/*
 * Copyright (c) 2018-2019 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/vnet.h>
#include <vlibmemory/api.h>

#include <vnet/udp/udp_encap.h>
#include <vnet/fib/fib_table.h>
#include <vnet/ip/ip_types_api.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_udp_api_msg            \
_(UDP_ENCAP_DEL, udp_encap_del)        \
_(UDP_ENCAP_ADD, udp_encap_add)        \
_(UDP_ENCAP_DUMP, udp_encap_dump)

static void
send_udp_encap_details (const udp_encap_t * ue, vl_api_registration_t * reg,
			u32 context)
{
  vl_api_udp_encap_details_t *mp;

  mp = vl_msg_api_alloc (sizeof (*mp));
  clib_memset (mp, 0, sizeof (*mp));
  mp->_vl_msg_id = ntohs (VL_API_UDP_ENCAP_DETAILS);
  mp->context = context;

  if (FIB_PROTOCOL_IP4 == ue->ue_ip_proto)
    {
      clib_memcpy (&mp->udp_encap.src_ip.un.ip4,
		   &ue->ue_hdrs.ip4.ue_ip4.src_address, 4);
      clib_memcpy (&mp->udp_encap.dst_ip.un.ip4,
		   &ue->ue_hdrs.ip4.ue_ip4.dst_address, 4);
      mp->udp_encap.dst_ip.af = ip_address_family_encode (AF_IP4);
      mp->udp_encap.src_ip.af = ip_address_family_encode (AF_IP4);

      /* ports aren't byte swapped because they are stored in network
       * byte order */
      mp->udp_encap.src_port = ue->ue_hdrs.ip4.ue_udp.src_port;
      mp->udp_encap.dst_port = ue->ue_hdrs.ip4.ue_udp.dst_port;
    }
  else
    {
      clib_memcpy (&mp->udp_encap.src_ip.un.ip6,
		   &ue->ue_hdrs.ip6.ue_ip6.src_address, 16);
      clib_memcpy (&mp->udp_encap.dst_ip.un.ip6,
		   &ue->ue_hdrs.ip6.ue_ip6.dst_address, 16);
      mp->udp_encap.dst_ip.af = ip_address_family_encode (AF_IP6);
      mp->udp_encap.src_ip.af = ip_address_family_encode (AF_IP6);

      /* ports aren't byte swapped because they are stored in network
       * byte order */
      mp->udp_encap.src_port = ue->ue_hdrs.ip6.ue_udp.src_port;
      mp->udp_encap.dst_port = ue->ue_hdrs.ip6.ue_udp.dst_port;
    }

  mp->udp_encap.table_id =
    htonl (fib_table_get_table_id (ue->ue_fib_index, ue->ue_ip_proto));
  mp->udp_encap.id = htonl (ue - udp_encap_pool);

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

static void
vl_api_udp_encap_dump_t_handler (vl_api_udp_encap_dump_t * mp,
				 vlib_main_t * vm)
{
  vl_api_registration_t *reg;
  udp_encap_t *ue;

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

  /* *INDENT-OFF* */
  pool_foreach(ue, udp_encap_pool,
  ({
    send_udp_encap_details(ue, reg, mp->context);
  }));
  /* *INDENT-ON* */
}

static void
vl_api_udp_encap_add_t_handler (vl_api_udp_encap_add_t * mp, vlib_main_t * vm)
{
  vl_api_udp_encap_add_reply_t *rmp;
  ip46_address_t src_ip, dst_ip;
  u32 fib_index, table_id;
  fib_protocol_t fproto;
  ip46_type_t itype;
  index_t uei;
  int rv = 0;

  uei = INDEX_INVALID;
  table_id = ntohl (mp->udp_encap.table_id);

  itype = ip_address_decode (&mp->udp_encap.src_ip, &src_ip);
  itype = ip_address_decode (&mp->udp_encap.dst_ip, &dst_ip);
  fproto = fib_proto_from_ip46 (itype);
  fib_index = fib_table_find (fproto, table_id);

  if (~0 == fib_index)
    {
      rv = VNET_API_ERROR_NO_SUCH_TABLE;
      goto done;
    }

  uei = udp_encap_add_and_lock (fproto, fib_index,
				&src_ip, &dst_ip,
				ntohs (mp->udp_encap.src_port),
				ntohs (mp->udp_encap.dst_port),
				UDP_ENCAP_FIXUP_NONE);

done:
  /* *INDENT-OFF* */
  REPLY_MACRO2 (VL_API_UDP_ENCAP_ADD_REPLY,
  ({
    rmp->id = ntohl (uei);
  }));
  /* *INDENT-ON* */

}

static void
vl_api_udp_encap_del_t_handler (vl_api_udp_encap_del_t * mp, vlib_main_t * vm)
{
  vl_api_udp_encap_del_reply_t *rmp;
  int rv = 0;

  udp_encap_unlock (ntohl (mp->id));

  REPLY_MACRO (VL_API_UDP_ENCAP_DEL_REPLY);
}

#define vl_msg_name_crc_list
#include <vnet/udp/udp.api.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_udp;
#undef _
}

static clib_error_t *
udp_api_hookup (vlib_main_t * vm)
{
  api_main_t *am = vlibapi_get_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_udp_api_msg;
#undef _

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

  return 0;
}

VLIB_API_INIT_FUNCTION (udp_api_hookup);

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