/*
 * 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 <math.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 *);
  u32 indent = format_get_indent (s);

  s = format (s, "%U\n%U%U",
	      format_tcp_header, &t->tcp_header, 128,
	      format_white_space, indent,
	      format_tcp_connection, &t->tcp_connection, 1);

  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;

  ASSERT (tc->rcv_opts.mss < transport_rx_fifo_size (&tc->connection));

  /*
   * Figure out how much space we have available
   */
  available_space = transport_max_rx_enqueue (&tc->connection);
  if (PREDICT_FALSE (available_space < tc->rcv_opts.mss))
    {
      tc->rcv_wnd = 0;
      return;
    }

  /*
   * 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);

  /* Bad. Thou shalt not shrink */
  if (PREDICT_FALSE ((i32) available_space < observed_wnd))
    {
      wnd = clib_max (observed_wnd, 0);
      TCP_EVT (TCP_EVT_RCV_WND_SHRUNK, tc, observed_wnd, available_space);
    }
  else
    {
      wnd = available_space;
    }

  /* Make sure we have a multiple of rcv_wscale */
  if (wnd && tc->rcv_wscale)
    {
      wnd &= ~((1 << tc->rcv_wscale) - 1);
      if (wnd == 0)
	wnd = 1 << tc->rcv_wscale;
    }

  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;
}

/**
 * Write TCP options to segment.
 */
static u32
tcp_options_write (u8 * data, tcp_options_t * opts)
{
  u32 opts_len = 0;
  u32 buf, seq_len = 4;

  if (tcp_opts_mss (opts))
    {
      *data++ = TCP_OPTION_MSS;
      *data++ = TCP_OPTION_LEN_MSS;
      buf = clib_host_to_net_u16 (opts->mss);
      clib_memcpy_fast (data, &buf, sizeof (opts->mss));
      data += sizeof (opts->mss);
      opts_len += TCP_OPTION_LEN_MSS;
    }

  if (tcp_opts_wscale (opts))
    {
      *data++ = TCP_OPTION_WINDOW_SCALE;
      *data++ = TCP_OPTION_LEN_WINDOW_SCALE;
      *data++ = opts->wscale;
      opts_len += TCP_OPTION_LEN_WINDOW_SCALE;
    }

  if (tcp_opts_sack_permitted (opts))
    {
      *data++ = TCP_OPTION_SACK_PERMITTED;
      *data++ = TCP_OPTION_LEN_SACK_PERMITTED;
      opts_len += TCP_OPTION_LEN_SACK_PERMITTED;
    }

  if (tcp_opts_tstamp (opts))
    {
      *data++ = TCP_OPTION_TIMESTAMP;
      *data++ = TCP_OPTION_LEN_TIMESTAMP;
      buf = clib_host_to_net_u32 (opts->tsval);
      clib_memcpy_fast (data, &buf, sizeof (opts->tsval));
      data += sizeof (opts->tsval);
      buf = clib_host_to_net_u32 (opts->tsecr);
      clib_memcpy_fast (data, &buf, sizeof (opts->tsecr));
      data += sizeof (opts->tsecr);
      opts_len += TCP_OPTION_LEN_TIMESTAMP;
    }

  if (tcp_opts_sack (opts))
    {
      int i;

      if (opts->n_sack_blocks != 0)
	{
	  *data++ = TCP_OPTION_SACK_BLOCK;
	  *data++ = 2 + opts->n_sack_blocks * TCP_OPTION_LEN_SACK_BLOCK;
	  for (i = 0; i < opts->n_sack_blocks; i++)
	    {
	      buf = clib_host_to_net_u32 (opts->sacks[i].start);
	      clib_memcpy_fast (data, &buf, seq_len);
	      data += seq_len;
	      buf = clib_host_to_net_u32 (opts->sacks[i].end);
	      clib_memcpy_fast (data, &buf, seq_len);
	      data += seq_len;
	    }
	  opts_len += 2 + opts->n_sack_blocks * TCP_OPTION_LEN_SACK_BLOCK;
	}
    }

  /* Terminate TCP options */
  if (opts_len % 4)
    {
      *data++ = TCP_OPTION_EOL;
      opts_len += TCP_OPTION_LEN_EOL;
    }

  /* Pad with zeroes to a u32 boundary */
  while (opts_len % 4)
    {
      *data++ = TCP_OPTION_NOOP;
      opts_len += TCP_OPTION_LEN_NOOP;
    }
  return opts_len;
}

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_now ();
  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_now ();
      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);
    }
}

#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;

  /* 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;
  VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b);
  /* 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
    {
      b->flags |= VNET_BUFFER_F_OFFLOAD_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)
    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
 */
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
 */
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);
}

always_inline void
tcp_enqueue_to_ip_lookup_i (tcp_worker_ctx_t * wrk, vlib_buffer_t * b, u32 bi,
			    u8 is_ip4, u32 fib_index, u8 flush)
{
  vlib_main_t *vm = wrk->vm;
  u32 *to_next, next_index;
  vlib_frame_t *f;

  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;

  /* Send to IP lookup */
  next_index = is_ip4 ? ip4_lookup_node.index : ip6_lookup_node.index;
  tcp_trajectory_add_start (b, 1);

  f = wrk->ip_lookup_tx_frames[!is_ip4];
  if (!f)
    {
      f = vlib_get_frame_to_node (vm, next_index);
      ASSERT (f);
      wrk->ip_lookup_tx_frames[!is_ip4] = f;
    }

  to_next = vlib_frame_vector_args (f);
  to_next[f->n_vectors] = bi;
  f->n_vectors += 1;
  if (flush || f->n_vectors == VLIB_FRAME_SIZE)
    {
      vlib_put_frame_to_node (vm, next_index, f);
      wrk->ip_lookup_tx_frames[!is_ip4] = 0;
    }
}

static void
tcp_enqueue_to_ip_lookup_now (tcp_worker_ctx_t * wrk, vlib_buffer_t * b,
			      u32 bi, u8 is_ip4, u32 fib_index)
{
  tcp_enqueue_to_ip_lookup_i (wrk, b, bi, is_ip4, fib_index, 1);
}

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_enqueue_to_ip_lookup_i (wrk, b, bi, is_ip4, fib_index, 0);
  if (wrk->vm->thread_index == 0 && vlib_num_workers ())
    session_flush_frames_main_thread (wrk->vm);
}

static void
tcp_enqueue_to_output (tcp_worker_ctx_t * wrk, vlib_buffer_t * b, u32 bi,
		       u8 is_ip4)
{
  session_type_t st;

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

  st = session_type_from_proto_and_ip (TRANSPORT_PROTO_TCP, is_ip4);
  session_add_pending_tx_buffer (st, wrk->vm->thread_index, bi);
}

#endif /* CLIB_MARCH_VARIANT */

static int
tcp_make_reset_in_place (vlib_main_t * vm, vlib_buffer_t * b0,
			 tcp_state_t state, u8 thread_index, u8 is_ip4)
{
  ip4_header_t *ih4;
  ip6_header_t *ih6;
  tcp_header_t *th0;
  ip4_address_t src_ip40, dst_ip40;
  ip6_address_t src_ip60, dst_ip60;
  u16 src_port, dst_port;
  u32 tmp;
  u32 seq, ack;
  u8 flags;

  /* Find IP and TCP headers */
  th0 = tcp_buffer_hdr (b0);

  /* Save src and dst ip */
  if (is_ip4)
    {
      ih4 = vlib_buffer_get_current (b0);
      ASSERT ((ih4->ip_version_and_header_length & 0xF0) == 0x40);
      src_ip40.as_u32 = ih4->src_address.as_u32;
      dst_ip40.as_u32 = ih4->dst_address.as_u32;
    }
  else
    {
      ih6 = vlib_buffer_get_current (b0);
      ASSERT ((ih6->ip_version_traffic_class_and_flow_label & 0xF0) == 0x60);
      clib_memcpy_fast (&src_ip60, &ih6->src_address, sizeof (ip6_address_t));
      clib_memcpy_fast (&dst_ip60, &ih6->dst_address, sizeof (ip6_address_t));
    }

  src_port = th0->src_port;
  dst_port = th0->dst_port;

  /* Try to determine what/why we're actually resetting */
  if (state == TCP_STATE_CLOSED)
    {
      if (!tcp_syn (th0))
	return -1;

      tmp = clib_net_to_host_u32 (th0->seq_number);

      /* Got a SYN for no listener. */
      flags = TCP_FLAG_RST | TCP_FLAG_ACK;
      ack = clib_host_to_net_u32 (tmp + 1);
      seq = 0;
    }
  else
    {
      flags = TCP_FLAG_RST;
      seq = th0->ack_number;
      ack = 0;
    }

  tcp_reuse_buffer (vm, b0);
  tcp_trajectory_add_start (b0, 4);
  th0 = vlib_buffer_push_tcp_net_order (b0, dst_port, src_port, seq, ack,
					sizeof (tcp_header_t), flags, 0);

  if (is_ip4)
    {
      ih4 = vlib_buffer_push_ip4 (vm, b0, &dst_ip40, &src_ip40,
				  IP_PROTOCOL_TCP, 1);
      th0->checksum = ip4_tcp_udp_compute_checksum (vm, b0, ih4);
    }
  else
    {
      int bogus = ~0;
      ih6 = vlib_buffer_push_ip6 (vm, b0, &dst_ip60, &src_ip60,
				  IP_PROTOCOL_TCP);
      th0->checksum = ip6_tcp_udp_icmp_compute_checksum (vm, b0, 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)))
    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_now (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)))
    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 = tcp_window_to_advertise (tc, TCP_STATE_ESTABLISHED);
  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 (tc, TCP_TIMER_RETRANSMIT_SYN,
		    tc->rto * TCP_TO_TIMER_TICK);

  if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
    {
      tcp_timer_update (tc, TCP_TIMER_RETRANSMIT_SYN, 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;

  tcp_retransmit_timer_force_update (tc);

  if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
    {
      tcp_timer_update (tc, TCP_TIMER_RETRANSMIT, 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);
}

/**
 * Flush ip lookup tx frames populated by timer pops
 */
static void
tcp_flush_frame_to_ip_lookup (tcp_worker_ctx_t * wrk, u8 is_ip4)
{
  if (wrk->ip_lookup_tx_frames[!is_ip4])
    {
      u32 next_index;
      next_index = is_ip4 ? ip4_lookup_node.index : ip6_lookup_node.index;
      vlib_put_frame_to_node (wrk->vm, next_index,
			      wrk->ip_lookup_tx_frames[!is_ip4]);
      wrk->ip_lookup_tx_frames[!is_ip4] = 0;
    }
}

/**
 * Flush v4 and v6 tcp and ip-lookup tx frames for thread index
 */
void
tcp_flush_frames_to_output (tcp_worker_ctx_t * wrk)
{
  tcp_flush_frame_to_ip_lookup (wrk, 1);
  tcp_flush_frame_to_ip_lookup (wrk, 0);
}

/**
 *  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 (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;
      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;

  tcp_retransmit_timer_force_update (tc);
  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;
  if (!fin_snt)
    {
      tc->flags |= TCP_CONN_FINSNT;
      tc->flags &= ~TCP_CONN_FINPNDG;
      tc->snd_una_max = seq_max (tc->snd_una_max, tc->snd_nxt);
    }
}

/**
 * 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);

  tc->snd_una_max = seq_max (tc->snd_nxt, tc->snd_una_max);
  tcp_validate_txf_size (tc, tc->snd_una_max - 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_retransmit_timer_set (tc);
      tc->rto_boff = 0;
    }
  tcp_trajectory_add_start (b, 3);
  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);
      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;
    }
}

/**
 * Delayed ack timer handler
 *
 * Sends delayed ACK when timer expires
 */
void
tcp_timer_delack_handler (u32 index, u32 thread_index)
{
  tcp_connection_t *tc;

  tc = tcp_connection_get (index, thread_index);
  tcp_send_ack (tc);
}

/**
 * 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)))
	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);
	  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_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;
  tcp_recovery_on (tc);
}

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

  tc = tcp_connection_get (tc_index, thread_index);

  /* Note: the connection may have been closed and pool_put */
  if (PREDICT_FALSE (tc == 0 || 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. This condition is tricky because it has to take
       * into account boff > 0 due to persist timeout. */
      if ((tc->rto_boff == 0 && tc->snd_una == tc->snd_nxt)
	  || (tc->rto_boff > 0 && seq_geq (tc->snd_una, tc->snd_congestion)
	      && !tcp_flight_size (tc)))
	{
	  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_timer_update (tc, TCP_TIMER_WAITCLOSE, tcp_cfg.closewait_time);
	  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 (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_force_update (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_timer_update (tc, TCP_TIMER_WAITCLOSE, tcp_cfg.cleanup_time);
	  return;
	}

      if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
	{
	  tcp_timer_update (tc, TCP_TIMER_RETRANSMIT, 1);
	  return;
	}

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

      tcp_retransmit_timer_force_update (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 (u32 tc_index, u32 thread_index)
{
  tcp_worker_ctx_t *wrk = tcp_get_worker (thread_index);
  vlib_main_t *vm = wrk->vm;
  tcp_connection_t *tc;
  vlib_buffer_t *b = 0;
  u32 bi;

  tc = tcp_half_open_connection_get (tc_index);

  /* Note: the connection may have transitioned to ESTABLISHED... */
  if (PREDICT_FALSE (tc == 0 || 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, 1 /* fail */ );
      tcp_connection_cleanup (tc);
      return;
    }

  if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
    {
      tcp_timer_update (tc, TCP_TIMER_RETRANSMIT_SYN, 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 (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 (u32 index, u32 thread_index)
{
  tcp_worker_ctx_t *wrk = tcp_get_worker (thread_index);
  u32 bi, max_snd_bytes, available_bytes, offset;
  tcp_main_t *tm = vnet_get_tcp_main ();
  vlib_main_t *vm = wrk->vm;
  tcp_connection_t *tc;
  vlib_buffer_t *b;
  int n_bytes = 0;
  u8 *data;

  tc = tcp_connection_get_if_valid (index, thread_index);
  if (!tc)
    return;

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

  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 (tc);
      return;
    }

  if (available_bytes <= offset)
    {
      ASSERT (tcp_timer_is_active (tc, TCP_TIMER_RETRANSMIT));
      return;
    }

  /* 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 (tc);
      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_nxt == tc->snd_una_max
			   || 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);
  tc->snd_una_max = seq_max (tc->snd_nxt, tc->snd_una_max);
  tcp_validate_txf_size (tc, tc->snd_una_max - tc->snd_una);
  tcp_enqueue_to_output (wrk, b, bi, tc->c_is_ip4);

  /* Just sent new data, enable retransmit */
  tcp_retransmit_timer_update (tc);
}

/**
 * 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;
      tc->snd_una_max = seq_max (tc->snd_nxt, tc->snd_una_max);
    }

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->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, u32 max_burst_size)
{
  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, max_burst_size);
      max_burst_size -= n_segs;
    }

  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 (!max_burst_size)
    {
      tcp_program_ack (tc);
      return max_burst_size;
    }

  n_segs += tcp_send_acks (tc, max_burst_size);

  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)
{
  u32 n_trace = vlib_get_trace_count (vm, node);
  tcp_connection_t *tc;
  tcp_tx_trace_t *t;
  vlib_buffer_t *b;
  tcp_header_t *th;
  int i;

  for (i = 0; i < clib_min (n_trace, n_bufs); i++)
    {
      b = vlib_get_buffer (vm, to_next[i]);
      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;
	}
    }

  if (!TCP_ALWAYS_ACK)
    tcp_timer_reset (tc0, TCP_TIMER_DELACK);

  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;
  vlib_node_runtime_t *error_node;

  error_node = vlib_node_get_runtime (vm, tcp_node_index (output, is_ip4));

  from = vlib_frame_vector_args (frame);
  n_left_from = frame->n_vectors;
  tcp_set_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], error_node, &next[0], is_ip4);
	  tcp_output_handle_packet (tc1, b[1], error_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], error_node, &next[0],
					is_ip4);
	    }
	  else
	    {
	      b[0]->error = 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], error_node, &next[1],
					is_ip4);
	    }
	  else
	    {
	      b[1]->error = 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], error_node, &next[0], is_ip4);
	}
      else
	{
	  b[0]->error = 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 n_left_from, next_index, *from, *to_next;
  u32 my_thread_index = vm->thread_index;

  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)
	{
	  u32 bi0;
	  vlib_buffer_t *b0;
	  tcp_tx_trace_t *t0;
	  tcp_header_t *th0;
	  u32 error0 = TCP_ERROR_RST_SENT, next0 = TCP_RESET_NEXT_IP_LOOKUP;

	  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);

	  if (tcp_make_reset_in_place (vm, b0, vnet_buffer (b0)->tcp.flags,
				       my_thread_index, is_ip4))
	    {
	      error0 = TCP_ERROR_LOOKUP_DROPS;
	      next0 = TCP_RESET_NEXT_DROP;
	      goto done;
	    }

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

	done:
	  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:
 */
