/*
 * Copyright (c) 2017-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/session/application.h>
#include <vnet/session/session.h>

u8 *
format_session_fifos (u8 * s, va_list * args)
{
  session_t *ss = va_arg (*args, session_t *);
  int verbose = va_arg (*args, int);
  session_event_t _e, *e = &_e;
  u8 found;

  if (!ss->rx_fifo || !ss->tx_fifo)
    return s;

  s = format (s, " Rx fifo: %U", format_svm_fifo, ss->rx_fifo, verbose);
  if (verbose > 2 && ss->rx_fifo->has_event)
    {
      found = session_node_lookup_fifo_event (ss->rx_fifo, e);
      s = format (s, " session node event: %s\n",
		  found ? "found" : "not found");
    }
  s = format (s, " Tx fifo: %U", format_svm_fifo, ss->tx_fifo, verbose);
  if (verbose > 2 && ss->tx_fifo->has_event)
    {
      found = session_node_lookup_fifo_event (ss->tx_fifo, e);
      s = format (s, " session node event: %s\n",
		  found ? "found" : "not found");
    }
  return s;
}

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

u8 *
format_session_state (u8 * s, va_list * args)
{
  session_t *ss = va_arg (*args, session_t *);

  if (ss->session_state < SESSION_N_STATES)
    s = format (s, "%s", session_state_str[ss->session_state]);
  else
    s = format (s, "UNKNOWN STATE (%d)", ss->session_state);

  return s;
}

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

u8 *
format_session_flags (u8 * s, va_list * args)
{
  session_t *ss = va_arg (*args, session_t *);
  int i, last = -1;

  for (i = 0; i < SESSION_N_FLAGS; i++)
    if (ss->flags & (1 << i))
      last = i;

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

  return s;
}

/**
 * Format stream session as per the following format
 *
 * verbose:
 *   "Connection", "Rx fifo", "Tx fifo", "Session Index"
 * non-verbose:
 *   "Connection"
 */
u8 *
format_session (u8 * s, va_list * args)
{
  session_t *ss = va_arg (*args, session_t *);
  int verbose = va_arg (*args, int);
  u32 tp = session_get_transport_proto (ss);
  u8 *str = 0;

  if (ss->session_state >= SESSION_STATE_TRANSPORT_DELETED)
    {
      s = format (s, "[%u:%u] CLOSED", ss->thread_index, ss->session_index);
      return s;
    }

  if (verbose == 1)
    {
      u32 rxf, txf;

      rxf = ss->rx_fifo ? svm_fifo_max_dequeue (ss->rx_fifo) : 0;
      txf = ss->tx_fifo ? svm_fifo_max_dequeue (ss->tx_fifo) : 0;
      str = format (0, "%-10u%-10u", rxf, txf);
    }

  if (ss->session_state >= SESSION_STATE_ACCEPTING
      || ss->session_state == SESSION_STATE_CREATED)
    {
      s = format (s, "%U", format_transport_connection, tp,
		  ss->connection_index, ss->thread_index, verbose);
      if (verbose == 1)
	s = format (s, "%v", str);
      if (verbose > 1)
	{
	  s = format (s, "%U", format_session_fifos, ss, verbose);
	  s = format (s, " session: state: %U opaque: 0x%x flags: %U\n",
		      format_session_state, ss, ss->opaque,
		      format_session_flags, ss);
	}
    }
  else if (ss->session_state == SESSION_STATE_LISTENING)
    {
      s = format (s, "%U%v", format_transport_listen_connection,
		  tp, ss->connection_index, ss->thread_index, verbose, str);
      if (verbose > 1)
	s = format (s, "\n%U", format_session_fifos, ss, verbose);
    }
  else if (ss->session_state == SESSION_STATE_CONNECTING)
    {
      s = format (s, "%-40U%v", format_transport_half_open_connection,
		  tp, ss->connection_index, ss->thread_index, str);
    }
  else
    {
      clib_warning ("Session in state: %d!", ss->session_state);
    }
  vec_free (str);

  return s;
}

uword
unformat_stream_session_id (unformat_input_t * input, va_list * args)
{
  u8 *proto = va_arg (*args, u8 *);
  u32 *fib_index = va_arg (*args, u32 *);
  ip46_address_t *lcl = va_arg (*args, ip46_address_t *);
  ip46_address_t *rmt = va_arg (*args, ip46_address_t *);
  u16 *lcl_port = va_arg (*args, u16 *);
  u16 *rmt_port = va_arg (*args, u16 *);
  u8 *is_ip4 = va_arg (*args, u8 *);
  u8 tuple_is_set = 0;
  u32 vrf = ~0;

  clib_memset (lcl, 0, sizeof (*lcl));
  clib_memset (rmt, 0, sizeof (*rmt));

  if (unformat (input, "tcp"))
    {
      *proto = TRANSPORT_PROTO_TCP;
    }
  else if (unformat (input, "udp"))
    {
      *proto = TRANSPORT_PROTO_UDP;
    }
  else
    return 0;

  if (unformat (input, "vrf %u", &vrf))
    ;

  if (unformat (input, "%U:%d->%U:%d", unformat_ip4_address, &lcl->ip4,
		lcl_port, unformat_ip4_address, &rmt->ip4, rmt_port))
    {
      *is_ip4 = 1;
      tuple_is_set = 1;
    }
  else if (unformat (input, "%U:%d->%U:%d", unformat_ip6_address, &lcl->ip6,
		     lcl_port, unformat_ip6_address, &rmt->ip6, rmt_port))
    {
      *is_ip4 = 0;
      tuple_is_set = 1;
    }

  if (vrf != ~0)
    {
      fib_protocol_t fib_proto;
      fib_proto = *is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6;
      *fib_index = fib_table_find (fib_proto, vrf);
    }

  return tuple_is_set;
}

uword
unformat_session_state (unformat_input_t * input, va_list * args)
{
  session_state_t *state = va_arg (*args, session_state_t *);
  u8 *state_vec = 0;
  int rv = 0;

#define _(sym, str)					\
  if (unformat (input, str))				\
    {							\
      *state = SESSION_STATE_ ## sym;			\
      rv = 1;						\
      goto done;					\
    }
  foreach_session_state
#undef _
done:
  vec_free (state_vec);
  return rv;
}

uword
unformat_session (unformat_input_t * input, va_list * args)
{
  session_t **result = va_arg (*args, session_t **);
  u32 lcl_port = 0, rmt_port = 0, fib_index = 0;
  ip46_address_t lcl, rmt;
  session_t *s;
  u8 proto = ~0;
  u8 is_ip4 = 0;

  if (!unformat (input, "%U", unformat_stream_session_id, &proto, &fib_index,
		 &lcl, &rmt, &lcl_port, &rmt_port, &is_ip4))
    return 0;

  if (is_ip4)
    s = session_lookup_safe4 (fib_index, &lcl.ip4, &rmt.ip4,
			      clib_host_to_net_u16 (lcl_port),
			      clib_host_to_net_u16 (rmt_port), proto);
  else
    s = session_lookup_safe6 (fib_index, &lcl.ip6, &rmt.ip6,
			      clib_host_to_net_u16 (lcl_port),
			      clib_host_to_net_u16 (rmt_port), proto);
  if (s)
    {
      *result = s;
      session_pool_remove_peeker (s->thread_index);
      return 1;
    }
  return 0;
}

uword
unformat_transport_connection (unformat_input_t * input, va_list * args)
{
  transport_connection_t **result = va_arg (*args, transport_connection_t **);
  u32 suggested_proto = va_arg (*args, u32);
  transport_connection_t *tc;
  u8 proto = ~0;
  ip46_address_t lcl, rmt;
  u32 lcl_port = 0, rmt_port = 0, fib_index = 0;
  u8 is_ip4 = 0;

  if (!unformat (input, "%U", unformat_stream_session_id, &fib_index, &proto,
		 &lcl, &rmt, &lcl_port, &rmt_port, &is_ip4))
    return 0;

  proto = (proto == (u8) ~ 0) ? suggested_proto : proto;
  if (proto == (u8) ~ 0)
    return 0;
  if (is_ip4)
    tc = session_lookup_connection4 (fib_index, &lcl.ip4, &rmt.ip4,
				     clib_host_to_net_u16 (lcl_port),
				     clib_host_to_net_u16 (rmt_port), proto);
  else
    tc = session_lookup_connection6 (fib_index, &lcl.ip6, &rmt.ip6,
				     clib_host_to_net_u16 (lcl_port),
				     clib_host_to_net_u16 (rmt_port), proto);

  if (tc)
    {
      *result = tc;
      return 1;
    }
  return 0;
}

static void
session_cli_show_all_sessions (vlib_main_t * vm, int verbose)
{
  session_main_t *smm = &session_main;
  u32 n_closed, thread_index;
  session_t *pool, *s;

  for (thread_index = 0; thread_index < vec_len (smm->wrk); thread_index++)
    {
      pool = smm->wrk[thread_index].sessions;

      if (!pool_elts (pool))
	{
	  vlib_cli_output (vm, "Thread %d: no sessions", thread_index);
	  continue;
	}

      if (!verbose)
	{
	  vlib_cli_output (vm, "Thread %d: %d sessions", thread_index,
			   pool_elts (pool));
	  continue;
	}

      if (pool_elts (pool) > 50)
	{
	  vlib_cli_output (vm, "Thread %u: %d sessions. Verbose output "
			   "suppressed. For more details use filters.",
			   thread_index, pool_elts (pool));
	  continue;
	}

      if (verbose == 1)
	vlib_cli_output (vm, "%s%-" SESSION_CLI_ID_LEN "s%-"
			 SESSION_CLI_STATE_LEN "s%-10s%-10s",
			 thread_index ? "\n" : "",
			 "Connection", "State", "Rx-f", "Tx-f");

      n_closed = 0;

      /* *INDENT-OFF* */
      pool_foreach(s, pool, ({
        if (s->session_state >= SESSION_STATE_TRANSPORT_DELETED)
          {
            n_closed += 1;
            continue;
          }
        vlib_cli_output (vm, "%U", format_session, s, verbose);
      }));
      /* *INDENT-ON* */

      if (!n_closed)
	vlib_cli_output (vm, "Thread %d: active sessions %u", thread_index,
			 pool_elts (pool) - n_closed);
      else
	vlib_cli_output (vm, "Thread %d: active sessions %u closed %u",
			 thread_index, pool_elts (pool) - n_closed, n_closed);
    }
}

static int
session_cli_filter_check (session_t * s, session_state_t * states,
			  transport_proto_t tp)
{
  if (states)
    {
      session_state_t *state;
      vec_foreach (state, states) if (s->session_state == *state)
	goto check_transport;
      return 0;
    }

check_transport:

  if (tp != TRANSPORT_PROTO_INVALID && session_get_transport_proto (s) != tp)
    return 0;

  return 1;
}

static void
session_cli_show_session_filter (vlib_main_t * vm, u32 thread_index,
				 u32 start, u32 end, session_state_t * states,
				 transport_proto_t tp, int verbose)
{
  u8 output_suppressed = 0;
  session_worker_t *wrk;
  session_t *pool, *s;
  u32 count = 0, max_index;
  int i;

  wrk = session_main_get_worker_if_valid (thread_index);
  if (!wrk)
    {
      vlib_cli_output (vm, "invalid thread index %u", thread_index);
      return;
    }

  pool = wrk->sessions;

  if (tp == TRANSPORT_PROTO_INVALID && states == 0 && !verbose
      && (start == 0 && end == ~0))
    {
      vlib_cli_output (vm, "Thread %d: %u sessions", thread_index,
		       pool_elts (pool));
      return;
    }

  max_index = pool_len (pool) ? pool_len (pool) - 1 : 0;
  for (i = start; i <= clib_min (end, max_index); i++)
    {
      if (pool_is_free_index (pool, i))
	continue;

      s = pool_elt_at_index (pool, i);

      if (session_cli_filter_check (s, states, tp))
	{
	  count += 1;
	  if (verbose)
	    {
	      if (count > 50 || (verbose > 1 && count > 10))
		{
		  output_suppressed = 1;
		  continue;
		}
	      if (s->session_state < SESSION_STATE_TRANSPORT_DELETED)
		vlib_cli_output (vm, "%U", format_session, s, verbose);
	    }
	}
    }

  if (!output_suppressed)
    vlib_cli_output (vm, "Thread %d: %u sessions matched filter",
		     thread_index, count);
  else
    vlib_cli_output (vm, "Thread %d: %u sessions matched filter. Not all"
		     " shown. Use finer grained filter.", thread_index,
		     count);
}

void
session_cli_show_events_thread (vlib_main_t * vm, u32 thread_index)
{
  session_worker_t *wrk;

  wrk = session_main_get_worker_if_valid (thread_index);
  if (!wrk)
    {
      vlib_cli_output (vm, "invalid thread index %u", thread_index);
      return;
    }

  vlib_cli_output (vm, "Thread %d:\n", thread_index);
  vlib_cli_output (vm, " evt elements alloc: %u",
		   pool_elts (wrk->event_elts));
  vlib_cli_output (vm, " ctrl evt elt data alloc: %d",
		   pool_elts (wrk->ctrl_evts_data));
}

static void
session_cli_show_events (vlib_main_t * vm, u32 thread_index)
{
  session_main_t *smm = &session_main;
  if (!thread_index)
    {
      session_cli_show_events_thread (vm, thread_index);
      return;
    }

  for (thread_index = 0; thread_index < vec_len (smm->wrk); thread_index++)
    session_cli_show_events_thread (vm, thread_index);
}

static void
session_cli_print_session_states (vlib_main_t * vm)
{
#define _(sym, str) vlib_cli_output (vm, str);
  foreach_session_state
#undef _
}

static clib_error_t *
show_session_command_fn (vlib_main_t * vm, unformat_input_t * input,
			 vlib_cli_command_t * cmd)
{
  u8 one_session = 0, do_listeners = 0, sst, do_elog = 0, do_filter = 0;
  u32 track_index, thread_index = 0, start = 0, end = ~0, session_index;
  unformat_input_t _line_input, *line_input = &_line_input;
  transport_proto_t transport_proto = TRANSPORT_PROTO_INVALID;
  session_state_t state = SESSION_N_STATES, *states = 0;
  session_main_t *smm = &session_main;
  clib_error_t *error = 0;
  app_worker_t *app_wrk;
  u32 transport_index;
  const u8 *app_name;
  u8 do_events = 0;
  int verbose = 0;
  session_t *s;

  session_cli_return_if_not_enabled ();

  if (!unformat_user (input, unformat_line_input, line_input))
    {
      session_cli_show_all_sessions (vm, 0);
      return 0;
    }

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (line_input, "verbose %d", &verbose))
	;
      else if (unformat (line_input, "verbose"))
	verbose = 1;
      else if (unformat (line_input, "listeners %U", unformat_transport_proto,
			 &transport_proto))
	do_listeners = 1;
      else if (unformat (line_input, "%U", unformat_session, &s))
	{
	  one_session = 1;
	}
      else if (unformat (line_input, "thread %u index %u", &thread_index,
			 &session_index))
	{
	  s = session_get_if_valid (session_index, thread_index);
	  if (!s)
	    {
	      vlib_cli_output (vm, "session is not allocated");
	      goto done;
	    }
	  one_session = 1;
	}
      else if (unformat (line_input, "thread %u", &thread_index))
	{
	  do_filter = 1;
	}
      else
	if (unformat (line_input, "state %U", unformat_session_state, &state))
	{
	  vec_add1 (states, state);
	  do_filter = 1;
	}
      else if (unformat (line_input, "proto %U index %u",
			 unformat_transport_proto, &transport_proto,
			 &transport_index))
	{
	  transport_connection_t *tc;
	  tc = transport_get_connection (transport_proto, transport_index,
					 thread_index);
	  if (!tc)
	    {
	      vlib_cli_output (vm, "transport connection %u thread %u is not"
			       " allocated", transport_index, thread_index);
	      goto done;
	    }
	  s = session_get_if_valid (tc->s_index, thread_index);
	  if (!s)
	    {
	      vlib_cli_output (vm, "session for transport connection %u "
			       "thread %u does not exist", transport_index,
			       thread_index);
	      goto done;
	    }
	  one_session = 1;
	}
      else if (unformat (line_input, "proto %U", unformat_transport_proto,
			 &transport_proto))
	do_filter = 1;
      else if (unformat (line_input, "range %u %u", &start, &end))
	do_filter = 1;
      else if (unformat (line_input, "range %u", &start))
	{
	  end = start + 50;
	  do_filter = 1;
	}
      else if (unformat (line_input, "elog"))
	do_elog = 1;
      else if (unformat (line_input, "protos"))
	{
	  vlib_cli_output (vm, "%U", format_transport_protos);
	  goto done;
	}
      else if (unformat (line_input, "states"))
	{
	  session_cli_print_session_states (vm);
	  goto done;
	}
      else if (unformat (line_input, "events"))
	do_events = 1;
      else
	{
	  error = clib_error_return (0, "unknown input `%U'",
				     format_unformat_error, line_input);
	  goto done;
	}
    }

  if (one_session)
    {
      u8 *str = format (0, "%U", format_session, s, 3);
      if (do_elog && s->session_state != SESSION_STATE_LISTENING)
	{
	  elog_main_t *em = &vm->elog_main;
	  transport_connection_t *tc;
	  f64 dt;

	  tc = session_get_transport (s);
	  track_index = transport_elog_track_index (tc);
	  dt = (em->init_time.cpu - vm->clib_time.init_cpu_time)
	    * vm->clib_time.seconds_per_clock;
	  if (track_index != ~0)
	    str = format (str, " session elog:\n%U", format_elog_track, em,
			  dt, track_index);
	}
      vlib_cli_output (vm, "%v", str);
      vec_free (str);
      goto done;
    }

  if (do_listeners)
    {
      sst = session_type_from_proto_and_ip (transport_proto, 1);
      vlib_cli_output (vm, "%-" SESSION_CLI_ID_LEN "s%-24s", "Listener",
		       "App");

      /* *INDENT-OFF* */
      pool_foreach (s, smm->wrk[0].sessions, ({
	if (s->session_state != SESSION_STATE_LISTENING
	    || s->session_type != sst)
	  continue;
	app_wrk = app_worker_get (s->app_wrk_index);
	app_name = application_name_from_index (app_wrk->app_index);
	vlib_cli_output (vm, "%U%-25v%", format_session, s, 0,
			 app_name);
      }));
      /* *INDENT-ON* */
      goto done;
    }

  if (do_events)
    {
      session_cli_show_events (vm, thread_index);
      goto done;
    }

  if (do_filter)
    {
      if (end < start)
	{
	  error = clib_error_return (0, "invalid range start: %u end: %u",
				     start, end);
	  goto done;
	}
      session_cli_show_session_filter (vm, thread_index, start, end, states,
				       transport_proto, verbose);
      goto done;
    }

  session_cli_show_all_sessions (vm, verbose);

done:
  unformat_free (line_input);
  vec_free (states);
  return error;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (vlib_cli_show_session_command) =
{
  .path = "show session",
  .short_help = "show session [verbose [n]] [listeners <proto>] "
		"[<session-id> [elog]] [thread <n> [index <n>] "
		"[proto <proto>] [state <state>] [range <min> [<max>]] "
		"[protos] [states] ",
  .function = show_session_command_fn,
};
/* *INDENT-ON* */

static int
clear_session (session_t * s)
{
  app_worker_t *server_wrk = app_worker_get (s->app_wrk_index);
  app_worker_close_notify (server_wrk, s);
  return 0;
}

static clib_error_t *
clear_session_command_fn (vlib_main_t * vm, unformat_input_t * input,
			  vlib_cli_command_t * cmd)
{
  session_main_t *smm = &session_main;
  u32 thread_index = 0, clear_all = 0;
  session_worker_t *wrk;
  u32 session_index = ~0;
  session_t *session;

  if (!smm->is_enabled)
    {
      return clib_error_return (0, "session layer is not enabled");
    }

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "thread %d", &thread_index))
	;
      else if (unformat (input, "session %d", &session_index))
	;
      else if (unformat (input, "all"))
	clear_all = 1;
      else
	return clib_error_return (0, "unknown input `%U'",
				  format_unformat_error, input);
    }

  if (!clear_all && session_index == ~0)
    return clib_error_return (0, "session <nn> required, but not set.");

  if (session_index != ~0)
    {
      session = session_get_if_valid (session_index, thread_index);
      if (!session)
	return clib_error_return (0, "no session %d on thread %d",
				  session_index, thread_index);
      clear_session (session);
    }

  if (clear_all)
    {
      /* *INDENT-OFF* */
      vec_foreach (wrk, smm->wrk)
	{
	  pool_foreach(session, wrk->sessions, ({
	    clear_session (session);
	  }));
	};
      /* *INDENT-ON* */
    }

  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (clear_session_command, static) =
{
  .path = "clear session",
  .short_help = "clear session thread <thread> session <index>",
  .function = clear_session_command_fn,
};
/* *INDENT-ON* */

static clib_error_t *
show_session_fifo_trace_command_fn (vlib_main_t * vm,
				    unformat_input_t * input,
				    vlib_cli_command_t * cmd)
{
  session_t *s = 0;
  u8 is_rx = 0, *str = 0;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "%U", unformat_session, &s))
	;
      else if (unformat (input, "rx"))
	is_rx = 1;
      else if (unformat (input, "tx"))
	is_rx = 0;
      else
	return clib_error_return (0, "unknown input `%U'",
				  format_unformat_error, input);
    }

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

  if (!s)
    {
      vlib_cli_output (vm, "could not find session");
      return 0;
    }

  str = is_rx ?
    svm_fifo_dump_trace (str, s->rx_fifo) :
    svm_fifo_dump_trace (str, s->tx_fifo);

  vlib_cli_output (vm, "%v", str);
  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_session_fifo_trace_command, static) =
{
  .path = "show session fifo trace",
  .short_help = "show session fifo trace <session>",
  .function = show_session_fifo_trace_command_fn,
};
/* *INDENT-ON* */

static clib_error_t *
session_replay_fifo_command_fn (vlib_main_t * vm, unformat_input_t * input,
				vlib_cli_command_t * cmd)
{
  session_t *s = 0;
  u8 is_rx = 0, *str = 0;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "%U", unformat_session, &s))
	;
      else if (unformat (input, "rx"))
	is_rx = 1;
      else
	return clib_error_return (0, "unknown input `%U'",
				  format_unformat_error, input);
    }

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

  if (!s)
    {
      vlib_cli_output (vm, "could not find session");
      return 0;
    }

  str = is_rx ?
    svm_fifo_replay (str, s->rx_fifo, 0, 1) :
    svm_fifo_replay (str, s->tx_fifo, 0, 1);

  vlib_cli_output (vm, "%v", str);
  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (session_replay_fifo_trace_command, static) =
{
  .path = "session replay fifo",
  .short_help = "session replay fifo <session>",
  .function = session_replay_fifo_command_fn,
};
/* *INDENT-ON* */

static clib_error_t *
session_enable_disable_fn (vlib_main_t * vm, unformat_input_t * input,
			   vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  u8 is_en = 1;
  clib_error_t *error;

  if (!unformat_user (input, unformat_line_input, line_input))
    return clib_error_return (0, "expected enable | disable");

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (line_input, "enable"))
	is_en = 1;
      else if (unformat (line_input, "disable"))
	is_en = 0;
      else
	{
	  error = clib_error_return (0, "unknown input `%U'",
				     format_unformat_error, line_input);
	  unformat_free (line_input);
	  return error;
	}
    }

  unformat_free (line_input);
  return vnet_session_enable_disable (vm, is_en);
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (session_enable_disable_command, static) =
{
  .path = "session",
  .short_help = "session [enable|disable]",
  .function = session_enable_disable_fn,
};
/* *INDENT-ON* */

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