/*
 *------------------------------------------------------------------
 * dhcp_api.c - dhcp api
 *
 * Copyright (c) 2016 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/interface.h>
#include <vnet/api_errno.h>
#include <vnet/dhcp/dhcp_proxy.h>
#include <vnet/dhcp/client.h>
#include <vnet/dhcp/dhcp6_pd_client_dp.h>
#include <vnet/dhcp/dhcp6_ia_na_client_dp.h>
#include <vnet/dhcp/dhcp6_client_common_dp.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_vpe_api_msg                       \
_(DHCP_PROXY_CONFIG,dhcp_proxy_config)            \
_(DHCP_PROXY_DUMP,dhcp_proxy_dump)                \
_(DHCP_PROXY_SET_VSS,dhcp_proxy_set_vss)          \
_(DHCP_CLIENT_CONFIG, dhcp_client_config)         \
_(DHCP_CLIENT_DUMP, dhcp_client_dump)             \
_(WANT_DHCP6_PD_REPLY_EVENTS, want_dhcp6_pd_reply_events)               \
_(DHCP6_PD_SEND_CLIENT_MESSAGE, dhcp6_pd_send_client_message)           \
_(WANT_DHCP6_REPLY_EVENTS, want_dhcp6_reply_events)               \
_(DHCP6_SEND_CLIENT_MESSAGE, dhcp6_send_client_message)           \
_(DHCP6_CLIENTS_ENABLE_DISABLE, dhcp6_clients_enable_disable)     \
_(DHCP6_DUID_LL_SET, dhcp6_duid_ll_set)


static void
vl_api_dhcp_proxy_set_vss_t_handler (vl_api_dhcp_proxy_set_vss_t * mp)
{
  vl_api_dhcp_proxy_set_vss_reply_t *rmp;
  u8 *vpn_ascii_id;
  int rv;

  mp->vpn_ascii_id[sizeof (mp->vpn_ascii_id) - 1] = 0;
  vpn_ascii_id = format (0, "%s", mp->vpn_ascii_id);
  rv =
    dhcp_proxy_set_vss ((mp->is_ipv6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4),
			ntohl (mp->tbl_id), ntohl (mp->vss_type),
			vpn_ascii_id, ntohl (mp->oui), ntohl (mp->vpn_index),
			mp->is_add == 0);

  REPLY_MACRO (VL_API_DHCP_PROXY_SET_VSS_REPLY);
}


static void vl_api_dhcp_proxy_config_t_handler
  (vl_api_dhcp_proxy_config_t * mp)
{
  vl_api_dhcp_proxy_set_vss_reply_t *rmp;
  ip46_address_t src, server;
  int rv = -1;

  if (mp->dhcp_src_address.af != mp->dhcp_server.af)
    {
      rv = VNET_API_ERROR_INVALID_ARGUMENT;
      goto reply;
    }

  ip_address_decode (&mp->dhcp_src_address, &src);
  ip_address_decode (&mp->dhcp_server, &server);

  if (mp->dhcp_src_address.af == ADDRESS_IP4)
    {
      rv = dhcp4_proxy_set_server (&server,
				   &src,
				   (u32) ntohl (mp->rx_vrf_id),
				   (u32) ntohl (mp->server_vrf_id),
				   (int) (mp->is_add == 0));
    }
  else
    {
      rv = dhcp6_proxy_set_server (&server,
				   &src,
				   (u32) ntohl (mp->rx_vrf_id),
				   (u32) ntohl (mp->server_vrf_id),
				   (int) (mp->is_add == 0));
    }

reply:
  REPLY_MACRO (VL_API_DHCP_PROXY_CONFIG_REPLY);
}

static void
vl_api_dhcp_proxy_dump_t_handler (vl_api_dhcp_proxy_dump_t * mp)
{
  vl_api_registration_t *reg;

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

  dhcp_proxy_dump ((mp->is_ip6 == 1 ?
		    FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4), reg, mp->context);
}

void
dhcp_send_details (fib_protocol_t proto,
		   void *opaque, u32 context, dhcp_proxy_t * proxy)
{
  vl_api_dhcp_proxy_details_t *mp;
  vl_api_registration_t *reg = opaque;
  vl_api_dhcp_server_t *v_server;
  dhcp_server_t *server;
  fib_table_t *s_fib;
  dhcp_vss_t *vss;
  u32 count;
  size_t n;

  count = vec_len (proxy->dhcp_servers);
  n = sizeof (*mp) + (count * sizeof (vl_api_dhcp_server_t));
  mp = vl_msg_api_alloc (n);
  if (!mp)
    return;
  clib_memset (mp, 0, n);
  mp->_vl_msg_id = ntohs (VL_API_DHCP_PROXY_DETAILS);
  mp->context = context;
  mp->count = count;

  mp->is_ipv6 = (proto == FIB_PROTOCOL_IP6);
  mp->rx_vrf_id =
    htonl (dhcp_proxy_rx_table_get_table_id (proto, proxy->rx_fib_index));

  vss = dhcp_get_vss_info (&dhcp_proxy_main, proxy->rx_fib_index, proto);

  if (vss)
    {
      mp->vss_type = ntohl (vss->vss_type);
      if (vss->vss_type == VSS_TYPE_ASCII)
	{
	  u32 id_len = vec_len (vss->vpn_ascii_id);
	  clib_memcpy (mp->vss_vpn_ascii_id, vss->vpn_ascii_id, id_len);
	}
      else if (vss->vss_type == VSS_TYPE_VPN_ID)
	{
	  u32 oui = ((u32) vss->vpn_id[0] << 16) + ((u32) vss->vpn_id[1] << 8)
	    + ((u32) vss->vpn_id[2]);
	  u32 fib_id = ((u32) vss->vpn_id[3] << 24) +
	    ((u32) vss->vpn_id[4] << 16) + ((u32) vss->vpn_id[5] << 8) +
	    ((u32) vss->vpn_id[6]);
	  mp->vss_oui = htonl (oui);
	  mp->vss_fib_id = htonl (fib_id);
	}
    }
  else
    mp->vss_type = VSS_TYPE_INVALID;

  vec_foreach_index (count, proxy->dhcp_servers)
  {
    server = &proxy->dhcp_servers[count];
    v_server = &mp->servers[count];

    s_fib = fib_table_get (server->server_fib_index, proto);

    v_server->server_vrf_id = htonl (s_fib->ft_table_id);

    if (mp->is_ipv6)
      {
	memcpy (&v_server->dhcp_server.un, &server->dhcp_server.ip6, 16);
      }
    else
      {
	/* put the address in the first bytes */
	memcpy (&v_server->dhcp_server.un, &server->dhcp_server.ip4, 4);
      }
  }

  if (mp->is_ipv6)
    {
      memcpy (&mp->dhcp_src_address.un, &proxy->dhcp_src_address.ip6, 16);
    }
  else
    {
      /* put the address in the first bytes */
      memcpy (&mp->dhcp_src_address.un, &proxy->dhcp_src_address.ip4, 4);
    }
  vl_api_send_msg (reg, (u8 *) mp);
}

static void
dhcp_client_lease_encode (vl_api_dhcp_lease_t * lease,
			  const dhcp_client_t * client)
{
  size_t len;
  u8 i;

  lease->is_ipv6 = 0;		// only support IPv6 clients
  lease->sw_if_index = ntohl (client->sw_if_index);
  lease->state = ntohl (client->state);
  len = clib_min (sizeof (lease->hostname) - 1, vec_len (client->hostname));
  clib_memcpy (&lease->hostname, client->hostname, len);
  lease->hostname[len] = 0;

  lease->mask_width = client->subnet_mask_width;
  clib_memcpy (&lease->host_address.un, (u8 *) & client->leased_address,
	       sizeof (ip4_address_t));
  clib_memcpy (&lease->router_address.un, (u8 *) & client->router_address,
	       sizeof (ip4_address_t));

  lease->count = vec_len (client->domain_server_address);
  for (i = 0; i < lease->count; i++)
    clib_memcpy (&lease->domain_server[i].address,
		 (u8 *) & client->domain_server_address[i],
		 sizeof (ip4_address_t));

  clib_memcpy (&lease->host_mac[0], client->client_hardware_address, 6);
}

static void
dhcp_client_data_encode (vl_api_dhcp_client_t * vclient,
			 const dhcp_client_t * client)
{
  size_t len;

  vclient->sw_if_index = ntohl (client->sw_if_index);
  len = clib_min (sizeof (vclient->hostname) - 1, vec_len (client->hostname));
  clib_memcpy (&vclient->hostname, client->hostname, len);
  vclient->hostname[len] = 0;

  len = clib_min (sizeof (vclient->id) - 1,
		  vec_len (client->client_identifier));
  clib_memcpy (&vclient->id, client->client_identifier, len);
  vclient->id[len] = 0;

  if (NULL != client->event_callback)
    vclient->want_dhcp_event = 1;
  else
    vclient->want_dhcp_event = 0;
  vclient->set_broadcast_flag = client->set_broadcast_flag;
  vclient->dscp = ip_dscp_encode (client->dscp);
  vclient->pid = client->pid;
}

static void
dhcp_compl_event_callback (u32 client_index, const dhcp_client_t * client)
{
  vl_api_registration_t *reg;
  vl_api_dhcp_compl_event_t *mp;

  reg = vl_api_client_index_to_registration (client_index);
  if (!reg)
    return;

  mp = vl_msg_api_alloc (sizeof (*mp));
  mp->client_index = client_index;
  mp->pid = client->pid;
  dhcp_client_lease_encode (&mp->lease, client);

  mp->_vl_msg_id = ntohs (VL_API_DHCP_COMPL_EVENT);

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

static void vl_api_dhcp_client_config_t_handler
  (vl_api_dhcp_client_config_t * mp)
{
  vlib_main_t *vm = vlib_get_main ();
  vl_api_dhcp_client_config_reply_t *rmp;
  u32 sw_if_index;
  ip_dscp_t dscp;
  int rv = 0;

  VALIDATE_SW_IF_INDEX (&(mp->client));

  sw_if_index = ntohl (mp->client.sw_if_index);
  dscp = ip_dscp_decode (mp->client.dscp);

  rv = dhcp_client_config (mp->is_add,
			   mp->client_index,
			   vm,
			   sw_if_index,
			   mp->client.hostname,
			   mp->client.id,
			   (mp->client.want_dhcp_event ?
			    dhcp_compl_event_callback :
			    NULL),
			   mp->client.set_broadcast_flag,
			   dscp, mp->client.pid);

  BAD_SW_IF_INDEX_LABEL;
  REPLY_MACRO (VL_API_DHCP_CLIENT_CONFIG_REPLY);
}

typedef struct dhcp_client_send_walk_ctx_t_
{
  vl_api_registration_t *reg;
  u32 context;
} dhcp_client_send_walk_ctx_t;

static int
send_dhcp_client_entry (const dhcp_client_t * client, void *arg)
{
  dhcp_client_send_walk_ctx_t *ctx;
  vl_api_dhcp_client_details_t *mp;

  ctx = arg;

  mp = vl_msg_api_alloc (sizeof (*mp));
  clib_memset (mp, 0, sizeof (*mp));

  mp->_vl_msg_id = ntohs (VL_API_DHCP_CLIENT_DETAILS);
  mp->context = ctx->context;

  dhcp_client_data_encode (&mp->client, client);
  dhcp_client_lease_encode (&mp->lease, client);

  vl_api_send_msg (ctx->reg, (u8 *) mp);

  return (1);
}

static void
vl_api_dhcp_client_dump_t_handler (vl_api_dhcp_client_dump_t * mp)
{
  vl_api_registration_t *reg;

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

  dhcp_client_send_walk_ctx_t ctx = {
    .reg = reg,
    .context = mp->context,
  };
  dhcp_client_walk (send_dhcp_client_entry, &ctx);
}

/*
 * dhcp_api_hookup
 * Add vpe's API message handlers to the table.
 * vlib has already 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_dhcp;
#undef _
}

static clib_error_t *
dhcp_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);

  dhcp6_pd_set_publisher_node (dhcp6_pd_reply_process_node.index,
			       DHCP6_PD_DP_REPLY_REPORT);
  dhcp6_set_publisher_node (dhcp6_reply_process_node.index,
			    DHCP6_DP_REPLY_REPORT);

  return 0;
}

VLIB_API_INIT_FUNCTION (dhcp_api_hookup);

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