/*
 * 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.
 */
#include <vnet/sctp/sctp.h>
#include <vnet/sctp/sctp_debug.h>

sctp_main_t sctp_main;

static u32
sctp_connection_bind (u32 session_index, transport_endpoint_t * tep)
{
  sctp_main_t *tm = &sctp_main;
  sctp_connection_t *listener;
  void *iface_ip;

  pool_get (tm->listener_pool, listener);
  memset (listener, 0, sizeof (*listener));

  listener->sub_conn[SCTP_PRIMARY_PATH_IDX].subconn_idx =
    SCTP_PRIMARY_PATH_IDX;
  listener->sub_conn[SCTP_PRIMARY_PATH_IDX].c_c_index =
    listener - tm->listener_pool;
  listener->sub_conn[SCTP_PRIMARY_PATH_IDX].connection.lcl_port = tep->port;

  /* If we are provided a sw_if_index, bind using one of its IPs */
  if (ip_is_zero (&tep->ip, 1) && tep->sw_if_index != ENDPOINT_INVALID_INDEX)
    {
      if ((iface_ip = ip_interface_get_first_ip (tep->sw_if_index,
						 tep->is_ip4)))
	ip_set (&tep->ip, iface_ip, tep->is_ip4);
    }
  ip_copy (&listener->sub_conn[SCTP_PRIMARY_PATH_IDX].connection.lcl_ip,
	   &tep->ip, tep->is_ip4);

  listener->sub_conn[SCTP_PRIMARY_PATH_IDX].PMTU =
    vnet_sw_interface_get_mtu (vnet_get_main (), tep->sw_if_index, VLIB_TX);
  listener->sub_conn[SCTP_PRIMARY_PATH_IDX].connection.is_ip4 = tep->is_ip4;
  listener->sub_conn[SCTP_PRIMARY_PATH_IDX].connection.proto =
    TRANSPORT_PROTO_SCTP;
  listener->sub_conn[SCTP_PRIMARY_PATH_IDX].c_s_index = session_index;
  listener->sub_conn[SCTP_PRIMARY_PATH_IDX].connection.fib_index =
    tep->fib_index;
  listener->state = SCTP_STATE_CLOSED;

  sctp_connection_timers_init (listener);

  return listener->sub_conn[SCTP_PRIMARY_PATH_IDX].c_c_index;
}

u32
sctp_session_bind (u32 session_index, transport_endpoint_t * tep)
{
  return sctp_connection_bind (session_index, tep);
}

static void
sctp_connection_unbind (u32 listener_index)
{
  sctp_main_t *tm = vnet_get_sctp_main ();
  sctp_connection_t *sctp_conn;

  sctp_conn = pool_elt_at_index (tm->listener_pool, listener_index);

  /* Poison the entry */
  if (CLIB_DEBUG > 0)
    memset (sctp_conn, 0xFA, sizeof (*sctp_conn));

  pool_put_index (tm->listener_pool, listener_index);
}

u32
sctp_session_unbind (u32 listener_index)
{
  sctp_connection_unbind (listener_index);
  return 0;
}

void
sctp_punt_unknown (vlib_main_t * vm, u8 is_ip4, u8 is_add)
{
  sctp_main_t *tm = &sctp_main;
  if (is_ip4)
    tm->punt_unknown4 = is_add;
  else
    tm->punt_unknown6 = is_add;
}

static int
sctp_alloc_custom_local_endpoint (sctp_main_t * tm, ip46_address_t * lcl_addr,
				  u16 * lcl_port, u8 is_ip4)
{
  int index, port;
  if (is_ip4)
    {
      index = tm->last_v4_address_rotor++;
      if (tm->last_v4_address_rotor >= vec_len (tm->ip4_src_addresses))
	tm->last_v4_address_rotor = 0;
      lcl_addr->ip4.as_u32 = tm->ip4_src_addresses[index].as_u32;
    }
  else
    {
      index = tm->last_v6_address_rotor++;
      if (tm->last_v6_address_rotor >= vec_len (tm->ip6_src_addresses))
	tm->last_v6_address_rotor = 0;
      clib_memcpy (&lcl_addr->ip6, &tm->ip6_src_addresses[index],
		   sizeof (ip6_address_t));
    }
  port = transport_alloc_local_port (TRANSPORT_PROTO_SCTP, lcl_addr);
  if (port < 1)
    {
      clib_warning ("Failed to allocate src port");
      return -1;
    }
  *lcl_port = port;
  return 0;
}

/**
 * Initialize all connection timers as invalid
 */
void
sctp_connection_timers_init (sctp_connection_t * sctp_conn)
{
  int i, j;

  /* Set all to invalid */
  for (i = 0; i < MAX_SCTP_CONNECTIONS; i++)
    {
      sctp_conn->sub_conn[i].RTO = SCTP_RTO_INIT;

      for (j = 0; j < SCTP_N_TIMERS; j++)
	{
	  sctp_conn->sub_conn[i].timers[j] = SCTP_TIMER_HANDLE_INVALID;
	}
    }
}

/**
 * Stop all connection timers
 */
void
sctp_connection_timers_reset (sctp_connection_t * sctp_conn)
{
  int i, j;
  for (i = 0; i < MAX_SCTP_CONNECTIONS; i++)
    {
      for (j = 0; j < SCTP_N_TIMERS; j++)
	sctp_timer_reset (sctp_conn, i, j);
    }
}

const char *sctp_fsm_states[] = {
#define _(sym, str) str,
  foreach_sctp_fsm_state
#undef _
};

u8 *
format_sctp_state (u8 * s, va_list * args)
{
  u32 state = va_arg (*args, u32);

  if (state < SCTP_N_STATES)
    s = format (s, "%s", sctp_fsm_states[state]);
  else
    s = format (s, "UNKNOWN (%d (0x%x))", state, state);
  return s;
}

u8 *
format_sctp_connection_id (u8 * s, va_list * args)
{
  sctp_connection_t *sctp_conn = va_arg (*args, sctp_connection_t *);
  if (!sctp_conn)
    return s;

  u8 i;
  for (i = 0; i < MAX_SCTP_CONNECTIONS; i++)
    {
      if (sctp_conn->sub_conn[i].connection.is_ip4)
	{
	  s = format (s, "%U[#%d][%s] %U:%d->%U:%d",
		      s,
		      sctp_conn->sub_conn[i].connection.thread_index,
		      "T",
		      format_ip4_address,
		      &sctp_conn->sub_conn[i].connection.lcl_ip.ip4,
		      clib_net_to_host_u16 (sctp_conn->sub_conn[i].
					    connection.lcl_port),
		      format_ip4_address,
		      &sctp_conn->sub_conn[i].connection.rmt_ip.ip4,
		      clib_net_to_host_u16 (sctp_conn->sub_conn[i].
					    connection.rmt_port));
	}
      else
	{
	  s = format (s, "%U[#%d][%s] %U:%d->%U:%d",
		      s,
		      sctp_conn->sub_conn[i].connection.thread_index,
		      "T",
		      format_ip6_address,
		      &sctp_conn->sub_conn[i].connection.lcl_ip.ip6,
		      clib_net_to_host_u16 (sctp_conn->sub_conn[i].
					    connection.lcl_port),
		      format_ip6_address,
		      &sctp_conn->sub_conn[i].connection.rmt_ip.ip6,
		      clib_net_to_host_u16 (sctp_conn->sub_conn[i].
					    connection.rmt_port));
	}
    }
  return s;
}

u8 *
format_sctp_connection (u8 * s, va_list * args)
{
  sctp_connection_t *sctp_conn = va_arg (*args, sctp_connection_t *);
  u32 verbose = va_arg (*args, u32);

  if (!sctp_conn)
    return s;
  s = format (s, "%-50U", format_sctp_connection_id, sctp_conn);
  if (verbose)
    {
      s = format (s, "%-15U", format_sctp_state, sctp_conn->state);
    }

  return s;
}

/**
 * Initialize connection send variables.
 */
void
sctp_init_snd_vars (sctp_connection_t * sctp_conn)
{
  u32 time_now;
  /*
   * We use the time to randomize iss and for setting up the initial
   * timestamp. Make sure it's updated otherwise syn and ack in the
   * handshake may make it look as if time has flown in the opposite
   * direction for us.
   */

  sctp_set_time_now (vlib_get_thread_index ());
  time_now = sctp_time_now ();

  sctp_conn->local_initial_tsn = random_u32 (&time_now);
  sctp_conn->last_unacked_tsn = sctp_conn->local_initial_tsn;
  sctp_conn->next_tsn = sctp_conn->local_initial_tsn + 1;

  sctp_conn->remote_initial_tsn = 0x0;
  sctp_conn->last_rcvd_tsn = sctp_conn->remote_initial_tsn;
}

always_inline sctp_connection_t *
sctp_sub_connection_add (u8 thread_index)
{
  sctp_main_t *tm = vnet_get_sctp_main ();
  sctp_connection_t *sctp_conn = tm->connections[thread_index];

  u8 subconn_idx = sctp_next_avail_subconn (sctp_conn);

  ASSERT (subconn_idx < MAX_SCTP_CONNECTIONS);

  sctp_conn->sub_conn[subconn_idx].connection.c_index =
    sctp_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].connection.c_index;
  sctp_conn->sub_conn[subconn_idx].connection.thread_index = thread_index;
  sctp_conn->sub_conn[subconn_idx].subconn_idx = subconn_idx;

  return sctp_conn;
}

u8
sctp_sub_connection_add_ip4 (vlib_main_t * vm,
			     ip4_address_t * lcl_addr,
			     ip4_address_t * rmt_addr)
{
  sctp_connection_t *sctp_conn = sctp_sub_connection_add (vm->thread_index);

  u8 subconn_idx = sctp_next_avail_subconn (sctp_conn);

  if (subconn_idx == MAX_SCTP_CONNECTIONS)
    return SCTP_ERROR_MAX_CONNECTIONS;

  clib_memcpy (&sctp_conn->sub_conn[subconn_idx].connection.lcl_ip,
	       &lcl_addr, sizeof (lcl_addr));

  clib_memcpy (&sctp_conn->sub_conn[subconn_idx].connection.rmt_ip,
	       &rmt_addr, sizeof (rmt_addr));

  sctp_conn->forming_association_changed = 1;

  return SCTP_ERROR_NONE;
}

u8
sctp_sub_connection_del_ip4 (ip4_address_t * lcl_addr,
			     ip4_address_t * rmt_addr)
{
  sctp_main_t *sctp_main = vnet_get_sctp_main ();

  u32 thread_idx = vlib_get_thread_index ();
  u8 i;

  ASSERT (thread_idx == 0);

  for (i = 0; i < MAX_SCTP_CONNECTIONS; i++)
    {
      sctp_connection_t *sctp_conn = sctp_main->connections[thread_idx];
      sctp_sub_connection_t *sub_conn =
	&sctp_main->connections[thread_idx]->sub_conn[i];
      ip46_address_t *lcl_ip =
	&sctp_main->connections[thread_idx]->sub_conn[i].connection.lcl_ip;
      ip46_address_t *rmt_ip =
	&sctp_main->connections[thread_idx]->sub_conn[i].connection.rmt_ip;

      if (!sub_conn->connection.is_ip4)
	continue;
      if (lcl_ip->ip4.as_u32 == lcl_addr->as_u32 &&
	  rmt_ip->ip4.as_u32 == rmt_addr->as_u32)
	{
	  sub_conn->state = SCTP_SUBCONN_STATE_DOWN;
	  sctp_conn->forming_association_changed = 1;
	  break;
	}
    }
  return SCTP_ERROR_NONE;
}

u8
sctp_sub_connection_add_ip6 (vlib_main_t * vm,
			     ip6_address_t * lcl_addr,
			     ip6_address_t * rmt_addr)
{
  sctp_connection_t *sctp_conn = sctp_sub_connection_add (vm->thread_index);

  u8 subconn_idx = sctp_next_avail_subconn (sctp_conn);

  if (subconn_idx == MAX_SCTP_CONNECTIONS)
    return SCTP_ERROR_MAX_CONNECTIONS;

  clib_memcpy (&sctp_conn->sub_conn[subconn_idx].connection.lcl_ip,
	       &lcl_addr, sizeof (lcl_addr));

  clib_memcpy (&sctp_conn->sub_conn[subconn_idx].connection.rmt_ip,
	       &rmt_addr, sizeof (rmt_addr));

  sctp_conn->forming_association_changed = 1;

  return SCTP_ERROR_NONE;
}

u8
sctp_sub_connection_del_ip6 (ip6_address_t * lcl_addr,
			     ip6_address_t * rmt_addr)
{
  sctp_main_t *sctp_main = vnet_get_sctp_main ();

  u32 thread_idx = vlib_get_thread_index ();
  u8 i;

  ASSERT (thread_idx == 0);

  for (i = 0; i < MAX_SCTP_CONNECTIONS; i++)
    {
      sctp_connection_t *sctp_conn = sctp_main->connections[thread_idx];
      sctp_sub_connection_t *sub_conn =
	&sctp_main->connections[thread_idx]->sub_conn[i];
      ip46_address_t *lcl_ip =
	&sctp_main->connections[thread_idx]->sub_conn[i].connection.lcl_ip;
      ip46_address_t *rmt_ip =
	&sctp_main->connections[thread_idx]->sub_conn[i].connection.rmt_ip;

      if (!sub_conn->connection.is_ip4)
	continue;
      if ((lcl_ip->ip6.as_u64[0] == lcl_addr->as_u64[0]
	   && lcl_ip->ip6.as_u64[1] == lcl_addr->as_u64[1])
	  && (rmt_ip->ip6.as_u64[0] == rmt_addr->as_u64[0]
	      && rmt_ip->ip6.as_u64[1] == rmt_addr->as_u64[1]))
	{
	  sub_conn->state = SCTP_SUBCONN_STATE_DOWN;
	  sctp_conn->forming_association_changed = 1;
	  break;
	}
    }
  return SCTP_ERROR_NONE;
}

u8
sctp_configure (sctp_user_configuration_t config)
{
  sctp_main_t *sctp_main = vnet_get_sctp_main ();

  u32 thread_idx = vlib_get_thread_index ();

  sctp_main->connections[thread_idx]->conn_config.never_delay_sack =
    config.never_delay_sack;
  sctp_main->connections[thread_idx]->conn_config.never_bundle =
    config.never_bundle;

  return 0;
}

sctp_connection_t *
sctp_connection_new (u8 thread_index)
{
  sctp_main_t *sctp_main = vnet_get_sctp_main ();
  sctp_connection_t *sctp_conn;

  pool_get (sctp_main->connections[thread_index], sctp_conn);
  memset (sctp_conn, 0, sizeof (*sctp_conn));
  sctp_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].subconn_idx =
    SCTP_PRIMARY_PATH_IDX;
  sctp_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].c_c_index =
    sctp_conn - sctp_main->connections[thread_index];
  sctp_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].c_thread_index = thread_index;
  sctp_conn->local_tag = 0;

  return sctp_conn;
}

sctp_connection_t *
sctp_half_open_connection_new (u8 thread_index)
{
  sctp_main_t *tm = vnet_get_sctp_main ();
  sctp_connection_t *sctp_conn = 0;
  ASSERT (vlib_get_thread_index () == 0);
  pool_get (tm->half_open_connections, sctp_conn);
  memset (sctp_conn, 0, sizeof (*sctp_conn));
  sctp_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].c_c_index =
    sctp_conn - tm->half_open_connections;
  sctp_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].subconn_idx =
    SCTP_PRIMARY_PATH_IDX;
  return sctp_conn;
}

static inline int
sctp_connection_open (transport_endpoint_t * rmt)
{
  sctp_main_t *tm = vnet_get_sctp_main ();
  sctp_connection_t *sctp_conn;
  ip46_address_t lcl_addr;
  u16 lcl_port;
  uword thread_id;
  int rv;

  u8 idx = SCTP_PRIMARY_PATH_IDX;

  /*
   * Allocate local endpoint
   */
  if ((rmt->is_ip4 && vec_len (tm->ip4_src_addresses))
      || (!rmt->is_ip4 && vec_len (tm->ip6_src_addresses)))
    rv = sctp_alloc_custom_local_endpoint (tm, &lcl_addr, &lcl_port,
					   rmt->is_ip4);
  else
    rv = transport_alloc_local_endpoint (TRANSPORT_PROTO_SCTP,
					 rmt, &lcl_addr, &lcl_port);

  if (rv)
    return -1;

  /*
   * Create connection and send INIT CHUNK
   */
  thread_id = vlib_get_thread_index ();
  ASSERT (thread_id == 0);

  clib_spinlock_lock_if_init (&tm->half_open_lock);
  sctp_conn = sctp_half_open_connection_new (thread_id);
  sctp_conn->sub_conn[idx].PMTU =
    vnet_sw_interface_get_mtu (vnet_get_main (), rmt->sw_if_index, VLIB_TX);

  transport_connection_t *trans_conn = &sctp_conn->sub_conn[idx].connection;
  ip_copy (&trans_conn->rmt_ip, &rmt->ip, rmt->is_ip4);
  ip_copy (&trans_conn->lcl_ip, &lcl_addr, rmt->is_ip4);
  sctp_conn->sub_conn[idx].subconn_idx = idx;
  trans_conn->rmt_port = rmt->port;
  trans_conn->lcl_port = clib_host_to_net_u16 (lcl_port);
  trans_conn->is_ip4 = rmt->is_ip4;
  trans_conn->proto = TRANSPORT_PROTO_SCTP;
  trans_conn->fib_index = rmt->fib_index;

  sctp_connection_timers_init (sctp_conn);
  /* The other connection vars will be initialized after INIT_ACK chunk received */
  sctp_init_snd_vars (sctp_conn);

  sctp_send_init (sctp_conn);

  clib_spinlock_unlock_if_init (&tm->half_open_lock);

  return sctp_conn->sub_conn[idx].connection.c_index;
}

/**
 * Cleans up connection state.
 *
 * No notifications.
 */
void
sctp_connection_cleanup (sctp_connection_t * sctp_conn)
{
  sctp_main_t *tm = &sctp_main;
  u8 i;

  /* Cleanup local endpoint if this was an active connect */
  for (i = 0; i < MAX_SCTP_CONNECTIONS; i++)
    transport_endpoint_cleanup (TRANSPORT_PROTO_SCTP,
				&sctp_conn->sub_conn[i].connection.lcl_ip,
				sctp_conn->sub_conn[i].connection.lcl_port);

  int thread_index =
    sctp_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].connection.thread_index;

  /* Make sure all timers are cleared */
  sctp_connection_timers_reset (sctp_conn);

  /* Poison the entry */
  if (CLIB_DEBUG > 0)
    memset (sctp_conn, 0xFA, sizeof (*sctp_conn));
  pool_put (tm->connections[thread_index], sctp_conn);
}

int
sctp_session_open (transport_endpoint_t * tep)
{
  return sctp_connection_open (tep);
}

u16
sctp_check_outstanding_data_chunks (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)
	continue;

      if (sctp_conn->sub_conn[i].is_retransmitting == 1 ||
	  sctp_conn->sub_conn[i].enqueue_state != SCTP_ERROR_ENQUEUED)
	{
	  SCTP_DBG_OUTPUT
	    ("Connection %u has still DATA to be enqueued inboud / outboud",
	     sctp_conn->sub_conn[i].connection.c_index);
	  return 1;
	}

    }
  return 0;			/* Indicates no more data to be read/sent */
}

void
sctp_connection_close (sctp_connection_t * sctp_conn)
{
  SCTP_DBG ("Closing connection %u...",
	    sctp_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].connection.c_index);

  sctp_conn->state = SCTP_STATE_SHUTDOWN_PENDING;

  sctp_send_shutdown (sctp_conn);
}

void
sctp_session_close (u32 conn_index, u32 thread_index)
{
  ASSERT (thread_index == 0);

  sctp_connection_t *sctp_conn =
    sctp_connection_get (conn_index, thread_index);
  if (sctp_conn != NULL)
    sctp_connection_close (sctp_conn);
}

void
sctp_session_cleanup (u32 conn_index, u32 thread_index)
{
  sctp_connection_t *sctp_conn =
    sctp_connection_get (conn_index, thread_index);

  if (sctp_conn != NULL)
    {
      sctp_connection_timers_reset (sctp_conn);
      /* Wait for the session tx events to clear */
      sctp_conn->state = SCTP_STATE_CLOSED;
    }
}

/**
 * Compute maximum segment size for session layer.
 */
u16
sctp_session_send_mss (transport_connection_t * trans_conn)
{
  sctp_connection_t *sctp_conn =
    sctp_get_connection_from_transport (trans_conn);

  if (sctp_conn == NULL)
    {
      SCTP_DBG ("sctp_conn == NULL");
      return 0;
    }

  update_cwnd (sctp_conn);
  update_smallest_pmtu_idx (sctp_conn);

  return sctp_conn->sub_conn[sctp_conn->smallest_PMTU_idx].cwnd;
}

u16
sctp_snd_space (sctp_connection_t * sctp_conn)
{
  /* Finally, let's subtract the DATA chunk headers overhead */
  return sctp_conn->sub_conn[sctp_conn->smallest_PMTU_idx].cwnd -
    sizeof (sctp_payload_data_chunk_t) - sizeof (sctp_full_hdr_t);
}

/**
 * Compute TX window session is allowed to fill.
 */
u32
sctp_session_send_space (transport_connection_t * trans_conn)
{
  sctp_connection_t *sctp_conn =
    sctp_get_connection_from_transport (trans_conn);

  return sctp_snd_space (sctp_conn);
}

transport_connection_t *
sctp_session_get_transport (u32 conn_index, u32 thread_index)
{
  sctp_connection_t *sctp_conn =
    sctp_connection_get (conn_index, thread_index);

  if (PREDICT_TRUE (sctp_conn != NULL))
    return &sctp_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].connection;

  return NULL;
}

transport_connection_t *
sctp_session_get_listener (u32 listener_index)
{
  sctp_main_t *tm = vnet_get_sctp_main ();
  sctp_connection_t *sctp_conn;
  sctp_conn = pool_elt_at_index (tm->listener_pool, listener_index);
  return &sctp_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].connection;
}

u8 *
format_sctp_session (u8 * s, va_list * args)
{
  u32 tci = va_arg (*args, u32);
  u32 thread_index = va_arg (*args, u32);
  u32 verbose = va_arg (*args, u32);
  sctp_connection_t *tc;

  tc = sctp_connection_get (tci, thread_index);
  if (tc)
    s = format (s, "%U", format_sctp_connection, tc, verbose);
  else
    s = format (s, "empty\n");
  return s;
}

u8 *
format_sctp_listener_session (u8 * s, va_list * args)
{
  u32 tci = va_arg (*args, u32);
  sctp_connection_t *tc = sctp_listener_get (tci);
  return format (s, "%U", format_sctp_connection_id, tc);
}

void
sctp_expired_timers_cb (u32 conn_index, u32 timer_id)
{
  sctp_connection_t *sctp_conn;

  sctp_conn = sctp_connection_get (conn_index, vlib_get_thread_index ());
  /* note: the connection may have already disappeared */
  if (PREDICT_FALSE (sctp_conn == 0))
    return;

  SCTP_DBG ("%s expired", sctp_timer_to_string (timer_id));

  if (sctp_conn->sub_conn[conn_index].unacknowledged_hb >
      SCTP_PATH_MAX_RETRANS)
    {
      // The remote-peer is considered to be unreachable hence shutting down
      u8 i, total_subs_down = 1;
      for (i = 0; i < MAX_SCTP_CONNECTIONS; i++)
	{
	  if (sctp_conn->sub_conn[i].state == SCTP_SUBCONN_STATE_DOWN)
	    continue;

	  u32 now = sctp_time_now ();
	  if (now > (sctp_conn->sub_conn[i].last_seen + SCTP_HB_INTERVAL))
	    {
	      total_subs_down += 1;
	      sctp_conn->sub_conn[i].state = SCTP_SUBCONN_STATE_DOWN;
	    }
	}

      if (total_subs_down == MAX_SCTP_CONNECTIONS)
	{
	  /* Start cleanup. App wasn't notified yet so use delete notify as
	   * opposed to delete to cleanup session layer state. */
	  stream_session_delete_notify (&sctp_conn->sub_conn
					[SCTP_PRIMARY_PATH_IDX].connection);

	  sctp_connection_timers_reset (sctp_conn);

	  sctp_connection_cleanup (sctp_conn);
	}
      return;
    }

  switch (timer_id)
    {
    case SCTP_TIMER_T1_INIT:
      sctp_send_init (sctp_conn);
      break;
    case SCTP_TIMER_T1_COOKIE:
      sctp_send_cookie_echo (sctp_conn);
      break;
    case SCTP_TIMER_T2_SHUTDOWN:
      sctp_send_shutdown (sctp_conn);
      break;
    case SCTP_TIMER_T3_RXTX:
      sctp_timer_reset (sctp_conn, conn_index, timer_id);
      sctp_data_retransmit (sctp_conn);
      break;
    case SCTP_TIMER_T4_HEARTBEAT:
      sctp_timer_reset (sctp_conn, conn_index, timer_id);
      goto heartbeat;
    }
  return;

heartbeat:
  sctp_send_heartbeat (sctp_conn);
}

static void
sctp_expired_timers_dispatch (u32 * expired_timers)
{
  int i;
  u32 connection_index, timer_id;

  for (i = 0; i < vec_len (expired_timers); i++)
    {
      /* Get session index and timer id */
      connection_index = expired_timers[i] & 0x0FFFFFFF;
      timer_id = expired_timers[i] >> 28;

      SCTP_DBG ("Expired timer ID: %u", timer_id);

      /* Handle expiration */
      sctp_expired_timers_cb (connection_index, timer_id);
    }
}

void
sctp_initialize_timer_wheels (sctp_main_t * tm)
{
  tw_timer_wheel_16t_2w_512sl_t *tw;
  /* *INDENT-OFF* */
  foreach_vlib_main (({
    tw = &tm->timer_wheels[ii];
    tw_timer_wheel_init_16t_2w_512sl (tw, sctp_expired_timers_dispatch,
				      100e-3 /* timer period 100ms */ , ~0);
    tw->last_run_time = vlib_time_now (this_vlib_main);
  }));
  /* *INDENT-ON* */
}

clib_error_t *
sctp_main_enable (vlib_main_t * vm)
{
  sctp_main_t *tm = vnet_get_sctp_main ();
  vlib_thread_main_t *vtm = vlib_get_thread_main ();
  clib_error_t *error = 0;
  u32 num_threads;
  int thread;
  sctp_connection_t *sctp_conn __attribute__ ((unused));
  u32 preallocated_connections_per_thread;

  if ((error = vlib_call_init_function (vm, ip_main_init)))
    return error;
  if ((error = vlib_call_init_function (vm, ip4_lookup_init)))
    return error;
  if ((error = vlib_call_init_function (vm, ip6_lookup_init)))
    return error;

  /*
   * Registrations
   */

  ip4_register_protocol (IP_PROTOCOL_SCTP, sctp4_input_node.index);
  ip6_register_protocol (IP_PROTOCOL_SCTP, sctp6_input_node.index);

  /*
   * Initialize data structures
   */

  num_threads = 1 /* main thread */  + vtm->n_threads;
  vec_validate (tm->connections, num_threads - 1);

  /*
   * Preallocate connections. Assume that thread 0 won't
   * use preallocated threads when running multi-core
   */
  if (num_threads == 1)
    {
      thread = 0;
      preallocated_connections_per_thread = tm->preallocated_connections;
    }
  else
    {
      thread = 1;
      preallocated_connections_per_thread =
	tm->preallocated_connections / (num_threads - 1);
    }
  for (; thread < num_threads; thread++)
    {
      if (preallocated_connections_per_thread)
	pool_init_fixed (tm->connections[thread],
			 preallocated_connections_per_thread);
    }

  /* Initialize per worker thread tx buffers (used for control messages) */
  vec_validate (tm->tx_buffers, num_threads - 1);

  /* Initialize timer wheels */
  vec_validate (tm->timer_wheels, num_threads - 1);
  sctp_initialize_timer_wheels (tm);

  /* Initialize clocks per tick for SCTP timestamp. Used to compute
   * monotonically increasing timestamps. */
  tm->tstamp_ticks_per_clock = vm->clib_time.seconds_per_clock
    / SCTP_TSTAMP_RESOLUTION;

  if (num_threads > 1)
    {
      clib_spinlock_init (&tm->half_open_lock);
    }

  vec_validate (tm->tx_frames[0], num_threads - 1);
  vec_validate (tm->tx_frames[1], num_threads - 1);
  vec_validate (tm->ip_lookup_tx_frames[0], num_threads - 1);
  vec_validate (tm->ip_lookup_tx_frames[1], num_threads - 1);

  tm->bytes_per_buffer = vlib_buffer_free_list_buffer_size
    (vm, VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX);

  vec_validate (tm->time_now, num_threads - 1);
  return error;
}

clib_error_t *
sctp_enable_disable (vlib_main_t * vm, u8 is_en)
{
  if (is_en)
    {
      if (sctp_main.is_enabled)
	return 0;

      return sctp_main_enable (vm);
    }
  else
    {
      sctp_main.is_enabled = 0;
    }

  return 0;
}

transport_connection_t *
sctp_half_open_session_get_transport (u32 conn_index)
{
  sctp_connection_t *sctp_conn = sctp_half_open_connection_get (conn_index);
  return &sctp_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].connection;
}

u8 *
format_sctp_half_open (u8 * s, va_list * args)
{
  u32 tci = va_arg (*args, u32);
  sctp_connection_t *sctp_conn = sctp_half_open_connection_get (tci);
  return format (s, "%U", format_sctp_connection_id, sctp_conn);
}

void
sctp_update_time (f64 now, u8 thread_index)
{
  sctp_set_time_now (thread_index);
  tw_timer_expire_timers_16t_2w_512sl (&sctp_main.timer_wheels[thread_index],
				       now);
  sctp_flush_frames_to_output (thread_index);
}

/* *INDENT OFF* */
const static transport_proto_vft_t sctp_proto = {
  .enable = sctp_enable_disable,
  .bind = sctp_session_bind,
  .unbind = sctp_session_unbind,
  .open = sctp_session_open,
  .close = sctp_session_close,
  .cleanup = sctp_session_cleanup,
  .push_header = sctp_push_header,
  .send_mss = sctp_session_send_mss,
  .send_space = sctp_session_send_space,
  .update_time = sctp_update_time,
  .get_connection = sctp_session_get_transport,
  .get_listener = sctp_session_get_listener,
  .get_half_open = sctp_half_open_session_get_transport,
  .format_connection = format_sctp_session,
  .format_listener = format_sctp_listener_session,
  .format_half_open = format_sctp_half_open,
  .tx_type = TRANSPORT_TX_DEQUEUE,
  .service_type = TRANSPORT_SERVICE_VC,
};

/* *INDENT ON* */

clib_error_t *
sctp_init (vlib_main_t * vm)
{
  sctp_main_t *tm = vnet_get_sctp_main ();
  ip_main_t *im = &ip_main;
  ip_protocol_info_t *pi;
  /* Session layer, and by implication SCTP, are disabled by default */
  tm->is_enabled = 0;

  /* Register with IP for header parsing */
  pi = ip_get_protocol_info (im, IP_PROTOCOL_SCTP);
  if (pi == 0)
    return clib_error_return (0, "SCTP protocol info AWOL");
  pi->format_header = format_sctp_header;
  pi->unformat_pg_edit = unformat_pg_sctp_header;

  /* Register as transport with session layer */
  transport_register_protocol (TRANSPORT_PROTO_SCTP, &sctp_proto,
			       FIB_PROTOCOL_IP4, sctp4_output_node.index);
  transport_register_protocol (TRANSPORT_PROTO_SCTP, &sctp_proto,
			       FIB_PROTOCOL_IP6, sctp6_output_node.index);

  sctp_api_reference ();

  return 0;
}

VLIB_INIT_FUNCTION (sctp_init);

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