/*
 * Copyright (c) 2017 SUSE LLC.
 * 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_vnet_sctp_h
#define included_vnet_sctp_h

#include <vnet/vnet.h>
#include <vnet/ip/ip.h>
#include <vnet/sctp/sctp_timer.h>
#include <vnet/sctp/sctp_packet.h>
#include <vnet/session/transport.h>
#include <vnet/session/session.h>

/* SCTP timers */
#define foreach_sctp_timer              	\
  _(T1_INIT, "T1_INIT")           			\
  _(T1_COOKIE, "T1_COOKIE")        			\
  _(T2_SHUTDOWN, "T2_SHUTDOWN")         	\
  _(T3_RXTX, "T3_RXTX")   					\
  _(T4_HEARTBEAT, "T4_HB")					\
  _(T5_SHUTDOWN_GUARD, "T5_SHUTDOWN_GUARD")

typedef enum _sctp_timers
{
#define _(sym, str) SCTP_TIMER_##sym,
  foreach_sctp_timer
#undef _
  SCTP_N_TIMERS
} sctp_timers_e;

#define SCTP_TIMER_HANDLE_INVALID ((u32) ~0)

always_inline char *
sctp_timer_to_string (u8 timer_id)
{
  switch (timer_id)
    {
    case SCTP_TIMER_T1_INIT:
      return "SCTP_TIMER_T1_INIT";
    case SCTP_TIMER_T1_COOKIE:
      return "SCTP_TIMER_T1_COOKIE";
    case SCTP_TIMER_T2_SHUTDOWN:
      return "SCTP_TIMER_T2_SHUTDOWN";
    case SCTP_TIMER_T3_RXTX:
      return "SCTP_TIMER_T3_RXTX";
    case SCTP_TIMER_T4_HEARTBEAT:
      return "SCTP_TIMER_T4_HEARTBEAT";
    case SCTP_TIMER_T5_SHUTDOWN_GUARD:
      return "SCTP_TIMER_T5_SHUTDOWN_GUARD";
    }
  return NULL;
}

typedef enum _sctp_error
{
#define sctp_error(n,s) SCTP_ERROR_##n,
#include <vnet/sctp/sctp_error.def>
#undef sctp_error
  SCTP_N_ERROR,
} sctp_error_t;

#define NO_FLAG 0

#define IS_T_BIT_SET(var) ((var) & (1))
#define IS_E_BIT_SET(var) ((var) & (1))
#define IS_B_BIT_SET(var) ((var) & (1<<1))
#define IS_U_BIT_SET(var) ((var) & (1<<2))

#define MAX_SCTP_CONNECTIONS 8
#define SCTP_PRIMARY_PATH_IDX 0

#if (VLIB_BUFFER_TRACE_TRAJECTORY)
#define sctp_trajectory_add_start(b, start)			\
{								\
    (*vlib_buffer_trace_trajectory_cb) (b, start);		\
}
#else
#define sctp_trajectory_add_start(b, start)
#endif

enum _sctp_subconn_state
{
  SCTP_SUBCONN_STATE_DOWN = 0,
  SCTP_SUBCONN_STATE_UP,
  SCTP_SUBCONN_STATE_ALLOW_HB
};

#define SCTP_INITIAL_SSHTRESH 65535
typedef struct _sctp_sub_connection
{
  transport_connection_t connection;	      /**< Common transport data. First! */

  u8 subconn_idx; /**< This indicates the position of this sub-connection in the super-set container of connections pool */
  u32 error_count; /**< The current error count for this destination. */
  u32 error_threshold; /**< Current error threshold for this destination,
				i.e. what value marks the destination down if error count reaches this value. */
  u32 cwnd; /**< Congestion control window (cwnd, in bytes), which is adjusted by
      the sender based on observed network conditions. */
  u32 ssthresh;	/**< Slow-start threshold (in bytes), which is used by the
      sender to distinguish slow-start and congestion avoidance phases. */

  u32 rtt_ts;	/**< USED to hold the timestamp of when the packet has been sent */

  u32 RTO; /**< The current retransmission timeout value. */
  u32 SRTT; /**< The current smoothed round-trip time. */
  f32 RTTVAR; /**< The current RTT variation. */

  u32 partially_acked_bytes; /**< The tracking method for increase of cwnd when in
  	  	  	  	  congestion avoidance mode (see Section 7.2.2).*/

  u8 state; /**< The current state of this destination, i.e., DOWN, UP, ALLOW-HB, NO-HEARTBEAT, etc. */

  u16 PMTU; /**< The current known path MTU. */

  u32 timers[SCTP_N_TIMERS]; /**< A timer used by each destination. */

  u8 RTO_pending; /**< A flag used to track if one of the DATA chunks sent to
  	  	  	  	  this address is currently being used to compute an RTT.
  	  	  	  	  If this flag is 0, the next DATA chunk sent to this destination
  	  	  	  	  should be used to compute an RTT and this flag should be set.
  	  	  	  	  Every time the RTT calculation completes (i.e., the DATA chunk is SACK'd),
  	  	  	  	  clear this flag. */

  u32 last_seen; /**< The time to which this destination was last sent a packet to.
  	  	  	  	  This can be used to determine if a HEARTBEAT is needed. */

  u32 last_data_ts; /**< Used to hold the timestamp value of last time we sent a DATA chunk */

  u8 unacknowledged_hb;	/**< Used to track how many unacknowledged heartbeats we had;
  	  	  	  	  If more than SCTP_PATH_MAX_RETRANS then connection is considered unreachable. */

  u8 is_retransmitting;	/**< A flag (0 = no, 1 = yes) indicating whether the connection is retransmitting a previous packet */

  u8 enqueue_state; /**< if set to 1 indicates that DATA is still being handled hence cannot shutdown this connection yet */

} sctp_sub_connection_t;

typedef struct
{
  u32 a_rwnd; /**< Maximum segment size advertised */

} sctp_options_t;

/* Useful macros to deal with the out_of_order_map (array of bit) */
#define SET_BIT(A,k)     ( A[(k/32)] |= (1 << (k%32)) )
#define CLEAR_BIT(A,k)   ( A[(k/32)] &= ~(1 << (k%32)) )
#define TEST_BIT(A,k)    ( A[(k/32)] & (1 << (k%32)) )

always_inline void
_bytes_swap (void *pv, size_t n)
{
  char *p = pv;
  size_t lo, hi;
  for (lo = 0, hi = n - 1; hi > lo; lo++, hi--)
    {
      char tmp = p[lo];
      p[lo] = p[hi];
      p[hi] = tmp;
    }
}

#define ENDIANESS_SWAP(x) _bytes_swap(&x, sizeof(x));

#define MAX_INFLIGHT_PACKETS	128
#define MAX_ENQUEABLE_SACKS 2

/* This parameter indicates to the receiver how much increment in
 * milliseconds the sender wishes the receiver to add to its default
 * cookie life-span.
 */
#define SUGGESTED_COOKIE_LIFE_SPAN_INCREMENT 1000

typedef struct _sctp_user_configuration
{
  u8 never_delay_sack;
  u8 never_bundle;

} sctp_user_configuration_t;

typedef struct _sctp_connection
{
  sctp_sub_connection_t sub_conn[MAX_SCTP_CONNECTIONS];	/**< Common transport data. First! */
  sctp_user_configuration_t conn_config; /**< Allows tuning of some SCTP behaviors */

  u8 state;			/**< SCTP state as per sctp_state_t */
  u16 flags;		/**< Chunk flag (see sctp_chunks_common_hdr_t) */

  u32 local_tag;	/**< INIT_TAG generated locally */
  u32 remote_tag;	/**< INIT_TAG generated by the remote peer */

  u32 local_initial_tsn; /**< Initial TSN generated locally */
  u32 remote_initial_tsn; /**< Initial TSN generated by the remote-peer */

  u32 peer_cookie_life_span_increment;

  u32 overall_err_count; /**< The overall association error count. */
  u32 overall_err_treshold; /**< The threshold for this association that if the Overall Error Count
  	  	  	  	  reaches will cause this association to be torn down. */

  u8 init_retransmit_err; /**< Error counter for the INIT transmission phase */

  u32 peer_rwnd; /**< Current calculated value of the peer's rwnd. */

  u32 next_tsn;	/**< The next TSN number to be assigned to a new DATA chunk.
                 This is sent in the INIT or INIT ACK chunk to the peer
                 and incremented each time a DATA chunk is assigned a
                 TSN (normally just prior to transmit or during
                 fragmentation). */

  u32 last_unacked_tsn;	/** < Last TSN number still unacked */
  u32 next_tsn_expected; /**< The next TSN number expected to be received. */

  u32 last_rcvd_tsn; /**< This is the last TSN received in sequence. This value
     	 	 	 is set initially by taking the peer's initial TSN,
                 received in the INIT or INIT ACK chunk, and
                 subtracting one from it. */

  u32 out_of_order_map[MAX_INFLIGHT_PACKETS]; /**< An array of bits or bytes indicating which out-of-order
				TSNs have been received (relative to the Last Rcvd TSN).
				If no gaps exist, i.e., no out-of-order packets have been received,
				this array will be set to all zero. */

  u8 ack_state;	/**< This flag indicates if the next received packet is set to be responded to with a SACK.
  	  	  	  	This is initialized to 0. When a packet is received it is incremented.
  	  	  	  	If this value reaches 2 or more, a SACK is sent and the value is reset to 0.
  	  	  	  	Note: This is used only when no DATA chunks are received out-of-order.
  	  	  	  	When DATA chunks are out-of-order, SACKs are not delayed (see Section 6). */

  u8 smallest_PMTU_idx;	/** The index of the sub-connection with the smallest PMTU discovered across all peer's transport addresses. */

  u8 overall_sending_status; /**< 0 indicates first fragment of a user message
  	  	  	  	  	  	  	  	  1 indicates normal stream
  	  	  	  	  	  	  	  	  2 indicates last fragment of a user message */

  u8 forming_association_changed; /**< This is a flag indicating whether the original association has been modified during
  	  	  	  	  the life-span of the association itself. For instance, a new sub-connection might have been added. */

  sctp_state_cookie_param_t cookie_param; /**< Temporary location to save cookie information; it can be used to
  	  	  	  	  when timeout expires and sending again a COOKIE is require. */

} sctp_connection_t;

typedef void (sctp_timer_expiration_handler) (u32 conn_index, u32 timer_id);

sctp_connection_t *sctp_connection_new (u8 thread_index);

u8
sctp_sub_connection_add_ip4 (vlib_main_t * vm,
			     ip4_address_t * lcl_addr,
			     ip4_address_t * rmt_addr);

u8
sctp_sub_connection_add_ip6 (vlib_main_t * vm,
			     ip6_address_t * lcl_addr,
			     ip6_address_t * rmt_addr);

u8
sctp_sub_connection_del_ip4 (ip4_address_t * lcl_addr,
			     ip4_address_t * rmt_addr);

u8
sctp_sub_connection_del_ip6 (ip6_address_t * lcl_addr,
			     ip6_address_t * rmt_addr);

u8 sctp_configure (sctp_user_configuration_t config);

void sctp_connection_close (sctp_connection_t * sctp_conn);
void sctp_connection_cleanup (sctp_connection_t * sctp_conn);
void sctp_connection_del (sctp_connection_t * sctp_conn);

u32 sctp_push_header (transport_connection_t * tconn, vlib_buffer_t * b);
void sctp_send_init (sctp_connection_t * sctp_conn);
void sctp_send_cookie_echo (sctp_connection_t * sctp_conn);
void sctp_send_shutdown (sctp_connection_t * sctp_conn);
void sctp_send_shutdown_ack (sctp_connection_t * sctp_conn, u8 idx,
			     vlib_buffer_t * b);
void sctp_send_shutdown_complete (sctp_connection_t * sctp_conn, u8 idx,
				  vlib_buffer_t * b0);
void sctp_send_heartbeat (sctp_connection_t * sctp_conn);
void sctp_data_retransmit (sctp_connection_t * sctp_conn);
void sctp_flush_frame_to_output (vlib_main_t * vm, u8 thread_index,
				 u8 is_ip4);
void sctp_flush_frames_to_output (u8 thread_index);
void sctp_punt_unknown (vlib_main_t * vm, u8 is_ip4, u8 is_add);

format_function_t format_sctp_state;

u8 *format_sctp_connection_id (u8 * s, va_list * args);
u8 *format_sctp_connection (u8 * s, va_list * args);
u8 *format_sctp_scoreboard (u8 * s, va_list * args);
u8 *format_sctp_header (u8 * s, va_list * args);
u8 *format_sctp_tx_trace (u8 * s, va_list * args);

clib_error_t *sctp_init (vlib_main_t * vm);
void sctp_connection_timers_init (sctp_connection_t * sctp_conn);
void sctp_connection_timers_reset (sctp_connection_t * sctp_conn);
void sctp_init_snd_vars (sctp_connection_t * sctp_conn);
void sctp_init_mss (sctp_connection_t * sctp_conn);

void sctp_prepare_initack_chunk (sctp_connection_t * sctp_conn, u8 idx,
				 vlib_buffer_t * b, ip4_address_t * ip4_addr,
				 ip6_address_t * ip6_addr);
void
sctp_prepare_initack_chunk_for_collision (sctp_connection_t * sctp_conn,
					  u8 idx, vlib_buffer_t * b,
					  ip4_address_t * ip4_addr,
					  ip6_address_t * ip6_addr);
void sctp_prepare_abort_for_collision (sctp_connection_t * sctp_conn, u8 idx,
				       vlib_buffer_t * b,
				       ip4_address_t * ip4_addr,
				       ip6_address_t * ip6_addr);
void
sctp_prepare_operation_error (sctp_connection_t * sctp_conn, u8 idx,
			      vlib_buffer_t * b, u8 err_cause);
void sctp_prepare_cookie_echo_chunk (sctp_connection_t * sctp_conn, u8 idx,
				     vlib_buffer_t * b, u8 reuse_buffer);
void sctp_prepare_cookie_ack_chunk (sctp_connection_t * sctp_conn, u8 idx,
				    vlib_buffer_t * b);
void sctp_prepare_sack_chunk (sctp_connection_t * sctp_conn, u8 idx,
			      vlib_buffer_t * b);
void sctp_prepare_heartbeat_ack_chunk (sctp_connection_t * sctp_conn, u8 idx,
				       vlib_buffer_t * b);

u16 sctp_check_outstanding_data_chunks (sctp_connection_t * sctp_conn);

void sctp_api_reference (void);

#define IP_PROTOCOL_SCTP	132

/** SSCTP FSM state definitions as per RFC4960. */
#define foreach_sctp_fsm_state                \
  _(CLOSED, "CLOSED")                         \
  _(COOKIE_WAIT, "COOKIE_WAIT")               \
  _(COOKIE_ECHOED, "COOKIE_ECHOED")           \
  _(ESTABLISHED, "ESTABLISHED")               \
  _(SHUTDOWN_PENDING, "SHUTDOWN_PENDING")     \
  _(SHUTDOWN_SENT, "SHUTDOWN_SENT")           \
  _(SHUTDOWN_RECEIVED, "SHUTDOWN_RECEIVED")   \
  _(SHUTDOWN_ACK_SENT, "SHUTDOWN_ACK_SENT")

typedef enum _sctp_state
{
#define _(sym, str) SCTP_STATE_##sym,
  foreach_sctp_fsm_state
#undef _
  SCTP_N_STATES
} sctp_state_t;

always_inline char *
sctp_state_to_string (u8 state)
{
  switch (state)
    {
    case SCTP_STATE_CLOSED:
      return "SCTP_STATE_CLOSED";
    case SCTP_STATE_COOKIE_WAIT:
      return "SCTP_STATE_COOKIE_WAIT";
    case SCTP_STATE_COOKIE_ECHOED:
      return "SCTP_STATE_COOKIE_ECHOED";
    case SCTP_STATE_ESTABLISHED:
      return "SCTP_STATE_ESTABLISHED";
    case SCTP_STATE_SHUTDOWN_PENDING:
      return "SCTP_STATE_SHUTDOWN_PENDING";
    case SCTP_STATE_SHUTDOWN_SENT:
      return "SCTP_STATE_SHUTDOWN_SENT";
    case SCTP_STATE_SHUTDOWN_RECEIVED:
      return "SCTP_STATE_SHUTDOWN_RECEIVED";
    case SCTP_STATE_SHUTDOWN_ACK_SENT:
      return "SCTP_STATE_SHUTDOWN_ACK_SENT";
    }
  return NULL;
}

always_inline char *
sctp_chunk_to_string (u8 type)
{
  switch (type)
    {
    case DATA:
      return "DATA";
    case INIT:
      return "INIT";
    case INIT_ACK:
      return "INIT_ACK";
    case SACK:
      return "SACK";
    case HEARTBEAT:
      return "HEARTBEAT";
    case HEARTBEAT_ACK:
      return "HEARTBEAT_ACK";
    case ABORT:
      return "ABORT";
    case SHUTDOWN:
      return "SHUTDOWN";
    case SHUTDOWN_ACK:
      return "SHUTDOWN_ACK";
    case OPERATION_ERROR:
      return "OPERATION_ERROR";
    case COOKIE_ECHO:
      return "COOKIE_ECHO";
    case COOKIE_ACK:
      return "COOKIE_ACK";
    case ECNE:
      return "ECNE";
    case CWR:
      return "CWR";
    case SHUTDOWN_COMPLETE:
      return "SHUTDOWN_COMPLETE";
    }
  return NULL;
}

always_inline char *
sctp_optparam_type_to_string (u8 type)
{
  switch (type)
    {
    case SCTP_IPV4_ADDRESS_TYPE:
      return "SCTP_IPV4_ADDRESS_TYPE";
    case SCTP_IPV6_ADDRESS_TYPE:
      return "SCTP_IPV6_ADDRESS_TYPE";
    case SCTP_STATE_COOKIE_TYPE:
      return "SCTP_STATE_COOKIE_TYPE";
    case SCTP_UNRECOGNIZED_TYPE:
      return "SCTP_UNRECOGNIZED_TYPE";
    case SCTP_COOKIE_PRESERVATIVE_TYPE:
      return "SCTP_COOKIE_PRESERVATIVE_TYPE";
    case SCTP_HOSTNAME_ADDRESS_TYPE:
      return "SCTP_HOSTNAME_ADDRESS_TYPE";
    case SCTP_SUPPORTED_ADDRESS_TYPES:
      return "SCTP_SUPPORTED_ADDRESS_TYPES";
    }
  return NULL;
}

#define SCTP_TICK 0.001			/**< SCTP tick period (s) */
#define SHZ (u32) (1/SCTP_TICK)		/**< SCTP tick frequency */
#define SCTP_TSTAMP_RESOLUTION SCTP_TICK	/**< Time stamp resolution */

/* As per RFC4960, page 83 */
#define SCTP_RTO_INIT 3 * SHZ	/* 3 seconds */
#define SCTP_RTO_MIN 1 * SHZ	/* 1 second */
#define SCTP_RTO_MAX 60 * SHZ	/* 60 seconds */
#define SCTP_RTO_BURST 4
#define SCTP_RTO_ALPHA 1/8
#define SCTP_RTO_BETA 1/4
#define SCTP_VALID_COOKIE_LIFE 60 * SHZ	/* 60 seconds */
#define SCTP_ASSOCIATION_MAX_RETRANS 10	// the overall connection
#define SCTP_PATH_MAX_RETRANS 5	// number of attempts per destination address
#define SCTP_MAX_INIT_RETRANS 8	// number of attempts
#define SCTP_HB_INTERVAL 30 * SHZ
#define SCTP_HB_MAX_BURST 1

#define SCTP_DATA_IDLE_INTERVAL 15 * SHZ	/* 15 seconds; the time-interval after which the connetion is considered IDLE */

#define SCTP_TO_TIMER_TICK       SCTP_TICK*10	/* Period for converting from SCTP_TICK */

typedef struct _sctp_lookup_dispatch
{
  u8 next, error;
} sctp_lookup_dispatch_t;

typedef struct _sctp_main
{
  /* Per-worker thread SCTP connection pools */
  sctp_connection_t **connections;

  /* Pool of listeners. */
  sctp_connection_t *listener_pool;

	  /** Dispatch table by state and flags */
  sctp_lookup_dispatch_t dispatch_table[SCTP_N_STATES][64];

  u8 log2_tstamp_clocks_per_tick;
  f64 tstamp_ticks_per_clock;
  u32 *time_now;

	  /** per-worker tx buffer free lists */
  u32 **tx_buffers;
	  /** per-worker tx frames to SCTP 4/6 output nodes */
  vlib_frame_t **tx_frames[2];
	  /** per-worker tx frames to ip 4/6 lookup nodes */
  vlib_frame_t **ip_lookup_tx_frames[2];

  /* Per worker-thread timer wheel for connections timers */
  tw_timer_wheel_16t_2w_512sl_t *timer_wheels;

  /* Pool of half-open connections on which we've sent a SYN */
  sctp_connection_t *half_open_connections;
  clib_spinlock_t half_open_lock;

  /* TODO: Congestion control algorithms registered */
  /* sctp_cc_algorithm_t *cc_algos; */

  /* Flag that indicates if stack is on or off */
  u8 is_enabled;

	  /** Number of preallocated connections */
  u32 preallocated_connections;

	  /** Transport table (preallocation) size parameters */
  u32 local_endpoints_table_memory;
  u32 local_endpoints_table_buckets;

	  /** Vectors of src addresses. Optional unless one needs > 63K active-opens */
  ip4_address_t *ip4_src_addresses;
  u32 last_v4_address_rotor;
  u32 last_v6_address_rotor;
  ip6_address_t *ip6_src_addresses;

	  /** vlib buffer size */
  u32 bytes_per_buffer;

  u8 punt_unknown4;
  u8 punt_unknown6;

} sctp_main_t;

extern sctp_main_t sctp_main;
extern vlib_node_registration_t sctp4_input_node;
extern vlib_node_registration_t sctp6_input_node;
extern vlib_node_registration_t sctp4_output_node;
extern vlib_node_registration_t sctp6_output_node;

always_inline sctp_main_t *
vnet_get_sctp_main ()
{
  return &sctp_main;
}

always_inline sctp_header_t *
sctp_buffer_hdr (vlib_buffer_t * b)
{
  ASSERT ((signed) b->current_data >= (signed) -VLIB_BUFFER_PRE_DATA_SIZE);
  return (sctp_header_t *) (b->data + b->current_data
			    + vnet_buffer (b)->sctp.hdr_offset);
}

clib_error_t *vnet_sctp_enable_disable (vlib_main_t * vm, u8 is_en);

always_inline sctp_connection_t *
sctp_half_open_connection_get (u32 conn_index)
{
  sctp_connection_t *tc = 0;
  clib_spinlock_lock_if_init (&sctp_main.half_open_lock);
  if (!pool_is_free_index (sctp_main.half_open_connections, conn_index))
    tc = pool_elt_at_index (sctp_main.half_open_connections, conn_index);
  tc->sub_conn[SCTP_PRIMARY_PATH_IDX].subconn_idx = SCTP_PRIMARY_PATH_IDX;
  clib_spinlock_unlock_if_init (&sctp_main.half_open_lock);
  return tc;
}

/**
 * Cleanup half-open connection
 *
 */
always_inline void
sctp_half_open_connection_del (sctp_connection_t * tc)
{
  sctp_main_t *sctp_main = vnet_get_sctp_main ();
  clib_spinlock_lock_if_init (&sctp_main->half_open_lock);
  pool_put_index (sctp_main->half_open_connections,
		  tc->sub_conn[SCTP_PRIMARY_PATH_IDX].c_c_index);
  if (CLIB_DEBUG)
    memset (tc, 0xFA, sizeof (*tc));
  clib_spinlock_unlock_if_init (&sctp_main->half_open_lock);
}

always_inline u32
sctp_set_time_now (u32 thread_index)
{
  sctp_main.time_now[thread_index] = clib_cpu_time_now ()
    * sctp_main.tstamp_ticks_per_clock;
  return sctp_main.time_now[thread_index];
}

always_inline void
sctp_timer_set (sctp_connection_t * tc, u8 conn_idx, u8 timer_id,
		u32 interval)
{
  ASSERT (tc->sub_conn[conn_idx].connection.thread_index ==
	  vlib_get_thread_index ());
  ASSERT (tc->sub_conn[conn_idx].timers[timer_id] ==
	  SCTP_TIMER_HANDLE_INVALID);

  sctp_sub_connection_t *sub = &tc->sub_conn[conn_idx];
  sub->timers[timer_id] =
    tw_timer_start_16t_2w_512sl (&sctp_main.timer_wheels[sub->c_thread_index],
				 sub->c_c_index, timer_id, interval);
}

always_inline void
sctp_timer_reset (sctp_connection_t * tc, u8 conn_idx, u8 timer_id)
{
  ASSERT (tc->sub_conn[conn_idx].c_thread_index == vlib_get_thread_index ());
  if (tc->sub_conn[conn_idx].timers[timer_id] == SCTP_TIMER_HANDLE_INVALID)
    return;

  sctp_sub_connection_t *sub = &tc->sub_conn[conn_idx];

  tw_timer_stop_16t_2w_512sl (&sctp_main.timer_wheels[sub->c_thread_index],
			      sub->timers[timer_id]);
  sub->timers[timer_id] = SCTP_TIMER_HANDLE_INVALID;
}

/**
 * Try to cleanup half-open connection
 *
 * If called from a thread that doesn't own tc, the call won't have any
 * effect.
 *
 * @param tc - connection to be cleaned up
 * @return non-zero if cleanup failed.
 */
always_inline int
sctp_half_open_connection_cleanup (sctp_connection_t * tc)
{
  /* Make sure this is the owning thread */
  if (tc->sub_conn[SCTP_PRIMARY_PATH_IDX].c_thread_index !=
      vlib_get_thread_index ())
    return 1;
  sctp_timer_reset (tc, SCTP_PRIMARY_PATH_IDX, SCTP_TIMER_T1_INIT);
  sctp_half_open_connection_del (tc);
  return 0;
}

always_inline u32
sctp_header_bytes ()
{
  return sizeof (sctp_header_t);
}

always_inline sctp_connection_t *
sctp_get_connection_from_transport (transport_connection_t * tconn)
{
  ASSERT (tconn != NULL);

  sctp_sub_connection_t *sub = (sctp_sub_connection_t *) tconn;
#if SCTP_ADV_DEBUG
  if (sub == NULL)
    SCTP_ADV_DBG ("sub == NULL");
  if (sub->parent == NULL)
    SCTP_ADV_DBG ("sub->parent == NULL");
#endif
  if (sub->subconn_idx > 0)
    return (sctp_connection_t *) sub -
      (sizeof (sctp_sub_connection_t) * (sub->subconn_idx - 1));

  return (sctp_connection_t *) sub;
}

always_inline u32
sctp_time_now (void)
{
  return sctp_main.time_now[vlib_get_thread_index ()];
}

#define ABS(x) ((x) > 0) ? (x) : -(x);

always_inline void
sctp_calculate_rto (sctp_connection_t * sctp_conn, u8 conn_idx)
{
  /* See RFC4960, 6.3.1.  RTO Calculation */
  u32 RTO = 0;
  f32 RTTVAR = 0;
  u32 now = sctp_time_now ();
  u32 prev_ts = sctp_conn->sub_conn[conn_idx].rtt_ts;
  u32 R = prev_ts - now;

  if (sctp_conn->sub_conn[conn_idx].RTO == 0)	// C1: Let's initialize our RTO
    {
      sctp_conn->sub_conn[conn_idx].RTO = SCTP_RTO_MIN;
      return;
    }

  if (sctp_conn->sub_conn[conn_idx].RTO == SCTP_RTO_MIN && sctp_conn->sub_conn[conn_idx].SRTT == 0)	// C2: First RTT calculation
    {
      sctp_conn->sub_conn[conn_idx].SRTT = R;
      RTTVAR = R / 2;

      if (RTTVAR == 0)
	RTTVAR = 100e-3;	/* 100 ms */

      sctp_conn->sub_conn[conn_idx].RTTVAR = RTTVAR;
    }
  else				// C3: RTT already exists; let's recalculate
    {
      RTTVAR = (1 - SCTP_RTO_BETA) * sctp_conn->sub_conn[conn_idx].RTTVAR +
	SCTP_RTO_BETA * ABS (sctp_conn->sub_conn[conn_idx].SRTT - R);

      if (RTTVAR == 0)
	RTTVAR = 100e-3;	/* 100 ms */

      sctp_conn->sub_conn[conn_idx].RTTVAR = RTTVAR;

      sctp_conn->sub_conn[conn_idx].SRTT =
	(1 - SCTP_RTO_ALPHA) * sctp_conn->sub_conn[conn_idx].SRTT +
	SCTP_RTO_ALPHA * R;
    }

  RTO =
    sctp_conn->sub_conn[conn_idx].SRTT +
    4 * sctp_conn->sub_conn[conn_idx].RTTVAR;
  if (RTO < SCTP_RTO_MIN)	// C6
    RTO = SCTP_RTO_MIN;

  if (RTO > SCTP_RTO_MAX)	// C7
    RTO = SCTP_RTO_MAX;

  sctp_conn->sub_conn[conn_idx].RTO = RTO;
}

always_inline void
sctp_timer_update (sctp_connection_t * tc, u8 conn_idx, u8 timer_id,
		   u32 interval)
{
  ASSERT (tc->sub_conn[conn_idx].connection.thread_index ==
	  vlib_get_thread_index ());
  sctp_sub_connection_t *sub = &tc->sub_conn[conn_idx];

  if (tc->sub_conn[conn_idx].timers[timer_id] != SCTP_TIMER_HANDLE_INVALID)
    tw_timer_stop_16t_2w_512sl (&sctp_main.timer_wheels[sub->c_thread_index],
				sub->timers[timer_id]);

  tc->sub_conn[conn_idx].timers[timer_id] =
    tw_timer_start_16t_2w_512sl (&sctp_main.timer_wheels[sub->c_thread_index],
				 sub->c_c_index, timer_id, interval);
}

always_inline sctp_connection_t *
sctp_listener_get (u32 tli)
{
  return pool_elt_at_index (sctp_main.listener_pool, tli);
}

#endif

always_inline sctp_connection_t *
sctp_connection_get (u32 conn_index, u32 thread_index)
{
  if (PREDICT_FALSE
      (pool_is_free_index (sctp_main.connections[thread_index], conn_index)))
    return 0;
  return pool_elt_at_index (sctp_main.connections[thread_index], conn_index);
}

#define SELECT_MAX_RETRIES 8

always_inline u8
sctp_data_subconn_select (sctp_connection_t * sctp_conn)
{
  u32 sub = SCTP_PRIMARY_PATH_IDX;
  u8 i, cwnd = sctp_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].cwnd;
  for (i = 1; i < MAX_SCTP_CONNECTIONS; i++)
    {
      if (sctp_conn->sub_conn[i].state == SCTP_SUBCONN_STATE_DOWN)
	continue;

      if (sctp_conn->sub_conn[i].cwnd > cwnd)
	{
	  sub = i;
	  cwnd = sctp_conn->sub_conn[i].cwnd;
	}
    }
  return sub;
}

always_inline u8
sctp_sub_conn_id_via_ip6h (sctp_connection_t * sctp_conn, ip6_header_t * ip6h)
{
  u8 i;

  for (i = 0; i < MAX_SCTP_CONNECTIONS; i++)
    {
      if (sctp_conn->sub_conn[i].connection.lcl_ip.ip6.as_u64[0] ==
	  ip6h->dst_address.as_u64[0] &&
	  sctp_conn->sub_conn[i].connection.lcl_ip.ip6.as_u64[1] ==
	  ip6h->dst_address.as_u64[1] &&
	  sctp_conn->sub_conn[i].connection.rmt_ip.ip6.as_u64[0] ==
	  ip6h->src_address.as_u64[0] &&
	  sctp_conn->sub_conn[i].connection.rmt_ip.ip6.as_u64[1] ==
	  ip6h->src_address.as_u64[1])
	return i;
    }
  clib_warning ("Did not find a sub-connection; defaulting to %u",
		SCTP_PRIMARY_PATH_IDX);
  return SCTP_PRIMARY_PATH_IDX;
}

always_inline u8
sctp_sub_conn_id_via_ip4h (sctp_connection_t * sctp_conn, ip4_header_t * ip4h)
{
  u8 i;

  for (i = 0; i < MAX_SCTP_CONNECTIONS; i++)
    {
      if (sctp_conn->sub_conn[i].connection.lcl_ip.ip4.as_u32 ==
	  ip4h->dst_address.as_u32
	  && sctp_conn->sub_conn[i].connection.rmt_ip.ip4.as_u32 ==
	  ip4h->src_address.as_u32)
	return i;
    }
  clib_warning ("Did not find a sub-connection; defaulting to %u",
		SCTP_PRIMARY_PATH_IDX);
  return SCTP_PRIMARY_PATH_IDX;
}

/**
 * Push SCTP header to buffer
 *
 * @param vm - vlib_main
 * @param b - buffer to write the header to
 * @param sp_net - source port net order
 * @param dp_net - destination port net order
 * @param sctp_hdr_opts_len - header and options length in bytes
 *
 * @return - pointer to start of SCTP header
 */
always_inline void *
vlib_buffer_push_sctp_net_order (vlib_buffer_t * b, u16 sp, u16 dp,
				 u8 sctp_hdr_opts_len)
{
  sctp_full_hdr_t *full_hdr;

  full_hdr = vlib_buffer_push_uninit (b, sctp_hdr_opts_len);

  full_hdr->hdr.src_port = sp;
  full_hdr->hdr.dst_port = dp;
  full_hdr->hdr.checksum = 0;
  return full_hdr;
}

/**
 * Push SCTP header to buffer
 *
 * @param b - buffer to write the header to
 * @param sp_net - source port net order
 * @param dp_net - destination port net order
 * @param sctp_hdr_opts_len - header and options length in bytes
 *
 * @return - pointer to start of SCTP header
 */
always_inline void *
vlib_buffer_push_sctp (vlib_buffer_t * b, u16 sp_net, u16 dp_net,
		       u8 sctp_hdr_opts_len)
{
  return vlib_buffer_push_sctp_net_order (b, sp_net, dp_net,
					  sctp_hdr_opts_len);
}

always_inline u8
sctp_next_avail_subconn (sctp_connection_t * sctp_conn)
{
  u8 i;

  for (i = 0; i < MAX_SCTP_CONNECTIONS; i++)
    {
      if (sctp_conn->sub_conn[i].state == SCTP_SUBCONN_STATE_DOWN)
	return i;
    }
  return MAX_SCTP_CONNECTIONS;
}

always_inline void
update_smallest_pmtu_idx (sctp_connection_t * sctp_conn)
{
  u8 i;
  u8 smallest_pmtu_index = SCTP_PRIMARY_PATH_IDX;

  for (i = 1; i < MAX_SCTP_CONNECTIONS; i++)
    {
      if (sctp_conn->sub_conn[i].state != SCTP_SUBCONN_STATE_DOWN)
	{
	  if (sctp_conn->sub_conn[i].PMTU <
	      sctp_conn->sub_conn[smallest_pmtu_index].PMTU)
	    smallest_pmtu_index = i;
	}
    }

  sctp_conn->smallest_PMTU_idx = smallest_pmtu_index;
}

/* As per RFC4960; section 7.2.1: Slow-Start */
always_inline void
sctp_init_cwnd (sctp_connection_t * sctp_conn)
{
  u8 i;
  for (i = 0; i < MAX_SCTP_CONNECTIONS; i++)
    {
      /* Section 7.2.1; point (1) */
      sctp_conn->sub_conn[i].cwnd =
	clib_min (4 * sctp_conn->sub_conn[i].PMTU,
		  clib_max (2 * sctp_conn->sub_conn[i].PMTU, 4380));

      /* Section 7.2.1; point (3) */
      sctp_conn->sub_conn[i].ssthresh = SCTP_INITIAL_SSHTRESH;

      /* Section 7.2.2; point (1) */
      sctp_conn->sub_conn[i].partially_acked_bytes = 0;
    }
}

always_inline u8
sctp_in_cong_recovery (sctp_connection_t * sctp_conn, u8 idx)
{
  return 0;
}

always_inline u8
cwnd_fully_utilized (sctp_connection_t * sctp_conn, u8 idx)
{
  return 0;
}

/* As per RFC4960; section 7.2.1: Slow-Start */
always_inline void
update_cwnd (sctp_connection_t * sctp_conn)
{
  u8 i;

  for (i = 0; i < MAX_SCTP_CONNECTIONS; i++)
    {
      /* Section 7.2.1; point (2) */
      if (sctp_conn->sub_conn[i].is_retransmitting)
	{
	  sctp_conn->sub_conn[i].cwnd = 1 * sctp_conn->sub_conn[i].PMTU;
	  continue;
	}

      /* Section 7.2.2; point (4) */
      if (sctp_conn->sub_conn[i].last_data_ts >
	  sctp_time_now () + SCTP_DATA_IDLE_INTERVAL)
	{
	  sctp_conn->sub_conn[i].cwnd =
	    clib_max (sctp_conn->sub_conn[i].cwnd / 2,
		      4 * sctp_conn->sub_conn[i].PMTU);
	  continue;
	}

      /* Section 7.2.1; point (5) */
      if (sctp_conn->sub_conn[i].cwnd <= sctp_conn->sub_conn[i].ssthresh)
	{
	  if (!cwnd_fully_utilized (sctp_conn, i))
	    continue;

	  if (sctp_in_cong_recovery (sctp_conn, i))
	    continue;

	  sctp_conn->sub_conn[i].cwnd =
	    clib_min (sctp_conn->sub_conn[i].PMTU, 1);
	}
    }
}

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