/*
 * Copyright (c) 2015-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.
 */

option version = "2.1.0";

import "vnet/interface_types.api";
import "vnet/ip/ip_types.api";

/** \brief Create or delete a VXLAN tunnel
    @param client_index - opaque cookie to identify the sender
    @param context - sender context, to match reply w/ request
    @param is_add - Use 1 to create the tunnel, 0 to remove it
    @param instance - optional unique custom device instance, else ~0.
    @param src_address - Source IP address
    @param dst_address - Destination IP address, can be multicast
    @param mcast_sw_if_index - Interface for multicast destination
    @param encap_vrf_id - Encap route table FIB index
    @param decap_next_index - index of decap next graph node
    @param vni - The VXLAN Network Identifier, uint24
*/
define vxlan_add_del_tunnel
{
  u32 client_index;
  u32 context;
  bool is_add [default=true];
  u32 instance;		/* If non-~0, specifies a custom dev instance */
  vl_api_address_t src_address;
  vl_api_address_t dst_address;
  vl_api_interface_index_t mcast_sw_if_index;
  u32 encap_vrf_id;
  u32 decap_next_index;
  u32 vni;
};

/** \brief Create or delete a VXLAN tunnel
    @param client_index - opaque cookie to identify the sender
    @param context - sender context, to match reply w/ request
    @param is_add - Use 1 to create the tunnel, 0 to remove it
    @param instance - optional unique custom device instance, else ~0.
    @param src_address - Source IP address
    @param dst_address - Destination IP address, can be multicast
    @param src_port - Source UDP port. It is not included in sent packets. Used only for port registration
    @param dst_port - Destination UDP port
    @param mcast_sw_if_index - Interface for multicast destination
    @param encap_vrf_id - Encap route table FIB index
    @param decap_next_index - index of decap next graph node
    @param vni - The VXLAN Network Identifier, uint24
*/
define vxlan_add_del_tunnel_v2
{
  u32 client_index;
  u32 context;
  bool is_add [default=true];
  u32 instance [default=0xffffffff];	/* If non-~0, specifies a custom dev instance */
  vl_api_address_t src_address;
  vl_api_address_t dst_address;
  u16 src_port;
  u16 dst_port;
  vl_api_interface_index_t mcast_sw_if_index;
  u32 encap_vrf_id;
  u32 decap_next_index;
  u32 vni;
};

/** \brief Create or delete a VXLAN tunnel
    @param client_index - opaque cookie to identify the sender
    @param context - sender context, to match reply w/ request
    @param is_add - Use 1 to create the tunnel, 0 to remove it
    @param instance - optional unique custom device instance, else ~0.
    @param src_address - Source IP address
    @param dst_address - Destination IP address, can be multicast
    @param src_port - Source UDP port. It is not included in sent packets. Used only for port registration
    @param dst_port - Destination UDP port
    @param mcast_sw_if_index - Interface for multicast destination
    @param encap_vrf_id - Encap route table FIB index
    @param decap_next_index - index of decap next graph node
    @param vni - The VXLAN Network Identifier, uint24
    @param is_l3 - if true, create the interface in L3 mode, w/o MAC
*/
define vxlan_add_del_tunnel_v3
{
  u32 client_index;
  u32 context;
  bool is_add [default=true];
  u32 instance [default=0xffffffff];	/* If non-~0, specifies a custom dev instance */
  vl_api_address_t src_address;
  vl_api_address_t dst_address;
  u16 src_port;
  u16 dst_port;
  vl_api_interface_index_t mcast_sw_if_index;
  u32 encap_vrf_id;
  u32 decap_next_index;
  u32 vni;
  bool is_l3 [default=false];
};

define vxlan_add_del_tunnel_reply
{
  u32 context;
  i32 retval;
  vl_api_interface_index_t sw_if_index;
};
define vxlan_add_del_tunnel_v2_reply
{
  u32 context;
  i32 retval;
  vl_api_interface_index_t sw_if_index;
};
define vxlan_add_del_tunnel_v3_reply
{
  u32 context;
  i32 retval;
  vl_api_interface_index_t sw_if_index;
};

define vxlan_tunnel_dump
{
  u32 client_index;
  u32 context;
  vl_api_interface_index_t sw_if_index;
};
define vxlan_tunnel_v2_dump
{
  u32 client_index;
  u32 context;
  vl_api_interface_index_t sw_if_index;
};

define vxlan_tunnel_details
{
  u32 context;
  vl_api_interface_index_t sw_if_index;
  u32 instance;
  vl_api_address_t src_address;
  vl_api_address_t dst_address;
  vl_api_interface_index_t mcast_sw_if_index;
  u32 encap_vrf_id;
  u32 decap_next_index;
  u32 vni;
};
define vxlan_tunnel_v2_details
{
  u32 context;
  vl_api_interface_index_t sw_if_index;
  u32 instance;
  vl_api_address_t src_address;
  vl_api_address_t dst_address;
  u16 src_port;
  u16 dst_port;
  vl_api_interface_index_t mcast_sw_if_index;
  u32 encap_vrf_id;
  u32 decap_next_index;
  u32 vni;
};

/** \brief Interface set vxlan-bypass request
    @param client_index - opaque cookie to identify the sender
    @param context - sender context, to match reply w/ request
    @param sw_if_index - interface used to reach neighbor
    @param is_ipv6 - if non-zero, enable ipv6-vxlan-bypass, else ipv4-vxlan-bypass
    @param enable - if non-zero enable, else disable
*/
autoreply define sw_interface_set_vxlan_bypass
{
  u32 client_index;
  u32 context;
  vl_api_interface_index_t sw_if_index;
  bool is_ipv6;
  bool enable [default=true];
};

/** \brief Offload vxlan rx request
    @param client_index - opaque cookie to identify the sender
    @param context - sender context, to match reply w/ request
    @param hw_if_index - rx hw interface
    @param sw_if_index - vxlan interface to offload
    @param enable - if non-zero enable, else disable
*/
autoreply define vxlan_offload_rx
{
  u32 client_index;
  u32 context;
  vl_api_interface_index_t hw_if_index;
  vl_api_interface_index_t sw_if_index;
  bool enable [default=true];
};
