/*
 * Copyright (c) 2017 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 <math.h>
#include <vlib/vlib.h>
#include <vnet/vnet.h>
#include <vppinfra/elog.h>
#include <vnet/session/transport.h>
#include <vnet/session/application.h>
#include <vnet/session/session_debug.h>
#include <svm/queue.h>

vlib_node_registration_t session_queue_node;

typedef struct
{
  u32 session_index;
  u32 server_thread_index;
} session_queue_trace_t;

/* packet trace format function */
static u8 *
format_session_queue_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 *);
  session_queue_trace_t *t = va_arg (*args, session_queue_trace_t *);

  s = format (s, "SESSION_QUEUE: session index %d, server thread index %d",
	      t->session_index, t->server_thread_index);
  return s;
}

vlib_node_registration_t session_queue_node;

#define foreach_session_queue_error		\
_(TX, "Packets transmitted")                  	\
_(TIMER, "Timer events")			\
_(NO_BUFFER, "Out of buffers")

typedef enum
{
#define _(sym,str) SESSION_QUEUE_ERROR_##sym,
  foreach_session_queue_error
#undef _
    SESSION_QUEUE_N_ERROR,
} session_queue_error_t;

static char *session_queue_error_strings[] = {
#define _(sym,string) string,
  foreach_session_queue_error
#undef _
};

always_inline void
session_tx_fifo_chain_tail (session_manager_main_t * smm, vlib_main_t * vm,
			    u8 thread_index, svm_fifo_t * fifo,
			    vlib_buffer_t * b0, u32 bi0, u8 n_bufs_per_seg,
			    u32 left_from_seg, u32 * left_to_snd0,
			    u16 * n_bufs, u32 * tx_offset, u16 deq_per_buf,
			    u8 peek_data)
{
  vlib_buffer_t *chain_b0, *prev_b0;
  u32 chain_bi0, to_deq;
  u16 len_to_deq0, n_bytes_read;
  u8 *data0, j;

  b0->flags |= VLIB_BUFFER_TOTAL_LENGTH_VALID;
  b0->total_length_not_including_first_buffer = 0;

  chain_bi0 = bi0;
  chain_b0 = b0;
  to_deq = left_from_seg;
  for (j = 1; j < n_bufs_per_seg; j++)
    {
      prev_b0 = chain_b0;
      len_to_deq0 = clib_min (to_deq, deq_per_buf);

      *n_bufs -= 1;
      chain_bi0 = smm->tx_buffers[thread_index][*n_bufs];
      _vec_len (smm->tx_buffers[thread_index]) = *n_bufs;

      chain_b0 = vlib_get_buffer (vm, chain_bi0);
      chain_b0->current_data = 0;
      data0 = vlib_buffer_get_current (chain_b0);
      if (peek_data)
	{
	  n_bytes_read = svm_fifo_peek (fifo, *tx_offset, len_to_deq0, data0);
	  *tx_offset += n_bytes_read;
	}
      else
	{
	  n_bytes_read = svm_fifo_dequeue_nowait (fifo, len_to_deq0, data0);
	}
      ASSERT (n_bytes_read == len_to_deq0);
      chain_b0->current_length = n_bytes_read;
      b0->total_length_not_including_first_buffer += chain_b0->current_length;

      /* update previous buffer */
      prev_b0->next_buffer = chain_bi0;
      prev_b0->flags |= VLIB_BUFFER_NEXT_PRESENT;

      /* update current buffer */
      chain_b0->next_buffer = 0;

      to_deq -= n_bytes_read;
      if (to_deq == 0)
	break;
    }
  ASSERT (to_deq == 0
	  && b0->total_length_not_including_first_buffer == left_from_seg);
  *left_to_snd0 -= left_from_seg;
}

always_inline int
session_tx_fifo_read_and_snd_i (vlib_main_t * vm, vlib_node_runtime_t * node,
				session_manager_main_t * smm,
				session_fifo_event_t * e0,
				stream_session_t * s0, u32 thread_index,
				int *n_tx_packets, u8 peek_data)
{
  u32 n_trace = vlib_get_trace_count (vm, node);
  u32 left_to_snd0, max_len_to_snd0, len_to_deq0, snd_space0;
  u32 n_bufs_per_evt, n_frames_per_evt, n_bufs_per_frame;
  transport_connection_t *tc0;
  transport_proto_vft_t *transport_vft;
  transport_proto_t tp;
  u32 next_index, next0, *to_next, n_left_to_next, bi0;
  vlib_buffer_t *b0;
  u32 tx_offset = 0, max_dequeue0, n_bytes_per_seg, left_for_seg;
  u16 snd_mss0, n_bufs_per_seg, n_bufs;
  u8 *data0;
  int i, n_bytes_read;
  u32 n_bytes_per_buf, deq_per_buf, deq_per_first_buf;
  u32 bufs_alloc, bufs_now;

  next_index = next0 = smm->session_type_to_next[s0->session_type];

  tp = session_get_transport_proto (s0);
  transport_vft = transport_protocol_get_vft (tp);
  tc0 = transport_vft->get_connection (s0->connection_index, thread_index);

  /* Make sure we have space to send and there's something to dequeue */
  snd_mss0 = transport_vft->send_mss (tc0);
  snd_space0 = transport_vft->send_space (tc0);

  /* Can't make any progress */
  if (snd_space0 == 0 || snd_mss0 == 0)
    {
      vec_add1 (smm->pending_event_vector[thread_index], *e0);
      return 0;
    }

  /* Allow enqueuing of a new event */
  svm_fifo_unset_event (s0->server_tx_fifo);

  /* Check how much we can pull. */
  max_dequeue0 = svm_fifo_max_dequeue (s0->server_tx_fifo);

  if (peek_data)
    {
      /* Offset in rx fifo from where to peek data */
      tx_offset = transport_vft->tx_fifo_offset (tc0);
      if (PREDICT_FALSE (tx_offset >= max_dequeue0))
	max_dequeue0 = 0;
      else
	max_dequeue0 -= tx_offset;
    }

  /* Nothing to read return */
  if (max_dequeue0 == 0)
    return 0;

  /* Ensure we're not writing more than transport window allows */
  if (max_dequeue0 < snd_space0)
    {
      /* Constrained by tx queue. Try to send only fully formed segments */
      max_len_to_snd0 = (max_dequeue0 > snd_mss0) ?
	max_dequeue0 - max_dequeue0 % snd_mss0 : max_dequeue0;
      /* TODO Nagle ? */
    }
  else
    {
      /* Expectation is that snd_space0 is already a multiple of snd_mss */
      max_len_to_snd0 = snd_space0;
    }

  n_bytes_per_buf = vlib_buffer_free_list_buffer_size
    (vm, VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX);
  ASSERT (n_bytes_per_buf > MAX_HDRS_LEN);
  n_bytes_per_seg = MAX_HDRS_LEN + snd_mss0;
  n_bufs_per_seg = ceil ((double) n_bytes_per_seg / n_bytes_per_buf);
  n_bufs_per_evt = ceil ((double) max_len_to_snd0 / n_bytes_per_seg);
  n_frames_per_evt = ceil ((double) n_bufs_per_evt / VLIB_FRAME_SIZE);
  n_bufs_per_frame = n_bufs_per_seg * VLIB_FRAME_SIZE;

  deq_per_buf = clib_min (snd_mss0, n_bytes_per_buf);
  deq_per_first_buf = clib_min (snd_mss0, n_bytes_per_buf - MAX_HDRS_LEN);

  n_bufs = vec_len (smm->tx_buffers[thread_index]);
  left_to_snd0 = max_len_to_snd0;
  for (i = 0; i < n_frames_per_evt; i++)
    {
      /* Make sure we have at least one full frame of buffers ready */
      if (PREDICT_FALSE (n_bufs < n_bufs_per_frame))
	{
	  vec_validate (smm->tx_buffers[thread_index],
			n_bufs + n_bufs_per_frame - 1);
	  bufs_alloc = 0;
	  do
	    {
	      bufs_now =
		vlib_buffer_alloc (vm,
				   &smm->tx_buffers[thread_index][n_bufs +
								  bufs_alloc],
				   n_bufs_per_frame - bufs_alloc);
	      bufs_alloc += bufs_now;
	    }
	  while (bufs_now > 0 && ((bufs_alloc + n_bufs < n_bufs_per_frame)));

	  n_bufs += bufs_alloc;
	  _vec_len (smm->tx_buffers[thread_index]) = n_bufs;

	  if (PREDICT_FALSE (n_bufs < n_bufs_per_frame))
	    {
	      vec_add1 (smm->pending_event_vector[thread_index], *e0);
	      return -1;
	    }
	  ASSERT (n_bufs >= n_bufs_per_frame);
	}

      vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
      while (left_to_snd0 && n_left_to_next)
	{
	  /*
	   * Handle first buffer in chain separately
	   */

	  len_to_deq0 = clib_min (left_to_snd0, deq_per_first_buf);
	  if (left_to_snd0 > len_to_deq0 && n_left_to_next > 1)
	    {
	      vlib_buffer_t *pb;
	      u32 pbi = smm->tx_buffers[thread_index][n_bufs - 2];
	      pb = vlib_get_buffer (vm, pbi);
	      vlib_prefetch_buffer_header (pb, LOAD);
	    }

	  /* Get free buffer */
	  ASSERT (n_bufs >= 1);
	  bi0 = smm->tx_buffers[thread_index][--n_bufs];
	  _vec_len (smm->tx_buffers[thread_index]) = n_bufs;

	  /* usual speculation, or the enqueue_x1 macro will barf */
	  to_next[0] = bi0;
	  to_next += 1;
	  n_left_to_next -= 1;

	  b0 = vlib_get_buffer (vm, bi0);
	  b0->error = 0;
	  b0->flags = VNET_BUFFER_F_LOCALLY_ORIGINATED;
	  b0->current_data = 0;
	  b0->total_length_not_including_first_buffer = 0;

	  data0 = vlib_buffer_make_headroom (b0, MAX_HDRS_LEN);
	  if (peek_data)
	    {
	      n_bytes_read = svm_fifo_peek (s0->server_tx_fifo, tx_offset,
					    len_to_deq0, data0);
	      if (n_bytes_read <= 0)
		goto dequeue_fail;
	      /* Keep track of progress locally, transport is also supposed to
	       * increment it independently when pushing the header */
	      tx_offset += n_bytes_read;
	    }
	  else
	    {
	      n_bytes_read = svm_fifo_dequeue_nowait (s0->server_tx_fifo,
						      len_to_deq0, data0);
	      if (n_bytes_read <= 0)
		goto dequeue_fail;
	    }

	  b0->current_length = n_bytes_read;

	  left_to_snd0 -= n_bytes_read;
	  *n_tx_packets = *n_tx_packets + 1;

	  /*
	   * Fill in the remaining buffers in the chain, if any
	   */
	  if (PREDICT_FALSE (n_bufs_per_seg > 1 && left_to_snd0))
	    {
	      left_for_seg = clib_min (snd_mss0 - n_bytes_read, left_to_snd0);
	      session_tx_fifo_chain_tail (smm, vm, thread_index,
					  s0->server_tx_fifo, b0, bi0,
					  n_bufs_per_seg, left_for_seg,
					  &left_to_snd0, &n_bufs, &tx_offset,
					  deq_per_buf, peek_data);
	    }

	  /* Ask transport to push header after current_length and
	   * total_length_not_including_first_buffer are updated */
	  transport_vft->push_header (tc0, b0);

	  /* *INDENT-OFF* */
	  SESSION_EVT_DBG(SESSION_EVT_DEQ, s0, ({
	      ed->data[0] = e0->event_type;
	      ed->data[1] = max_dequeue0;
	      ed->data[2] = len_to_deq0;
	      ed->data[3] = left_to_snd0;
	  }));
	  /* *INDENT-ON* */

	  VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);

	  if (PREDICT_FALSE (n_trace > 0))
	    {
	      session_queue_trace_t *t0;
	      vlib_trace_buffer (vm, node, next_index, b0,
				 1 /* follow_chain */ );
	      vlib_set_trace_count (vm, node, --n_trace);
	      t0 = vlib_add_trace (vm, node, b0, sizeof (*t0));
	      t0->session_index = s0->session_index;
	      t0->server_thread_index = s0->thread_index;
	    }

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

  /* If we couldn't dequeue all bytes mark as partially read */
  if (max_len_to_snd0 < max_dequeue0)
    {
      /* If we don't already have new event */
      if (svm_fifo_set_event (s0->server_tx_fifo))
	{
	  vec_add1 (smm->pending_event_vector[thread_index], *e0);
	}
    }
  return 0;

dequeue_fail:
  /*
   * Can't read from fifo. If we don't already have an event, save as partially
   * read, return buff to free list and return
   */
  clib_warning ("dequeue fail");

  if (svm_fifo_set_event (s0->server_tx_fifo))
    {
      vec_add1 (smm->pending_event_vector[thread_index], *e0);
    }
  vlib_put_next_frame (vm, node, next_index, n_left_to_next + 1);
  _vec_len (smm->tx_buffers[thread_index]) += 1;

  return 0;
}

int
session_tx_fifo_peek_and_snd (vlib_main_t * vm, vlib_node_runtime_t * node,
			      session_manager_main_t * smm,
			      session_fifo_event_t * e0,
			      stream_session_t * s0, u32 thread_index,
			      int *n_tx_pkts)
{
  return session_tx_fifo_read_and_snd_i (vm, node, smm, e0, s0, thread_index,
					 n_tx_pkts, 1);
}

int
session_tx_fifo_dequeue_and_snd (vlib_main_t * vm, vlib_node_runtime_t * node,
				 session_manager_main_t * smm,
				 session_fifo_event_t * e0,
				 stream_session_t * s0, u32 thread_index,
				 int *n_tx_pkts)
{
  return session_tx_fifo_read_and_snd_i (vm, node, smm, e0, s0, thread_index,
					 n_tx_pkts, 0);
}

int
session_tx_fifo_dequeue_internal (vlib_main_t * vm,
				  vlib_node_runtime_t * node,
				  session_manager_main_t * smm,
				  session_fifo_event_t * e0,
				  stream_session_t * s0, u32 thread_index,
				  int *n_tx_pkts)
{
  application_t *app;
  app = application_get (s0->opaque);
  svm_fifo_unset_event (s0->server_tx_fifo);
  return app->cb_fns.builtin_app_tx_callback (s0);
}

always_inline stream_session_t *
session_event_get_session (session_fifo_event_t * e, u8 thread_index)
{
  return session_get_if_valid (e->fifo->master_session_index, thread_index);
}

void
dump_thread_0_event_queue (void)
{
  session_manager_main_t *smm = vnet_get_session_manager_main ();
  vlib_main_t *vm = &vlib_global_main;
  u32 my_thread_index = vm->thread_index;
  session_fifo_event_t _e, *e = &_e;
  stream_session_t *s0;
  int i, index;
  i8 *headp;

  svm_queue_t *q;
  q = smm->vpp_event_queues[my_thread_index];

  index = q->head;

  for (i = 0; i < q->cursize; i++)
    {
      headp = (i8 *) (&q->data[0] + q->elsize * index);
      clib_memcpy (e, headp, q->elsize);

      switch (e->event_type)
	{
	case FIFO_EVENT_APP_TX:
	  s0 = session_event_get_session (e, my_thread_index);
	  fformat (stdout, "[%04d] TX session %d\n", i, s0->session_index);
	  break;

	case FIFO_EVENT_DISCONNECT:
	  s0 = session_get_from_handle (e->session_handle);
	  fformat (stdout, "[%04d] disconnect session %d\n", i,
		   s0->session_index);
	  break;

	case FIFO_EVENT_BUILTIN_RX:
	  s0 = session_event_get_session (e, my_thread_index);
	  fformat (stdout, "[%04d] builtin_rx %d\n", i, s0->session_index);
	  break;

	case FIFO_EVENT_RPC:
	  fformat (stdout, "[%04d] RPC call %llx with %llx\n",
		   i, (u64) (e->rpc_args.fp), (u64) (e->rpc_args.arg));
	  break;

	default:
	  fformat (stdout, "[%04d] unhandled event type %d\n",
		   i, e->event_type);
	  break;
	}

      index++;

      if (index == q->maxsize)
	index = 0;
    }
}

static u8
session_node_cmp_event (session_fifo_event_t * e, svm_fifo_t * f)
{
  stream_session_t *s;
  switch (e->event_type)
    {
    case FIFO_EVENT_APP_RX:
    case FIFO_EVENT_APP_TX:
    case FIFO_EVENT_BUILTIN_RX:
      if (e->fifo == f)
	return 1;
      break;
    case FIFO_EVENT_DISCONNECT:
      break;
    case FIFO_EVENT_RPC:
      s = session_get_from_handle (e->session_handle);
      if (!s)
	{
	  clib_warning ("session has event but doesn't exist!");
	  break;
	}
      if (s->server_rx_fifo == f || s->server_tx_fifo == f)
	return 1;
      break;
    default:
      break;
    }
  return 0;
}

u8
session_node_lookup_fifo_event (svm_fifo_t * f, session_fifo_event_t * e)
{
  session_manager_main_t *smm = vnet_get_session_manager_main ();
  svm_queue_t *q;
  session_fifo_event_t *pending_event_vector, *evt;
  int i, index, found = 0;
  i8 *headp;
  u8 thread_index;

  ASSERT (e);
  thread_index = f->master_thread_index;
  /*
   * Search evt queue
   */
  q = smm->vpp_event_queues[thread_index];
  index = q->head;
  for (i = 0; i < q->cursize; i++)
    {
      headp = (i8 *) (&q->data[0] + q->elsize * index);
      clib_memcpy (e, headp, q->elsize);
      found = session_node_cmp_event (e, f);
      if (found)
	return 1;
      if (++index == q->maxsize)
	index = 0;
    }
  /*
   * Search pending events vector
   */
  pending_event_vector = smm->pending_event_vector[thread_index];
  vec_foreach (evt, pending_event_vector)
  {
    found = session_node_cmp_event (evt, f);
    if (found)
      {
	clib_memcpy (e, evt, sizeof (*evt));
	break;
      }
  }
  return found;
}

static uword
session_queue_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
		       vlib_frame_t * frame)
{
  session_manager_main_t *smm = vnet_get_session_manager_main ();
  session_fifo_event_t *my_pending_event_vector, *pending_disconnects, *e;
  session_fifo_event_t *my_fifo_events;
  u32 n_to_dequeue, n_events;
  svm_queue_t *q;
  application_t *app;
  int n_tx_packets = 0;
  u32 my_thread_index = vm->thread_index;
  int i, rv;
  f64 now = vlib_time_now (vm);
  void (*fp) (void *);

  SESSION_EVT_DBG (SESSION_EVT_POLL_GAP_TRACK, smm, my_thread_index);

  /*
   *  Update transport time
   */
  transport_update_time (now, my_thread_index);

  /*
   * Get vpp queue events
   */
  q = smm->vpp_event_queues[my_thread_index];
  if (PREDICT_FALSE (q == 0))
    return 0;

  my_fifo_events = smm->free_event_vector[my_thread_index];

  /* min number of events we can dequeue without blocking */
  n_to_dequeue = q->cursize;
  my_pending_event_vector = smm->pending_event_vector[my_thread_index];
  pending_disconnects = smm->pending_disconnects[my_thread_index];

  if (!n_to_dequeue && !vec_len (my_pending_event_vector)
      && !vec_len (pending_disconnects))
    return 0;

  SESSION_EVT_DBG (SESSION_EVT_DEQ_NODE, 0);

  /*
   * If we didn't manage to process previous events try going
   * over them again without dequeuing new ones.
   */
  /* XXX: Block senders to sessions that can't keep up */
  if (0 && vec_len (my_pending_event_vector) >= 100)
    {
      clib_warning ("too many fifo events unsolved");
      goto skip_dequeue;
    }

  /* See you in the next life, don't be late */
  if (pthread_mutex_trylock (&q->mutex))
    return 0;

  for (i = 0; i < n_to_dequeue; i++)
    {
      vec_add2 (my_fifo_events, e, 1);
      svm_queue_sub_raw (q, (u8 *) e);
    }

  /* The other side of the connection is not polling */
  if (q->cursize < (q->maxsize / 8))
    (void) pthread_cond_broadcast (&q->condvar);
  pthread_mutex_unlock (&q->mutex);

  vec_append (my_fifo_events, my_pending_event_vector);
  vec_append (my_fifo_events, smm->pending_disconnects[my_thread_index]);

  _vec_len (my_pending_event_vector) = 0;
  smm->pending_event_vector[my_thread_index] = my_pending_event_vector;
  _vec_len (smm->pending_disconnects[my_thread_index]) = 0;

skip_dequeue:
  n_events = vec_len (my_fifo_events);
  for (i = 0; i < n_events; i++)
    {
      stream_session_t *s0;	/* $$$ prefetch 1 ahead maybe */
      session_fifo_event_t *e0;

      e0 = &my_fifo_events[i];

      switch (e0->event_type)
	{
	case FIFO_EVENT_APP_TX:
	  s0 = session_event_get_session (e0, my_thread_index);

	  if (PREDICT_FALSE (!s0))
	    {
	      clib_warning ("It's dead, Jim!");
	      continue;
	    }
	  /* Can retransmit for closed sessions but can't do anything if
	   * session is not ready or closed */
	  if (PREDICT_FALSE (s0->session_state < SESSION_STATE_READY))
	    {
	      vec_add1 (smm->pending_event_vector[my_thread_index], *e0);
	      continue;
	    }
	  /* Spray packets in per session type frames, since they go to
	   * different nodes */
	  rv = (smm->session_tx_fns[s0->session_type]) (vm, node, smm, e0, s0,
							my_thread_index,
							&n_tx_packets);
	  /* Out of buffers */
	  if (PREDICT_FALSE (rv < 0))
	    {
	      vlib_node_increment_counter (vm, node->node_index,
					   SESSION_QUEUE_ERROR_NO_BUFFER, 1);
	      continue;
	    }
	  break;
	case FIFO_EVENT_DISCONNECT:
	  /* Make sure disconnects run after the pending list is drained */
	  if (!e0->postponed)
	    {
	      e0->postponed = 1;
	      vec_add1 (smm->pending_disconnects[my_thread_index], *e0);
	      continue;
	    }
	  s0 = session_get_from_handle (e0->session_handle);
	  stream_session_disconnect_transport (s0);
	  break;
	case FIFO_EVENT_BUILTIN_RX:
	  s0 = session_event_get_session (e0, my_thread_index);
	  if (PREDICT_FALSE (!s0))
	    continue;
	  svm_fifo_unset_event (s0->server_rx_fifo);
	  app = application_get (s0->app_index);
	  app->cb_fns.builtin_app_rx_callback (s0);
	  break;
	case FIFO_EVENT_RPC:
	  fp = e0->rpc_args.fp;
	  (*fp) (e0->rpc_args.arg);
	  break;

	default:
	  clib_warning ("unhandled event type %d", e0->event_type);
	}
    }

  _vec_len (my_fifo_events) = 0;
  smm->free_event_vector[my_thread_index] = my_fifo_events;

  vlib_node_increment_counter (vm, session_queue_node.index,
			       SESSION_QUEUE_ERROR_TX, n_tx_packets);

  SESSION_EVT_DBG (SESSION_EVT_DEQ_NODE, 1);

  return n_tx_packets;
}

/* *INDENT-OFF* */
VLIB_REGISTER_NODE (session_queue_node) =
{
  .function = session_queue_node_fn,
  .name = "session-queue",
  .format_trace = format_session_queue_trace,
  .type = VLIB_NODE_TYPE_INPUT,
  .n_errors = ARRAY_LEN (session_queue_error_strings),
  .error_strings = session_queue_error_strings,
  .state = VLIB_NODE_STATE_DISABLED,
};
/* *INDENT-ON* */

static clib_error_t *
session_queue_exit (vlib_main_t * vm)
{
  if (vec_len (vlib_mains) < 2)
    return 0;

  /*
   * Shut off (especially) worker-thread session nodes.
   * Otherwise, vpp can crash as the main thread unmaps the
   * API segment.
   */
  vlib_worker_thread_barrier_sync (vm);
  session_node_enable_disable (0 /* is_enable */ );
  vlib_worker_thread_barrier_release (vm);
  return 0;
}

VLIB_MAIN_LOOP_EXIT_FUNCTION (session_queue_exit);

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