/*
 * ipip.h: types/functions for ipip.
 *
 * Copyright (c) 2018 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 aipiped 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.
 */

#ifndef included_ipip_h
#define included_ipip_h

#include <vnet/adj/adj_types.h>
#include <vnet/ip/ip6_packet.h>
#include <vnet/ip/format.h>
#include <vnet/ip/ip.h>
#include <vnet/vnet.h>

extern vnet_hw_interface_class_t ipip_hw_interface_class;

#define foreach_ipip_error			\
  /* Must be first. */				\
  _(DECAP_PKTS, "packets decapsulated")		\
  _(BAD_PROTOCOL, "bad protocol")		\
  _(NO_TUNNEL, "no tunnel")

typedef enum
{
#define _(sym, str) IPIP_ERROR_##sym,
  foreach_ipip_error
#undef _
    IPIP_N_ERROR,
} ipip_error_t;

/**
 * @brief IPIP Tunnel key
 */
typedef enum
{
  IPIP_TRANSPORT_IP4,
  IPIP_TRANSPORT_IP6,
} ipip_transport_t;

typedef struct
{
  ipip_transport_t transport;
  u32 fib_index;
  ip46_address_t src;
  ip46_address_t dst;
} __attribute__ ((packed)) ipip_tunnel_key_t;

typedef enum
{
  IPIP_MODE_P2P = 0,
  IPIP_MODE_6RD,
} ipip_mode_t;

/**
 * @brief A representation of a IPIP tunnel
 */
typedef struct
{
  ipip_mode_t mode;
  ipip_transport_t transport;
  ipip_tunnel_key_t *key;
  ip46_address_t tunnel_src;
  ip46_address_t tunnel_dst;
  u32 fib_index;
  u32 hw_if_index;
  u32 sw_if_index;
  u32 dev_instance;		/* Real device instance in tunnel vector */
  u32 user_instance;		/* Instance name being shown to user */

  union
  {
    struct
    {
      fib_node_t node;
      fib_node_index_t fib_entry_index;
      u32 sibling_index;
    } p2p;
    struct
    {
      ip6_address_t ip6_prefix;
      ip4_address_t ip4_prefix;
      u8 ip6_prefix_len;
      u8 ip4_prefix_len;
      u8 shift;
      bool security_check;
    } sixrd;
  };
} ipip_tunnel_t;

typedef struct
{
  ipip_tunnel_t *tunnels;
  uword *tunnel_by_key;
  u32 *tunnel_index_by_sw_if_index;
  fib_node_type_t fib_node_type;

  /* convenience */
  vlib_main_t *vlib_main;
  vnet_main_t *vnet_main;

  /* Record used instances */
  uword *instance_used;

  bool ip4_protocol_registered;
  bool ip6_protocol_registered;
} ipip_main_t;

extern ipip_main_t ipip_main;
extern vlib_node_registration_t ipip4_input_node;
extern vlib_node_registration_t ipip6_input_node;

/*
 * sixrd_get_addr_net
 */
static_always_inline u32
sixrd_get_addr_net (const ipip_tunnel_t * t, u64 dal)
{
  /* 1:1 mode */
  if (t->sixrd.ip4_prefix_len == 32)
    return (t->sixrd.ip4_prefix.as_u32);

  dal = clib_net_to_host_u64 (dal);

  /* Grab 32 - ip4_prefix_len bits out of IPv6 address from offset
   * ip6_prefix_len */
  u32 mask = ~(~0ULL << (32 - t->sixrd.ip4_prefix_len));
  u32 ip4 =
    clib_net_to_host_u32 (t->sixrd.
			  ip4_prefix.as_u32) | ((u32) (dal >> t->sixrd.
						       shift) & mask);
  return clib_host_to_net_u32 (ip4);
}

int ipip_add_tunnel (ipip_transport_t transport, u32 instance,
		     ip46_address_t * src, ip46_address_t * dst,
		     u32 fib_index, u32 * sw_if_indexp);
int ipip_del_tunnel (u32 sw_if_index);
int sixrd_add_tunnel (ip6_address_t * ip6_prefix, u8 ip6_prefix_len,
		      ip4_address_t * ip4_prefix, u8 ip4_prefix_len,
		      ip4_address_t * ip4_src, bool security_check,
		      u32 fib_index, u32 * sw_if_index);
int sixrd_del_tunnel (u32 sw_if_index);
void ipip_tunnel_db_add (ipip_tunnel_t * t, ipip_tunnel_key_t * key);
void ipip_tunnel_db_remove (ipip_tunnel_t * t);
ipip_tunnel_t *ipip_tunnel_db_find (ipip_tunnel_key_t * key);
ipip_tunnel_t *ipip_tunnel_db_find_by_sw_if_index (u32 sw_if_index);

#endif

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