/*
 * 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.
 */

/**
 * @file
 * @brief Segment Routing data structures definitions
 *
 */

#ifndef included_vnet_srv6_h
#define included_vnet_srv6_h

#include <vnet/vnet.h>
#include <vnet/srv6/sr_packet.h>
#include <vnet/ip/ip6_packet.h>
#include <vnet/ethernet/ethernet.h>

#include <stdlib.h>
#include <string.h>

#define IPv6_DEFAULT_HEADER_LENGTH 40
#define IPv6_DEFAULT_HOP_LIMIT 64
#define IPv6_DEFAULT_MAX_MASK_WIDTH 128

#define SR_BEHAVIOR_END 1
#define SR_BEHAVIOR_X 2
#define SR_BEHAVIOR_T 3
#define SR_BEHAVIOR_D_FIRST 4	/* Unused. Separator in between regular and D */
#define SR_BEHAVIOR_DX2 5
#define SR_BEHAVIOR_DX6 6
#define SR_BEHAVIOR_DX4 7
#define SR_BEHAVIOR_DT6 8
#define SR_BEHAVIOR_DT4 9
#define SR_BEHAVIOR_END_UN_PERF 10
#define SR_BEHAVIOR_END_UN 11
#define SR_BEHAVIOR_LAST 12	/* Must always be the last one */

#define SR_STEER_L2 2
#define SR_STEER_IPV4 4
#define SR_STEER_IPV6 6

#define SR_FUNCTION_SIZE 4
#define SR_ARGUMENT_SIZE 4

#define SR_SEGMENT_LIST_WEIGHT_DEFAULT 1

/* *INDENT-OFF* */
typedef struct
{
  ip6_header_t ip;
  ip6_sr_header_t sr;
} __attribute__ ((packed)) ip6srv_combo_header_t;
/* *INDENT-ON* */

/**
 * @brief SR Segment List (SID list)
 */
typedef struct
{
  ip6_address_t *segments;		/**< SIDs (key) */

  u32 weight;						/**< SID list weight (wECMP / UCMP) */

  u8 *rewrite;					/**< Precomputed rewrite header */
  u8 *rewrite_bsid;				/**< Precomputed rewrite header for bindingSID */
  u8 policy_type;

  u32 egress_fib_table; /**< Egress FIB table for encap packet */

  dpo_id_t bsid_dpo;				/**< DPO for Encaps/Insert for BSID */
  dpo_id_t ip6_dpo;				/**< DPO for Encaps/Insert IPv6 */
  dpo_id_t ip4_dpo;				/**< DPO for Encaps IPv6 */

  u16 plugin;
  void *plugin_mem;
} ip6_sr_sl_t;

/* SR policy types */
#define SR_POLICY_TYPE_DEFAULT 0
#define SR_POLICY_TYPE_SPRAY 1
/**
 * @brief SR Policy
 */
typedef struct
{
  u32 *segments_lists;		/**< SID lists indexes (vector) */

  ip6_address_t bsid;			/**< BindingSID (key) */

  u8 type;					/**< Type (default is 0) */
  /* SR Policy specific DPO                                       */
  /* IF Type = DEFAULT Then Load-Balancer DPO among SID lists     */
  /* IF Type = SPRAY then Spray DPO with all SID lists            */
  dpo_id_t bsid_dpo;			/**< SR Policy specific DPO - BSID */
  dpo_id_t ip4_dpo;			/**< SR Policy specific DPO - IPv6 */
  dpo_id_t ip6_dpo;			/**< SR Policy specific DPO - IPv4 */

  u32 fib_table;			/**< FIB table */

  u8 is_encap;				/**< Mode (0 is SRH insert, 1 Encaps) */

  u16 plugin;
  void *plugin_mem;
} ip6_sr_policy_t;

typedef int (sr_p_plugin_callback_t) (ip6_sr_policy_t * sr);

/**
 * @brief SR LocalSID
 */
typedef struct
{
  ip6_address_t localsid;		/**< LocalSID IPv6 address */

  u16 localsid_prefix_len;

  char end_psp;					/**< Combined with End.PSP? */

  u16 behavior;					/**< Behavior associated to this localsid */

  union
  {
    u32 sw_if_index;				/**< xconnect only */
    u32 vrf_index;				/**< vrf only */
  };

  u32 fib_table;				/**< FIB table where localsid is registered */

  u32 vlan_index;				/**< VLAN tag (not an index) */

  ip46_address_t next_hop;		/**< Next_hop for xconnect usage only */

  u32 nh_adj;						/**< Next_adj for xconnect usage only */

  ip6_address_t usid_block;
  ip6_address_t usid_block_mask;

  u8 usid_index;
  u8 usid_len;

  u8 usid_next_index;
  u8 usid_next_len;

  void *plugin_mem;				/**< Memory to be used by the plugin callback functions */
} ip6_sr_localsid_t;

typedef int (sr_plugin_callback_t) (ip6_sr_localsid_t * localsid);

/**
 * @brief SR LocalSID behavior registration
 */
typedef struct
{
  u16 sr_localsid_function_number;			/**< SR LocalSID plugin function (>SR_BEHAVIOR_LAST) */

  u8 *function_name;							/**< Function name. (key). */

  u8 *keyword_str;							/**< Behavior keyword (i.e. End.X) */

  u8 *def_str;								/**< Behavior definition (i.e. Endpoint with cross-connect) */

  u8 *params_str;							/**< Behavior parameters (i.e. <oif> <IP46next_hop>) */

  u8 prefix_length;

  dpo_type_t dpo;							/**< DPO type registration */

  format_function_t *ls_format;				/**< LocalSID format function */

  unformat_function_t *ls_unformat;			/**< LocalSID unformat function */

  sr_plugin_callback_t *creation;			/**< Function within plugin that will be called after localsid creation*/

  sr_plugin_callback_t *removal;			/**< Function within plugin that will be called before localsid removal */
} sr_localsid_fn_registration_t;

/**
 * @brief SR Policy behavior registration
 */
typedef struct
{
  u16 sr_policy_function_number;			/**< SR Policy plugin function */

  u8 *function_name;					/**< Function name. (key). */

  u8 *keyword_str;					/**< Behavior keyword (i.e. End.X) */

  u8 *def_str;						/**< Behavior definition (i.e. Endpoint with cross-connect) */

  u8 *params_str;					/**< Behavior parameters (i.e. <oif> <IP46next_hop>) */

  u8 prefix_length;

  dpo_type_t dpo;					/**< DPO type registration */

  format_function_t *ls_format;				/**< LocalSID format function */

  unformat_function_t *ls_unformat;			/**< LocalSID unformat function */

  sr_p_plugin_callback_t *creation;			/**< Function within plugin that will be called after localsid creation*/

  sr_p_plugin_callback_t *removal;			/**< Function within plugin that will be called before localsid removal */
} sr_policy_fn_registration_t;

/**
 * @brief Steering db key
 *
 * L3 is IPv4/IPv6 + mask
 * L2 is sf_if_index + vlan
 */
typedef struct
{
  union
  {
    struct
    {
      ip46_address_t prefix;			/**< IP address of the prefix */
      u32 mask_width;					/**< Mask width of the prefix */
      u32 fib_table;					/**< VRF of the prefix */
    } l3;
    struct
    {
      u32 sw_if_index;					/**< Incoming software interface */
    } l2;
  };
  u8 traffic_type;					/**< Traffic type (IPv4, IPv6, L2) */
  u8 padding[3];
} sr_steering_key_t;

typedef struct
{
  sr_steering_key_t classify;		/**< Traffic classification */
  u32 sr_policy;					/**< SR Policy index */
} ip6_sr_steering_policy_t;

typedef struct
{
  ip6_address_t address;
  u16 pref_len;
  u8 padding[2];
} sr_localsid_key_t;

/**
 * @brief Segment Routing main datastructure
 */
typedef struct
{
  /* L2-input -> SR rewrite next index */
  u32 l2_sr_policy_rewrite_index;

  /* SR SID lists */
  ip6_sr_sl_t *sid_lists;

  /* SRv6 policies */
  ip6_sr_policy_t *sr_policies;

  /* Hash table mapping BindingSID to SRv6 policy */
  mhash_t sr_policies_index_hash;

  /* Pool of SR localsid instances */
  ip6_sr_localsid_t *localsids;

  /* Hash table mapping LOC:FUNC to SR LocalSID instance */
  mhash_t sr_localsids_index_hash;

  /* Pool of SR steer policies instances */
  ip6_sr_steering_policy_t *steer_policies;

  /* Hash table mapping steering rules to SR steer instance */
  mhash_t sr_steer_policies_hash;

  /* L2 steering ifaces - sr_policies */
  u32 *sw_iface_sr_policies;

  /* Spray DPO */
  dpo_type_t sr_pr_spray_dpo_type;

  /* Plugin functions */
  sr_localsid_fn_registration_t *plugin_functions;

  /* Find plugin function by name */
  uword *plugin_functions_by_key;

  /* Plugin functions for Policy */
  sr_policy_fn_registration_t *policy_plugin_functions;

  /* Find plugin function by name */
  uword *policy_plugin_functions_by_key;

  /* Counters */
  vlib_combined_counter_main_t sr_ls_valid_counters;
  vlib_combined_counter_main_t sr_ls_invalid_counters;

  /* SR Policies FIBs */
  u32 fib_table_ip6;
  u32 fib_table_ip4;

  /* convenience */
  vlib_main_t *vlib_main;
  vnet_main_t *vnet_main;
  u16 msg_id_base;
} ip6_sr_main_t;

extern ip6_sr_main_t sr_main;

extern vlib_node_registration_t sr_policy_rewrite_encaps_node;
extern vlib_node_registration_t sr_policy_rewrite_insert_node;
extern vlib_node_registration_t sr_localsid_node;
extern vlib_node_registration_t sr_localsid_d_node;

extern void sr_dpo_lock (dpo_id_t * dpo);
extern void sr_dpo_unlock (dpo_id_t * dpo);

extern int
sr_localsid_register_function (vlib_main_t * vm, u8 * fn_name,
			       u8 * keyword_str, u8 * def_str,
			       u8 * params_str, u8 prefix_length,
			       dpo_type_t * dpo,
			       format_function_t * ls_format,
			       unformat_function_t * ls_unformat,
			       sr_plugin_callback_t * creation_fn,
			       sr_plugin_callback_t * removal_fn);

extern int
sr_policy_register_function (vlib_main_t * vm, u8 * fn_name,
			     u8 * keyword_str, u8 * def_str,
			     u8 * params_str, u8 prefix_length,
			     dpo_type_t * dpo,
			     format_function_t * ls_format,
			     unformat_function_t * ls_unformat,
			     sr_p_plugin_callback_t * creation_fn,
			     sr_p_plugin_callback_t * removal_fn);

extern int sr_policy_add (ip6_address_t *bsid, ip6_address_t *segments,
			  u32 weight, u8 type, u32 fib_table, u8 is_encap,
			  u16 plugin, void *plugin_mem);
extern int sr_policy_mod (ip6_address_t * bsid, u32 index, u32 fib_table,
			  u8 operation, ip6_address_t * segments,
			  u32 sl_index, u32 weight);
extern int sr_policy_del (ip6_address_t * bsid, u32 index);

extern int
sr_cli_localsid (char is_del, ip6_address_t * localsid_addr,
		 u16 localsid_prefix_len, char end_psp, u8 behavior,
		 u32 sw_if_index, u32 vlan_index, u32 fib_table,
		 ip46_address_t * nh_addr, int usid_len, void *ls_plugin_mem);

extern int
sr_steering_policy (int is_del, ip6_address_t * bsid, u32 sr_policy_index,
		    u32 table_id, ip46_address_t * prefix, u32 mask_width,
		    u32 sw_if_index, u8 traffic_type);

extern void sr_set_source (ip6_address_t * address);
extern ip6_address_t *sr_get_encaps_source ();

extern void sr_set_hop_limit (u8 hop_limit);
extern u8 sr_get_hop_limit (void);

/**
 * @brief SR rewrite string computation for SRH insertion (inline)
 *
 * @param sl is a vector of IPv6 addresses composing the Segment List
 *
 * @return precomputed rewrite string for SRH insertion
 */
static inline u8 *
ip6_sr_compute_rewrite_string_insert (ip6_address_t * sl)
{
  ip6_sr_header_t *srh;
  ip6_address_t *addrp, *this_address;
  u32 header_length = 0;
  u8 *rs = NULL;

  header_length = 0;
  header_length += sizeof (ip6_sr_header_t);
  header_length += (vec_len (sl) + 1) * sizeof (ip6_address_t);

  vec_validate (rs, header_length - 1);

  srh = (ip6_sr_header_t *) rs;
  srh->type = ROUTING_HEADER_TYPE_SR;
  srh->segments_left = vec_len (sl);
  srh->last_entry = vec_len (sl);
  srh->length = ((sizeof (ip6_sr_header_t) +
		  ((vec_len (sl) + 1) * sizeof (ip6_address_t))) / 8) - 1;
  srh->flags = 0x00;
  srh->tag = 0x0000;
  addrp = srh->segments + vec_len (sl);
  vec_foreach (this_address, sl)
  {
    clib_memcpy_fast (addrp->as_u8, this_address->as_u8,
		      sizeof (ip6_address_t));
    addrp--;
  }
  return rs;
}

#endif /* included_vnet_sr_h */

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