/*
 * Copyright (c) 2016-2019 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 TCP host stack utilities
 */

#include <vnet/tcp/tcp.h>
#include <vnet/session/session.h>
#include <vnet/fib/fib.h>
#include <vnet/dpo/load_balance.h>
#include <vnet/dpo/receive_dpo.h>
#include <vnet/ip/ip6_neighbor.h>
#include <math.h>
#include <vnet/ethernet/arp.h>

tcp_main_t tcp_main;

typedef struct
{
  fib_protocol_t nh_proto;
  vnet_link_t link_type;
  ip46_address_t ip;
  u32 sw_if_index;
  u8 is_add;
} tcp_add_del_adj_args_t;

static void
tcp_add_del_adj_cb (tcp_add_del_adj_args_t * args)
{
  u32 ai;
  if (args->is_add)
    {
      adj_nbr_add_or_lock (args->nh_proto, args->link_type, &args->ip,
			   args->sw_if_index);
    }
  else
    {
      ai = adj_nbr_find (FIB_PROTOCOL_IP6, VNET_LINK_IP6, &args->ip,
			 args->sw_if_index);
      if (ai != ADJ_INDEX_INVALID)
	adj_unlock (ai);
    }
}

static void
tcp_add_del_adjacency (tcp_connection_t * tc, u8 is_add)
{
  tcp_add_del_adj_args_t args = {
    .nh_proto = FIB_PROTOCOL_IP6,
    .link_type = VNET_LINK_IP6,
    .ip = tc->c_rmt_ip,
    .sw_if_index = tc->sw_if_index,
    .is_add = is_add
  };
  vlib_rpc_call_main_thread (tcp_add_del_adj_cb, (u8 *) & args,
			     sizeof (args));
}

static void
tcp_cc_init (tcp_connection_t * tc)
{
  tc->cc_algo->init (tc);
}

static void
tcp_cc_cleanup (tcp_connection_t * tc)
{
  if (tc->cc_algo->cleanup)
    tc->cc_algo->cleanup (tc);
}

void
tcp_cc_algo_register (tcp_cc_algorithm_type_e type,
		      const tcp_cc_algorithm_t * vft)
{
  tcp_main_t *tm = vnet_get_tcp_main ();
  vec_validate (tm->cc_algos, type);

  tm->cc_algos[type] = *vft;
  hash_set_mem (tm->cc_algo_by_name, vft->name, type);
}

tcp_cc_algorithm_t *
tcp_cc_algo_get (tcp_cc_algorithm_type_e type)
{
  tcp_main_t *tm = vnet_get_tcp_main ();
  return &tm->cc_algos[type];
}

tcp_cc_algorithm_type_e
tcp_cc_algo_new_type (const tcp_cc_algorithm_t * vft)
{
  tcp_main_t *tm = vnet_get_tcp_main ();
  tcp_cc_algo_register (++tm->cc_last_type, vft);
  return tm->cc_last_type;
}

static u32
tcp_connection_bind (u32 session_index, transport_endpoint_t * lcl)
{
  tcp_main_t *tm = &tcp_main;
  tcp_connection_t *listener;
  void *iface_ip;

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

  listener->c_c_index = listener - tm->listener_pool;
  listener->c_lcl_port = lcl->port;

  /* If we are provided a sw_if_index, bind using one of its ips */
  if (ip_is_zero (&lcl->ip, 1) && lcl->sw_if_index != ENDPOINT_INVALID_INDEX)
    {
      if ((iface_ip = ip_interface_get_first_ip (lcl->sw_if_index,
						 lcl->is_ip4)))
	ip_set (&lcl->ip, iface_ip, lcl->is_ip4);
    }
  ip_copy (&listener->c_lcl_ip, &lcl->ip, lcl->is_ip4);
  listener->c_is_ip4 = lcl->is_ip4;
  listener->c_proto = TRANSPORT_PROTO_TCP;
  listener->c_s_index = session_index;
  listener->c_fib_index = lcl->fib_index;
  listener->state = TCP_STATE_LISTEN;
  listener->cc_algo = tcp_cc_algo_get (tcp_cfg.cc_algo);

  tcp_connection_timers_init (listener);

  TCP_EVT (TCP_EVT_BIND, listener);

  return listener->c_c_index;
}

static u32
tcp_session_bind (u32 session_index, transport_endpoint_t * tep)
{
  return tcp_connection_bind (session_index, tep);
}

static void
tcp_connection_unbind (u32 listener_index)
{
  tcp_main_t *tm = vnet_get_tcp_main ();
  tcp_connection_t *tc;

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

  TCP_EVT (TCP_EVT_UNBIND, tc);

  /* Poison the entry */
  if (CLIB_DEBUG > 0)
    clib_memset (tc, 0xFA, sizeof (*tc));

  pool_put_index (tm->listener_pool, listener_index);
}

static u32
tcp_session_unbind (u32 listener_index)
{
  tcp_connection_unbind (listener_index);
  return 0;
}

static transport_connection_t *
tcp_session_get_listener (u32 listener_index)
{
  tcp_main_t *tm = vnet_get_tcp_main ();
  tcp_connection_t *tc;
  tc = pool_elt_at_index (tm->listener_pool, listener_index);
  return &tc->connection;
}

/**
 * Cleanup half-open connection
 *
 */
static void
tcp_half_open_connection_del (tcp_connection_t * tc)
{
  tcp_main_t *tm = vnet_get_tcp_main ();
  clib_spinlock_lock_if_init (&tm->half_open_lock);
  if (CLIB_DEBUG)
    clib_memset (tc, 0xFA, sizeof (*tc));
  pool_put (tm->half_open_connections, tc);
  clib_spinlock_unlock_if_init (&tm->half_open_lock);
}

/**
 * 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.
 */
int
tcp_half_open_connection_cleanup (tcp_connection_t * tc)
{
  /* Make sure this is the owning thread */
  if (tc->c_thread_index != vlib_get_thread_index ())
    return 1;
  tcp_timer_reset (tc, TCP_TIMER_RETRANSMIT_SYN);
  tcp_half_open_connection_del (tc);
  return 0;
}

static tcp_connection_t *
tcp_half_open_connection_new (void)
{
  tcp_main_t *tm = vnet_get_tcp_main ();
  tcp_connection_t *tc = 0;
  ASSERT (vlib_get_thread_index () == 0);
  pool_get (tm->half_open_connections, tc);
  clib_memset (tc, 0, sizeof (*tc));
  tc->c_c_index = tc - tm->half_open_connections;
  return tc;
}

/**
 * Cleans up connection state.
 *
 * No notifications.
 */
void
tcp_connection_cleanup (tcp_connection_t * tc)
{
  tcp_main_t *tm = &tcp_main;

  TCP_EVT (TCP_EVT_DELETE, tc);

  /* Cleanup local endpoint if this was an active connect */
  transport_endpoint_cleanup (TRANSPORT_PROTO_TCP, &tc->c_lcl_ip,
			      tc->c_lcl_port);

  /* Check if connection is not yet fully established */
  if (tc->state == TCP_STATE_SYN_SENT)
    {
      /* Try to remove the half-open connection. If this is not the owning
       * thread, tc won't be removed. Retransmit or establish timers will
       * eventually expire and call again cleanup on the right thread. */
      if (tcp_half_open_connection_cleanup (tc))
	tc->flags |= TCP_CONN_HALF_OPEN_DONE;
    }
  else
    {
      int thread_index = tc->c_thread_index;

      /* Make sure all timers are cleared */
      tcp_connection_timers_reset (tc);

      if (!tc->c_is_ip4 && ip6_address_is_link_local_unicast (&tc->c_rmt_ip6))
	tcp_add_del_adjacency (tc, 0);

      tcp_cc_cleanup (tc);
      vec_free (tc->snd_sacks);
      vec_free (tc->snd_sacks_fl);
      vec_free (tc->rcv_opts.sacks);
      pool_free (tc->sack_sb.holes);

      if (tc->cfg_flags & TCP_CFG_F_RATE_SAMPLE)
	tcp_bt_cleanup (tc);

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

/**
 * Connection removal.
 *
 * This should be called only once connection enters CLOSED state. Note
 * that it notifies the session of the removal event, so if the goal is to
 * just remove the connection, call tcp_connection_cleanup instead.
 */
void
tcp_connection_del (tcp_connection_t * tc)
{
  session_transport_delete_notify (&tc->connection);
  tcp_connection_cleanup (tc);
}

tcp_connection_t *
tcp_connection_alloc (u8 thread_index)
{
  tcp_main_t *tm = vnet_get_tcp_main ();
  tcp_connection_t *tc;

  pool_get (tm->connections[thread_index], tc);
  clib_memset (tc, 0, sizeof (*tc));
  tc->c_c_index = tc - tm->connections[thread_index];
  tc->c_thread_index = thread_index;
  return tc;
}

tcp_connection_t *
tcp_connection_alloc_w_base (u8 thread_index, tcp_connection_t * base)
{
  tcp_main_t *tm = vnet_get_tcp_main ();
  tcp_connection_t *tc;

  pool_get (tm->connections[thread_index], tc);
  clib_memcpy_fast (tc, base, sizeof (*tc));
  tc->c_c_index = tc - tm->connections[thread_index];
  tc->c_thread_index = thread_index;
  return tc;
}

void
tcp_connection_free (tcp_connection_t * tc)
{
  tcp_main_t *tm = &tcp_main;
  if (CLIB_DEBUG)
    {
      u8 thread_index = tc->c_thread_index;
      clib_memset (tc, 0xFA, sizeof (*tc));
      pool_put (tm->connections[thread_index], tc);
      return;
    }
  pool_put (tm->connections[tc->c_thread_index], tc);
}

/** Notify session that connection has been reset.
 *
 * Switch state to closed and wait for session to call cleanup.
 */
void
tcp_connection_reset (tcp_connection_t * tc)
{
  TCP_EVT (TCP_EVT_RST_RCVD, tc);
  switch (tc->state)
    {
    case TCP_STATE_SYN_RCVD:
      /* Cleanup everything. App wasn't notified yet */
      session_transport_delete_notify (&tc->connection);
      tcp_connection_cleanup (tc);
      break;
    case TCP_STATE_SYN_SENT:
      session_stream_connect_notify (&tc->connection, 1 /* fail */ );
      tcp_connection_cleanup (tc);
      break;
    case TCP_STATE_ESTABLISHED:
      tcp_connection_timers_reset (tc);
      /* Set the cleanup timer, in case the session layer/app don't
       * cleanly close the connection */
      tcp_timer_set (tc, TCP_TIMER_WAITCLOSE, tcp_cfg.closewait_time);
      session_transport_reset_notify (&tc->connection);
      tcp_connection_set_state (tc, TCP_STATE_CLOSED);
      session_transport_closed_notify (&tc->connection);
      break;
    case TCP_STATE_CLOSE_WAIT:
    case TCP_STATE_FIN_WAIT_1:
    case TCP_STATE_FIN_WAIT_2:
    case TCP_STATE_CLOSING:
    case TCP_STATE_LAST_ACK:
      tcp_connection_timers_reset (tc);
      tcp_timer_set (tc, TCP_TIMER_WAITCLOSE, tcp_cfg.closewait_time);
      /* Make sure we mark the session as closed. In some states we may
       * be still trying to send data */
      tcp_connection_set_state (tc, TCP_STATE_CLOSED);
      session_transport_closed_notify (&tc->connection);
      break;
    case TCP_STATE_CLOSED:
    case TCP_STATE_TIME_WAIT:
      break;
    default:
      TCP_DBG ("reset state: %u", tc->state);
    }
}

/**
 * Begin connection closing procedure.
 *
 * If at the end the connection is not in CLOSED state, it is not removed.
 * Instead, we rely on on TCP to advance through state machine to either
 * 1) LAST_ACK (passive close) whereby when the last ACK is received
 * tcp_connection_del is called. This notifies session of the delete and
 * calls cleanup.
 * 2) TIME_WAIT (active close) whereby after 2MSL the 2MSL timer triggers
 * and cleanup is called.
 *
 * N.B. Half-close connections are not supported
 */
void
tcp_connection_close (tcp_connection_t * tc)
{
  TCP_EVT (TCP_EVT_CLOSE, tc);

  /* Send/Program FIN if needed and switch state */
  switch (tc->state)
    {
    case TCP_STATE_SYN_SENT:
      /* Try to cleanup. If not on the right thread, mark as half-open done.
       * Connection will be cleaned up when establish timer pops */
      tcp_connection_cleanup (tc);
      break;
    case TCP_STATE_SYN_RCVD:
      tcp_connection_timers_reset (tc);
      tcp_send_fin (tc);
      tcp_connection_set_state (tc, TCP_STATE_FIN_WAIT_1);
      tcp_timer_update (tc, TCP_TIMER_WAITCLOSE, tcp_cfg.finwait1_time);
      break;
    case TCP_STATE_ESTABLISHED:
      /* If closing with unread data, reset the connection */
      if (transport_max_rx_dequeue (&tc->connection))
	{
	  tcp_send_reset (tc);
	  tcp_connection_timers_reset (tc);
	  tcp_connection_set_state (tc, TCP_STATE_CLOSED);
	  tcp_timer_set (tc, TCP_TIMER_WAITCLOSE, tcp_cfg.closewait_time);
	  session_transport_closed_notify (&tc->connection);
	  break;
	}
      if (!transport_max_tx_dequeue (&tc->connection))
	tcp_send_fin (tc);
      else
	tc->flags |= TCP_CONN_FINPNDG;
      tcp_connection_set_state (tc, TCP_STATE_FIN_WAIT_1);
      /* Set a timer in case the peer stops responding. Otherwise the
       * connection will be stuck here forever. */
      ASSERT (tc->timers[TCP_TIMER_WAITCLOSE] == TCP_TIMER_HANDLE_INVALID);
      tcp_timer_set (tc, TCP_TIMER_WAITCLOSE, tcp_cfg.finwait1_time);
      break;
    case TCP_STATE_CLOSE_WAIT:
      if (!transport_max_tx_dequeue (&tc->connection))
	{
	  tcp_send_fin (tc);
	  tcp_connection_timers_reset (tc);
	  tcp_connection_set_state (tc, TCP_STATE_LAST_ACK);
	  tcp_timer_update (tc, TCP_TIMER_WAITCLOSE, tcp_cfg.lastack_time);
	}
      else
	tc->flags |= TCP_CONN_FINPNDG;
      break;
    case TCP_STATE_FIN_WAIT_1:
      tcp_timer_update (tc, TCP_TIMER_WAITCLOSE, tcp_cfg.finwait1_time);
      break;
    case TCP_STATE_CLOSED:
      tcp_connection_timers_reset (tc);
      /* Delete connection but instead of doing it now wait until next
       * dispatch cycle to give the session layer a chance to clear
       * unhandled events */
      tcp_timer_update (tc, TCP_TIMER_WAITCLOSE, tcp_cfg.cleanup_time);
      break;
    default:
      TCP_DBG ("state: %u", tc->state);
    }
}

static void
tcp_session_close (u32 conn_index, u32 thread_index)
{
  tcp_connection_t *tc;
  tc = tcp_connection_get (conn_index, thread_index);
  tcp_connection_close (tc);
}

static void
tcp_session_cleanup (u32 conn_index, u32 thread_index)
{
  tcp_connection_t *tc;
  tc = tcp_connection_get (conn_index, thread_index);
  if (!tc)
    return;
  tcp_connection_set_state (tc, TCP_STATE_CLOSED);
  tcp_connection_cleanup (tc);
}

static void
tcp_session_reset (u32 conn_index, u32 thread_index)
{
  tcp_connection_t *tc;
  tc = tcp_connection_get (conn_index, thread_index);
  session_transport_closed_notify (&tc->connection);
  tcp_send_reset (tc);
  tcp_connection_timers_reset (tc);
  tcp_connection_set_state (tc, TCP_STATE_CLOSED);
  tcp_timer_update (tc, TCP_TIMER_WAITCLOSE, tcp_cfg.cleanup_time);
}

/**
 * Initialize all connection timers as invalid
 */
void
tcp_connection_timers_init (tcp_connection_t * tc)
{
  int i;

  /* Set all to invalid */
  for (i = 0; i < TCP_N_TIMERS; i++)
    {
      tc->timers[i] = TCP_TIMER_HANDLE_INVALID;
    }

  tc->rto = TCP_RTO_INIT;
}

/**
 * Stop all connection timers
 */
void
tcp_connection_timers_reset (tcp_connection_t * tc)
{
  int i;
  for (i = 0; i < TCP_N_TIMERS; i++)
    {
      tcp_timer_reset (tc, i);
    }
}

#if 0
typedef struct ip4_tcp_hdr
{
  ip4_header_t ip;
  tcp_header_t tcp;
} ip4_tcp_hdr_t;

typedef struct ip6_tcp_hdr
{
  ip6_header_t ip;
  tcp_header_t tcp;
} ip6_tcp_hdr_t;

static void
tcp_connection_select_lb_bucket (tcp_connection_t * tc, const dpo_id_t * dpo,
				 dpo_id_t * result)
{
  const dpo_id_t *choice;
  load_balance_t *lb;
  int hash;

  lb = load_balance_get (dpo->dpoi_index);
  if (tc->c_is_ip4)
    {
      ip4_tcp_hdr_t hdr;
      clib_memset (&hdr, 0, sizeof (hdr));
      hdr.ip.protocol = IP_PROTOCOL_TCP;
      hdr.ip.address_pair.src.as_u32 = tc->c_lcl_ip.ip4.as_u32;
      hdr.ip.address_pair.dst.as_u32 = tc->c_rmt_ip.ip4.as_u32;
      hdr.tcp.src_port = tc->c_lcl_port;
      hdr.tcp.dst_port = tc->c_rmt_port;
      hash = ip4_compute_flow_hash (&hdr.ip, lb->lb_hash_config);
    }
  else
    {
      ip6_tcp_hdr_t hdr;
      clib_memset (&hdr, 0, sizeof (hdr));
      hdr.ip.protocol = IP_PROTOCOL_TCP;
      clib_memcpy_fast (&hdr.ip.src_address, &tc->c_lcl_ip.ip6,
			sizeof (ip6_address_t));
      clib_memcpy_fast (&hdr.ip.dst_address, &tc->c_rmt_ip.ip6,
			sizeof (ip6_address_t));
      hdr.tcp.src_port = tc->c_lcl_port;
      hdr.tcp.dst_port = tc->c_rmt_port;
      hash = ip6_compute_flow_hash (&hdr.ip, lb->lb_hash_config);
    }
  choice = load_balance_get_bucket_i (lb, hash & lb->lb_n_buckets_minus_1);
  dpo_copy (result, choice);
}

fib_node_index_t
tcp_lookup_rmt_in_fib (tcp_connection_t * tc)
{
  fib_prefix_t prefix;
  u32 fib_index;

  clib_memcpy_fast (&prefix.fp_addr, &tc->c_rmt_ip, sizeof (prefix.fp_addr));
  prefix.fp_proto = tc->c_is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6;
  prefix.fp_len = tc->c_is_ip4 ? 32 : 128;
  fib_index = fib_table_find (prefix.fp_proto, tc->c_fib_index);
  return fib_table_lookup (fib_index, &prefix);
}

static int
tcp_connection_stack_on_fib_entry (tcp_connection_t * tc)
{
  dpo_id_t choice = DPO_INVALID;
  u32 output_node_index;
  fib_entry_t *fe;

  fe = fib_entry_get (tc->c_rmt_fei);
  if (fe->fe_lb.dpoi_type != DPO_LOAD_BALANCE)
    return -1;

  tcp_connection_select_lb_bucket (tc, &fe->fe_lb, &choice);

  output_node_index =
    tc->c_is_ip4 ? tcp4_output_node.index : tcp6_output_node.index;
  dpo_stack_from_node (output_node_index, &tc->c_rmt_dpo, &choice);
  return 0;
}

/** Stack tcp connection on peer's fib entry.
 *
 * This ultimately populates the dpo the connection will use to send packets.
 */
static void
tcp_connection_fib_attach (tcp_connection_t * tc)
{
  tc->c_rmt_fei = tcp_lookup_rmt_in_fib (tc);

  ASSERT (tc->c_rmt_fei != FIB_NODE_INDEX_INVALID);

  tcp_connection_stack_on_fib_entry (tc);
}
#endif /* 0 */

/**
 * Generate random iss as per rfc6528
 */
static u32
tcp_generate_random_iss (tcp_connection_t * tc)
{
  tcp_main_t *tm = &tcp_main;
  u64 tmp;

  if (tc->c_is_ip4)
    tmp = (u64) tc->c_lcl_ip.ip4.as_u32 << 32 | (u64) tc->c_rmt_ip.ip4.as_u32;
  else
    tmp = tc->c_lcl_ip.ip6.as_u64[0] ^ tc->c_lcl_ip.ip6.as_u64[1]
      ^ tc->c_rmt_ip.ip6.as_u64[0] ^ tc->c_rmt_ip.ip6.as_u64[1];

  tmp ^= tm->iss_seed.first | ((u64) tc->c_lcl_port << 16 | tc->c_rmt_port);
  tmp ^= tm->iss_seed.second;
  tmp = clib_xxhash (tmp) + clib_cpu_time_now ();
  return ((tmp >> 32) ^ (tmp & 0xffffffff));
}

/**
 * Initialize max segment size we're able to process.
 *
 * The value is constrained by the output interface's MTU and by the size
 * of the IP and TCP headers (see RFC6691). It is also what we advertise
 * to our peer.
 */
static void
tcp_init_rcv_mss (tcp_connection_t * tc)
{
  u8 ip_hdr_len;

  ip_hdr_len = tc->c_is_ip4 ? sizeof (ip4_header_t) : sizeof (ip6_header_t);
  tc->mss = tcp_cfg.default_mtu - sizeof (tcp_header_t) - ip_hdr_len;
}

static void
tcp_init_mss (tcp_connection_t * tc)
{
  u16 default_min_mss = 536;

  tcp_init_rcv_mss (tc);

  /* TODO consider PMTU discovery */
  tc->snd_mss = clib_min (tc->rcv_opts.mss, tc->mss);

  if (tc->snd_mss < 45)
    {
      /* Assume that at least the min default mss works */
      tc->snd_mss = default_min_mss;
      tc->rcv_opts.mss = default_min_mss;
    }

  /* We should have enough space for 40 bytes of options */
  ASSERT (tc->snd_mss > 45);

  /* If we use timestamp option, account for it */
  if (tcp_opts_tstamp (&tc->rcv_opts))
    tc->snd_mss -= TCP_OPTION_LEN_TIMESTAMP;
}

/**
 * Initialize connection send variables.
 */
void
tcp_init_snd_vars (tcp_connection_t * tc)
{
  /*
   * 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.
   */
  tcp_set_time_now (tcp_get_worker (vlib_get_thread_index ()));

  tcp_init_rcv_mss (tc);
  tc->iss = tcp_generate_random_iss (tc);
  tc->snd_una = tc->iss;
  tc->snd_nxt = tc->iss + 1;
  tc->snd_una_max = tc->snd_nxt;
  tc->srtt = 100;		/* 100 ms */
}

void
tcp_enable_pacing (tcp_connection_t * tc)
{
  u32 byte_rate;
  byte_rate = tc->cwnd / (tc->srtt * TCP_TICK);
  transport_connection_tx_pacer_init (&tc->connection, byte_rate, tc->cwnd);
  tc->mrtt_us = (u32) ~ 0;
}

/** Initialize tcp connection variables
 *
 * Should be called after having received a msg from the peer, i.e., a SYN or
 * a SYNACK, such that connection options have already been exchanged. */
void
tcp_connection_init_vars (tcp_connection_t * tc)
{
  tcp_connection_timers_init (tc);
  tcp_init_mss (tc);
  scoreboard_init (&tc->sack_sb);
  if (tc->state == TCP_STATE_SYN_RCVD)
    tcp_init_snd_vars (tc);

  tcp_cc_init (tc);

  if (!tc->c_is_ip4 && ip6_address_is_link_local_unicast (&tc->c_rmt_ip6))
    tcp_add_del_adjacency (tc, 1);

  /*  tcp_connection_fib_attach (tc); */

  if (transport_connection_is_tx_paced (&tc->connection)
      || tcp_cfg.enable_tx_pacing)
    tcp_enable_pacing (tc);

  if (tc->cfg_flags & TCP_CFG_F_RATE_SAMPLE)
    tcp_bt_init (tc);

  if (!tcp_cfg.allow_tso)
    tc->cfg_flags |= TCP_CFG_F_NO_TSO;

  tc->start_ts = tcp_time_now_us (tc->c_thread_index);
}

static int
tcp_alloc_custom_local_endpoint (tcp_main_t * tm, ip46_address_t * lcl_addr,
				 u16 * lcl_port, u8 is_ip4)
{
  int index, port;
  if (is_ip4)
    {
      index = tm->last_v4_addr_rotor++;
      if (tm->last_v4_addr_rotor >= vec_len (tcp_cfg.ip4_src_addrs))
	tm->last_v4_addr_rotor = 0;
      lcl_addr->ip4.as_u32 = tcp_cfg.ip4_src_addrs[index].as_u32;
    }
  else
    {
      index = tm->last_v6_addr_rotor++;
      if (tm->last_v6_addr_rotor >= vec_len (tcp_cfg.ip6_src_addrs))
	tm->last_v6_addr_rotor = 0;
      clib_memcpy_fast (&lcl_addr->ip6, &tcp_cfg.ip6_src_addrs[index],
			sizeof (ip6_address_t));
    }
  port = transport_alloc_local_port (TRANSPORT_PROTO_TCP, lcl_addr);
  if (port < 1)
    {
      clib_warning ("Failed to allocate src port");
      return -1;
    }
  *lcl_port = port;
  return 0;
}

static int
tcp_session_open (transport_endpoint_cfg_t * rmt)
{
  tcp_main_t *tm = vnet_get_tcp_main ();
  tcp_connection_t *tc;
  ip46_address_t lcl_addr;
  u16 lcl_port;
  int rv;

  /*
   * Allocate local endpoint
   */
  if ((rmt->is_ip4 && vec_len (tcp_cfg.ip4_src_addrs))
      || (!rmt->is_ip4 && vec_len (tcp_cfg.ip6_src_addrs)))
    rv = tcp_alloc_custom_local_endpoint (tm, &lcl_addr, &lcl_port,
					  rmt->is_ip4);
  else
    rv = transport_alloc_local_endpoint (TRANSPORT_PROTO_TCP,
					 rmt, &lcl_addr, &lcl_port);

  if (rv)
    return -1;

  /*
   * Create connection and send SYN
   */
  clib_spinlock_lock_if_init (&tm->half_open_lock);
  tc = tcp_half_open_connection_new ();
  ip_copy (&tc->c_rmt_ip, &rmt->ip, rmt->is_ip4);
  ip_copy (&tc->c_lcl_ip, &lcl_addr, rmt->is_ip4);
  tc->c_rmt_port = rmt->port;
  tc->c_lcl_port = clib_host_to_net_u16 (lcl_port);
  tc->c_is_ip4 = rmt->is_ip4;
  tc->c_proto = TRANSPORT_PROTO_TCP;
  tc->c_fib_index = rmt->fib_index;
  tc->cc_algo = tcp_cc_algo_get (tcp_cfg.cc_algo);
  /* The other connection vars will be initialized after SYN ACK */
  tcp_connection_timers_init (tc);

  TCP_EVT (TCP_EVT_OPEN, tc);
  tc->state = TCP_STATE_SYN_SENT;
  tcp_init_snd_vars (tc);
  tcp_send_syn (tc);
  clib_spinlock_unlock_if_init (&tm->half_open_lock);

  return tc->c_c_index;
}

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

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

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

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

static u8 *
format_tcp_cfg_flags (u8 * s, va_list * args)
{
  tcp_connection_t *tc = va_arg (*args, tcp_connection_t *);
  int i, last = -1;

  for (i = 0; i < TCP_CFG_N_FLAG_BITS; i++)
    if (tc->cfg_flags & (1 << i))
      last = i;
  for (i = 0; i < last; i++)
    {
      if (tc->cfg_flags & (1 << i))
	s = format (s, "%s, ", tcp_cfg_flags_str[i]);
    }
  if (last >= 0)
    s = format (s, "%s", tcp_cfg_flags_str[last]);
  return s;
}

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

static u8 *
format_tcp_connection_flags (u8 * s, va_list * args)
{
  tcp_connection_t *tc = va_arg (*args, tcp_connection_t *);
  int i, last = -1;

  for (i = 0; i < TCP_CONN_N_FLAG_BITS; i++)
    if (tc->flags & (1 << i))
      last = i;
  for (i = 0; i < last; i++)
    {
      if (tc->flags & (1 << i))
	s = format (s, "%s, ", tcp_connection_flags_str[i]);
    }
  if (last >= 0)
    s = format (s, "%s", tcp_connection_flags_str[last]);
  return s;
}

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

static u8 *
format_tcp_timers (u8 * s, va_list * args)
{
  tcp_connection_t *tc = va_arg (*args, tcp_connection_t *);
  int i, last = -1;

  for (i = 0; i < TCP_N_TIMERS; i++)
    if (tc->timers[i] != TCP_TIMER_HANDLE_INVALID)
      last = i;

  for (i = 0; i < last; i++)
    {
      if (tc->timers[i] != TCP_TIMER_HANDLE_INVALID)
	s = format (s, "%s,", tcp_conn_timers[i]);
    }

  if (last >= 0)
    s = format (s, "%s", tcp_conn_timers[i]);

  return s;
}

static u8 *
format_tcp_congestion_status (u8 * s, va_list * args)
{
  tcp_connection_t *tc = va_arg (*args, tcp_connection_t *);
  if (tcp_in_recovery (tc))
    s = format (s, "recovery");
  else if (tcp_in_fastrecovery (tc))
    s = format (s, "fastrecovery");
  else
    s = format (s, "none");
  return s;
}

static i32
tcp_rcv_wnd_available (tcp_connection_t * tc)
{
  return (i32) tc->rcv_wnd - (tc->rcv_nxt - tc->rcv_las);
}

static u8 *
format_tcp_congestion (u8 * s, va_list * args)
{
  tcp_connection_t *tc = va_arg (*args, tcp_connection_t *);
  u32 indent = format_get_indent (s), prr_space = 0;

  s = format (s, "%U ", format_tcp_congestion_status, tc);
  s = format (s, "algo %s cwnd %u ssthresh %u bytes_acked %u\n",
	      tc->cc_algo->name, tc->cwnd, tc->ssthresh, tc->bytes_acked);
  s = format (s, "%Ucc space %u prev_cwnd %u prev_ssthresh %u\n",
	      format_white_space, indent, tcp_available_cc_snd_space (tc),
	      tc->prev_cwnd, tc->prev_ssthresh);
  s = format (s, "%Usnd_cong %u dupack %u limited_tx %u\n",
	      format_white_space, indent, tc->snd_congestion - tc->iss,
	      tc->rcv_dupacks, tc->limited_transmit - tc->iss);
  s = format (s, "%Urxt_bytes %u rxt_delivered %u rxt_head %u rxt_ts %u\n",
	      format_white_space, indent, tc->snd_rxt_bytes,
	      tc->rxt_delivered, tc->rxt_head - tc->iss,
	      tcp_time_now_w_thread (tc->c_thread_index) - tc->snd_rxt_ts);
  if (tcp_in_fastrecovery (tc))
    prr_space = tcp_fastrecovery_prr_snd_space (tc);
  s = format (s, "%Uprr_start %u prr_delivered %u prr space %u\n",
	      format_white_space, indent, tc->prr_start - tc->iss,
	      tc->prr_delivered, prr_space);
  return s;
}

static u8 *
format_tcp_stats (u8 * s, va_list * args)
{
  tcp_connection_t *tc = va_arg (*args, tcp_connection_t *);
  u32 indent = format_get_indent (s);
  s = format (s, "in segs %lu dsegs %lu bytes %lu dupacks %u\n",
	      tc->segs_in, tc->data_segs_in, tc->bytes_in, tc->dupacks_in);
  s = format (s, "%Uout segs %lu dsegs %lu bytes %lu dupacks %u\n",
	      format_white_space, indent, tc->segs_out,
	      tc->data_segs_out, tc->bytes_out, tc->dupacks_out);
  s = format (s, "%Ufr %u tr %u rxt segs %lu bytes %lu duration %.3f\n",
	      format_white_space, indent, tc->fr_occurences,
	      tc->tr_occurences, tc->segs_retrans, tc->bytes_retrans,
	      tcp_time_now_us (tc->c_thread_index) - tc->start_ts);
  s = format (s, "%Uerr wnd data below %u above %u ack below %u above %u",
	      format_white_space, indent, tc->errors.below_data_wnd,
	      tc->errors.above_data_wnd, tc->errors.below_ack_wnd,
	      tc->errors.above_ack_wnd);
  return s;
}

static u8 *
format_tcp_vars (u8 * s, va_list * args)
{
  tcp_connection_t *tc = va_arg (*args, tcp_connection_t *);
  s = format (s, " index: %u cfg: %U flags: %U timers: %U\n", tc->c_c_index,
	      format_tcp_cfg_flags, tc, format_tcp_connection_flags, tc,
	      format_tcp_timers, tc);
  s = format (s, " snd_una %u snd_nxt %u snd_una_max %u",
	      tc->snd_una - tc->iss, tc->snd_nxt - tc->iss,
	      tc->snd_una_max - tc->iss);
  s = format (s, " rcv_nxt %u rcv_las %u\n",
	      tc->rcv_nxt - tc->irs, tc->rcv_las - tc->irs);
  s = format (s, " snd_wnd %u rcv_wnd %u rcv_wscale %u ",
	      tc->snd_wnd, tc->rcv_wnd, tc->rcv_wscale);
  s = format (s, "snd_wl1 %u snd_wl2 %u\n", tc->snd_wl1 - tc->irs,
	      tc->snd_wl2 - tc->iss);
  s = format (s, " flight size %u out space %u rcv_wnd_av %u",
	      tcp_flight_size (tc), tcp_available_output_snd_space (tc),
	      tcp_rcv_wnd_available (tc));
  s = format (s, " tsval_recent %u\n", tc->tsval_recent);
  s = format (s, " tsecr %u tsecr_last_ack %u tsval_recent_age %u",
	      tc->rcv_opts.tsecr, tc->tsecr_last_ack,
	      tcp_time_now () - tc->tsval_recent_age);
  s = format (s, " snd_mss %u\n", tc->snd_mss);
  s = format (s, " rto %u rto_boff %u srtt %u us %.3f rttvar %u rtt_ts %.4f",
	      tc->rto, tc->rto_boff, tc->srtt, tc->mrtt_us * 1000, tc->rttvar,
	      tc->rtt_ts);
  s = format (s, " rtt_seq %u\n", tc->rtt_seq - tc->iss);
  s = format (s, " cong:   %U", format_tcp_congestion, tc);

  if (tc->state >= TCP_STATE_ESTABLISHED)
    {
      s = format (s, " sboard: %U\n", format_tcp_scoreboard, &tc->sack_sb,
		  tc);
      s = format (s, " stats: %U\n", format_tcp_stats, tc);
    }
  if (vec_len (tc->snd_sacks))
    s = format (s, " sacks tx: %U\n", format_tcp_sacks, tc);

  return s;
}

static u8 *
format_tcp_connection_id (u8 * s, va_list * args)
{
  tcp_connection_t *tc = va_arg (*args, tcp_connection_t *);
  if (!tc)
    return s;
  if (tc->c_is_ip4)
    {
      s = format (s, "[%d:%d][%s] %U:%d->%U:%d", tc->c_thread_index,
		  tc->c_s_index, "T", format_ip4_address, &tc->c_lcl_ip4,
		  clib_net_to_host_u16 (tc->c_lcl_port), format_ip4_address,
		  &tc->c_rmt_ip4, clib_net_to_host_u16 (tc->c_rmt_port));
    }
  else
    {
      s = format (s, "[%d:%d][%s] %U:%d->%U:%d", tc->c_thread_index,
		  tc->c_s_index, "T", format_ip6_address, &tc->c_lcl_ip6,
		  clib_net_to_host_u16 (tc->c_lcl_port), format_ip6_address,
		  &tc->c_rmt_ip6, clib_net_to_host_u16 (tc->c_rmt_port));
    }

  return s;
}

u8 *
format_tcp_connection (u8 * s, va_list * args)
{
  tcp_connection_t *tc = va_arg (*args, tcp_connection_t *);
  u32 verbose = va_arg (*args, u32);

  if (!tc)
    return s;
  s = format (s, "%-50U", format_tcp_connection_id, tc);
  if (verbose)
    {
      s = format (s, "%-15U", format_tcp_state, tc->state);
      if (verbose > 1)
	s = format (s, "\n%U", format_tcp_vars, tc);
    }

  return s;
}

static u8 *
format_tcp_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);
  tcp_connection_t *tc;

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

static u8 *
format_tcp_listener_session (u8 * s, va_list * args)
{
  u32 tci = va_arg (*args, u32);
  u32 __clib_unused thread_index = va_arg (*args, u32);
  u32 verbose = va_arg (*args, u32);
  tcp_connection_t *tc = tcp_listener_get (tci);
  s = format (s, "%-50U", format_tcp_connection_id, tc);
  if (verbose)
    s = format (s, "%-15U", format_tcp_state, tc->state);
  return s;
}

static u8 *
format_tcp_half_open_session (u8 * s, va_list * args)
{
  u32 tci = va_arg (*args, u32);
  u32 __clib_unused thread_index = va_arg (*args, u32);
  tcp_connection_t *tc = tcp_half_open_connection_get (tci);
  return format (s, "%U", format_tcp_connection_id, tc);
}

u8 *
format_tcp_sacks (u8 * s, va_list * args)
{
  tcp_connection_t *tc = va_arg (*args, tcp_connection_t *);
  sack_block_t *sacks = tc->snd_sacks;
  sack_block_t *block;
  int i, len = 0;

  len = vec_len (sacks);
  for (i = 0; i < len - 1; i++)
    {
      block = &sacks[i];
      s = format (s, " start %u end %u\n", block->start - tc->irs,
		  block->end - tc->irs);
    }
  if (len)
    {
      block = &sacks[len - 1];
      s = format (s, " start %u end %u", block->start - tc->irs,
		  block->end - tc->irs);
    }
  return s;
}

u8 *
format_tcp_rcv_sacks (u8 * s, va_list * args)
{
  tcp_connection_t *tc = va_arg (*args, tcp_connection_t *);
  sack_block_t *sacks = tc->rcv_opts.sacks;
  sack_block_t *block;
  int i, len = 0;

  len = vec_len (sacks);
  for (i = 0; i < len - 1; i++)
    {
      block = &sacks[i];
      s = format (s, " start %u end %u\n", block->start - tc->iss,
		  block->end - tc->iss);
    }
  if (len)
    {
      block = &sacks[len - 1];
      s = format (s, " start %u end %u", block->start - tc->iss,
		  block->end - tc->iss);
    }
  return s;
}

static u8 *
format_tcp_sack_hole (u8 * s, va_list * args)
{
  sack_scoreboard_hole_t *hole = va_arg (*args, sack_scoreboard_hole_t *);
  tcp_connection_t *tc = va_arg (*args, tcp_connection_t *);
  if (tc)
    s = format (s, "  [%u, %u]", hole->start - tc->iss, hole->end - tc->iss);
  else
    s = format (s, "  [%u, %u]", hole->start, hole->end);
  return s;
}

u8 *
format_tcp_scoreboard (u8 * s, va_list * args)
{
  sack_scoreboard_t *sb = va_arg (*args, sack_scoreboard_t *);
  tcp_connection_t *tc = va_arg (*args, tcp_connection_t *);
  sack_scoreboard_hole_t *hole;
  u32 indent = format_get_indent (s);

  s = format (s, "sacked %u last_sacked %u lost %u last_lost %u"
	      " rxt_sacked %u\n",
	      sb->sacked_bytes, sb->last_sacked_bytes, sb->lost_bytes,
	      sb->last_lost_bytes, sb->rxt_sacked);
  s = format (s, "%Ulast_delivered %u high_sacked %u is_reneging %u\n",
	      format_white_space, indent, sb->last_bytes_delivered,
	      sb->high_sacked - tc->iss, sb->is_reneging);
  s = format (s, "%Ucur_rxt_hole %u high_rxt %u rescue_rxt %u",
	      format_white_space, indent, sb->cur_rxt_hole,
	      sb->high_rxt - tc->iss, sb->rescue_rxt - tc->iss);

  hole = scoreboard_first_hole (sb);
  if (hole)
    s = format (s, "\n%Uhead %u tail %u %u holes:\n%U", format_white_space,
		indent, sb->head, sb->tail, pool_elts (sb->holes),
		format_white_space, indent);

  while (hole)
    {
      s = format (s, "%U", format_tcp_sack_hole, hole, tc);
      hole = scoreboard_next_hole (sb, hole);
    }

  return s;
}

static transport_connection_t *
tcp_session_get_transport (u32 conn_index, u32 thread_index)
{
  tcp_connection_t *tc = tcp_connection_get (conn_index, thread_index);
  if (PREDICT_FALSE (!tc))
    return 0;
  return &tc->connection;
}

static transport_connection_t *
tcp_half_open_session_get_transport (u32 conn_index)
{
  tcp_connection_t *tc = tcp_half_open_connection_get (conn_index);
  return &tc->connection;
}

static u16
tcp_session_cal_goal_size (tcp_connection_t * tc)
{
  u16 goal_size = tc->snd_mss;

  goal_size = TCP_MAX_GSO_SZ - tc->snd_mss % TCP_MAX_GSO_SZ;
  goal_size = clib_min (goal_size, tc->snd_wnd / 2);

  return goal_size > tc->snd_mss ? goal_size : tc->snd_mss;
}

/**
 * Compute maximum segment size for session layer.
 *
 * Since the result needs to be the actual data length, it first computes
 * the tcp options to be used in the next burst and subtracts their
 * length from the connection's snd_mss.
 */
static u16
tcp_session_send_mss (transport_connection_t * trans_conn)
{
  tcp_connection_t *tc = (tcp_connection_t *) trans_conn;

  /* Ensure snd_mss does accurately reflect the amount of data we can push
   * in a segment. This also makes sure that options are updated according to
   * the current state of the connection. */
  tcp_update_burst_snd_vars (tc);

  if (PREDICT_FALSE (tc->cfg_flags & TCP_CFG_F_TSO))
    return tcp_session_cal_goal_size (tc);

  return tc->snd_mss;
}

always_inline u32
tcp_round_snd_space (tcp_connection_t * tc, u32 snd_space)
{
  if (PREDICT_FALSE (tc->snd_wnd < tc->snd_mss))
    {
      return tc->snd_wnd <= snd_space ? tc->snd_wnd : 0;
    }

  /* If not snd_wnd constrained and we can't write at least a segment,
   * don't try at all */
  if (PREDICT_FALSE (snd_space < tc->snd_mss))
    return snd_space < tc->cwnd ? 0 : snd_space;

  /* round down to mss multiple */
  return snd_space - (snd_space % tc->snd_mss);
}

/**
 * Compute tx window session is allowed to fill.
 *
 * Takes into account available send space, snd_mss and the congestion
 * state of the connection. If possible, the value returned is a multiple
 * of snd_mss.
 *
 * @param tc tcp connection
 * @return number of bytes session is allowed to write
 */
static inline u32
tcp_snd_space_inline (tcp_connection_t * tc)
{
  int snd_space;

  if (PREDICT_FALSE (tcp_in_fastrecovery (tc)
		     || tc->state == TCP_STATE_CLOSED))
    return 0;

  snd_space = tcp_available_output_snd_space (tc);

  /* If we got dupacks or sacked bytes but we're not yet in recovery, try
   * to force the peer to send enough dupacks to start retransmitting as
   * per Limited Transmit (RFC3042)
   */
  if (PREDICT_FALSE (tc->rcv_dupacks != 0 || tc->sack_sb.sacked_bytes))
    {
      if (tc->limited_transmit != tc->snd_nxt
	  && (seq_lt (tc->limited_transmit, tc->snd_nxt - 2 * tc->snd_mss)
	      || seq_gt (tc->limited_transmit, tc->snd_nxt)))
	tc->limited_transmit = tc->snd_nxt;

      ASSERT (seq_leq (tc->limited_transmit, tc->snd_nxt));

      int snt_limited = tc->snd_nxt - tc->limited_transmit;
      snd_space = clib_max ((int) 2 * tc->snd_mss - snt_limited, 0);
    }
  return tcp_round_snd_space (tc, snd_space);
}

u32
tcp_snd_space (tcp_connection_t * tc)
{
  return tcp_snd_space_inline (tc);
}

static u32
tcp_session_send_space (transport_connection_t * trans_conn)
{
  tcp_connection_t *tc = (tcp_connection_t *) trans_conn;
  return clib_min (tcp_snd_space_inline (tc),
		   tc->snd_wnd - (tc->snd_nxt - tc->snd_una));
}

static u32
tcp_session_tx_fifo_offset (transport_connection_t * trans_conn)
{
  tcp_connection_t *tc = (tcp_connection_t *) trans_conn;

  ASSERT (seq_geq (tc->snd_nxt, tc->snd_una));

  /* This still works if fast retransmit is on */
  return (tc->snd_nxt - tc->snd_una);
}

static void
tcp_update_time (f64 now, u8 thread_index)
{
  tcp_worker_ctx_t *wrk = tcp_get_worker (thread_index);

  tcp_set_time_now (wrk);
  tw_timer_expire_timers_16t_2w_512sl (&wrk->timer_wheel, now);
  tcp_flush_frames_to_output (wrk);
}

static void
tcp_session_flush_data (transport_connection_t * tconn)
{
  tcp_connection_t *tc = (tcp_connection_t *) tconn;
  if (tc->flags & TCP_CONN_PSH_PENDING)
    return;
  tc->flags |= TCP_CONN_PSH_PENDING;
  tc->psh_seq = tc->snd_una + transport_max_tx_dequeue (tconn) - 1;
}

/* *INDENT-OFF* */
const static transport_proto_vft_t tcp_proto = {
  .enable = vnet_tcp_enable_disable,
  .start_listen = tcp_session_bind,
  .stop_listen = tcp_session_unbind,
  .push_header = tcp_session_push_header,
  .get_connection = tcp_session_get_transport,
  .get_listener = tcp_session_get_listener,
  .get_half_open = tcp_half_open_session_get_transport,
  .connect = tcp_session_open,
  .close = tcp_session_close,
  .cleanup = tcp_session_cleanup,
  .reset = tcp_session_reset,
  .send_mss = tcp_session_send_mss,
  .send_space = tcp_session_send_space,
  .update_time = tcp_update_time,
  .tx_fifo_offset = tcp_session_tx_fifo_offset,
  .flush_data = tcp_session_flush_data,
  .custom_tx = tcp_session_custom_tx,
  .format_connection = format_tcp_session,
  .format_listener = format_tcp_listener_session,
  .format_half_open = format_tcp_half_open_session,
  .transport_options = {
    .tx_type = TRANSPORT_TX_PEEK,
    .service_type = TRANSPORT_SERVICE_VC,
  },
};
/* *INDENT-ON* */

void
tcp_connection_tx_pacer_update (tcp_connection_t * tc)
{
  if (!transport_connection_is_tx_paced (&tc->connection))
    return;

  transport_connection_tx_pacer_update (&tc->connection,
					tcp_cc_get_pacing_rate (tc));
}

void
tcp_connection_tx_pacer_reset (tcp_connection_t * tc, u32 window,
			       u32 start_bucket)
{
  tcp_worker_ctx_t *wrk = tcp_get_worker (tc->c_thread_index);
  f64 srtt = clib_min ((f64) tc->srtt * TCP_TICK, tc->mrtt_us);
  u64 last_time = wrk->vm->clib_time.last_cpu_time;
  transport_connection_tx_pacer_reset (&tc->connection, window / srtt,
				       start_bucket, last_time);
}

static void
tcp_timer_waitclose_handler (u32 conn_index)
{
  u32 thread_index = vlib_get_thread_index ();
  tcp_connection_t *tc;

  tc = tcp_connection_get (conn_index, thread_index);
  if (!tc)
    return;

  tc->timers[TCP_TIMER_WAITCLOSE] = TCP_TIMER_HANDLE_INVALID;

  switch (tc->state)
    {
    case TCP_STATE_CLOSE_WAIT:
      tcp_connection_timers_reset (tc);
      session_transport_closed_notify (&tc->connection);

      if (!(tc->flags & TCP_CONN_FINPNDG))
	{
	  tcp_connection_set_state (tc, TCP_STATE_CLOSED);
	  tcp_timer_set (tc, TCP_TIMER_WAITCLOSE, tcp_cfg.cleanup_time);
	  break;
	}

      /* Session didn't come back with a close. Send FIN either way
       * and switch to LAST_ACK. */
      tcp_cong_recovery_off (tc);
      /* Make sure we don't try to send unsent data */
      tc->snd_nxt = tc->snd_una;
      tcp_send_fin (tc);
      tcp_connection_set_state (tc, TCP_STATE_LAST_ACK);

      /* Make sure we don't wait in LAST ACK forever */
      tcp_timer_set (tc, TCP_TIMER_WAITCLOSE, tcp_cfg.lastack_time);

      /* Don't delete the connection yet */
      break;
    case TCP_STATE_FIN_WAIT_1:
      tcp_connection_timers_reset (tc);
      session_transport_closed_notify (&tc->connection);
      if (tc->flags & TCP_CONN_FINPNDG)
	{
	  /* If FIN pending, we haven't sent everything, but we did try.
	   * Notify session layer that transport is closed. */
	  tcp_connection_set_state (tc, TCP_STATE_CLOSED);
	  tcp_send_reset (tc);
	  tcp_timer_set (tc, TCP_TIMER_WAITCLOSE, tcp_cfg.cleanup_time);
	}
      else
	{
	  /* We've sent the fin but no progress. Close the connection and
	   * to make sure everything is flushed, setup a cleanup timer */
	  tcp_connection_set_state (tc, TCP_STATE_CLOSED);
	  tcp_timer_set (tc, TCP_TIMER_WAITCLOSE, tcp_cfg.cleanup_time);
	}
      break;
    case TCP_STATE_LAST_ACK:
    case TCP_STATE_CLOSING:
      tcp_connection_timers_reset (tc);
      tcp_connection_set_state (tc, TCP_STATE_CLOSED);
      tcp_timer_set (tc, TCP_TIMER_WAITCLOSE, tcp_cfg.cleanup_time);
      session_transport_closed_notify (&tc->connection);
      break;
    default:
      tcp_connection_del (tc);
      break;
    }
}

/* *INDENT-OFF* */
static timer_expiration_handler *timer_expiration_handlers[TCP_N_TIMERS] =
{
    tcp_timer_retransmit_handler,
    tcp_timer_delack_handler,
    tcp_timer_persist_handler,
    tcp_timer_waitclose_handler,
    tcp_timer_retransmit_syn_handler,
};
/* *INDENT-ON* */

static void
tcp_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;

      TCP_EVT (TCP_EVT_TIMER_POP, connection_index, timer_id);

      /* Handle expiration */
      (*timer_expiration_handlers[timer_id]) (connection_index);
    }
}

static void
tcp_initialize_timer_wheels (tcp_main_t * tm)
{
  tw_timer_wheel_16t_2w_512sl_t *tw;
  /* *INDENT-OFF* */
  foreach_vlib_main (({
    tw = &tm->wrk_ctx[ii].timer_wheel;
    tw_timer_wheel_init_16t_2w_512sl (tw, tcp_expired_timers_dispatch,
                                      TCP_TIMER_TICK, ~0);
    tw->last_run_time = vlib_time_now (this_vlib_main);
  }));
  /* *INDENT-ON* */
}

static void
tcp_initialize_iss_seed (tcp_main_t * tm)
{
  u32 default_seed = random_default_seed ();
  u64 time_now = clib_cpu_time_now ();

  tm->iss_seed.first = (u64) random_u32 (&default_seed) << 32;
  tm->iss_seed.second = random_u64 (&time_now);
}

static clib_error_t *
tcp_main_enable (vlib_main_t * vm)
{
  vlib_thread_main_t *vtm = vlib_get_thread_main ();
  u32 num_threads, n_workers, prealloc_conn_per_wrk;
  tcp_connection_t *tc __attribute__ ((unused));
  tcp_main_t *tm = vnet_get_tcp_main ();
  clib_error_t *error = 0;
  int 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_TCP, tcp4_input_node.index);
  ip6_register_protocol (IP_PROTOCOL_TCP, tcp6_input_node.index);

  /*
   * Initialize data structures
   */

  num_threads = 1 /* main thread */  + vtm->n_threads;
  vec_validate (tm->connections, num_threads - 1);
  vec_validate (tm->wrk_ctx, num_threads - 1);
  n_workers = num_threads == 1 ? 1 : vtm->n_threads;
  prealloc_conn_per_wrk = tcp_cfg.preallocated_connections / n_workers;

  for (thread = 0; thread < num_threads; thread++)
    {
      vec_validate (tm->wrk_ctx[thread].pending_deq_acked, 255);
      vec_validate (tm->wrk_ctx[thread].pending_disconnects, 255);
      vec_reset_length (tm->wrk_ctx[thread].pending_deq_acked);
      vec_reset_length (tm->wrk_ctx[thread].pending_disconnects);
      tm->wrk_ctx[thread].vm = vlib_mains[thread];

      /*
       * Preallocate connections. Assume that thread 0 won't
       * use preallocated threads when running multi-core
       */
      if ((thread > 0 || num_threads == 1) && prealloc_conn_per_wrk)
	pool_init_fixed (tm->connections[thread], prealloc_conn_per_wrk);
    }

  /*
   * Use a preallocated half-open connection pool?
   */
  if (tcp_cfg.preallocated_half_open_connections)
    pool_init_fixed (tm->half_open_connections,
		     tcp_cfg.preallocated_half_open_connections);

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

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

  tcp_initialize_timer_wheels (tm);
  tcp_initialize_iss_seed (tm);

  tm->bytes_per_buffer = vlib_buffer_get_default_data_size (vm);
  tm->cc_last_type = TCP_CC_LAST;
  return error;
}

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

      return tcp_main_enable (vm);
    }
  else
    {
      tcp_main.is_enabled = 0;
    }

  return 0;
}

void
tcp_punt_unknown (vlib_main_t * vm, u8 is_ip4, u8 is_add)
{
  tcp_main_t *tm = &tcp_main;
  if (is_ip4)
    tm->punt_unknown4 = is_add;
  else
    tm->punt_unknown6 = is_add;
}

/**
 * Initialize default values for tcp parameters
 */
static void
tcp_configuration_init (void)
{
  /* Initial wnd for SYN. Fifos are not allocated at that point so use some
   * predefined value. For SYN-ACK we still want the scale to be computed in
   * the same way */
  tcp_cfg.max_rx_fifo = 32 << 20;
  tcp_cfg.min_rx_fifo = 4 << 10;

  tcp_cfg.default_mtu = 1500;
  tcp_cfg.initial_cwnd_multiplier = 0;
  tcp_cfg.enable_tx_pacing = 1;
  tcp_cfg.allow_tso = 0;
  tcp_cfg.cc_algo = TCP_CC_NEWRENO;
  tcp_cfg.rwnd_min_update_ack = 1;

  /* Time constants defined as timer tick (100ms) multiples */
  tcp_cfg.delack_time = 1;	/* 0.1s */
  tcp_cfg.closewait_time = 20;	/* 2s */
  tcp_cfg.timewait_time = 100;	/* 10s */
  tcp_cfg.finwait1_time = 600;	/* 60s */
  tcp_cfg.lastack_time = 300;	/* 30s */
  tcp_cfg.finwait2_time = 300;	/* 30s */
  tcp_cfg.closing_time = 300;	/* 30s */
  tcp_cfg.cleanup_time = 1;	/* 0.1s */
}

static clib_error_t *
tcp_init (vlib_main_t * vm)
{
  tcp_main_t *tm = vnet_get_tcp_main ();
  ip_main_t *im = &ip_main;
  ip_protocol_info_t *pi;

  /* Session layer, and by implication tcp, are disabled by default */
  tm->is_enabled = 0;

  /* Register with IP for header parsing */
  pi = ip_get_protocol_info (im, IP_PROTOCOL_TCP);
  if (pi == 0)
    return clib_error_return (0, "TCP protocol info AWOL");
  pi->format_header = format_tcp_header;
  pi->unformat_pg_edit = unformat_pg_tcp_header;

  /* Register as transport with session layer */
  transport_register_protocol (TRANSPORT_PROTO_TCP, &tcp_proto,
			       FIB_PROTOCOL_IP4, tcp4_output_node.index);
  transport_register_protocol (TRANSPORT_PROTO_TCP, &tcp_proto,
			       FIB_PROTOCOL_IP6, tcp6_output_node.index);

  tcp_api_reference ();
  tcp_configuration_init ();

  tm->cc_algo_by_name = hash_create_string (0, sizeof (uword));

  return 0;
}

VLIB_INIT_FUNCTION (tcp_init);

uword
unformat_tcp_cc_algo (unformat_input_t * input, va_list * va)
{
  tcp_cc_algorithm_type_e *result = va_arg (*va, tcp_cc_algorithm_type_e *);
  tcp_main_t *tm = &tcp_main;
  char *cc_algo_name;
  u8 found = 0;
  uword *p;

  if (unformat (input, "%s", &cc_algo_name)
      && ((p = hash_get_mem (tm->cc_algo_by_name, cc_algo_name))))
    {
      *result = *p;
      found = 1;
    }

  vec_free (cc_algo_name);
  return found;
}

uword
unformat_tcp_cc_algo_cfg (unformat_input_t * input, va_list * va)
{
  tcp_main_t *tm = vnet_get_tcp_main ();
  tcp_cc_algorithm_t *cc_alg;
  unformat_input_t sub_input;
  int found = 0;

  vec_foreach (cc_alg, tm->cc_algos)
  {
    if (!unformat (input, cc_alg->name))
      continue;

    if (cc_alg->unformat_cfg
	&& unformat (input, "%U", unformat_vlib_cli_sub_input, &sub_input))
      {
	if (cc_alg->unformat_cfg (&sub_input))
	  found = 1;
      }
  }
  return found;
}

static clib_error_t *
tcp_config_fn (vlib_main_t * vm, unformat_input_t * input)
{
  u32 cwnd_multiplier, tmp_time;
  uword memory_size;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "preallocated-connections %d",
		    &tcp_cfg.preallocated_connections))
	;
      else if (unformat (input, "preallocated-half-open-connections %d",
			 &tcp_cfg.preallocated_half_open_connections))
	;
      else if (unformat (input, "buffer-fail-fraction %f",
			 &tcp_cfg.buffer_fail_fraction))
	;
      else if (unformat (input, "max-rx-fifo %U", unformat_memory_size,
			 &memory_size))
	tcp_cfg.max_rx_fifo = memory_size;
      else if (unformat (input, "min-rx-fifo %U", unformat_memory_size,
			 &memory_size))
	tcp_cfg.min_rx_fifo = memory_size;
      else if (unformat (input, "mtu %u", &tcp_cfg.default_mtu))
	;
      else if (unformat (input, "rwnd-min-update-ack %d",
			 &tcp_cfg.rwnd_min_update_ack))
	;
      else if (unformat (input, "initial-cwnd-multiplier %u",
			 &cwnd_multiplier))
	tcp_cfg.initial_cwnd_multiplier = cwnd_multiplier;
      else if (unformat (input, "no-tx-pacing"))
	tcp_cfg.enable_tx_pacing = 0;
      else if (unformat (input, "tso"))
	tcp_cfg.allow_tso = 1;
      else if (unformat (input, "cc-algo %U", unformat_tcp_cc_algo,
			 &tcp_cfg.cc_algo))
	;
      else if (unformat (input, "%U", unformat_tcp_cc_algo_cfg))
	;
      else if (unformat (input, "closewait-time %u", &tmp_time))
	tcp_cfg.closewait_time = tmp_time / TCP_TIMER_TICK;
      else if (unformat (input, "timewait-time %u", &tmp_time))
	tcp_cfg.timewait_time = tmp_time / TCP_TIMER_TICK;
      else if (unformat (input, "finwait1-time %u", &tmp_time))
	tcp_cfg.finwait1_time = tmp_time / TCP_TIMER_TICK;
      else if (unformat (input, "finwait2-time %u", &tmp_time))
	tcp_cfg.finwait2_time = tmp_time / TCP_TIMER_TICK;
      else if (unformat (input, "lastack-time %u", &tmp_time))
	tcp_cfg.lastack_time = tmp_time / TCP_TIMER_TICK;
      else if (unformat (input, "closing-time %u", &tmp_time))
	tcp_cfg.closing_time = tmp_time / TCP_TIMER_TICK;
      else if (unformat (input, "cleanup-time %u", &tmp_time))
	tcp_cfg.cleanup_time = tmp_time / TCP_TIMER_TICK;
      else
	return clib_error_return (0, "unknown input `%U'",
				  format_unformat_error, input);
    }
  return 0;
}

VLIB_CONFIG_FUNCTION (tcp_config_fn, "tcp");


/**
 * \brief Configure an ipv4 source address range
 * @param vm vlib_main_t pointer
 * @param start first ipv4 address in the source address range
 * @param end last ipv4 address in the source address range
 * @param table_id VRF / table ID, 0 for the default FIB
 * @return 0 if all OK, else an error indication from api_errno.h
 */

int
tcp_configure_v4_source_address_range (vlib_main_t * vm,
				       ip4_address_t * start,
				       ip4_address_t * end, u32 table_id)
{
  vnet_main_t *vnm = vnet_get_main ();
  u32 start_host_byte_order, end_host_byte_order;
  fib_prefix_t prefix;
  fib_node_index_t fei;
  u32 fib_index = 0;
  u32 sw_if_index;
  int rv;

  clib_memset (&prefix, 0, sizeof (prefix));

  fib_index = fib_table_find (FIB_PROTOCOL_IP4, table_id);

  if (fib_index == ~0)
    return VNET_API_ERROR_NO_SUCH_FIB;

  start_host_byte_order = clib_net_to_host_u32 (start->as_u32);
  end_host_byte_order = clib_net_to_host_u32 (end->as_u32);

  /* sanity check for reversed args or some such */
  if ((end_host_byte_order - start_host_byte_order) > (10 << 10))
    return VNET_API_ERROR_INVALID_ARGUMENT;

  /* Lookup the last address, to identify the interface involved */
  prefix.fp_len = 32;
  prefix.fp_proto = FIB_PROTOCOL_IP4;
  memcpy (&prefix.fp_addr.ip4, end, sizeof (ip4_address_t));

  fei = fib_table_lookup (fib_index, &prefix);

  /* Couldn't find route to destination. Bail out. */
  if (fei == FIB_NODE_INDEX_INVALID)
    return VNET_API_ERROR_NEXT_HOP_NOT_IN_FIB;

  sw_if_index = fib_entry_get_resolving_interface (fei);

  /* Configure proxy arp across the range */
  rv = vnet_proxy_arp_add_del (start, end, fib_index, 0 /* is_del */ );

  if (rv)
    return rv;

  rv = vnet_proxy_arp_enable_disable (vnm, sw_if_index, 1);

  if (rv)
    return rv;

  do
    {
      dpo_id_t dpo = DPO_INVALID;

      vec_add1 (tcp_cfg.ip4_src_addrs, start[0]);

      /* Add local adjacencies for the range */

      receive_dpo_add_or_lock (DPO_PROTO_IP4, ~0 /* sw_if_index */ ,
			       NULL, &dpo);
      prefix.fp_len = 32;
      prefix.fp_proto = FIB_PROTOCOL_IP4;
      prefix.fp_addr.ip4.as_u32 = start->as_u32;

      fib_table_entry_special_dpo_update (fib_index,
					  &prefix,
					  FIB_SOURCE_API,
					  FIB_ENTRY_FLAG_EXCLUSIVE, &dpo);
      dpo_reset (&dpo);

      start_host_byte_order++;
      start->as_u32 = clib_host_to_net_u32 (start_host_byte_order);
    }
  while (start_host_byte_order <= end_host_byte_order);

  return 0;
}

/**
 * \brief Configure an ipv6 source address range
 * @param vm vlib_main_t pointer
 * @param start first ipv6 address in the source address range
 * @param end last ipv6 address in the source address range
 * @param table_id VRF / table ID, 0 for the default FIB
 * @return 0 if all OK, else an error indication from api_errno.h
 */

int
tcp_configure_v6_source_address_range (vlib_main_t * vm,
				       ip6_address_t * start,
				       ip6_address_t * end, u32 table_id)
{
  fib_prefix_t prefix;
  u32 fib_index = 0;
  fib_node_index_t fei;
  u32 sw_if_index;

  clib_memset (&prefix, 0, sizeof (prefix));

  fib_index = fib_table_find (FIB_PROTOCOL_IP6, table_id);

  if (fib_index == ~0)
    return VNET_API_ERROR_NO_SUCH_FIB;

  while (1)
    {
      int i;
      ip6_address_t tmp;
      dpo_id_t dpo = DPO_INVALID;

      /* Remember this address */
      vec_add1 (tcp_cfg.ip6_src_addrs, start[0]);

      /* Lookup the prefix, to identify the interface involved */
      prefix.fp_len = 128;
      prefix.fp_proto = FIB_PROTOCOL_IP6;
      memcpy (&prefix.fp_addr.ip6, start, sizeof (ip6_address_t));

      fei = fib_table_lookup (fib_index, &prefix);

      /* Couldn't find route to destination. Bail out. */
      if (fei == FIB_NODE_INDEX_INVALID)
	return VNET_API_ERROR_NEXT_HOP_NOT_IN_FIB;

      sw_if_index = fib_entry_get_resolving_interface (fei);

      if (sw_if_index == (u32) ~ 0)
	return VNET_API_ERROR_NO_MATCHING_INTERFACE;

      /* Add a proxy neighbor discovery entry for this address */
      ip6_neighbor_proxy_add_del (sw_if_index, start, 0 /* is_del */ );

      /* Add a receive adjacency for this address */
      receive_dpo_add_or_lock (DPO_PROTO_IP6, ~0 /* sw_if_index */ ,
			       NULL, &dpo);

      fib_table_entry_special_dpo_update (fib_index,
					  &prefix,
					  FIB_SOURCE_API,
					  FIB_ENTRY_FLAG_EXCLUSIVE, &dpo);
      dpo_reset (&dpo);

      /* Done with the entire range? */
      if (!memcmp (start, end, sizeof (start[0])))
	break;

      /* Increment the address. DGMS. */
      tmp = start[0];
      for (i = 15; i >= 0; i--)
	{
	  tmp.as_u8[i] += 1;
	  if (tmp.as_u8[i] != 0)
	    break;
	}
      start[0] = tmp;
    }
  return 0;
}

static clib_error_t *
tcp_src_address (vlib_main_t * vm,
		 unformat_input_t * input, vlib_cli_command_t * cmd_arg)
{
  ip4_address_t v4start, v4end;
  ip6_address_t v6start, v6end;
  u32 table_id = 0;
  int v4set = 0;
  int v6set = 0;
  int rv;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "%U - %U", unformat_ip4_address, &v4start,
		    unformat_ip4_address, &v4end))
	v4set = 1;
      else if (unformat (input, "%U", unformat_ip4_address, &v4start))
	{
	  memcpy (&v4end, &v4start, sizeof (v4start));
	  v4set = 1;
	}
      else if (unformat (input, "%U - %U", unformat_ip6_address, &v6start,
			 unformat_ip6_address, &v6end))
	v6set = 1;
      else if (unformat (input, "%U", unformat_ip6_address, &v6start))
	{
	  memcpy (&v6end, &v6start, sizeof (v6start));
	  v6set = 1;
	}
      else if (unformat (input, "fib-table %d", &table_id))
	;
      else
	break;
    }

  if (!v4set && !v6set)
    return clib_error_return (0, "at least one v4 or v6 address required");

  if (v4set)
    {
      rv = tcp_configure_v4_source_address_range (vm, &v4start, &v4end,
						  table_id);
      switch (rv)
	{
	case 0:
	  break;

	case VNET_API_ERROR_NO_SUCH_FIB:
	  return clib_error_return (0, "Invalid table-id %d", table_id);

	case VNET_API_ERROR_INVALID_ARGUMENT:
	  return clib_error_return (0, "Invalid address range %U - %U",
				    format_ip4_address, &v4start,
				    format_ip4_address, &v4end);
	default:
	  return clib_error_return (0, "error %d", rv);
	  break;
	}
    }
  if (v6set)
    {
      rv = tcp_configure_v6_source_address_range (vm, &v6start, &v6end,
						  table_id);
      switch (rv)
	{
	case 0:
	  break;

	case VNET_API_ERROR_NO_SUCH_FIB:
	  return clib_error_return (0, "Invalid table-id %d", table_id);

	default:
	  return clib_error_return (0, "error %d", rv);
	  break;
	}
    }
  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (tcp_src_address_command, static) =
{
  .path = "tcp src-address",
  .short_help = "tcp src-address <ip-addr> [- <ip-addr>] add src address range",
  .function = tcp_src_address,
};
/* *INDENT-ON* */

static u8 *
tcp_scoreboard_dump_trace (u8 * s, sack_scoreboard_t * sb)
{
#if TCP_SCOREBOARD_TRACE

  scoreboard_trace_elt_t *block;
  int i = 0;

  if (!sb->trace)
    return s;

  s = format (s, "scoreboard trace:");
  vec_foreach (block, sb->trace)
  {
    s = format (s, "{%u, %u, %u, %u, %u}, ", block->start, block->end,
		block->ack, block->snd_una_max, block->group);
    if ((++i % 3) == 0)
      s = format (s, "\n");
  }
  return s;
#else
  return 0;
#endif
}

static clib_error_t *
tcp_show_scoreboard_trace_fn (vlib_main_t * vm, unformat_input_t * input,
			      vlib_cli_command_t * cmd_arg)
{
  transport_connection_t *tconn = 0;
  tcp_connection_t *tc;
  u8 *s = 0;
  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "%U", unformat_transport_connection, &tconn,
		    TRANSPORT_PROTO_TCP))
	;
      else
	return clib_error_return (0, "unknown input `%U'",
				  format_unformat_error, input);
    }

  if (!TCP_SCOREBOARD_TRACE)
    {
      vlib_cli_output (vm, "scoreboard tracing not enabled");
      return 0;
    }

  tc = tcp_get_connection_from_transport (tconn);
  s = tcp_scoreboard_dump_trace (s, &tc->sack_sb);
  vlib_cli_output (vm, "%v", s);
  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (tcp_show_scoreboard_trace_command, static) =
{
  .path = "show tcp scoreboard trace",
  .short_help = "show tcp scoreboard trace <connection>",
  .function = tcp_show_scoreboard_trace_fn,
};
/* *INDENT-ON* */

u8 *
tcp_scoreboard_replay (u8 * s, tcp_connection_t * tc, u8 verbose)
{
  int i, trace_len;
  scoreboard_trace_elt_t *trace;
  u32 next_ack, left, group, has_new_ack = 0;
  tcp_connection_t _dummy_tc, *dummy_tc = &_dummy_tc;
  sack_block_t *block;

  if (!TCP_SCOREBOARD_TRACE)
    {
      s = format (s, "scoreboard tracing not enabled");
      return s;
    }

  if (!tc)
    return s;

  clib_memset (dummy_tc, 0, sizeof (*dummy_tc));
  tcp_connection_timers_init (dummy_tc);
  scoreboard_init (&dummy_tc->sack_sb);
  dummy_tc->rcv_opts.flags |= TCP_OPTS_FLAG_SACK;

#if TCP_SCOREBOARD_TRACE
  trace = tc->sack_sb.trace;
  trace_len = vec_len (tc->sack_sb.trace);
#endif

  for (i = 0; i < trace_len; i++)
    {
      if (trace[i].ack != 0)
	{
	  dummy_tc->snd_una = trace[i].ack - 1448;
	  dummy_tc->snd_una_max = trace[i].ack;
	}
    }

  left = 0;
  while (left < trace_len)
    {
      group = trace[left].group;
      vec_reset_length (dummy_tc->rcv_opts.sacks);
      has_new_ack = 0;
      while (trace[left].group == group)
	{
	  if (trace[left].ack != 0)
	    {
	      if (verbose)
		s = format (s, "Adding ack %u, snd_una_max %u, segs: ",
			    trace[left].ack, trace[left].snd_una_max);
	      dummy_tc->snd_una_max = trace[left].snd_una_max;
	      next_ack = trace[left].ack;
	      has_new_ack = 1;
	    }
	  else
	    {
	      if (verbose)
		s = format (s, "[%u, %u], ", trace[left].start,
			    trace[left].end);
	      vec_add2 (dummy_tc->rcv_opts.sacks, block, 1);
	      block->start = trace[left].start;
	      block->end = trace[left].end;
	    }
	  left++;
	}

      /* Push segments */
      tcp_rcv_sacks (dummy_tc, next_ack);
      if (has_new_ack)
	dummy_tc->snd_una = next_ack;

      if (verbose)
	s = format (s, "result: %U", format_tcp_scoreboard,
		    &dummy_tc->sack_sb);

    }
  s = format (s, "result: %U", format_tcp_scoreboard, &dummy_tc->sack_sb);

  return s;
}

static clib_error_t *
tcp_scoreboard_trace_fn (vlib_main_t * vm, unformat_input_t * input,
			 vlib_cli_command_t * cmd_arg)
{
  transport_connection_t *tconn = 0;
  tcp_connection_t *tc = 0;
  u8 *str = 0;
  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "%U", unformat_transport_connection, &tconn,
		    TRANSPORT_PROTO_TCP))
	;
      else
	return clib_error_return (0, "unknown input `%U'",
				  format_unformat_error, input);
    }

  if (!TCP_SCOREBOARD_TRACE)
    {
      vlib_cli_output (vm, "scoreboard tracing not enabled");
      return 0;
    }

  tc = tcp_get_connection_from_transport (tconn);
  if (!tc)
    {
      vlib_cli_output (vm, "connection not found");
      return 0;
    }
  str = tcp_scoreboard_replay (str, tc, 1);
  vlib_cli_output (vm, "%v", str);
  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (tcp_replay_scoreboard_command, static) =
{
  .path = "tcp replay scoreboard",
  .short_help = "tcp replay scoreboard <connection>",
  .function = tcp_scoreboard_trace_fn,
};
/* *INDENT-ON* */

static clib_error_t *
show_tcp_punt_fn (vlib_main_t * vm, unformat_input_t * input,
		  vlib_cli_command_t * cmd_arg)
{
  tcp_main_t *tm = vnet_get_tcp_main ();
  if (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    return clib_error_return (0, "unknown input `%U'", format_unformat_error,
			      input);
  vlib_cli_output (vm, "IPv4 TCP punt: %s",
		   tm->punt_unknown4 ? "enabled" : "disabled");
  vlib_cli_output (vm, "IPv6 TCP punt: %s",
		   tm->punt_unknown6 ? "enabled" : "disabled");
  return 0;
}
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_tcp_punt_command, static) =
{
  .path = "show tcp punt",
  .short_help = "show tcp punt",
  .function = show_tcp_punt_fn,
};
/* *INDENT-ON* */

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