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

#ifndef included_gre_h
#define included_gre_h

#include <vnet/vnet.h>
#include <vnet/gre/packet.h>
#include <vnet/ip/ip.h>
#include <vnet/pg/pg.h>
#include <vnet/ip/format.h>
#include <vnet/adj/adj_types.h>
#include <vnet/tunnel/tunnel.h>
#include <vnet/teib/teib.h>

extern vnet_hw_interface_class_t gre_hw_interface_class;
extern vnet_hw_interface_class_t mgre_hw_interface_class;

typedef enum
{
#define gre_error(n,s) GRE_ERROR_##n,
#include <vnet/gre/error.def>
#undef gre_error
  GRE_N_ERROR,
} gre_error_t;

/**
 * L3: GRE (i.e. this tunnel is in L3 mode)
 * TEB: Transparent Ethernet Bridging - the tunnel is in L2 mode
 * ERSPAN: type 2 - the tunnel is for port mirror SPAN output. Each tunnel is
 *         associated with a session ID and expected to be used for encap
 *         and output of mirrored packet from a L2 network only. There is
 *         no support for receiving ERSPAN packets from a GRE ERSPAN tunnel
 */
#define foreach_gre_tunnel_type \
  _(L3, "L3")                   \
  _(TEB, "TEB")                 \
  _(ERSPAN, "ERSPAN")           \

/**
 * @brief The GRE tunnel type
 */
typedef enum gre_tunnel_type_t_
{
#define _(n, s) GRE_TUNNEL_TYPE_##n,
  foreach_gre_tunnel_type
#undef _
} __clib_packed gre_tunnel_type_t;

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


/**
 * A GRE payload protocol registration
 */
typedef struct
{
  /** Name (a c string). */
  char *name;

  /** GRE protocol type in host byte order. */
  gre_protocol_t protocol;

  /** GRE tunnel type */
  gre_tunnel_type_t tunnel_type;

  /** Node which handles this type. */
  u32 node_index;

  /** Next index for this type. */
  u32 next_index;
} gre_protocol_info_t;

/**
 * Elements of the GRE key that are common for v6 and v6 addresses
 */
typedef struct gre_tunnel_key_common_t_
{
  union
  {
    struct
    {
      u32 fib_index;
      u16 session_id;
      gre_tunnel_type_t type;
      tunnel_mode_t mode;
    };
    u64 as_u64;
  };
} gre_tunnel_key_common_t;

STATIC_ASSERT_SIZEOF (gre_tunnel_key_common_t, sizeof (u64));

/**
 * @brief Key for a IPv4 GRE Tunnel
 */
typedef struct gre_tunnel_key4_t_
{
  /**
   * Source and destination IP addresses
   */
  union
  {
    struct
    {
      ip4_address_t gtk_src;
      ip4_address_t gtk_dst;
    };
    u64 gtk_as_u64;
  };

  /** address independent attributes */
  gre_tunnel_key_common_t gtk_common;
} __attribute__ ((packed)) gre_tunnel_key4_t;

STATIC_ASSERT_SIZEOF (gre_tunnel_key4_t, 2 * sizeof (u64));

/**
 * @brief Key for a IPv6 GRE Tunnel
 * We use a different type so that the V4 key hash is as small as possible
 */
typedef struct gre_tunnel_key6_t_
{
  /**
   * Source and destination IP addresses
   */
  ip6_address_t gtk_src;
  ip6_address_t gtk_dst;

  /** address independent attributes */
  gre_tunnel_key_common_t gtk_common;
} __attribute__ ((packed)) gre_tunnel_key6_t;

STATIC_ASSERT_SIZEOF (gre_tunnel_key6_t, 5 * sizeof (u64));

/**
 * Union of the two possible key types
 */
typedef union gre_tunnel_key_t_
{
  gre_tunnel_key4_t gtk_v4;
  gre_tunnel_key6_t gtk_v6;
} gre_tunnel_key_t;

/**
 * The session ID is only a 10 bit value
 */
#define GTK_SESSION_ID_MAX (0x3ff)

/**
 * Used for GRE header seq number generation for ERSPAN encap
 */
typedef struct
{
  u32 seq_num;
  u32 ref_count;
} gre_sn_t;

/**
 * Hash key for GRE header seq number generation for ERSPAN encap
 */
typedef struct
{
  ip46_address_t src;
  ip46_address_t dst;
  u32 fib_index;
} gre_sn_key_t;

/**
 * @brief A representation of a GRE tunnel
 */
typedef struct
{
  /**
   * Required for pool_get_aligned
   */
  CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);

  /**
   * The tunnel's source/local address
   */
  ip46_address_t tunnel_src;
  /**
   * The tunnel's destination/remote address
   */
  fib_prefix_t tunnel_dst;
  /**
   * The FIB in which the src.dst address are present
   */
  u32 outer_fib_index;
  u32 hw_if_index;
  u32 sw_if_index;
  gre_tunnel_type_t type;
  tunnel_mode_t mode;
  tunnel_encap_decap_flags_t flags;

  /**
   * an L2 tunnel always rquires an L2 midchain. cache here for DP.
   */
  adj_index_t l2_adj_index;

  /**
   * ERSPAN type 2 session ID, least significant 10 bits of u16
   */
  u16 session_id;

  /**
   * GRE header sequence number (SN) used for ERSPAN type 2 header, must be
   * bumped automically to be thread safe. As multiple GRE tunnels are created
   * for the same fib-idx/DIP/SIP with different ERSPAN session number, they all
   * share the same SN which is kept per FIB/DIP/SIP, as specified by RFC2890.
   */
  gre_sn_t *gre_sn;


  u32 dev_instance;		/* Real device instance in tunnel vector */
  u32 user_instance;		/* Instance name being shown to user */
} gre_tunnel_t;

typedef struct
{
  u8 next_index;
  u8 tunnel_type;
} next_info_t;

/**
 * @brief GRE related global data
 */
typedef struct
{
  /**
   * pool of tunnel instances
   */
  gre_tunnel_t *tunnels;

  /**
   * GRE payload protocol registrations
   */
  gre_protocol_info_t *protocol_infos;

  /**
   *  Hash tables mapping name/protocol to protocol info index.
   */
  uword *protocol_info_by_name, *protocol_info_by_protocol;

  /**
   * Hash mapping to tunnels with ipv4 src/dst addr
   */
  uword *tunnel_by_key4;

  /**
   * Hash mapping to tunnels with ipv6 src/dst addr
   */
  uword *tunnel_by_key6;

  /**
   * Hash mapping tunnel src/dst addr and fib-idx to sequence number
   */
  uword *seq_num_by_key;

  /**
   * Mapping from sw_if_index to tunnel index
   */
  u32 *tunnel_index_by_sw_if_index;

  /* Sparse vector mapping gre protocol in network byte order
     to next index. */
  next_info_t *next_by_protocol;

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

  /* Record used instances */
  uword *instance_used;
} gre_main_t;

/**
 * @brief IPv4 and GRE header.
 */
/* *INDENT-OFF* */
typedef CLIB_PACKED (struct {
  ip4_header_t ip4;
  gre_header_t gre;
}) ip4_and_gre_header_t;
/* *INDENT-ON* */

/**
 * @brief IPv6 and GRE header.
 */
/* *INDENT-OFF* */
typedef CLIB_PACKED (struct {
  ip6_header_t ip6;
  gre_header_t gre;
}) ip6_and_gre_header_t;
/* *INDENT-ON* */

always_inline gre_protocol_info_t *
gre_get_protocol_info (gre_main_t * em, gre_protocol_t protocol)
{
  uword *p = hash_get (em->protocol_info_by_protocol, protocol);
  return p ? vec_elt_at_index (em->protocol_infos, p[0]) : 0;
}

extern gre_main_t gre_main;

extern clib_error_t *gre_interface_admin_up_down (vnet_main_t * vnm,
						  u32 hw_if_index, u32 flags);

extern void gre_tunnel_stack (adj_index_t ai);
extern void gre_update_adj (vnet_main_t * vnm,
			    u32 sw_if_index, adj_index_t ai);

typedef struct mgre_walk_ctx_t_
{
  const gre_tunnel_t *t;
  const teib_entry_t *ne;
} mgre_walk_ctx_t;

adj_walk_rc_t mgre_mk_complete_walk (adj_index_t ai, void *data);
adj_walk_rc_t mgre_mk_incomplete_walk (adj_index_t ai, void *data);

format_function_t format_gre_protocol;
format_function_t format_gre_header;
format_function_t format_gre_header_with_length;

extern vlib_node_registration_t gre4_input_node;
extern vlib_node_registration_t gre6_input_node;
extern vlib_node_registration_t gre_encap_node;
extern vnet_device_class_t gre_device_class;

/* Parse gre protocol as 0xXXXX or protocol name.
   In either host or network byte order. */
unformat_function_t unformat_gre_protocol_host_byte_order;
unformat_function_t unformat_gre_protocol_net_byte_order;

/* Parse gre header. */
unformat_function_t unformat_gre_header;
unformat_function_t unformat_pg_gre_header;

void
gre_register_input_protocol (vlib_main_t * vm, gre_protocol_t protocol,
			     u32 node_index, gre_tunnel_type_t tunnel_type);

/* manually added to the interface output node in gre.c */
#define GRE_OUTPUT_NEXT_LOOKUP	1

typedef struct
{
  u8 is_add;
  gre_tunnel_type_t type;
  tunnel_mode_t mode;
  u8 is_ipv6;
  u32 instance;
  ip46_address_t src, dst;
  u32 outer_table_id;
  u16 session_id;
  tunnel_encap_decap_flags_t flags;
} vnet_gre_tunnel_add_del_args_t;

extern int vnet_gre_tunnel_add_del (vnet_gre_tunnel_add_del_args_t * a,
				    u32 * sw_if_indexp);

static inline void
gre_mk_key4 (ip4_address_t src,
	     ip4_address_t dst,
	     u32 fib_index,
	     gre_tunnel_type_t ttype,
	     tunnel_mode_t tmode, u16 session_id, gre_tunnel_key4_t * key)
{
  key->gtk_src = src;
  key->gtk_dst = dst;
  key->gtk_common.type = ttype;
  key->gtk_common.mode = tmode;
  key->gtk_common.fib_index = fib_index;
  key->gtk_common.session_id = session_id;
}

static inline int
gre_match_key4 (const gre_tunnel_key4_t * key1,
		const gre_tunnel_key4_t * key2)
{
  return ((key1->gtk_as_u64 == key2->gtk_as_u64) &&
	  (key1->gtk_common.as_u64 == key2->gtk_common.as_u64));
}

static inline void
gre_mk_key6 (const ip6_address_t * src,
	     const ip6_address_t * dst,
	     u32 fib_index,
	     gre_tunnel_type_t ttype,
	     tunnel_mode_t tmode, u16 session_id, gre_tunnel_key6_t * key)
{
  key->gtk_src = *src;
  key->gtk_dst = *dst;
  key->gtk_common.type = ttype;
  key->gtk_common.mode = tmode;
  key->gtk_common.fib_index = fib_index;
  key->gtk_common.session_id = session_id;
}

static inline int
gre_match_key6 (const gre_tunnel_key6_t * key1,
		const gre_tunnel_key6_t * key2)
{
  return (ip6_address_is_equal (&key1->gtk_src, &key2->gtk_src) &&
	  ip6_address_is_equal (&key1->gtk_dst, &key2->gtk_dst) &&
	  (key1->gtk_common.as_u64 == key2->gtk_common.as_u64));
}

static inline void
gre_mk_sn_key (const gre_tunnel_t * gt, gre_sn_key_t * key)
{
  key->src = gt->tunnel_src;
  key->dst = gt->tunnel_dst.fp_addr;
  key->fib_index = gt->outer_fib_index;
}

#endif /* included_gre_h */

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