/*
 *------------------------------------------------------------------
 * bond_api.c - vnet bonding device driver API support
 *
 * Copyright (c) 2017 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/ethernet/ethernet.h>
#include <vnet/ethernet/ethernet_types_api.h>
#include <vnet/bonding/node.h>

#include <vnet/format_fns.h>
#include <vnet/bonding/bond.api_enum.h>
#include <vnet/bonding/bond.api_types.h>

#define REPLY_MSG_ID_BASE msg_id_base
#include <vlibapi/api_helper_macros.h>

static u16 msg_id_base;

static void
vl_api_bond_delete_t_handler (vl_api_bond_delete_t * mp)
{
  vlib_main_t *vm = vlib_get_main ();
  int rv;
  vl_api_bond_delete_reply_t *rmp;
  u32 sw_if_index = ntohl (mp->sw_if_index);

  VALIDATE_SW_IF_INDEX (mp);

  rv = bond_delete_if (vm, sw_if_index);

  BAD_SW_IF_INDEX_LABEL;
  REPLY_MACRO (VL_API_BOND_DELETE_REPLY);
}

static void
vl_api_bond_create_t_handler (vl_api_bond_create_t * mp)
{
  vlib_main_t *vm = vlib_get_main ();
  vl_api_bond_create_reply_t *rmp;
  bond_create_if_args_t _a, *ap = &_a;

  clib_memset (ap, 0, sizeof (*ap));

  ap->id = ntohl (mp->id);

  if (mp->use_custom_mac)
    {
      mac_address_decode (mp->mac_address, (mac_address_t *) ap->hw_addr);
      ap->hw_addr_set = 1;
    }

  ap->mode = ntohl (mp->mode);
  ap->lb = ntohl (mp->lb);
  ap->numa_only = mp->numa_only;
  bond_create_if (vm, ap);

  int rv = ap->rv;

  REPLY_MACRO2(VL_API_BOND_CREATE_REPLY,
  ({
    rmp->sw_if_index = ntohl (ap->sw_if_index);
  }));
}

static void
vl_api_bond_create2_t_handler (vl_api_bond_create2_t * mp)
{
  vlib_main_t *vm = vlib_get_main ();
  vl_api_bond_create2_reply_t *rmp;
  bond_create_if_args_t _a, *ap = &_a;

  clib_memset (ap, 0, sizeof (*ap));

  ap->id = ntohl (mp->id);

  if (mp->use_custom_mac)
    {
      mac_address_decode (mp->mac_address, (mac_address_t *) ap->hw_addr);
      ap->hw_addr_set = 1;
    }

  ap->mode = ntohl (mp->mode);
  ap->lb = ntohl (mp->lb);
  ap->numa_only = mp->numa_only;
  ap->gso = mp->enable_gso;
  bond_create_if (vm, ap);

  int rv = ap->rv;

  REPLY_MACRO2(VL_API_BOND_CREATE2_REPLY,
  ({
    rmp->sw_if_index = ntohl (ap->sw_if_index);
  }));
}

static void
vl_api_bond_add_member_t_handler (vl_api_bond_add_member_t * mp)
{
  vlib_main_t *vm = vlib_get_main ();
  vl_api_bond_add_member_reply_t *rmp;
  bond_add_member_args_t _a, *ap = &_a;
  int rv = 0;

  clib_memset (ap, 0, sizeof (*ap));

  ap->group = ntohl (mp->bond_sw_if_index);
  VALIDATE_SW_IF_INDEX (mp);
  ap->member = ntohl (mp->sw_if_index);
  ap->is_passive = mp->is_passive;
  ap->is_long_timeout = mp->is_long_timeout;

  bond_add_member (vm, ap);
  rv = ap->rv;

  BAD_SW_IF_INDEX_LABEL;
  REPLY_MACRO (VL_API_BOND_ADD_MEMBER_REPLY);
}

static void
vl_api_bond_enslave_t_handler (vl_api_bond_enslave_t * mp)
{
  vlib_main_t *vm = vlib_get_main ();
  vl_api_bond_enslave_reply_t *rmp;
  bond_add_member_args_t _a, *ap = &_a;
  int rv = 0;

  clib_memset (ap, 0, sizeof (*ap));

  ap->group = ntohl (mp->bond_sw_if_index);
  VALIDATE_SW_IF_INDEX (mp);
  ap->member = ntohl (mp->sw_if_index);
  ap->is_passive = mp->is_passive;
  ap->is_long_timeout = mp->is_long_timeout;

  bond_add_member (vm, ap);
  rv = ap->rv;

  BAD_SW_IF_INDEX_LABEL;
  REPLY_MACRO (VL_API_BOND_ENSLAVE_REPLY);
}

static void
  vl_api_sw_interface_set_bond_weight_t_handler
  (vl_api_sw_interface_set_bond_weight_t * mp)
{
  vlib_main_t *vm = vlib_get_main ();
  bond_set_intf_weight_args_t _a, *ap = &_a;
  vl_api_sw_interface_set_bond_weight_reply_t *rmp;
  int rv = 0;

  VALIDATE_SW_IF_INDEX (mp);

  clib_memset (ap, 0, sizeof (*ap));

  ap->sw_if_index = ntohl (mp->sw_if_index);
  ap->weight = ntohl (mp->weight);

  bond_set_intf_weight (vm, ap);
  rv = ap->rv;

  BAD_SW_IF_INDEX_LABEL;
  REPLY_MACRO (VL_API_SW_INTERFACE_SET_BOND_WEIGHT_REPLY);
}

static void
vl_api_bond_detach_slave_t_handler (vl_api_bond_detach_slave_t * mp)
{
  vlib_main_t *vm = vlib_get_main ();
  vl_api_bond_detach_slave_reply_t *rmp;
  bond_detach_member_args_t _a, *ap = &_a;
  int rv = 0;

  VALIDATE_SW_IF_INDEX (mp);

  clib_memset (ap, 0, sizeof (*ap));

  ap->member = ntohl (mp->sw_if_index);
  bond_detach_member (vm, ap);
  rv = ap->rv;

  BAD_SW_IF_INDEX_LABEL;
  REPLY_MACRO (VL_API_BOND_DETACH_SLAVE_REPLY);
}

static void
vl_api_bond_detach_member_t_handler (vl_api_bond_detach_member_t * mp)
{
  vlib_main_t *vm = vlib_get_main ();
  vl_api_bond_detach_member_reply_t *rmp;
  bond_detach_member_args_t _a, *ap = &_a;
  int rv = 0;

  VALIDATE_SW_IF_INDEX (mp);

  clib_memset (ap, 0, sizeof (*ap));

  ap->member = ntohl (mp->sw_if_index);
  bond_detach_member (vm, ap);
  rv = ap->rv;

  BAD_SW_IF_INDEX_LABEL;
  REPLY_MACRO (VL_API_BOND_DETACH_MEMBER_REPLY);
}

static void
bond_send_sw_interface_details (vpe_api_main_t * am,
				vl_api_registration_t * reg,
				bond_interface_details_t * bond_if,
				u32 context)
{
  vl_api_sw_interface_bond_details_t *mp;

  mp = vl_msg_api_alloc (sizeof (*mp));
  clib_memset (mp, 0, sizeof (*mp));
  mp->_vl_msg_id =
    htons (REPLY_MSG_ID_BASE + VL_API_SW_INTERFACE_BOND_DETAILS);
  mp->sw_if_index = htonl (bond_if->sw_if_index);
  mp->id = htonl (bond_if->id);
  clib_memcpy (mp->interface_name, bond_if->interface_name,
	       MIN (ARRAY_LEN (mp->interface_name) - 1,
		    strlen ((const char *) bond_if->interface_name)));
  mp->mode = htonl (bond_if->mode);
  mp->lb = htonl (bond_if->lb);
  mp->numa_only = bond_if->numa_only;
  mp->active_slaves = htonl (bond_if->active_members);
  mp->slaves = htonl (bond_if->members);

  mp->context = context;
  vl_api_send_msg (reg, (u8 *) mp);
}

static void
vl_api_sw_interface_bond_dump_t_handler (vl_api_sw_interface_bond_dump_t * mp)
{
  int rv;
  vpe_api_main_t *am = &vpe_api_main;
  vl_api_registration_t *reg;
  bond_interface_details_t *bondifs = NULL;
  bond_interface_details_t *bond_if = NULL;

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

  rv = bond_dump_ifs (&bondifs);
  if (rv)
    return;

  vec_foreach (bond_if, bondifs)
  {
    bond_send_sw_interface_details (am, reg, bond_if, mp->context);
  }

  vec_free (bondifs);
}

static void
bond_send_sw_bond_interface_details (vpe_api_main_t * am,
				     vl_api_registration_t * reg,
				     bond_interface_details_t * bond_if,
				     u32 context)
{
  vl_api_sw_bond_interface_details_t *mp;

  mp = vl_msg_api_alloc (sizeof (*mp));
  clib_memset (mp, 0, sizeof (*mp));
  mp->_vl_msg_id =
    htons (REPLY_MSG_ID_BASE + VL_API_SW_BOND_INTERFACE_DETAILS);
  mp->sw_if_index = htonl (bond_if->sw_if_index);
  mp->id = htonl (bond_if->id);
  clib_memcpy (mp->interface_name, bond_if->interface_name,
	       MIN (ARRAY_LEN (mp->interface_name) - 1,
		    strlen ((const char *) bond_if->interface_name)));
  mp->mode = htonl (bond_if->mode);
  mp->lb = htonl (bond_if->lb);
  mp->numa_only = bond_if->numa_only;
  mp->active_members = htonl (bond_if->active_members);
  mp->members = htonl (bond_if->members);

  mp->context = context;
  vl_api_send_msg (reg, (u8 *) mp);
}

static void
vl_api_sw_bond_interface_dump_t_handler (vl_api_sw_bond_interface_dump_t * mp)
{
  int rv;
  vpe_api_main_t *am = &vpe_api_main;
  vl_api_registration_t *reg;
  bond_interface_details_t *bondifs = NULL;
  bond_interface_details_t *bond_if = NULL;
  u32 filter_sw_if_index;

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

  filter_sw_if_index = htonl (mp->sw_if_index);
  if (filter_sw_if_index != ~0)
    VALIDATE_SW_IF_INDEX (mp);

  rv = bond_dump_ifs (&bondifs);
  if (rv)
    return;

  vec_foreach (bond_if, bondifs)
  {
    if ((filter_sw_if_index == ~0) ||
	(bond_if->sw_if_index == filter_sw_if_index))
      bond_send_sw_bond_interface_details (am, reg, bond_if, mp->context);
  }

  BAD_SW_IF_INDEX_LABEL;
  vec_free (bondifs);
}

static void
bond_send_sw_member_interface_details (vpe_api_main_t * am,
				       vl_api_registration_t * reg,
				       member_interface_details_t * member_if,
				       u32 context)
{
  vl_api_sw_interface_slave_details_t *mp;

  mp = vl_msg_api_alloc (sizeof (*mp));
  clib_memset (mp, 0, sizeof (*mp));
  mp->_vl_msg_id =
    htons (REPLY_MSG_ID_BASE + VL_API_SW_INTERFACE_SLAVE_DETAILS);
  mp->sw_if_index = htonl (member_if->sw_if_index);
  clib_memcpy (mp->interface_name, member_if->interface_name,
	       MIN (ARRAY_LEN (mp->interface_name) - 1,
		    strlen ((const char *) member_if->interface_name)));
  mp->is_passive = member_if->is_passive;
  mp->is_long_timeout = member_if->is_long_timeout;
  mp->is_local_numa = member_if->is_local_numa;
  mp->weight = htonl (member_if->weight);

  mp->context = context;
  vl_api_send_msg (reg, (u8 *) mp);
}

static void
vl_api_sw_interface_slave_dump_t_handler (vl_api_sw_interface_slave_dump_t *
					  mp)
{
  int rv;
  vpe_api_main_t *am = &vpe_api_main;
  vl_api_registration_t *reg;
  member_interface_details_t *memberifs = NULL;
  member_interface_details_t *member_if = NULL;

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

  rv = bond_dump_member_ifs (&memberifs, ntohl (mp->sw_if_index));
  if (rv)
    return;

  vec_foreach (member_if, memberifs)
  {
    bond_send_sw_member_interface_details (am, reg, member_if, mp->context);
  }

  vec_free (memberifs);
}

static void
bond_send_member_interface_details (vpe_api_main_t * am,
				    vl_api_registration_t * reg,
				    member_interface_details_t * member_if,
				    u32 context)
{
  vl_api_sw_member_interface_details_t *mp;

  mp = vl_msg_api_alloc (sizeof (*mp));
  clib_memset (mp, 0, sizeof (*mp));
  mp->_vl_msg_id =
    htons (REPLY_MSG_ID_BASE + VL_API_SW_MEMBER_INTERFACE_DETAILS);
  mp->sw_if_index = htonl (member_if->sw_if_index);
  clib_memcpy (mp->interface_name, member_if->interface_name,
	       MIN (ARRAY_LEN (mp->interface_name) - 1,
		    strlen ((const char *) member_if->interface_name)));
  mp->is_passive = member_if->is_passive;
  mp->is_long_timeout = member_if->is_long_timeout;
  mp->is_local_numa = member_if->is_local_numa;
  mp->weight = htonl (member_if->weight);

  mp->context = context;
  vl_api_send_msg (reg, (u8 *) mp);
}

static void
vl_api_sw_member_interface_dump_t_handler (vl_api_sw_member_interface_dump_t *
					   mp)
{
  int rv;
  vpe_api_main_t *am = &vpe_api_main;
  vl_api_registration_t *reg;
  member_interface_details_t *memberifs = NULL;
  member_interface_details_t *member_if = NULL;

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

  rv = bond_dump_member_ifs (&memberifs, ntohl (mp->sw_if_index));
  if (rv)
    return;

  vec_foreach (member_if, memberifs)
  {
    bond_send_member_interface_details (am, reg, member_if, mp->context);
  }

  vec_free (memberifs);
}

#include <vnet/bonding/bond.api.c>
static clib_error_t *
bond_api_hookup (vlib_main_t * vm)
{
  /*
   * Set up the (msg_name, crc, message-id) table
   */
  REPLY_MSG_ID_BASE = setup_message_id_table ();

  return 0;
}

VLIB_API_INIT_FUNCTION (bond_api_hookup);

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