/*
 * 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=broadcast, 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 [default=0xFFFFFFFF];
  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:
 */
