/*
 * ipsec_tun.h : IPSEC tunnel protection
 *
 * Copyright (c) 2015 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/ipsec/ipsec.h>

#define foreach_ipsec_protect_flags \
  _(L2, 1, "l2")                    \
  _(ENCAPED, 2, "encapped")         \
  _(ITF, 4, "itf")                  \

typedef enum ipsec_protect_flags_t_
{
  IPSEC_PROTECT_NONE = 0,
#define _(a,b,c) IPSEC_PROTECT_##a = b,
  foreach_ipsec_protect_flags
#undef _
} __clib_packed ipsec_protect_flags_t;

extern u8 *format_ipsec_tun_protect_flags (u8 * s, va_list * args);

/**
 * result of a lookup in the protection bihash
 */
typedef struct ipsec_tun_lkup_result_t_
{
  u32 tun_index;
  u32 sa_index;
  u32 sw_if_index;
  ipsec_protect_flags_t flags;
  u8 __pad[3];
} ipsec_tun_lkup_result_t;

typedef struct ipsec4_tunnel_kv_t
{
  /*
   * Key fields: remote ip and spi on incoming packet
   * all fields in NET byte order
   */
  u64 key;
  ipsec_tun_lkup_result_t value;
} __clib_packed ipsec4_tunnel_kv_t;

STATIC_ASSERT_SIZEOF (ipsec4_tunnel_kv_t, sizeof (clib_bihash_kv_8_16_t));
STATIC_ASSERT_OFFSET_OF (ipsec4_tunnel_kv_t, value,
			 STRUCT_OFFSET_OF (clib_bihash_kv_8_16_t, value));

static inline void
ipsec4_tunnel_mk_key (ipsec4_tunnel_kv_t * k,
		      const ip4_address_t * ip, u32 spi)
{
  k->key = (((u64) ip->as_u32) << 32 | spi);
}

static inline void
ipsec4_tunnel_extract_key (const ipsec4_tunnel_kv_t * k,
			   ip4_address_t * ip, u32 * spi)
{
  *spi = (u32) k->key;
  (*ip).as_u32 = k->key >> 32;
}

typedef struct ipsec6_tunnel_kv_t_
{
  /*
   * Key fields: remote ip and spi on incoming packet
   * all fields in NET byte order
   */
  struct
  {
    ip6_address_t remote_ip;
    u32 spi;
    u32 __pad;
  } key;
  ipsec_tun_lkup_result_t value;
} __clib_packed ipsec6_tunnel_kv_t;

STATIC_ASSERT_SIZEOF (ipsec6_tunnel_kv_t, sizeof (clib_bihash_kv_24_16_t));
STATIC_ASSERT_OFFSET_OF (ipsec6_tunnel_kv_t, value,
			 STRUCT_OFFSET_OF (clib_bihash_kv_24_16_t, value));

extern u8 *format_ipsec4_tunnel_kv (u8 * s, va_list * args);
extern u8 *format_ipsec6_tunnel_kv (u8 * s, va_list * args);

typedef struct ipsec_ep_t_
{
  ip46_address_t src;
  ip46_address_t dst;
} ipsec_ep_t;

#define ITP_MAX_N_SA_IN 4

typedef struct ipsec_tun_protect_t_
{
  CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
  index_t itp_out_sa;

  /* not using a vector since we want the memory inline
   * with this struct */
  u32 itp_n_sa_in;
  index_t itp_in_sas[ITP_MAX_N_SA_IN];

  u32 itp_sw_if_index;

  ipsec_ep_t itp_crypto;

  ipsec_protect_flags_t itp_flags;
  adj_index_t itp_ai;

  ipsec_ep_t itp_tun;

  ip_address_t *itp_key;

} ipsec_tun_protect_t;

#define FOR_EACH_IPSEC_PROTECT_INPUT_SAI(_itp, _sai, body) \
{                                                          \
  u32 __ii;                                                \
  for (__ii = 0; __ii < _itp->itp_n_sa_in; __ii++) {       \
    _sai = itp->itp_in_sas[__ii];                          \
    body;                                                  \
  }                                                        \
}
#define FOR_EACH_IPSEC_PROTECT_INPUT_SA(_itp, _sa, body)   \
{                                                          \
  u32 __ii;                                                \
  for (__ii = 0; __ii < _itp->itp_n_sa_in; __ii++) {       \
    _sa = ipsec_sa_get(itp->itp_in_sas[__ii]);             \
    body;                                                  \
  }                                                        \
}

extern int ipsec_tun_protect_update_one (u32 sw_if_index,
					 const ip_address_t * nh,
					 u32 sa_out, u32 sa_in);
extern int ipsec_tun_protect_update (u32 sw_if_index,
				     const ip_address_t * nh,
				     u32 sa_out, u32 * sa_ins);
extern int ipsec_tun_protect_update_in (u32 sw_if_index,
					const ip_address_t * nh, u32 sa_in);
extern int ipsec_tun_protect_update_out (u32 sw_if_index,
					 const ip_address_t * nh, u32 sa_out);

extern int ipsec_tun_protect_del (u32 sw_if_index, const ip_address_t * nh);

typedef walk_rc_t (*ipsec_tun_protect_walk_cb_t) (index_t itpi, void *arg);
extern void ipsec_tun_protect_walk (ipsec_tun_protect_walk_cb_t fn,
				    void *cttx);
extern void ipsec_tun_protect_walk_itf (u32 sw_if_index,
					ipsec_tun_protect_walk_cb_t fn,
					void *cttx);

extern u8 *format_ipsec_tun_protect (u8 * s, va_list * args);
extern u8 *format_ipsec_tun_protect_index (u8 * s, va_list * args);

extern void ipsec_tun_register_nodes (ip_address_family_t af);
extern void ipsec_tun_unregister_nodes (ip_address_family_t af);

extern void ipsec_tun_table_init (ip_address_family_t af,
				  uword table_size, u32 n_buckets);

// FIXME
extern vlib_node_registration_t ipsec4_tun_input_node;
extern vlib_node_registration_t ipsec6_tun_input_node;

/*
 * DP API
 */
extern ipsec_tun_protect_t *ipsec_tun_protect_pool;

always_inline ipsec_tun_protect_t *
ipsec_tun_protect_get (u32 index)
{
  return (pool_elt_at_index (ipsec_tun_protect_pool, index));
}

extern index_t *ipsec_tun_protect_sa_by_adj_index;
always_inline index_t
ipsec_tun_protect_get_sa_out (adj_index_t ai)
{
  ASSERT (vec_len (ipsec_tun_protect_sa_by_adj_index) > ai);
  ASSERT (INDEX_INVALID != ipsec_tun_protect_sa_by_adj_index[ai]);

  return (ipsec_tun_protect_sa_by_adj_index[ai]);
}

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