/*
 * 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.
 */

/** \file

    This file defines vpe control-plane API messages for
    the bonding device driver
*/

option version = "2.0.0";

import "vnet/interface_types.api";
import "vnet/ethernet/ethernet_types.api";

enum bond_mode
{
  BOND_API_MODE_ROUND_ROBIN = 1,
  BOND_API_MODE_ACTIVE_BACKUP = 2,
  BOND_API_MODE_XOR = 3,
  BOND_API_MODE_BROADCAST = 4,
  BOND_API_MODE_LACP = 5,
};

enum bond_lb_algo
{
 BOND_API_LB_ALGO_L2 = 0,
 BOND_API_LB_ALGO_L34 = 1,
 BOND_API_LB_ALGO_L23 = 2,
 BOND_API_LB_ALGO_RR = 3,
 BOND_API_LB_ALGO_BC = 4,
 BOND_API_LB_ALGO_AB = 5,
};

/** \brief Initialize a new bond interface with the given paramters
    @param client_index - opaque cookie to identify the sender
    @param context - sender context, to match reply w/ request
    @param id - if non-~0, specifies a custom interface ID
    @param use_custom_mac - if set, mac_address is valid
    @param mac_address - mac addr to assign to the interface if use_custom_mac is set
    @param mode - mode, required (1=round-robin, 2=active-backup, 3=xor, 4=broadcastcast, 5=lacp)
    @param lb - load balance, optional (0=l2, 1=l34, 2=l23) valid for xor and lacp modes. Otherwise ignored
    @param numa_only - if numa_only is set, pkts will be transmitted by LAG members on local numa node only if have at least one, otherwise it works as usual.
*/
define bond_create
{
  u32 client_index;
  u32 context;
  u32 id;
  bool use_custom_mac;
  vl_api_mac_address_t mac_address;
  vl_api_bond_mode_t mode;
  vl_api_bond_lb_algo_t lb;
  bool numa_only;
};

/** \brief Reply for bond create reply
    @param context - returned sender context, to match reply w/ request
    @param retval - return code
    @param sw_if_index - software index allocated for the new tap interface
*/
define bond_create_reply
{
  u32 context;
  i32 retval;
  vl_api_interface_index_t sw_if_index;
};

/** \brief Delete bond interface
    @param client_index - opaque cookie to identify the sender
    @param context - sender context, to match reply w/ request
    @param sw_if_index - interface index of slave interface
*/
autoreply define bond_delete
{
  u32 client_index;
  u32 context;
  vl_api_interface_index_t sw_if_index;
};

/** \brief Initialize a new bond interface with the given paramters
    @param client_index - opaque cookie to identify the sender
    @param context - sender context, to match reply w/ request
    @param sw_if_index - slave sw_if_index
    @param bond_sw_if_index - bond sw_if_index
    @param is_passive - interface does not initiate the lacp protocol, remote must be active speaker
    @param is_long_timeout - 90 seconds vs default 3 seconds neighbor timeout
*/
define bond_enslave
{
  u32 client_index;
  u32 context;
  vl_api_interface_index_t sw_if_index;
  vl_api_interface_index_t bond_sw_if_index;
  bool is_passive;
  bool is_long_timeout;
};

/** \brief Reply for bond enslave reply
    @param context - returned sender context, to match reply w/ request
    @param retval - return code
*/
define bond_enslave_reply
{
  u32 context;
  i32 retval;
};

/** \brief bond detach slave
    @param client_index - opaque cookie to identify the sender
    @param context - sender context, to match reply w/ request
    @param sw_if_index - interface index of slave interface
*/
autoreply define bond_detach_slave
{
  u32 client_index;
  u32 context;
  vl_api_interface_index_t sw_if_index;
};

/** \brief Dump bond interfaces request */
define sw_interface_bond_dump
{
  u32 client_index;
  u32 context;
};

/** \brief Reply for bond dump request
    @param sw_if_index - software index of bond interface
    @param id - ID of interface
    @param mode - bonding mode
    @param lb - load balance algo
    @param numa_only - enable local numa TX for lacp mode
    @param active_slaves - active slaves count
    @param slaves - config slave count
    @param interface_name - name of interface
*/
define sw_interface_bond_details
{
  u32 context;
  vl_api_interface_index_t sw_if_index;
  u32 id;
  vl_api_bond_mode_t mode;
  vl_api_bond_lb_algo_t lb;
  bool numa_only;
  u32 active_slaves;
  u32 slaves;
  string interface_name[64];
};

/** \brief bond slave dump
    @param client_index - opaque cookie to identify the sender
    @param context - sender context, to match reply w/ request
    @param sw_if_index - interface index of bond interface
*/
define sw_interface_slave_dump
{
  u32 client_index;
  u32 context;
  vl_api_interface_index_t sw_if_index;
};

/** \brief Reply for slave dump request
    @param sw_if_index - software index of slave interface
    @param interface_name - name of interface
    @param is_passve - interface does not initiate the lacp protocol, remote must be active speaker
    @param is_long_timeout - 90 seconds vs default 3 seconds neighbor timeout
    @param is_local_numa - the slave interface is local numa
    @param weight - the weight for the slave interface (active-backup mode only)
*/
define sw_interface_slave_details
{
  u32 context;
  vl_api_interface_index_t sw_if_index;
  string interface_name[64];
  bool is_passive;
  bool is_long_timeout;
  bool is_local_numa;
  u32 weight;
};

/** \brief Interface set bond weight
    @param client_index - opaque cookie to identify the sender
    @param context - sender context, to match reply w/ request
    @param sw_if_index - slave interface for which to set the weight
    @param weight - weight value to be set for the slave interface
*/
autoreply define sw_interface_set_bond_weight
{
  u32 client_index;
  u32 context;
  vl_api_interface_index_t sw_if_index;
  u32 weight;
};

/*
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
