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

#include <vnet/tcp/tcp.h>
#include <vnet/tcp/tcp_inlines.h>
#include <math.h>
#include <vnet/ip/ip4_inlines.h>
#include <vnet/ip/ip6_inlines.h>

typedef enum _tcp_output_next
{
  TCP_OUTPUT_NEXT_DROP,
  TCP_OUTPUT_NEXT_IP_LOOKUP,
  TCP_OUTPUT_NEXT_IP_REWRITE,
  TCP_OUTPUT_NEXT_IP_ARP,
  TCP_OUTPUT_N_NEXT
} tcp_output_next_t;

#define foreach_tcp4_output_next              	\
  _ (DROP, "error-drop")                        \
  _ (IP_LOOKUP, "ip4-lookup")			\
  _ (IP_REWRITE, "ip4-rewrite")			\
  _ (IP_ARP, "ip4-arp")

#define foreach_tcp6_output_next              	\
  _ (DROP, "error-drop")                        \
  _ (IP_LOOKUP, "ip6-lookup")			\
  _ (IP_REWRITE, "ip6-rewrite")			\
  _ (IP_ARP, "ip6-discover-neighbor")

static char *tcp_error_strings[] = {
#define tcp_error(n,s) s,
#include <vnet/tcp/tcp_error.def>
#undef tcp_error
};

typedef struct
{
  tcp_header_t tcp_header;
  tcp_connection_t tcp_connection;
} tcp_tx_trace_t;

static u8 *
format_tcp_tx_trace (u8 * s, va_list * args)
{
  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
  tcp_tx_trace_t *t = va_arg (*args, tcp_tx_trace_t *);
  tcp_connection_t *tc = &t->tcp_connection;
  u32 indent = format_get_indent (s);

  s = format (s, "%U state %U\n%U%U", format_tcp_connection_id, tc,
	      format_tcp_state, tc->state, format_white_space, indent,
	      format_tcp_header, &t->tcp_header, 128);

  return s;
}

#ifndef CLIB_MARCH_VARIANT
static u8
tcp_window_compute_scale (u32 window)
{
  u8 wnd_scale = 0;
  while (wnd_scale < TCP_MAX_WND_SCALE && (window >> wnd_scale) > TCP_WND_MAX)
    wnd_scale++;
  return wnd_scale;
}

/**
 * TCP's initial window
 */
always_inline u32
tcp_initial_wnd_unscaled (tcp_connection_t * tc)
{
  /* RFC 6928 recommends the value lower. However at the time our connections
   * are initialized, fifos may not be allocated. Therefore, advertise the
   * smallest possible unscaled window size and update once fifos are
   * assigned to the session.
   */
  /*
     tcp_update_rcv_mss (tc);
     TCP_IW_N_SEGMENTS * tc->mss;
   */
  return tcp_cfg.min_rx_fifo;
}

/**
 * Compute initial window and scale factor. As per RFC1323, window field in
 * SYN and SYN-ACK segments is never scaled.
 */
u32
tcp_initial_window_to_advertise (tcp_connection_t * tc)
{
  /* Compute rcv wscale only if peer advertised support for it */
  if (tc->state != TCP_STATE_SYN_RCVD || tcp_opts_wscale (&tc->rcv_opts))
    tc->rcv_wscale = tcp_window_compute_scale (tcp_cfg.max_rx_fifo);

  tc->rcv_wnd = tcp_initial_wnd_unscaled (tc);

  return clib_min (tc->rcv_wnd, TCP_WND_MAX);
}

static inline void
tcp_update_rcv_wnd (tcp_connection_t * tc)
{
  u32 available_space, wnd;
  i32 observed_wnd;

  /*
   * Figure out how much space we have available
   */
  available_space = transport_max_rx_enqueue (&tc->connection);

  /*
   * Use the above and what we know about what we've previously advertised
   * to compute the new window
   */
  observed_wnd = (i32) tc->rcv_wnd - (tc->rcv_nxt - tc->rcv_las);

  /* Check if we are about to retract the window. Do the comparison before
   * rounding to avoid errors. Per RFC7323 sec. 2.4 we could remove this */
  if (PREDICT_FALSE ((i32) available_space < observed_wnd))
    {
      wnd = round_down_pow2 (clib_max (observed_wnd, 0), 1 << tc->rcv_wscale);
      TCP_EVT (TCP_EVT_RCV_WND_SHRUNK, tc, observed_wnd, available_space);
    }
  else
    {
      /* Make sure we have a multiple of 1 << rcv_wscale. We round down to
       * avoid advertising a window larger than what can be buffered */
      wnd = round_down_pow2 (available_space, 1 << tc->rcv_wscale);
    }

  if (PREDICT_FALSE (wnd < tc->rcv_opts.mss))
    wnd = 0;

  tc->rcv_wnd = clib_min (wnd, TCP_WND_MAX << tc->rcv_wscale);
}

/**
 * Compute and return window to advertise, scaled as per RFC1323
 */
static inline u32
tcp_window_to_advertise (tcp_connection_t * tc, tcp_state_t state)
{
  if (state < TCP_STATE_ESTABLISHED)
    return tcp_initial_window_to_advertise (tc);

  tcp_update_rcv_wnd (tc);
  return tc->rcv_wnd >> tc->rcv_wscale;
}

static int
tcp_make_syn_options (tcp_connection_t * tc, tcp_options_t * opts)
{
  u8 len = 0;

  opts->flags |= TCP_OPTS_FLAG_MSS;
  opts->mss = tc->mss;
  len += TCP_OPTION_LEN_MSS;

  opts->flags |= TCP_OPTS_FLAG_WSCALE;
  opts->wscale = tc->rcv_wscale;
  len += TCP_OPTION_LEN_WINDOW_SCALE;

  opts->flags |= TCP_OPTS_FLAG_TSTAMP;
  opts->tsval = tcp_time_tstamp (tc->c_thread_index);
  opts->tsecr = 0;
  len += TCP_OPTION_LEN_TIMESTAMP;

  if (TCP_USE_SACKS)
    {
      opts->flags |= TCP_OPTS_FLAG_SACK_PERMITTED;
      len += TCP_OPTION_LEN_SACK_PERMITTED;
    }

  /* Align to needed boundary */
  len += (TCP_OPTS_ALIGN - len % TCP_OPTS_ALIGN) % TCP_OPTS_ALIGN;
  return len;
}

static int
tcp_make_synack_options (tcp_connection_t * tc, tcp_options_t * opts)
{
  u8 len = 0;

  opts->flags |= TCP_OPTS_FLAG_MSS;
  opts->mss = tc->mss;
  len += TCP_OPTION_LEN_MSS;

  if (tcp_opts_wscale (&tc->rcv_opts))
    {
      opts->flags |= TCP_OPTS_FLAG_WSCALE;
      opts->wscale = tc->rcv_wscale;
      len += TCP_OPTION_LEN_WINDOW_SCALE;
    }

  if (tcp_opts_tstamp (&tc->rcv_opts))
    {
      opts->flags |= TCP_OPTS_FLAG_TSTAMP;
      opts->tsval = tcp_time_tstamp (tc->c_thread_index);
      opts->tsecr = tc->tsval_recent;
      len += TCP_OPTION_LEN_TIMESTAMP;
    }

  if (tcp_opts_sack_permitted (&tc->rcv_opts))
    {
      opts->flags |= TCP_OPTS_FLAG_SACK_PERMITTED;
      len += TCP_OPTION_LEN_SACK_PERMITTED;
    }

  /* Align to needed boundary */
  len += (TCP_OPTS_ALIGN - len % TCP_OPTS_ALIGN) % TCP_OPTS_ALIGN;
  return len;
}

static int
tcp_make_established_options (tcp_connection_t * tc, tcp_options_t * opts)
{
  u8 len = 0;

  opts->flags = 0;

  if (tcp_opts_tstamp (&tc->rcv_opts))
    {
      opts->flags |= TCP_OPTS_FLAG_TSTAMP;
      opts->tsval = tcp_tstamp (tc);
      opts->tsecr = tc->tsval_recent;
      len += TCP_OPTION_LEN_TIMESTAMP;
    }
  if (tcp_opts_sack_permitted (&tc->rcv_opts))
    {
      if (vec_len (tc->snd_sacks))
	{
	  opts->flags |= TCP_OPTS_FLAG_SACK;
	  if (tc->snd_sack_pos >= vec_len (tc->snd_sacks))
	    tc->snd_sack_pos = 0;
	  opts->sacks = &tc->snd_sacks[tc->snd_sack_pos];
	  opts->n_sack_blocks = vec_len (tc->snd_sacks) - tc->snd_sack_pos;
	  opts->n_sack_blocks = clib_min (opts->n_sack_blocks,
					  TCP_OPTS_MAX_SACK_BLOCKS);
	  tc->snd_sack_pos += opts->n_sack_blocks;
	  len += 2 + TCP_OPTION_LEN_SACK_BLOCK * opts->n_sack_blocks;
	}
    }

  /* Align to needed boundary */
  len += (TCP_OPTS_ALIGN - len % TCP_OPTS_ALIGN) % TCP_OPTS_ALIGN;
  return len;
}

always_inline int
tcp_make_options (tcp_connection_t * tc, tcp_options_t * opts,
		  tcp_state_t state)
{
  switch (state)
    {
    case TCP_STATE_ESTABLISHED:
    case TCP_STATE_CLOSE_WAIT:
    case TCP_STATE_FIN_WAIT_1:
    case TCP_STATE_LAST_ACK:
    case TCP_STATE_CLOSING:
    case TCP_STATE_FIN_WAIT_2:
    case TCP_STATE_TIME_WAIT:
    case TCP_STATE_CLOSED:
      return tcp_make_established_options (tc, opts);
    case TCP_STATE_SYN_RCVD:
      return tcp_make_synack_options (tc, opts);
    case TCP_STATE_SYN_SENT:
      return tcp_make_syn_options (tc, opts);
    default:
      clib_warning ("State not handled! %d", state);
      return 0;
    }
}

/**
 * Update burst send vars
 *
 * - Updates snd_mss to reflect the effective segment size that we can send
 * by taking into account all TCP options, including SACKs.
 * - Cache 'on the wire' options for reuse
 * - Updates receive window which can be reused for a burst.
 *
 * This should *only* be called when doing bursts
 */
void
tcp_update_burst_snd_vars (tcp_connection_t * tc)
{
  tcp_main_t *tm = &tcp_main;

  /* Compute options to be used for connection. These may be reused when
   * sending data or to compute the effective mss (snd_mss) */
  tc->snd_opts_len = tcp_make_options (tc, &tc->snd_opts,
				       TCP_STATE_ESTABLISHED);

  /* XXX check if MTU has been updated */
  tc->snd_mss = clib_min (tc->mss, tc->rcv_opts.mss) - tc->snd_opts_len;
  ASSERT (tc->snd_mss > 0);

  tcp_options_write (tm->wrk_ctx[tc->c_thread_index].cached_opts,
		     &tc->snd_opts);

  tcp_update_rcv_wnd (tc);

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

  if (tc->snd_una == tc->snd_nxt)
    {
      tcp_cc_event (tc, TCP_CC_EVT_START_TX);
      tcp_connection_tx_pacer_reset (tc, tc->cwnd, TRANSPORT_PACER_MIN_BURST);
    }

  if (tc->flags & TCP_CONN_PSH_PENDING)
    {
      u32 max_deq = transport_max_tx_dequeue (&tc->connection);
      /* Last byte marked for push */
      tc->psh_seq = tc->snd_una + max_deq - 1;
    }
}

#endif /* CLIB_MARCH_VARIANT */

static void *
tcp_reuse_buffer (vlib_main_t * vm, vlib_buffer_t * b)
{
  if (b->flags & VLIB_BUFFER_NEXT_PRESENT)
    vlib_buffer_free_one (vm, b->next_buffer);
  /* Zero all flags but free list index and trace flag */
  b->flags &= VLIB_BUFFER_NEXT_PRESENT - 1;
  b->current_data = 0;
  b->current_length = 0;
  b->total_length_not_including_first_buffer = 0;
  vnet_buffer (b)->tcp.flags = 0;
  VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b);
  /* Leave enough space for headers */
  return vlib_buffer_make_headroom (b, TRANSPORT_MAX_HDRS_LEN);
}

#ifndef CLIB_MARCH_VARIANT
static void *
tcp_init_buffer (vlib_main_t * vm, vlib_buffer_t * b)
{
  ASSERT ((b->flags & VLIB_BUFFER_NEXT_PRESENT) == 0);
  b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
  b->total_length_not_including_first_buffer = 0;
  b->current_data = 0;
  vnet_buffer (b)->tcp.flags = 0;
  /* Leave enough space for headers */
  return vlib_buffer_make_headroom (b, TRANSPORT_MAX_HDRS_LEN);
}


/* Compute TCP checksum in software when offloading is disabled for a connection */
u16
ip6_tcp_compute_checksum_custom (vlib_main_t * vm, vlib_buffer_t * p0,
				 ip46_address_t * src, ip46_address_t * dst)
{
  ip_csum_t sum0;
  u16 payload_length_host_byte_order;
  u32 i;

  /* Initialize checksum with ip header. */
  sum0 = clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, p0)) +
    clib_host_to_net_u16 (IP_PROTOCOL_TCP);
  payload_length_host_byte_order = vlib_buffer_length_in_chain (vm, p0);

  for (i = 0; i < ARRAY_LEN (src->ip6.as_uword); i++)
    {
      sum0 = ip_csum_with_carry
	(sum0, clib_mem_unaligned (&src->ip6.as_uword[i], uword));
      sum0 = ip_csum_with_carry
	(sum0, clib_mem_unaligned (&dst->ip6.as_uword[i], uword));
    }

  return ip_calculate_l4_checksum (vm, p0, sum0,
				   payload_length_host_byte_order, NULL, 0,
				   NULL);
}

u16
ip4_tcp_compute_checksum_custom (vlib_main_t * vm, vlib_buffer_t * p0,
				 ip46_address_t * src, ip46_address_t * dst)
{
  ip_csum_t sum0;
  u32 payload_length_host_byte_order;

  payload_length_host_byte_order = vlib_buffer_length_in_chain (vm, p0);
  sum0 =
    clib_host_to_net_u32 (payload_length_host_byte_order +
			  (IP_PROTOCOL_TCP << 16));

  sum0 = ip_csum_with_carry (sum0, clib_mem_unaligned (&src->ip4, u32));
  sum0 = ip_csum_with_carry (sum0, clib_mem_unaligned (&dst->ip4, u32));

  return ip_calculate_l4_checksum (vm, p0, sum0,
				   payload_length_host_byte_order, NULL, 0,
				   NULL);
}

static inline u16
tcp_compute_checksum (tcp_connection_t * tc, vlib_buffer_t * b)
{
  u16 checksum = 0;
  if (PREDICT_FALSE (tc->cfg_flags & TCP_CFG_F_NO_CSUM_OFFLOAD))
    {
      tcp_worker_ctx_t *wrk = tcp_get_worker (tc->c_thread_index);
      vlib_main_t *vm = wrk->vm;

      if (tc->c_is_ip4)
	checksum = ip4_tcp_compute_checksum_custom
	  (vm, b, &tc->c_lcl_ip, &tc->c_rmt_ip);
      else
	checksum = ip6_tcp_compute_checksum_custom
	  (vm, b, &tc->c_lcl_ip, &tc->c_rmt_ip);
    }
  else
    {
      vnet_buffer_offload_flags_set (b, VNET_BUFFER_OFFLOAD_F_TCP_CKSUM);
    }
  return checksum;
}

/**
 * Prepare ACK
 */
static inline void
tcp_make_ack_i (tcp_connection_t * tc, vlib_buffer_t * b, tcp_state_t state,
		u8 flags)
{
  tcp_options_t _snd_opts, *snd_opts = &_snd_opts;
  u8 tcp_opts_len, tcp_hdr_opts_len;
  tcp_header_t *th;
  u16 wnd;

  wnd = tcp_window_to_advertise (tc, state);

  /* Make and write options */
  tcp_opts_len = tcp_make_established_options (tc, snd_opts);
  tcp_hdr_opts_len = tcp_opts_len + sizeof (tcp_header_t);

  th = vlib_buffer_push_tcp (b, tc->c_lcl_port, tc->c_rmt_port, tc->snd_nxt,
			     tc->rcv_nxt, tcp_hdr_opts_len, flags, wnd);

  tcp_options_write ((u8 *) (th + 1), snd_opts);

  th->checksum = tcp_compute_checksum (tc, b);

  vnet_buffer (b)->tcp.connection_index = tc->c_c_index;

  if (wnd == 0)
    {
      transport_rx_fifo_req_deq_ntf (&tc->connection);
      tcp_zero_rwnd_sent_on (tc);
    }
  else
    tcp_zero_rwnd_sent_off (tc);
}

/**
 * Convert buffer to ACK
 */
static inline void
tcp_make_ack (tcp_connection_t * tc, vlib_buffer_t * b)
{
  tcp_make_ack_i (tc, b, TCP_STATE_ESTABLISHED, TCP_FLAG_ACK);
  TCP_EVT (TCP_EVT_ACK_SENT, tc);
  tc->rcv_las = tc->rcv_nxt;
}

/**
 * Convert buffer to FIN-ACK
 */
static void
tcp_make_fin (tcp_connection_t * tc, vlib_buffer_t * b)
{
  tcp_make_ack_i (tc, b, TCP_STATE_ESTABLISHED, TCP_FLAG_FIN | TCP_FLAG_ACK);
}

/**
 * Convert buffer to SYN
 */
void
tcp_make_syn (tcp_connection_t * tc, vlib_buffer_t * b)
{
  u8 tcp_hdr_opts_len, tcp_opts_len;
  tcp_header_t *th;
  u16 initial_wnd;
  tcp_options_t snd_opts;

  initial_wnd = tcp_initial_window_to_advertise (tc);

  /* Make and write options */
  clib_memset (&snd_opts, 0, sizeof (snd_opts));
  tcp_opts_len = tcp_make_syn_options (tc, &snd_opts);
  tcp_hdr_opts_len = tcp_opts_len + sizeof (tcp_header_t);

  th = vlib_buffer_push_tcp (b, tc->c_lcl_port, tc->c_rmt_port, tc->iss,
			     tc->rcv_nxt, tcp_hdr_opts_len, TCP_FLAG_SYN,
			     initial_wnd);
  vnet_buffer (b)->tcp.connection_index = tc->c_c_index;
  tcp_options_write ((u8 *) (th + 1), &snd_opts);
  th->checksum = tcp_compute_checksum (tc, b);
}

/**
 * Convert buffer to SYN-ACK
 */
static void
tcp_make_synack (tcp_connection_t * tc, vlib_buffer_t * b)
{
  tcp_options_t _snd_opts, *snd_opts = &_snd_opts;
  u8 tcp_opts_len, tcp_hdr_opts_len;
  tcp_header_t *th;
  u16 initial_wnd;

  clib_memset (snd_opts, 0, sizeof (*snd_opts));
  initial_wnd = tcp_initial_window_to_advertise (tc);
  tcp_opts_len = tcp_make_synack_options (tc, snd_opts);
  tcp_hdr_opts_len = tcp_opts_len + sizeof (tcp_header_t);

  th = vlib_buffer_push_tcp (b, tc->c_lcl_port, tc->c_rmt_port, tc->iss,
			     tc->rcv_nxt, tcp_hdr_opts_len,
			     TCP_FLAG_SYN | TCP_FLAG_ACK, initial_wnd);
  tcp_options_write ((u8 *) (th + 1), snd_opts);

  vnet_buffer (b)->tcp.connection_index = tc->c_c_index;
  th->checksum = tcp_compute_checksum (tc, b);
}

static void
tcp_enqueue_to_ip_lookup (tcp_worker_ctx_t * wrk, vlib_buffer_t * b, u32 bi,
			  u8 is_ip4, u32 fib_index)
{
  tcp_main_t *tm = &tcp_main;
  vlib_main_t *vm = wrk->vm;

  b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
  b->error = 0;

  vnet_buffer (b)->sw_if_index[VLIB_TX] = fib_index;
  vnet_buffer (b)->sw_if_index[VLIB_RX] = 0;

  session_add_pending_tx_buffer (vm->thread_index, bi,
				 tm->ipl_next_node[!is_ip4]);

  if (vm->thread_index == 0 && vlib_num_workers ())
    session_queue_run_on_main_thread (wrk->vm);
}

static void
tcp_enqueue_to_output (tcp_worker_ctx_t * wrk, vlib_buffer_t * b, u32 bi,
		       u8 is_ip4)
{
  b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
  b->error = 0;

  session_add_pending_tx_buffer (wrk->vm->thread_index, bi,
				 wrk->tco_next_node[!is_ip4]);
}

#endif /* CLIB_MARCH_VARIANT */

static int
tcp_make_reset_in_place (vlib_main_t * vm, vlib_buffer_t * b, u8 is_ip4)
{
  ip4_header_t *ih4;
  ip6_header_t *ih6;
  tcp_header_t *th;
  ip4_address_t src_ip4, dst_ip4;
  ip6_address_t src_ip6, dst_ip6;
  u16 src_port, dst_port;
  u32 tmp, len, seq, ack;
  u8 flags;

  /* Find IP and TCP headers */
  th = tcp_buffer_hdr (b);

  /* Save src and dst ip */
  if (is_ip4)
    {
      ih4 = vlib_buffer_get_current (b);
      ASSERT ((ih4->ip_version_and_header_length & 0xF0) == 0x40);
      src_ip4.as_u32 = ih4->src_address.as_u32;
      dst_ip4.as_u32 = ih4->dst_address.as_u32;
    }
  else
    {
      ih6 = vlib_buffer_get_current (b);
      ASSERT ((ih6->ip_version_traffic_class_and_flow_label & 0xF0) == 0x60);
      clib_memcpy_fast (&src_ip6, &ih6->src_address, sizeof (ip6_address_t));
      clib_memcpy_fast (&dst_ip6, &ih6->dst_address, sizeof (ip6_address_t));
    }

  src_port = th->src_port;
  dst_port = th->dst_port;
  flags = TCP_FLAG_RST;

  /*
   * RFC 793. If the ACK bit is off, sequence number zero is used,
   *   <SEQ=0><ACK=SEG.SEQ+SEG.LEN><CTL=RST,ACK>
   * If the ACK bit is on,
   *   <SEQ=SEG.ACK><CTL=RST>
   */
  if (tcp_ack (th))
    {
      seq = th->ack_number;
      ack = 0;
    }
  else
    {
      flags |= TCP_FLAG_ACK;
      tmp = clib_net_to_host_u32 (th->seq_number);
      len = vnet_buffer (b)->tcp.data_len + tcp_is_syn (th) + tcp_is_fin (th);
      ack = clib_host_to_net_u32 (tmp + len);
      seq = 0;
    }

  tcp_reuse_buffer (vm, b);
  th = vlib_buffer_push_tcp_net_order (b, dst_port, src_port, seq, ack,
				       sizeof (tcp_header_t), flags, 0);

  if (is_ip4)
    {
      ih4 = vlib_buffer_push_ip4 (vm, b, &dst_ip4, &src_ip4,
				  IP_PROTOCOL_TCP, 1);
      th->checksum = ip4_tcp_udp_compute_checksum (vm, b, ih4);
    }
  else
    {
      int bogus = ~0;
      ih6 = vlib_buffer_push_ip6 (vm, b, &dst_ip6, &src_ip6, IP_PROTOCOL_TCP);
      th->checksum = ip6_tcp_udp_icmp_compute_checksum (vm, b, ih6, &bogus);
      ASSERT (!bogus);
    }

  return 0;
}

#ifndef CLIB_MARCH_VARIANT
/**
 *  Send reset without reusing existing buffer
 *
 *  It extracts connection info out of original packet
 */
void
tcp_send_reset_w_pkt (tcp_connection_t * tc, vlib_buffer_t * pkt,
		      u32 thread_index, u8 is_ip4)
{
  tcp_worker_ctx_t *wrk = tcp_get_worker (thread_index);
  vlib_main_t *vm = wrk->vm;
  vlib_buffer_t *b;
  u32 bi, sw_if_index, fib_index;
  u8 tcp_hdr_len, flags = 0;
  tcp_header_t *th, *pkt_th;
  u32 seq, ack;
  ip4_header_t *ih4, *pkt_ih4;
  ip6_header_t *ih6, *pkt_ih6;
  fib_protocol_t fib_proto;

  if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
    {
      tcp_worker_stats_inc (wrk, no_buffer, 1);
      return;
    }

  b = vlib_get_buffer (vm, bi);
  sw_if_index = vnet_buffer (pkt)->sw_if_index[VLIB_RX];
  fib_proto = is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6;
  fib_index = fib_table_get_index_for_sw_if_index (fib_proto, sw_if_index);
  tcp_init_buffer (vm, b);

  /* Make and write options */
  tcp_hdr_len = sizeof (tcp_header_t);

  if (is_ip4)
    {
      pkt_ih4 = vlib_buffer_get_current (pkt);
      pkt_th = ip4_next_header (pkt_ih4);
    }
  else
    {
      pkt_ih6 = vlib_buffer_get_current (pkt);
      pkt_th = ip6_next_header (pkt_ih6);
    }

  if (tcp_ack (pkt_th))
    {
      flags = TCP_FLAG_RST;
      seq = pkt_th->ack_number;
      ack = (tc->state >= TCP_STATE_SYN_RCVD) ? tc->rcv_nxt : 0;
    }
  else
    {
      flags = TCP_FLAG_RST | TCP_FLAG_ACK;
      seq = 0;
      ack = clib_host_to_net_u32 (vnet_buffer (pkt)->tcp.seq_end);
    }

  th = vlib_buffer_push_tcp_net_order (b, pkt_th->dst_port, pkt_th->src_port,
				       seq, ack, tcp_hdr_len, flags, 0);

  /* Swap src and dst ip */
  if (is_ip4)
    {
      ASSERT ((pkt_ih4->ip_version_and_header_length & 0xF0) == 0x40);
      ih4 = vlib_buffer_push_ip4 (vm, b, &pkt_ih4->dst_address,
				  &pkt_ih4->src_address, IP_PROTOCOL_TCP,
				  tcp_csum_offload (tc));
      th->checksum = ip4_tcp_udp_compute_checksum (vm, b, ih4);
    }
  else
    {
      int bogus = ~0;
      ASSERT ((pkt_ih6->ip_version_traffic_class_and_flow_label & 0xF0) ==
	      0x60);
      ih6 = vlib_buffer_push_ip6_custom (vm, b, &pkt_ih6->dst_address,
					 &pkt_ih6->src_address,
					 IP_PROTOCOL_TCP,
					 tc->ipv6_flow_label);
      th->checksum = ip6_tcp_udp_icmp_compute_checksum (vm, b, ih6, &bogus);
      ASSERT (!bogus);
    }

  tcp_enqueue_to_ip_lookup (wrk, b, bi, is_ip4, fib_index);
  TCP_EVT (TCP_EVT_RST_SENT, tc);
  vlib_node_increment_counter (vm, tcp_node_index (output, tc->c_is_ip4),
			       TCP_ERROR_RST_SENT, 1);
}

/**
 * Build and set reset packet for connection
 */
void
tcp_send_reset (tcp_connection_t * tc)
{
  tcp_worker_ctx_t *wrk = tcp_get_worker (tc->c_thread_index);
  vlib_main_t *vm = wrk->vm;
  vlib_buffer_t *b;
  u32 bi;
  tcp_header_t *th;
  u16 tcp_hdr_opts_len, advertise_wnd, opts_write_len;
  u8 flags;

  if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
    {
      tcp_worker_stats_inc (wrk, no_buffer, 1);
      return;
    }
  b = vlib_get_buffer (vm, bi);
  tcp_init_buffer (vm, b);

  tc->snd_opts_len = tcp_make_options (tc, &tc->snd_opts, tc->state);
  tcp_hdr_opts_len = tc->snd_opts_len + sizeof (tcp_header_t);
  advertise_wnd = tc->rcv_wnd >> tc->rcv_wscale;
  flags = TCP_FLAG_RST;
  th = vlib_buffer_push_tcp (b, tc->c_lcl_port, tc->c_rmt_port, tc->snd_nxt,
			     tc->rcv_nxt, tcp_hdr_opts_len, flags,
			     advertise_wnd);
  opts_write_len = tcp_options_write ((u8 *) (th + 1), &tc->snd_opts);
  th->checksum = tcp_compute_checksum (tc, b);
  ASSERT (opts_write_len == tc->snd_opts_len);
  vnet_buffer (b)->tcp.connection_index = tc->c_c_index;
  tcp_enqueue_to_output (wrk, b, bi, tc->c_is_ip4);
  TCP_EVT (TCP_EVT_RST_SENT, tc);
  vlib_node_increment_counter (vm, tcp_node_index (output, tc->c_is_ip4),
			       TCP_ERROR_RST_SENT, 1);
}

static void
tcp_push_ip_hdr (tcp_worker_ctx_t * wrk, tcp_connection_t * tc,
		 vlib_buffer_t * b)
{
  if (tc->c_is_ip4)
    {
      vlib_buffer_push_ip4 (wrk->vm, b, &tc->c_lcl_ip4, &tc->c_rmt_ip4,
			    IP_PROTOCOL_TCP, tcp_csum_offload (tc));
    }
  else
    {
      vlib_buffer_push_ip6_custom (wrk->vm, b, &tc->c_lcl_ip6, &tc->c_rmt_ip6,
				   IP_PROTOCOL_TCP, tc->ipv6_flow_label);
    }
}

/**
 *  Send SYN
 *
 *  Builds a SYN packet for a half-open connection and sends it to ipx_lookup.
 *  The packet is not forwarded through tcpx_output to avoid doing lookups
 *  in the half_open pool.
 */
void
tcp_send_syn (tcp_connection_t * tc)
{
  tcp_worker_ctx_t *wrk = tcp_get_worker (tc->c_thread_index);
  vlib_main_t *vm = wrk->vm;
  vlib_buffer_t *b;
  u32 bi;

  /*
   * Setup retransmit and establish timers before requesting buffer
   * such that we can return if we've ran out.
   */
  tcp_timer_update (&wrk->timer_wheel, tc, TCP_TIMER_RETRANSMIT_SYN,
		    tc->rto * TCP_TO_TIMER_TICK);

  if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
    {
      tcp_timer_update (&wrk->timer_wheel, tc, TCP_TIMER_RETRANSMIT_SYN, 1);
      tcp_worker_stats_inc (wrk, no_buffer, 1);
      return;
    }

  b = vlib_get_buffer (vm, bi);
  tcp_init_buffer (vm, b);
  tcp_make_syn (tc, b);

  /* Measure RTT with this */
  tc->rtt_ts = tcp_time_now_us (vlib_num_workers ()? 1 : 0);
  tc->rtt_seq = tc->snd_nxt;
  tc->rto_boff = 0;

  tcp_push_ip_hdr (wrk, tc, b);
  tcp_enqueue_to_ip_lookup (wrk, b, bi, tc->c_is_ip4, tc->c_fib_index);
  TCP_EVT (TCP_EVT_SYN_SENT, tc);
}

void
tcp_send_synack (tcp_connection_t * tc)
{
  tcp_worker_ctx_t *wrk = tcp_get_worker (tc->c_thread_index);
  vlib_main_t *vm = wrk->vm;
  vlib_buffer_t *b;
  u32 bi;

  ASSERT (tc->snd_una != tc->snd_nxt);
  tcp_retransmit_timer_update (&wrk->timer_wheel, tc);

  if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
    {
      tcp_timer_update (&wrk->timer_wheel, tc, TCP_TIMER_RETRANSMIT, 1);
      tcp_worker_stats_inc (wrk, no_buffer, 1);
      return;
    }

  tc->rtt_ts = tcp_time_now_us (tc->c_thread_index);
  b = vlib_get_buffer (vm, bi);
  tcp_init_buffer (vm, b);
  tcp_make_synack (tc, b);
  tcp_enqueue_to_output (wrk, b, bi, tc->c_is_ip4);
  TCP_EVT (TCP_EVT_SYNACK_SENT, tc);
}

/**
 *  Send FIN
 */
void
tcp_send_fin (tcp_connection_t * tc)
{
  tcp_worker_ctx_t *wrk = tcp_get_worker (tc->c_thread_index);
  vlib_main_t *vm = wrk->vm;
  vlib_buffer_t *b;
  u32 bi;
  u8 fin_snt = 0;

  fin_snt = tc->flags & TCP_CONN_FINSNT;
  if (fin_snt)
    tc->snd_nxt -= 1;

  if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
    {
      /* Out of buffers so program fin retransmit ASAP */
      tcp_timer_update (&wrk->timer_wheel, tc, TCP_TIMER_RETRANSMIT, 1);
      if (fin_snt)
	tc->snd_nxt += 1;
      else
	/* Make sure retransmit retries a fin not data */
	tc->flags |= TCP_CONN_FINSNT;
      tcp_worker_stats_inc (wrk, no_buffer, 1);
      return;
    }

  /* If we have non-dupacks programmed, no need to send them */
  if ((tc->flags & TCP_CONN_SNDACK) && !tc->pending_dupacks)
    tc->flags &= ~TCP_CONN_SNDACK;

  b = vlib_get_buffer (vm, bi);
  tcp_init_buffer (vm, b);
  tcp_make_fin (tc, b);
  tcp_enqueue_to_output (wrk, b, bi, tc->c_is_ip4);
  TCP_EVT (TCP_EVT_FIN_SENT, tc);
  /* Account for the FIN */
  tc->snd_nxt += 1;
  tcp_retransmit_timer_update (&wrk->timer_wheel, tc);
  if (!fin_snt)
    {
      tc->flags |= TCP_CONN_FINSNT;
      tc->flags &= ~TCP_CONN_FINPNDG;
    }
}

/**
 * Push TCP header and update connection variables. Should only be called
 * for segments with data, not for 'control' packets.
 */
always_inline void
tcp_push_hdr_i (tcp_connection_t * tc, vlib_buffer_t * b, u32 snd_nxt,
		u8 compute_opts, u8 maybe_burst, u8 update_snd_nxt)
{
  u8 tcp_hdr_opts_len, flags = TCP_FLAG_ACK;
  u32 advertise_wnd, data_len;
  tcp_main_t *tm = &tcp_main;
  tcp_header_t *th;

  data_len = b->current_length;
  if (PREDICT_FALSE (b->flags & VLIB_BUFFER_NEXT_PRESENT))
    data_len += b->total_length_not_including_first_buffer;

  vnet_buffer (b)->tcp.flags = 0;
  vnet_buffer (b)->tcp.connection_index = tc->c_c_index;

  if (compute_opts)
    tc->snd_opts_len = tcp_make_options (tc, &tc->snd_opts, tc->state);

  tcp_hdr_opts_len = tc->snd_opts_len + sizeof (tcp_header_t);

  if (maybe_burst)
    advertise_wnd = tc->rcv_wnd >> tc->rcv_wscale;
  else
    advertise_wnd = tcp_window_to_advertise (tc, TCP_STATE_ESTABLISHED);

  if (PREDICT_FALSE (tc->flags & TCP_CONN_PSH_PENDING))
    {
      if (seq_geq (tc->psh_seq, snd_nxt)
	  && seq_lt (tc->psh_seq, snd_nxt + data_len))
	flags |= TCP_FLAG_PSH;
    }
  th = vlib_buffer_push_tcp (b, tc->c_lcl_port, tc->c_rmt_port, snd_nxt,
			     tc->rcv_nxt, tcp_hdr_opts_len, flags,
			     advertise_wnd);

  if (maybe_burst)
    {
      clib_memcpy_fast ((u8 *) (th + 1),
			tm->wrk_ctx[tc->c_thread_index].cached_opts,
			tc->snd_opts_len);
    }
  else
    {
      u8 len = tcp_options_write ((u8 *) (th + 1), &tc->snd_opts);
      ASSERT (len == tc->snd_opts_len);
    }

  /*
   * Update connection variables
   */

  if (update_snd_nxt)
    tc->snd_nxt += data_len;
  tc->rcv_las = tc->rcv_nxt;

  tc->bytes_out += data_len;
  tc->data_segs_out += 1;

  th->checksum = tcp_compute_checksum (tc, b);

  TCP_EVT (TCP_EVT_PKTIZE, tc);
}

always_inline u32
tcp_buffer_len (vlib_buffer_t * b)
{
  u32 data_len = b->current_length;
  if (PREDICT_FALSE (b->flags & VLIB_BUFFER_NEXT_PRESENT))
    data_len += b->total_length_not_including_first_buffer;
  return data_len;
}

u32
tcp_session_push_header (transport_connection_t * tconn, vlib_buffer_t * b)
{
  tcp_connection_t *tc = (tcp_connection_t *) tconn;

  if (tc->cfg_flags & TCP_CFG_F_RATE_SAMPLE)
    tcp_bt_track_tx (tc, tcp_buffer_len (b));

  tcp_push_hdr_i (tc, b, tc->snd_nxt, /* compute opts */ 0, /* burst */ 1,
		  /* update_snd_nxt */ 1);

  tcp_validate_txf_size (tc, tc->snd_nxt - tc->snd_una);
  /* If not tracking an ACK, start tracking */
  if (tc->rtt_ts == 0 && !tcp_in_cong_recovery (tc))
    {
      tc->rtt_ts = tcp_time_now_us (tc->c_thread_index);
      tc->rtt_seq = tc->snd_nxt;
    }
  if (PREDICT_FALSE (!tcp_timer_is_active (tc, TCP_TIMER_RETRANSMIT)))
    {
      tcp_worker_ctx_t *wrk = tcp_get_worker (tc->c_thread_index);
      tcp_retransmit_timer_set (&wrk->timer_wheel, tc);
      tc->rto_boff = 0;
    }
  return 0;
}

void
tcp_send_ack (tcp_connection_t * tc)
{
  tcp_worker_ctx_t *wrk = tcp_get_worker (tc->c_thread_index);
  vlib_main_t *vm = wrk->vm;
  vlib_buffer_t *b;
  u32 bi;

  if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
    {
      tcp_update_rcv_wnd (tc);
      tcp_worker_stats_inc (wrk, no_buffer, 1);
      return;
    }
  b = vlib_get_buffer (vm, bi);
  tcp_init_buffer (vm, b);
  tcp_make_ack (tc, b);
  tcp_enqueue_to_output (wrk, b, bi, tc->c_is_ip4);
}

void
tcp_program_ack (tcp_connection_t * tc)
{
  if (!(tc->flags & TCP_CONN_SNDACK))
    {
      session_add_self_custom_tx_evt (&tc->connection, 1);
      tc->flags |= TCP_CONN_SNDACK;
    }
}

void
tcp_program_dupack (tcp_connection_t * tc)
{
  if (!(tc->flags & TCP_CONN_SNDACK))
    {
      session_add_self_custom_tx_evt (&tc->connection, 1);
      tc->flags |= TCP_CONN_SNDACK;
    }
  if (tc->pending_dupacks < 255)
    tc->pending_dupacks += 1;
}

void
tcp_program_retransmit (tcp_connection_t * tc)
{
  if (!(tc->flags & TCP_CONN_RXT_PENDING))
    {
      session_add_self_custom_tx_evt (&tc->connection, 0);
      tc->flags |= TCP_CONN_RXT_PENDING;
    }
}

/**
 * Send window update ack
 *
 * Ensures that it will be sent only once, after a zero rwnd has been
 * advertised in a previous ack, and only if rwnd has grown beyond a
 * configurable value.
 */
void
tcp_send_window_update_ack (tcp_connection_t * tc)
{
  if (tcp_zero_rwnd_sent (tc))
    {
      tcp_update_rcv_wnd (tc);
      if (tc->rcv_wnd >= tcp_cfg.rwnd_min_update_ack * tc->snd_mss)
	{
	  tcp_zero_rwnd_sent_off (tc);
	  tcp_program_ack (tc);
	}
    }
}

/**
 * Allocate a new buffer and build a new tcp segment
 *
 * @param wrk		tcp worker
 * @param tc		connection for which the segment will be allocated
 * @param offset	offset of the first byte in the tx fifo
 * @param max_deq_byte	segment size
 * @param[out] b	pointer to buffer allocated
 *
 * @return 	the number of bytes in the segment or 0 if buffer cannot be
 * 		allocated or no data available
 */
static int
tcp_prepare_segment (tcp_worker_ctx_t * wrk, tcp_connection_t * tc,
		     u32 offset, u32 max_deq_bytes, vlib_buffer_t ** b)
{
  u32 bytes_per_buffer = vnet_get_tcp_main ()->bytes_per_buffer;
  vlib_main_t *vm = wrk->vm;
  u32 bi, seg_size;
  int n_bytes = 0;
  u8 *data;

  seg_size = max_deq_bytes + TRANSPORT_MAX_HDRS_LEN;

  /*
   * Prepare options
   */
  tc->snd_opts_len = tcp_make_options (tc, &tc->snd_opts, tc->state);

  /*
   * Allocate and fill in buffer(s)
   */

  /* Easy case, buffer size greater than mss */
  if (PREDICT_TRUE (seg_size <= bytes_per_buffer))
    {
      if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
	{
	  tcp_worker_stats_inc (wrk, no_buffer, 1);
	  return 0;
	}
      *b = vlib_get_buffer (vm, bi);
      data = tcp_init_buffer (vm, *b);
      n_bytes = session_tx_fifo_peek_bytes (&tc->connection, data, offset,
					    max_deq_bytes);
      ASSERT (n_bytes == max_deq_bytes);
      b[0]->current_length = n_bytes;
      tcp_push_hdr_i (tc, *b, tc->snd_una + offset, /* compute opts */ 0,
		      /* burst */ 0, /* update_snd_nxt */ 0);
    }
  /* Split mss into multiple buffers */
  else
    {
      u32 chain_bi = ~0, n_bufs_per_seg, n_bufs;
      u16 n_peeked, len_to_deq;
      vlib_buffer_t *chain_b, *prev_b;
      int i;

      /* Make sure we have enough buffers */
      n_bufs_per_seg = ceil ((double) seg_size / bytes_per_buffer);
      vec_validate_aligned (wrk->tx_buffers, n_bufs_per_seg - 1,
			    CLIB_CACHE_LINE_BYTES);
      n_bufs = vlib_buffer_alloc (vm, wrk->tx_buffers, n_bufs_per_seg);
      if (PREDICT_FALSE (n_bufs != n_bufs_per_seg))
	{
	  if (n_bufs)
	    vlib_buffer_free (vm, wrk->tx_buffers, n_bufs);
	  tcp_worker_stats_inc (wrk, no_buffer, 1);
	  return 0;
	}

      *b = vlib_get_buffer (vm, wrk->tx_buffers[--n_bufs]);
      data = tcp_init_buffer (vm, *b);
      n_bytes = session_tx_fifo_peek_bytes (&tc->connection, data, offset,
					    bytes_per_buffer -
					    TRANSPORT_MAX_HDRS_LEN);
      b[0]->current_length = n_bytes;
      b[0]->flags |= VLIB_BUFFER_TOTAL_LENGTH_VALID;
      b[0]->total_length_not_including_first_buffer = 0;
      max_deq_bytes -= n_bytes;

      chain_b = *b;
      for (i = 1; i < n_bufs_per_seg; i++)
	{
	  prev_b = chain_b;
	  len_to_deq = clib_min (max_deq_bytes, bytes_per_buffer);
	  chain_bi = wrk->tx_buffers[--n_bufs];
	  chain_b = vlib_get_buffer (vm, chain_bi);
	  chain_b->current_data = 0;
	  data = vlib_buffer_get_current (chain_b);
	  n_peeked = session_tx_fifo_peek_bytes (&tc->connection, data,
						 offset + n_bytes,
						 len_to_deq);
	  ASSERT (n_peeked == len_to_deq);
	  n_bytes += n_peeked;
	  chain_b->current_length = n_peeked;
	  chain_b->next_buffer = 0;

	  /* update previous buffer */
	  prev_b->next_buffer = chain_bi;
	  prev_b->flags |= VLIB_BUFFER_NEXT_PRESENT;

	  max_deq_bytes -= n_peeked;
	  b[0]->total_length_not_including_first_buffer += n_peeked;
	}

      tcp_push_hdr_i (tc, *b, tc->snd_una + offset, /* compute opts */ 0,
		      /* burst */ 0, /* update_snd_nxt */ 0);

      if (PREDICT_FALSE (n_bufs))
	{
	  clib_warning ("not all buffers consumed");
	  vlib_buffer_free (vm, wrk->tx_buffers, n_bufs);
	}
    }

  ASSERT (n_bytes > 0);
  ASSERT (((*b)->current_data + (*b)->current_length) <= bytes_per_buffer);

  return n_bytes;
}

/**
 * Build a retransmit segment
 *
 * @return the number of bytes in the segment or 0 if there's nothing to
 *         retransmit
 */
static u32
tcp_prepare_retransmit_segment (tcp_worker_ctx_t * wrk,
				tcp_connection_t * tc, u32 offset,
				u32 max_deq_bytes, vlib_buffer_t ** b)
{
  u32 start, available_bytes;
  int n_bytes = 0;

  ASSERT (tc->state >= TCP_STATE_ESTABLISHED);
  ASSERT (max_deq_bytes != 0);

  /*
   * Make sure we can retransmit something
   */
  available_bytes = transport_max_tx_dequeue (&tc->connection);
  ASSERT (available_bytes >= offset);
  available_bytes -= offset;
  if (!available_bytes)
    return 0;

  max_deq_bytes = clib_min (tc->snd_mss, max_deq_bytes);
  max_deq_bytes = clib_min (available_bytes, max_deq_bytes);

  start = tc->snd_una + offset;
  ASSERT (seq_leq (start + max_deq_bytes, tc->snd_nxt));

  n_bytes = tcp_prepare_segment (wrk, tc, offset, max_deq_bytes, b);
  if (!n_bytes)
    return 0;

  tc->snd_rxt_bytes += n_bytes;

  if (tc->cfg_flags & TCP_CFG_F_RATE_SAMPLE)
    tcp_bt_track_rxt (tc, start, start + n_bytes);

  tc->bytes_retrans += n_bytes;
  tc->segs_retrans += 1;
  tcp_worker_stats_inc (wrk, rxt_segs, 1);
  TCP_EVT (TCP_EVT_CC_RTX, tc, offset, n_bytes);

  return n_bytes;
}

static void
tcp_check_sack_reneging (tcp_connection_t * tc)
{
  sack_scoreboard_t *sb = &tc->sack_sb;
  sack_scoreboard_hole_t *hole;

  hole = scoreboard_first_hole (sb);
  if (!sb->is_reneging && (!hole || hole->start == tc->snd_una))
    return;

  scoreboard_clear_reneging (sb, tc->snd_una, tc->snd_nxt);
}

/**
 * Reset congestion control, switch cwnd to loss window and try again.
 */
static void
tcp_cc_init_rxt_timeout (tcp_connection_t * tc)
{
  TCP_EVT (TCP_EVT_CC_EVT, tc, 6);

  tc->prev_ssthresh = tc->ssthresh;
  tc->prev_cwnd = tc->cwnd;

  /* If we entrered loss without fast recovery, notify cc algo of the
   * congestion event such that it can update ssthresh and its state */
  if (!tcp_in_fastrecovery (tc))
    tcp_cc_congestion (tc);

  /* Let cc algo decide loss cwnd and ssthresh post unrecovered loss */
  tcp_cc_loss (tc);

  tc->rtt_ts = 0;
  tc->cwnd_acc_bytes = 0;
  tc->tr_occurences += 1;
  tc->sack_sb.reorder = TCP_DUPACK_THRESHOLD;
  tcp_recovery_on (tc);
}

void
tcp_timer_retransmit_handler (tcp_connection_t * tc)
{
  tcp_worker_ctx_t *wrk = tcp_get_worker (tc->c_thread_index);
  vlib_main_t *vm = wrk->vm;
  vlib_buffer_t *b = 0;
  u32 bi, n_bytes;

  tcp_worker_stats_inc (wrk, tr_events, 1);

  /* Should be handled by a different handler */
  if (PREDICT_FALSE (tc->state == TCP_STATE_SYN_SENT))
    return;

  /* Wait-close and retransmit could pop at the same time */
  if (tc->state == TCP_STATE_CLOSED)
    return;

  if (tc->state >= TCP_STATE_ESTABLISHED)
    {
      TCP_EVT (TCP_EVT_CC_EVT, tc, 2);

      /* Lost FIN, retransmit and return */
      if (tc->flags & TCP_CONN_FINSNT)
	{
	  tcp_send_fin (tc);
	  tc->rto_boff += 1;
	  tc->rto = clib_min (tc->rto << 1, TCP_RTO_MAX);
	  return;
	}

      /* Shouldn't be here */
      if (tc->snd_una == tc->snd_nxt)
	{
	  ASSERT (!tcp_in_recovery (tc));
	  tc->rto_boff = 0;
	  return;
	}

      /* We're not in recovery so make sure rto_boff is 0. Can be non 0 due
       * to persist timer timeout */
      if (!tcp_in_recovery (tc) && tc->rto_boff > 0)
	{
	  tc->rto_boff = 0;
	  tcp_update_rto (tc);
	}

      /* Peer is dead or network connectivity is lost. Close connection.
       * RFC 1122 section 4.2.3.5 recommends a value of at least 100s. For
       * a min rto of 0.2s we need to retry about 8 times. */
      if (tc->rto_boff >= TCP_RTO_BOFF_MAX)
	{
	  tcp_send_reset (tc);
	  tcp_connection_set_state (tc, TCP_STATE_CLOSED);
	  session_transport_closing_notify (&tc->connection);
	  session_transport_closed_notify (&tc->connection);
	  tcp_connection_timers_reset (tc);
	  tcp_program_cleanup (wrk, tc);
	  tcp_worker_stats_inc (wrk, tr_abort, 1);
	  return;
	}

      if (tcp_opts_sack_permitted (&tc->rcv_opts))
	tcp_check_sack_reneging (tc);

      /* Update send congestion to make sure that rxt has data to send */
      tc->snd_congestion = tc->snd_nxt;

      /* Send the first unacked segment. If we're short on buffers, return
       * as soon as possible */
      n_bytes = clib_min (tc->snd_mss, tc->snd_nxt - tc->snd_una);
      n_bytes = tcp_prepare_retransmit_segment (wrk, tc, 0, n_bytes, &b);
      if (!n_bytes)
	{
	  tcp_timer_update (&wrk->timer_wheel, tc, TCP_TIMER_RETRANSMIT, 1);
	  return;
	}

      bi = vlib_get_buffer_index (vm, b);
      tcp_enqueue_to_output (wrk, b, bi, tc->c_is_ip4);

      tc->rto = clib_min (tc->rto << 1, TCP_RTO_MAX);
      tcp_retransmit_timer_update (&wrk->timer_wheel, tc);

      tc->rto_boff += 1;
      if (tc->rto_boff == 1)
	{
	  tcp_cc_init_rxt_timeout (tc);
	  /* Record timestamp. Eifel detection algorithm RFC3522 */
	  tc->snd_rxt_ts = tcp_tstamp (tc);
	}

      if (tcp_opts_sack_permitted (&tc->rcv_opts))
	scoreboard_init_rxt (&tc->sack_sb, tc->snd_una + n_bytes);

      tcp_program_retransmit (tc);
    }
  /* Retransmit SYN-ACK */
  else if (tc->state == TCP_STATE_SYN_RCVD)
    {
      TCP_EVT (TCP_EVT_CC_EVT, tc, 2);

      tc->rtt_ts = 0;

      /* Passive open establish timeout */
      if (tc->rto > TCP_ESTABLISH_TIME >> 1)
	{
	  tcp_connection_set_state (tc, TCP_STATE_CLOSED);
	  tcp_connection_timers_reset (tc);
	  tcp_program_cleanup (wrk, tc);
	  tcp_worker_stats_inc (wrk, tr_abort, 1);
	  return;
	}

      if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
	{
	  tcp_timer_update (&wrk->timer_wheel, tc, TCP_TIMER_RETRANSMIT, 1);
	  tcp_worker_stats_inc (wrk, no_buffer, 1);
	  return;
	}

      tc->rto_boff += 1;
      if (tc->rto_boff > TCP_RTO_SYN_RETRIES)
	tc->rto = clib_min (tc->rto << 1, TCP_RTO_MAX);

      ASSERT (tc->snd_una != tc->snd_nxt);
      tcp_retransmit_timer_update (&wrk->timer_wheel, tc);

      b = vlib_get_buffer (vm, bi);
      tcp_init_buffer (vm, b);
      tcp_make_synack (tc, b);
      TCP_EVT (TCP_EVT_SYN_RXT, tc, 1);

      /* Retransmit timer already updated, just enqueue to output */
      tcp_enqueue_to_output (wrk, b, bi, tc->c_is_ip4);
    }
  else
    {
      ASSERT (tc->state == TCP_STATE_CLOSED);
      return;
    }
}

/**
 * SYN retransmit timer handler. Active open only.
 */
void
tcp_timer_retransmit_syn_handler (tcp_connection_t * tc)
{
  tcp_worker_ctx_t *wrk = tcp_get_worker (tc->c_thread_index);
  vlib_main_t *vm = wrk->vm;
  vlib_buffer_t *b = 0;
  u32 bi;

  /* Note: the connection may have transitioned to ESTABLISHED... */
  if (PREDICT_FALSE (tc->state != TCP_STATE_SYN_SENT))
    return;

  /* Half-open connection actually moved to established but we were
   * waiting for syn retransmit to pop to call cleanup from the right
   * thread. */
  if (tc->flags & TCP_CONN_HALF_OPEN_DONE)
    {
      if (tcp_half_open_connection_cleanup (tc))
	TCP_DBG ("could not remove half-open connection");
      return;
    }

  TCP_EVT (TCP_EVT_CC_EVT, tc, 2);
  tc->rtt_ts = 0;

  /* Active open establish timeout */
  if (tc->rto >= TCP_ESTABLISH_TIME >> 1)
    {
      session_stream_connect_notify (&tc->connection, SESSION_E_TIMEDOUT);
      tcp_connection_cleanup (tc);
      return;
    }

  if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
    {
      tcp_timer_update (&wrk->timer_wheel, tc, TCP_TIMER_RETRANSMIT_SYN, 1);
      tcp_worker_stats_inc (wrk, no_buffer, 1);
      return;
    }

  /* Try without increasing RTO a number of times. If this fails,
   * start growing RTO exponentially */
  tc->rto_boff += 1;
  if (tc->rto_boff > TCP_RTO_SYN_RETRIES)
    tc->rto = clib_min (tc->rto << 1, TCP_RTO_MAX);

  b = vlib_get_buffer (vm, bi);
  tcp_init_buffer (vm, b);
  tcp_make_syn (tc, b);

  TCP_EVT (TCP_EVT_SYN_RXT, tc, 0);

  /* This goes straight to ipx_lookup */
  tcp_push_ip_hdr (wrk, tc, b);
  tcp_enqueue_to_ip_lookup (wrk, b, bi, tc->c_is_ip4, tc->c_fib_index);

  tcp_timer_update (&wrk->timer_wheel, tc, TCP_TIMER_RETRANSMIT_SYN,
		    tc->rto * TCP_TO_TIMER_TICK);
}

/**
 * Got 0 snd_wnd from peer, try to do something about it.
 *
 */
void
tcp_timer_persist_handler (tcp_connection_t * tc)
{
  tcp_worker_ctx_t *wrk = tcp_get_worker (tc->c_thread_index);
  u32 bi, max_snd_bytes, available_bytes, offset;
  tcp_main_t *tm = vnet_get_tcp_main ();
  vlib_main_t *vm = wrk->vm;
  vlib_buffer_t *b;
  int n_bytes = 0;
  u8 *data;

  /* Problem already solved or worse */
  if (tc->state == TCP_STATE_CLOSED || tc->snd_wnd > tc->snd_mss
      || (tc->flags & TCP_CONN_FINSNT))
    goto update_scheduler;

  available_bytes = transport_max_tx_dequeue (&tc->connection);
  offset = tc->snd_nxt - tc->snd_una;

  /* Reprogram persist if no new bytes available to send. We may have data
   * next time */
  if (!available_bytes)
    {
      tcp_persist_timer_set (&wrk->timer_wheel, tc);
      return;
    }

  if (available_bytes <= offset)
    goto update_scheduler;

  /* Increment RTO backoff */
  tc->rto_boff += 1;
  tc->rto = clib_min (tc->rto << 1, TCP_RTO_MAX);

  /*
   * Try to force the first unsent segment (or buffer)
   */
  if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
    {
      tcp_persist_timer_set (&wrk->timer_wheel, tc);
      tcp_worker_stats_inc (wrk, no_buffer, 1);
      return;
    }

  b = vlib_get_buffer (vm, bi);
  data = tcp_init_buffer (vm, b);

  tcp_validate_txf_size (tc, offset);
  tc->snd_opts_len = tcp_make_options (tc, &tc->snd_opts, tc->state);
  max_snd_bytes = clib_min (tc->snd_mss,
			    tm->bytes_per_buffer - TRANSPORT_MAX_HDRS_LEN);
  n_bytes = session_tx_fifo_peek_bytes (&tc->connection, data, offset,
					max_snd_bytes);
  b->current_length = n_bytes;
  ASSERT (n_bytes != 0 && (tcp_timer_is_active (tc, TCP_TIMER_RETRANSMIT)
			   || tc->snd_una == tc->snd_nxt
			   || tc->rto_boff > 1));

  if (tc->cfg_flags & TCP_CFG_F_RATE_SAMPLE)
    {
      tcp_bt_check_app_limited (tc);
      tcp_bt_track_tx (tc, n_bytes);
    }

  tcp_push_hdr_i (tc, b, tc->snd_nxt, /* compute opts */ 0,
		  /* burst */ 0, /* update_snd_nxt */ 1);
  tcp_validate_txf_size (tc, tc->snd_nxt - tc->snd_una);
  tcp_enqueue_to_output (wrk, b, bi, tc->c_is_ip4);

  /* Just sent new data, enable retransmit */
  tcp_retransmit_timer_update (&wrk->timer_wheel, tc);

  return;

update_scheduler:

  if (tcp_is_descheduled (tc))
    transport_connection_reschedule (&tc->connection);
}

/**
 * Retransmit first unacked segment
 */
int
tcp_retransmit_first_unacked (tcp_worker_ctx_t * wrk, tcp_connection_t * tc)
{
  vlib_main_t *vm = wrk->vm;
  vlib_buffer_t *b;
  u32 bi, n_bytes;

  TCP_EVT (TCP_EVT_CC_EVT, tc, 1);

  n_bytes = tcp_prepare_retransmit_segment (wrk, tc, 0, tc->snd_mss, &b);
  if (!n_bytes)
    return -1;

  bi = vlib_get_buffer_index (vm, b);
  tcp_enqueue_to_output (wrk, b, bi, tc->c_is_ip4);

  return 0;
}

static int
tcp_transmit_unsent (tcp_worker_ctx_t * wrk, tcp_connection_t * tc,
		     u32 burst_size)
{
  u32 offset, n_segs = 0, n_written, bi, available_wnd;
  vlib_main_t *vm = wrk->vm;
  vlib_buffer_t *b = 0;

  offset = tc->snd_nxt - tc->snd_una;
  available_wnd = tc->snd_wnd - offset;
  burst_size = clib_min (burst_size, available_wnd / tc->snd_mss);

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

  while (n_segs < burst_size)
    {
      n_written = tcp_prepare_segment (wrk, tc, offset, tc->snd_mss, &b);
      if (!n_written)
	goto done;

      bi = vlib_get_buffer_index (vm, b);
      tcp_enqueue_to_output (wrk, b, bi, tc->c_is_ip4);
      offset += n_written;
      n_segs += 1;

      if (tc->cfg_flags & TCP_CFG_F_RATE_SAMPLE)
	tcp_bt_track_tx (tc, n_written);

      tc->snd_nxt += n_written;
    }

done:
  return n_segs;
}

/**
 * Estimate send space using proportional rate reduction (RFC6937)
 */
int
tcp_fastrecovery_prr_snd_space (tcp_connection_t * tc)
{
  u32 pipe, prr_out;
  int space;

  pipe = tcp_flight_size (tc);
  prr_out = tc->snd_rxt_bytes + (tc->snd_nxt - tc->snd_congestion);

  if (pipe > tc->ssthresh)
    {
      space = ((int) tc->prr_delivered * ((f64) tc->ssthresh / tc->prev_cwnd))
	- prr_out;
    }
  else
    {
      int limit;
      limit = clib_max ((int) (tc->prr_delivered - prr_out), 0) + tc->snd_mss;
      space = clib_min (tc->ssthresh - pipe, limit);
    }
  space = clib_max (space, prr_out ? 0 : tc->snd_mss);
  return space;
}

static inline u8
tcp_retransmit_should_retry_head (tcp_connection_t * tc,
				  sack_scoreboard_t * sb)
{
  u32 tx_adv_sack = sb->high_sacked - tc->snd_congestion;
  f64 rr = (f64) tc->ssthresh / tc->prev_cwnd;

  if (tcp_fastrecovery_first (tc))
    return 1;

  return (tx_adv_sack > (tc->snd_una - tc->prr_start) * rr);
}

static inline u8
tcp_max_tx_deq (tcp_connection_t * tc)
{
  return (transport_max_tx_dequeue (&tc->connection)
	  - (tc->snd_nxt - tc->snd_una));
}

#define scoreboard_rescue_rxt_valid(_sb, _tc)			\
    (seq_geq (_sb->rescue_rxt, _tc->snd_una) 			\
	&& seq_leq (_sb->rescue_rxt, _tc->snd_congestion))

/**
 * Do retransmit with SACKs
 */
static int
tcp_retransmit_sack (tcp_worker_ctx_t * wrk, tcp_connection_t * tc,
		     u32 burst_size)
{
  u32 n_written = 0, offset, max_bytes, n_segs = 0;
  u8 snd_limited = 0, can_rescue = 0;
  u32 bi, max_deq, burst_bytes;
  sack_scoreboard_hole_t *hole;
  vlib_main_t *vm = wrk->vm;
  vlib_buffer_t *b = 0;
  sack_scoreboard_t *sb;
  int snd_space;

  ASSERT (tcp_in_cong_recovery (tc));

  burst_bytes = transport_connection_tx_pacer_burst (&tc->connection);
  burst_size = clib_min (burst_size, burst_bytes / tc->snd_mss);
  if (!burst_size)
    {
      tcp_program_retransmit (tc);
      return 0;
    }

  if (tcp_in_recovery (tc))
    snd_space = tcp_available_cc_snd_space (tc);
  else
    snd_space = tcp_fastrecovery_prr_snd_space (tc);

  if (snd_space < tc->snd_mss)
    goto done;

  sb = &tc->sack_sb;

  /* Check if snd_una is a lost retransmit */
  if (pool_elts (sb->holes)
      && seq_gt (sb->high_sacked, tc->snd_congestion)
      && tc->rxt_head != tc->snd_una
      && tcp_retransmit_should_retry_head (tc, sb))
    {
      max_bytes = clib_min (tc->snd_mss, tc->snd_congestion - tc->snd_una);
      n_written = tcp_prepare_retransmit_segment (wrk, tc, 0, max_bytes, &b);
      if (!n_written)
	{
	  tcp_program_retransmit (tc);
	  goto done;
	}
      bi = vlib_get_buffer_index (vm, b);
      tcp_enqueue_to_output (wrk, b, bi, tc->c_is_ip4);
      n_segs = 1;

      tc->rxt_head = tc->snd_una;
      tc->rxt_delivered += n_written;
      tc->prr_delivered += n_written;
      ASSERT (tc->rxt_delivered <= tc->snd_rxt_bytes);
    }

  tcp_fastrecovery_first_off (tc);

  TCP_EVT (TCP_EVT_CC_EVT, tc, 0);
  hole = scoreboard_get_hole (sb, sb->cur_rxt_hole);

  max_deq = transport_max_tx_dequeue (&tc->connection);
  max_deq -= tc->snd_nxt - tc->snd_una;

  while (snd_space > 0 && n_segs < burst_size)
    {
      hole = scoreboard_next_rxt_hole (sb, hole, max_deq != 0, &can_rescue,
				       &snd_limited);
      if (!hole)
	{
	  /* We are out of lost holes to retransmit so send some new data. */
	  if (max_deq > tc->snd_mss)
	    {
	      u32 n_segs_new;
	      int av_wnd;

	      /* Make sure we don't exceed available window and leave space
	       * for one more packet, to avoid zero window acks */
	      av_wnd = (int) tc->snd_wnd - (tc->snd_nxt - tc->snd_una);
	      av_wnd = clib_max (av_wnd - tc->snd_mss, 0);
	      snd_space = clib_min (snd_space, av_wnd);
	      snd_space = clib_min (max_deq, snd_space);
	      burst_size = clib_min (burst_size - n_segs,
				     snd_space / tc->snd_mss);
	      burst_size = clib_min (burst_size, TCP_RXT_MAX_BURST);
	      n_segs_new = tcp_transmit_unsent (wrk, tc, burst_size);
	      if (max_deq > n_segs_new * tc->snd_mss)
		tcp_program_retransmit (tc);

	      n_segs += n_segs_new;
	      goto done;
	    }

	  if (tcp_in_recovery (tc) || !can_rescue
	      || scoreboard_rescue_rxt_valid (sb, tc))
	    break;

	  /* If rescue rxt undefined or less than snd_una then one segment of
	   * up to SMSS octets that MUST include the highest outstanding
	   * unSACKed sequence number SHOULD be returned, and RescueRxt set to
	   * RecoveryPoint. HighRxt MUST NOT be updated.
	   */
	  hole = scoreboard_last_hole (sb);
	  max_bytes = clib_min (tc->snd_mss, hole->end - hole->start);
	  max_bytes = clib_min (max_bytes, snd_space);
	  offset = hole->end - tc->snd_una - max_bytes;
	  n_written = tcp_prepare_retransmit_segment (wrk, tc, offset,
						      max_bytes, &b);
	  if (!n_written)
	    goto done;

	  sb->rescue_rxt = tc->snd_congestion;
	  bi = vlib_get_buffer_index (vm, b);
	  tcp_enqueue_to_output (wrk, b, bi, tc->c_is_ip4);
	  n_segs += 1;
	  break;
	}

      max_bytes = clib_min (hole->end - sb->high_rxt, snd_space);
      max_bytes = snd_limited ? clib_min (max_bytes, tc->snd_mss) : max_bytes;
      if (max_bytes == 0)
	break;

      offset = sb->high_rxt - tc->snd_una;
      n_written = tcp_prepare_retransmit_segment (wrk, tc, offset, max_bytes,
						  &b);
      ASSERT (n_written <= snd_space);

      /* Nothing left to retransmit */
      if (n_written == 0)
	break;

      bi = vlib_get_buffer_index (vm, b);
      tcp_enqueue_to_output (wrk, b, bi, tc->c_is_ip4);

      sb->high_rxt += n_written;
      ASSERT (seq_leq (sb->high_rxt, tc->snd_nxt));

      snd_space -= n_written;
      n_segs += 1;
    }

  if (hole)
    tcp_program_retransmit (tc);

done:

  transport_connection_tx_pacer_reset_bucket (&tc->connection, 0);
  return n_segs;
}

/**
 * Fast retransmit without SACK info
 */
static int
tcp_retransmit_no_sack (tcp_worker_ctx_t * wrk, tcp_connection_t * tc,
			u32 burst_size)
{
  u32 n_written = 0, offset = 0, bi, max_deq, n_segs_now, max_bytes;
  u32 burst_bytes, sent_bytes;
  vlib_main_t *vm = wrk->vm;
  int snd_space, n_segs = 0;
  u8 cc_limited = 0;
  vlib_buffer_t *b;

  ASSERT (tcp_in_cong_recovery (tc));
  TCP_EVT (TCP_EVT_CC_EVT, tc, 0);

  burst_bytes = transport_connection_tx_pacer_burst (&tc->connection);
  burst_size = clib_min (burst_size, burst_bytes / tc->snd_mss);
  if (!burst_size)
    {
      tcp_program_retransmit (tc);
      return 0;
    }

  snd_space = tcp_available_cc_snd_space (tc);
  cc_limited = snd_space < burst_bytes;

  if (!tcp_fastrecovery_first (tc))
    goto send_unsent;

  /* RFC 6582: [If a partial ack], retransmit the first unacknowledged
   * segment. */
  while (snd_space > 0 && n_segs < burst_size)
    {
      max_bytes = clib_min (tc->snd_mss,
			    tc->snd_congestion - tc->snd_una - offset);
      if (!max_bytes)
	break;
      n_written = tcp_prepare_retransmit_segment (wrk, tc, offset, max_bytes,
						  &b);

      /* Nothing left to retransmit */
      if (n_written == 0)
	break;

      bi = vlib_get_buffer_index (vm, b);
      tcp_enqueue_to_output (wrk, b, bi, tc->c_is_ip4);
      snd_space -= n_written;
      offset += n_written;
      n_segs += 1;
    }

  if (n_segs == burst_size)
    goto done;

send_unsent:

  /* RFC 6582: Send a new segment if permitted by the new value of cwnd. */
  if (snd_space < tc->snd_mss || tc->snd_mss == 0)
    goto done;

  max_deq = transport_max_tx_dequeue (&tc->connection);
  max_deq -= tc->snd_nxt - tc->snd_una;
  if (max_deq)
    {
      snd_space = clib_min (max_deq, snd_space);
      burst_size = clib_min (burst_size - n_segs, snd_space / tc->snd_mss);
      n_segs_now = tcp_transmit_unsent (wrk, tc, burst_size);
      if (n_segs_now && max_deq > n_segs_now * tc->snd_mss)
	tcp_program_retransmit (tc);
      n_segs += n_segs_now;
    }

done:
  tcp_fastrecovery_first_off (tc);

  sent_bytes = clib_min (n_segs * tc->snd_mss, burst_bytes);
  sent_bytes = cc_limited ? burst_bytes : sent_bytes;
  transport_connection_tx_pacer_update_bytes (&tc->connection, sent_bytes);

  return n_segs;
}

static int
tcp_send_acks (tcp_connection_t * tc, u32 max_burst_size)
{
  int j, n_acks;

  if (!tc->pending_dupacks)
    {
      if (tcp_in_cong_recovery (tc) || !tcp_max_tx_deq (tc)
	  || tc->state != TCP_STATE_ESTABLISHED)
	{
	  tcp_send_ack (tc);
	  return 1;
	}
      return 0;
    }

  /* If we're supposed to send dupacks but have no ooo data
   * send only one ack */
  if (!vec_len (tc->snd_sacks))
    {
      tcp_send_ack (tc);
      tc->dupacks_out += 1;
      tc->pending_dupacks = 0;
      return 1;
    }

  /* Start with first sack block */
  tc->snd_sack_pos = 0;

  /* Generate enough dupacks to cover all sack blocks. Do not generate
   * more sacks than the number of packets received. But do generate at
   * least 3, i.e., the number needed to signal congestion, if needed. */
  n_acks = vec_len (tc->snd_sacks) / TCP_OPTS_MAX_SACK_BLOCKS;
  n_acks = clib_min (n_acks, tc->pending_dupacks);
  n_acks = clib_max (n_acks, clib_min (tc->pending_dupacks, 3));
  for (j = 0; j < clib_min (n_acks, max_burst_size); j++)
    tcp_send_ack (tc);

  if (n_acks < max_burst_size)
    {
      tc->pending_dupacks = 0;
      tc->snd_sack_pos = 0;
      tc->dupacks_out += n_acks;
      return n_acks;
    }
  else
    {
      TCP_DBG ("constrained by burst size");
      tc->pending_dupacks = n_acks - max_burst_size;
      tc->dupacks_out += max_burst_size;
      tcp_program_dupack (tc);
      return max_burst_size;
    }
}

static int
tcp_do_retransmit (tcp_connection_t * tc, u32 max_burst_size)
{
  tcp_worker_ctx_t *wrk;
  u32 n_segs;

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

  wrk = tcp_get_worker (tc->c_thread_index);

  if (tcp_opts_sack_permitted (&tc->rcv_opts))
    n_segs = tcp_retransmit_sack (wrk, tc, max_burst_size);
  else
    n_segs = tcp_retransmit_no_sack (wrk, tc, max_burst_size);

  return n_segs;
}

int
tcp_session_custom_tx (void *conn, transport_send_params_t * sp)
{
  tcp_connection_t *tc = (tcp_connection_t *) conn;
  u32 n_segs = 0;

  if (tcp_in_cong_recovery (tc) && (tc->flags & TCP_CONN_RXT_PENDING))
    {
      tc->flags &= ~TCP_CONN_RXT_PENDING;
      n_segs = tcp_do_retransmit (tc, sp->max_burst_size);
    }

  if (!(tc->flags & TCP_CONN_SNDACK))
    return n_segs;

  tc->flags &= ~TCP_CONN_SNDACK;

  /* We have retransmitted packets and no dupack */
  if (n_segs && !tc->pending_dupacks)
    return n_segs;

  if (sp->max_burst_size <= n_segs)
    {
      tcp_program_ack (tc);
      return n_segs;
    }

  n_segs += tcp_send_acks (tc, sp->max_burst_size - n_segs);

  return n_segs;
}
#endif /* CLIB_MARCH_VARIANT */

static void
tcp_output_handle_link_local (tcp_connection_t * tc0, vlib_buffer_t * b0,
			      u16 * next0, u32 * error0)
{
  ip_adjacency_t *adj;
  adj_index_t ai;

  /* Not thread safe but as long as the connection exists the adj should
   * not be removed */
  ai = adj_nbr_find (FIB_PROTOCOL_IP6, VNET_LINK_IP6, &tc0->c_rmt_ip,
		     tc0->sw_if_index);
  if (ai == ADJ_INDEX_INVALID)
    {
      vnet_buffer (b0)->sw_if_index[VLIB_TX] = ~0;
      *next0 = TCP_OUTPUT_NEXT_DROP;
      *error0 = TCP_ERROR_LINK_LOCAL_RW;
      return;
    }

  adj = adj_get (ai);
  if (PREDICT_TRUE (adj->lookup_next_index == IP_LOOKUP_NEXT_REWRITE))
    *next0 = TCP_OUTPUT_NEXT_IP_REWRITE;
  else if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP)
    *next0 = TCP_OUTPUT_NEXT_IP_ARP;
  else
    {
      *next0 = TCP_OUTPUT_NEXT_DROP;
      *error0 = TCP_ERROR_LINK_LOCAL_RW;
    }
  vnet_buffer (b0)->ip.adj_index[VLIB_TX] = ai;
}

static void
tcp46_output_trace_frame (vlib_main_t * vm, vlib_node_runtime_t * node,
			  u32 * to_next, u32 n_bufs)
{
  tcp_connection_t *tc;
  tcp_tx_trace_t *t;
  vlib_buffer_t *b;
  tcp_header_t *th;
  int i;

  for (i = 0; i < n_bufs; i++)
    {
      b = vlib_get_buffer (vm, to_next[i]);
      if (!(b->flags & VLIB_BUFFER_IS_TRACED))
	continue;
      th = vlib_buffer_get_current (b);
      tc = tcp_connection_get (vnet_buffer (b)->tcp.connection_index,
			       vm->thread_index);
      t = vlib_add_trace (vm, node, b, sizeof (*t));
      clib_memcpy_fast (&t->tcp_header, th, sizeof (t->tcp_header));
      clib_memcpy_fast (&t->tcp_connection, tc, sizeof (t->tcp_connection));
    }
}

always_inline void
tcp_output_push_ip (vlib_main_t * vm, vlib_buffer_t * b0,
		    tcp_connection_t * tc0, u8 is_ip4)
{
  TCP_EVT (TCP_EVT_OUTPUT, tc0,
	   ((tcp_header_t *) vlib_buffer_get_current (b0))->flags,
	   b0->current_length);

  if (is_ip4)
    vlib_buffer_push_ip4 (vm, b0, &tc0->c_lcl_ip4, &tc0->c_rmt_ip4,
			  IP_PROTOCOL_TCP, tcp_csum_offload (tc0));
  else
    vlib_buffer_push_ip6_custom (vm, b0, &tc0->c_lcl_ip6, &tc0->c_rmt_ip6,
				 IP_PROTOCOL_TCP, tc0->ipv6_flow_label);
}

always_inline void
tcp_check_if_gso (tcp_connection_t * tc, vlib_buffer_t * b)
{
  if (PREDICT_TRUE (!(tc->cfg_flags & TCP_CFG_F_TSO)))
    return;

  u16 data_len = b->current_length - sizeof (tcp_header_t) - tc->snd_opts_len;

  if (PREDICT_FALSE (b->flags & VLIB_BUFFER_TOTAL_LENGTH_VALID))
    data_len += b->total_length_not_including_first_buffer;

  if (PREDICT_TRUE (data_len <= tc->snd_mss))
    return;
  else
    {
      ASSERT ((b->flags & VNET_BUFFER_F_L3_HDR_OFFSET_VALID) != 0);
      ASSERT ((b->flags & VNET_BUFFER_F_L4_HDR_OFFSET_VALID) != 0);
      b->flags |= VNET_BUFFER_F_GSO;
      vnet_buffer2 (b)->gso_l4_hdr_sz =
	sizeof (tcp_header_t) + tc->snd_opts_len;
      vnet_buffer2 (b)->gso_size = tc->snd_mss;
    }
}

always_inline void
tcp_output_handle_packet (tcp_connection_t * tc0, vlib_buffer_t * b0,
			  vlib_node_runtime_t * error_node, u16 * next0,
			  u8 is_ip4)
{
  /* If next_index is not drop use it */
  if (tc0->next_node_index)
    {
      *next0 = tc0->next_node_index;
      vnet_buffer (b0)->tcp.next_node_opaque = tc0->next_node_opaque;
    }
  else
    {
      *next0 = TCP_OUTPUT_NEXT_IP_LOOKUP;
    }

  vnet_buffer (b0)->sw_if_index[VLIB_TX] = tc0->c_fib_index;
  vnet_buffer (b0)->sw_if_index[VLIB_RX] = 0;

  if (!is_ip4)
    {
      u32 error0 = 0;

      if (PREDICT_FALSE (ip6_address_is_link_local_unicast (&tc0->c_rmt_ip6)))
	tcp_output_handle_link_local (tc0, b0, next0, &error0);

      if (PREDICT_FALSE (error0))
	{
	  b0->error = error_node->errors[error0];
	  return;
	}
    }

  tc0->segs_out += 1;
}

always_inline uword
tcp46_output_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
		     vlib_frame_t * frame, int is_ip4)
{
  u32 n_left_from, *from, thread_index = vm->thread_index;
  vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b;
  u16 nexts[VLIB_FRAME_SIZE], *next;

  from = vlib_frame_vector_args (frame);
  n_left_from = frame->n_vectors;
  tcp_update_time_now (tcp_get_worker (thread_index));

  if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE))
    tcp46_output_trace_frame (vm, node, from, n_left_from);

  vlib_get_buffers (vm, from, bufs, n_left_from);
  b = bufs;
  next = nexts;

  while (n_left_from >= 4)
    {
      tcp_connection_t *tc0, *tc1;

      {
	vlib_prefetch_buffer_header (b[2], STORE);
	CLIB_PREFETCH (b[2]->data, 2 * CLIB_CACHE_LINE_BYTES, STORE);

	vlib_prefetch_buffer_header (b[3], STORE);
	CLIB_PREFETCH (b[3]->data, 2 * CLIB_CACHE_LINE_BYTES, STORE);
      }

      tc0 = tcp_connection_get (vnet_buffer (b[0])->tcp.connection_index,
				thread_index);
      tc1 = tcp_connection_get (vnet_buffer (b[1])->tcp.connection_index,
				thread_index);

      if (PREDICT_TRUE (!tc0 + !tc1 == 0))
	{
	  tcp_output_push_ip (vm, b[0], tc0, is_ip4);
	  tcp_output_push_ip (vm, b[1], tc1, is_ip4);

	  tcp_check_if_gso (tc0, b[0]);
	  tcp_check_if_gso (tc1, b[1]);

	  tcp_output_handle_packet (tc0, b[0], node, &next[0], is_ip4);
	  tcp_output_handle_packet (tc1, b[1], node, &next[1], is_ip4);
	}
      else
	{
	  if (tc0 != 0)
	    {
	      tcp_output_push_ip (vm, b[0], tc0, is_ip4);
	      tcp_check_if_gso (tc0, b[0]);
	      tcp_output_handle_packet (tc0, b[0], node, &next[0], is_ip4);
	    }
	  else
	    {
	      b[0]->error = node->errors[TCP_ERROR_INVALID_CONNECTION];
	      next[0] = TCP_OUTPUT_NEXT_DROP;
	    }
	  if (tc1 != 0)
	    {
	      tcp_output_push_ip (vm, b[1], tc1, is_ip4);
	      tcp_check_if_gso (tc1, b[1]);
	      tcp_output_handle_packet (tc1, b[1], node, &next[1], is_ip4);
	    }
	  else
	    {
	      b[1]->error = node->errors[TCP_ERROR_INVALID_CONNECTION];
	      next[1] = TCP_OUTPUT_NEXT_DROP;
	    }
	}

      b += 2;
      next += 2;
      n_left_from -= 2;
    }
  while (n_left_from > 0)
    {
      tcp_connection_t *tc0;

      if (n_left_from > 1)
	{
	  vlib_prefetch_buffer_header (b[1], STORE);
	  CLIB_PREFETCH (b[1]->data, 2 * CLIB_CACHE_LINE_BYTES, STORE);
	}

      tc0 = tcp_connection_get (vnet_buffer (b[0])->tcp.connection_index,
				thread_index);

      if (PREDICT_TRUE (tc0 != 0))
	{
	  tcp_output_push_ip (vm, b[0], tc0, is_ip4);
	  tcp_check_if_gso (tc0, b[0]);
	  tcp_output_handle_packet (tc0, b[0], node, &next[0], is_ip4);
	}
      else
	{
	  b[0]->error = node->errors[TCP_ERROR_INVALID_CONNECTION];
	  next[0] = TCP_OUTPUT_NEXT_DROP;
	}

      b += 1;
      next += 1;
      n_left_from -= 1;
    }

  vlib_buffer_enqueue_to_next (vm, node, from, nexts, frame->n_vectors);
  vlib_node_increment_counter (vm, tcp_node_index (output, is_ip4),
			       TCP_ERROR_PKTS_SENT, frame->n_vectors);
  return frame->n_vectors;
}

VLIB_NODE_FN (tcp4_output_node) (vlib_main_t * vm, vlib_node_runtime_t * node,
				 vlib_frame_t * from_frame)
{
  return tcp46_output_inline (vm, node, from_frame, 1 /* is_ip4 */ );
}

VLIB_NODE_FN (tcp6_output_node) (vlib_main_t * vm, vlib_node_runtime_t * node,
				 vlib_frame_t * from_frame)
{
  return tcp46_output_inline (vm, node, from_frame, 0 /* is_ip4 */ );
}

/* *INDENT-OFF* */
VLIB_REGISTER_NODE (tcp4_output_node) =
{
  .name = "tcp4-output",
  /* Takes a vector of packets. */
  .vector_size = sizeof (u32),
  .n_errors = TCP_N_ERROR,
  .protocol_hint = VLIB_NODE_PROTO_HINT_TCP,
  .error_strings = tcp_error_strings,
  .n_next_nodes = TCP_OUTPUT_N_NEXT,
  .next_nodes = {
#define _(s,n) [TCP_OUTPUT_NEXT_##s] = n,
    foreach_tcp4_output_next
#undef _
  },
  .format_buffer = format_tcp_header,
  .format_trace = format_tcp_tx_trace,
};
/* *INDENT-ON* */

/* *INDENT-OFF* */
VLIB_REGISTER_NODE (tcp6_output_node) =
{
  .name = "tcp6-output",
    /* Takes a vector of packets. */
  .vector_size = sizeof (u32),
  .n_errors = TCP_N_ERROR,
  .protocol_hint = VLIB_NODE_PROTO_HINT_TCP,
  .error_strings = tcp_error_strings,
  .n_next_nodes = TCP_OUTPUT_N_NEXT,
  .next_nodes = {
#define _(s,n) [TCP_OUTPUT_NEXT_##s] = n,
    foreach_tcp6_output_next
#undef _
  },
  .format_buffer = format_tcp_header,
  .format_trace = format_tcp_tx_trace,
};
/* *INDENT-ON* */

typedef enum _tcp_reset_next
{
  TCP_RESET_NEXT_DROP,
  TCP_RESET_NEXT_IP_LOOKUP,
  TCP_RESET_N_NEXT
} tcp_reset_next_t;

#define foreach_tcp4_reset_next        	\
  _(DROP, "error-drop")                 \
  _(IP_LOOKUP, "ip4-lookup")

#define foreach_tcp6_reset_next        	\
  _(DROP, "error-drop")                 \
  _(IP_LOOKUP, "ip6-lookup")

static uword
tcp46_send_reset_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
			 vlib_frame_t * from_frame, u8 is_ip4)
{
  u32 error0 = TCP_ERROR_RST_SENT, next0 = TCP_RESET_NEXT_IP_LOOKUP;
  u32 n_left_from, next_index, *from, *to_next;

  from = vlib_frame_vector_args (from_frame);
  n_left_from = from_frame->n_vectors;

  next_index = node->cached_next_index;

  while (n_left_from > 0)
    {
      u32 n_left_to_next;

      vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);

      while (n_left_from > 0 && n_left_to_next > 0)
	{
	  vlib_buffer_t *b0;
	  tcp_tx_trace_t *t0;
	  tcp_header_t *th0;
	  u32 bi0;

	  bi0 = from[0];
	  to_next[0] = bi0;
	  from += 1;
	  to_next += 1;
	  n_left_from -= 1;
	  n_left_to_next -= 1;

	  b0 = vlib_get_buffer (vm, bi0);
	  tcp_make_reset_in_place (vm, b0, is_ip4);

	  /* Prepare to send to IP lookup */
	  vnet_buffer (b0)->sw_if_index[VLIB_TX] = ~0;

	  b0->error = node->errors[error0];
	  b0->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
	  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
	    {
	      th0 = vlib_buffer_get_current (b0);
	      if (is_ip4)
		th0 = ip4_next_header ((ip4_header_t *) th0);
	      else
		th0 = ip6_next_header ((ip6_header_t *) th0);
	      t0 = vlib_add_trace (vm, node, b0, sizeof (*t0));
	      clib_memcpy_fast (&t0->tcp_header, th0,
				sizeof (t0->tcp_header));
	    }

	  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
					   n_left_to_next, bi0, next0);
	}
      vlib_put_next_frame (vm, node, next_index, n_left_to_next);
    }
  return from_frame->n_vectors;
}

VLIB_NODE_FN (tcp4_reset_node) (vlib_main_t * vm, vlib_node_runtime_t * node,
				vlib_frame_t * from_frame)
{
  return tcp46_send_reset_inline (vm, node, from_frame, 1);
}

VLIB_NODE_FN (tcp6_reset_node) (vlib_main_t * vm, vlib_node_runtime_t * node,
				vlib_frame_t * from_frame)
{
  return tcp46_send_reset_inline (vm, node, from_frame, 0);
}

/* *INDENT-OFF* */
VLIB_REGISTER_NODE (tcp4_reset_node) = {
  .name = "tcp4-reset",
  .vector_size = sizeof (u32),
  .n_errors = TCP_N_ERROR,
  .error_strings = tcp_error_strings,
  .n_next_nodes = TCP_RESET_N_NEXT,
  .next_nodes = {
#define _(s,n) [TCP_RESET_NEXT_##s] = n,
    foreach_tcp4_reset_next
#undef _
  },
  .format_trace = format_tcp_tx_trace,
};
/* *INDENT-ON* */

/* *INDENT-OFF* */
VLIB_REGISTER_NODE (tcp6_reset_node) = {
  .name = "tcp6-reset",
  .vector_size = sizeof (u32),
  .n_errors = TCP_N_ERROR,
  .error_strings = tcp_error_strings,
  .n_next_nodes = TCP_RESET_N_NEXT,
  .next_nodes = {
#define _(s,n) [TCP_RESET_NEXT_##s] = n,
    foreach_tcp6_reset_next
#undef _
  },
  .format_trace = format_tcp_tx_trace,
};
/* *INDENT-ON* */

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