/*
 * 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 <vnet/session/application.h>
#include <vnet/session/application_interface.h>
#include <vnet/session/application_namespace.h>
#include <vnet/session/session.h>

static app_main_t app_main;

static app_listener_t *
app_listener_alloc (application_t * app)
{
  app_listener_t *app_listener;
  pool_get (app->listeners, app_listener);
  clib_memset (app_listener, 0, sizeof (*app_listener));
  app_listener->al_index = app_listener - app->listeners;
  return app_listener;
}

static app_listener_t *
app_listener_get (application_t * app, u32 app_listener_index)
{
  return pool_elt_at_index (app->listeners, app_listener_index);
}

static void
app_listener_free (application_t * app, app_listener_t * app_listener)
{
  clib_bitmap_free (app_listener->workers);
  pool_put (app->listeners, app_listener);
  if (CLIB_DEBUG)
    clib_memset (app_listener, 0xfa, sizeof (*app_listener));
}

static app_listener_t *
app_local_listener_alloc (application_t * app)
{
  app_listener_t *app_listener;
  pool_get (app->local_listeners, app_listener);
  clib_memset (app_listener, 0, sizeof (*app_listener));
  app_listener->al_index = app_listener - app->local_listeners;
  return app_listener;
}

static app_listener_t *
app_local_listener_get (application_t * app, u32 app_listener_index)
{
  return pool_elt_at_index (app->local_listeners, app_listener_index);
}

static void
app_local_listener_free (application_t * app, app_listener_t * app_listener)
{
  clib_bitmap_free (app_listener->workers);
  pool_put (app->local_listeners, app_listener);
  if (CLIB_DEBUG)
    clib_memset (app_listener, 0xfa, sizeof (*app_listener));
}

static app_worker_map_t *
app_worker_map_alloc (application_t * app)
{
  app_worker_map_t *map;
  pool_get (app->worker_maps, map);
  clib_memset (map, 0, sizeof (*map));
  return map;
}

static u32
app_worker_map_index (application_t * app, app_worker_map_t * map)
{
  return (map - app->worker_maps);
}

static void
app_worker_map_free (application_t * app, app_worker_map_t * map)
{
  pool_put (app->worker_maps, map);
}

static app_worker_map_t *
app_worker_map_get (application_t * app, u32 map_index)
{
  return pool_elt_at_index (app->worker_maps, map_index);
}

static u8 *
app_get_name_from_reg_index (application_t * app)
{
  u8 *app_name;

  vl_api_registration_t *regp;
  regp = vl_api_client_index_to_registration (app->api_client_index);
  if (!regp)
    app_name = format (0, "builtin-%d%c", app->app_index, 0);
  else
    app_name = format (0, "%s%c", regp->name, 0);

  return app_name;
}

static u8 *
app_get_name (application_t * app)
{
  if (!app->name)
    return app_get_name_from_reg_index (app);
  return app->name;
}

u32
application_session_table (application_t * app, u8 fib_proto)
{
  app_namespace_t *app_ns;
  app_ns = app_namespace_get (app->ns_index);
  if (!application_has_global_scope (app))
    return APP_INVALID_INDEX;
  if (fib_proto == FIB_PROTOCOL_IP4)
    return session_lookup_get_index_for_fib (fib_proto,
					     app_ns->ip4_fib_index);
  else
    return session_lookup_get_index_for_fib (fib_proto,
					     app_ns->ip6_fib_index);
}

u32
application_local_session_table (application_t * app)
{
  app_namespace_t *app_ns;
  if (!application_has_local_scope (app))
    return APP_INVALID_INDEX;
  app_ns = app_namespace_get (app->ns_index);
  return app_ns->local_table_index;
}

static void
application_local_listener_session_endpoint (local_session_t * ll,
					     session_endpoint_t * sep)
{
  sep->transport_proto =
    session_type_transport_proto (ll->listener_session_type);
  sep->port = ll->port;
  sep->is_ip4 = ll->listener_session_type & 1;
}

int
application_api_queue_is_full (application_t * app)
{
  svm_queue_t *q;

  /* builtin servers are always OK */
  if (app->api_client_index == ~0)
    return 0;

  q = vl_api_client_index_to_input_queue (app->api_client_index);
  if (!q)
    return 1;

  if (q->cursize == q->maxsize)
    return 1;
  return 0;
}

/**
 * Returns app name
 *
 * Since the name is not stored per app, we generate it on the fly. It is
 * the caller's responsibility to free the vector
 */
u8 *
application_name_from_index (u32 app_index)
{
  application_t *app = application_get (app_index);
  if (!app)
    return 0;
  return app_get_name_from_reg_index (app);
}

static void
application_table_add (application_t * app)
{
  if (app->api_client_index != APP_INVALID_INDEX)
    hash_set (app_main.app_by_api_client_index, app->api_client_index,
	      app->app_index);
  else if (app->name)
    hash_set_mem (app_main.app_by_name, app->name, app->app_index);
}

static void
application_table_del (application_t * app)
{
  if (app->api_client_index != APP_INVALID_INDEX)
    hash_unset (app_main.app_by_api_client_index, app->api_client_index);
  else if (app->name)
    hash_unset_mem (app_main.app_by_name, app->name);
}

application_t *
application_lookup (u32 api_client_index)
{
  uword *p;
  p = hash_get (app_main.app_by_api_client_index, api_client_index);
  if (p)
    return application_get (p[0]);

  return 0;
}

application_t *
application_lookup_name (const u8 * name)
{
  uword *p;
  p = hash_get_mem (app_main.app_by_name, name);
  if (p)
    return application_get (p[0]);

  return 0;
}

application_t *
application_alloc (void)
{
  application_t *app;
  pool_get (app_main.app_pool, app);
  clib_memset (app, 0, sizeof (*app));
  app->app_index = app - app_main.app_pool;
  return app;
}

application_t *
application_get (u32 app_index)
{
  if (app_index == APP_INVALID_INDEX)
    return 0;
  return pool_elt_at_index (app_main.app_pool, app_index);
}

application_t *
application_get_if_valid (u32 app_index)
{
  if (pool_is_free_index (app_main.app_pool, app_index))
    return 0;

  return pool_elt_at_index (app_main.app_pool, app_index);
}

u32
application_index (application_t * app)
{
  return app - app_main.app_pool;
}

static void
application_verify_cb_fns (session_cb_vft_t * cb_fns)
{
  if (cb_fns->session_accept_callback == 0)
    clib_warning ("No accept callback function provided");
  if (cb_fns->session_connected_callback == 0)
    clib_warning ("No session connected callback function provided");
  if (cb_fns->session_disconnect_callback == 0)
    clib_warning ("No session disconnect callback function provided");
  if (cb_fns->session_reset_callback == 0)
    clib_warning ("No session reset callback function provided");
}

/**
 * Check app config for given segment type
 *
 * Returns 1 on success and 0 otherwise
 */
static u8
application_verify_cfg (ssvm_segment_type_t st)
{
  u8 is_valid;
  if (st == SSVM_SEGMENT_MEMFD)
    {
      is_valid = (session_manager_get_evt_q_segment () != 0);
      if (!is_valid)
	clib_warning ("memfd seg: vpp's event qs IN binary api svm region");
      return is_valid;
    }
  else if (st == SSVM_SEGMENT_SHM)
    {
      is_valid = (session_manager_get_evt_q_segment () == 0);
      if (!is_valid)
	clib_warning ("shm seg: vpp's event qs NOT IN binary api svm region");
      return is_valid;
    }
  else
    return 1;
}

int
application_alloc_and_init (app_init_args_t * a)
{
  ssvm_segment_type_t seg_type = SSVM_SEGMENT_MEMFD;
  segment_manager_properties_t *props;
  vl_api_registration_t *reg;
  application_t *app;
  u64 *options;

  app = application_alloc ();
  options = a->options;
  /*
   * Make sure we support the requested configuration
   */
  if (!(options[APP_OPTIONS_FLAGS] & APP_OPTIONS_FLAGS_IS_BUILTIN))
    {
      reg = vl_api_client_index_to_registration (a->api_client_index);
      if (!reg)
	return VNET_API_ERROR_APP_UNSUPPORTED_CFG;
      if (vl_api_registration_file_index (reg) == VL_API_INVALID_FI)
	seg_type = SSVM_SEGMENT_SHM;
    }
  else
    {
      if (options[APP_OPTIONS_FLAGS] & APP_OPTIONS_FLAGS_EVT_MQ_USE_EVENTFD)
	{
	  clib_warning ("mq eventfds can only be used if socket transport is "
			"used for api");
	  return VNET_API_ERROR_APP_UNSUPPORTED_CFG;
	}
      seg_type = SSVM_SEGMENT_PRIVATE;
    }

  if (!application_verify_cfg (seg_type))
    return VNET_API_ERROR_APP_UNSUPPORTED_CFG;

  /* Check that the obvious things are properly set up */
  application_verify_cb_fns (a->session_cb_vft);

  app->api_client_index = a->api_client_index;
  app->flags = options[APP_OPTIONS_FLAGS];
  app->cb_fns = *a->session_cb_vft;
  app->ns_index = options[APP_OPTIONS_NAMESPACE];
  app->proxied_transports = options[APP_OPTIONS_PROXY_TRANSPORT];
  app->name = vec_dup (a->name);

  /* If no scope enabled, default to global */
  if (!application_has_global_scope (app)
      && !application_has_local_scope (app))
    app->flags |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;

  props = application_segment_manager_properties (app);
  segment_manager_properties_init (props);
  props->segment_size = options[APP_OPTIONS_ADD_SEGMENT_SIZE];
  props->prealloc_fifos = options[APP_OPTIONS_PREALLOC_FIFO_PAIRS];
  if (options[APP_OPTIONS_ADD_SEGMENT_SIZE])
    {
      props->add_segment_size = options[APP_OPTIONS_ADD_SEGMENT_SIZE];
      props->add_segment = 1;
    }
  if (options[APP_OPTIONS_RX_FIFO_SIZE])
    props->rx_fifo_size = options[APP_OPTIONS_RX_FIFO_SIZE];
  if (options[APP_OPTIONS_TX_FIFO_SIZE])
    props->tx_fifo_size = options[APP_OPTIONS_TX_FIFO_SIZE];
  if (options[APP_OPTIONS_EVT_QUEUE_SIZE])
    props->evt_q_size = options[APP_OPTIONS_EVT_QUEUE_SIZE];
  if (options[APP_OPTIONS_FLAGS] & APP_OPTIONS_FLAGS_EVT_MQ_USE_EVENTFD)
    props->use_mq_eventfd = 1;
  if (options[APP_OPTIONS_TLS_ENGINE])
    app->tls_engine = options[APP_OPTIONS_TLS_ENGINE];
  props->segment_type = seg_type;

  /* Add app to lookup by api_client_index table */
  application_table_add (app);
  a->app_index = application_index (app);

  APP_DBG ("New app name: %v api index: %u index %u", app->name,
	   app->api_client_index, app->app_index);

  return 0;
}

void
application_free (application_t * app)
{
  app_worker_map_t *wrk_map;
  app_worker_t *app_wrk;
  u32 table_index;
  local_session_t *ll;
  session_endpoint_t sep;

  /*
   * The app event queue allocated in first segment is cleared with
   * the segment manager. No need to explicitly free it.
   */
  APP_DBG ("Delete app name %v api index: %d index: %d", app->name,
	   app->api_client_index, app->app_index);

  if (application_is_proxy (app))
    application_remove_proxy (app);

  /*
   * Free workers
   */

  /* *INDENT-OFF* */
  pool_flush (wrk_map, app->worker_maps, ({
    app_wrk = app_worker_get (wrk_map->wrk_index);
    app_worker_free (app_wrk);
  }));
  /* *INDENT-ON* */
  pool_free (app->worker_maps);

  /*
   * Free local listeners. Global table unbinds stop local listeners
   * as well, but if we have only local binds, these won't be cleaned up.
   * Don't bother with local accepted sessions, we clean them when
   * cleaning up the worker.
   */
  table_index = application_local_session_table (app);
  /* *INDENT-OFF* */
  pool_foreach (ll, app->local_listen_sessions, ({
    application_local_listener_session_endpoint (ll, &sep);
    session_lookup_del_session_endpoint (table_index, &sep);
  }));
  /* *INDENT-ON* */
  pool_free (app->local_listen_sessions);

  /*
   * Cleanup remaining state
   */
  application_table_del (app);
  vec_free (app->name);
  vec_free (app->tls_cert);
  vec_free (app->tls_key);
  pool_put (app_main.app_pool, app);
}

app_worker_t *
application_get_worker (application_t * app, u32 wrk_map_index)
{
  app_worker_map_t *map;
  map = app_worker_map_get (app, wrk_map_index);
  if (!map)
    return 0;
  return app_worker_get (map->wrk_index);
}

app_worker_t *
application_get_default_worker (application_t * app)
{
  return application_get_worker (app, 0);
}

app_worker_t *
application_listener_select_worker (stream_session_t * ls, u8 is_local)
{
  app_listener_t *app_listener;
  application_t *app;
  u32 wrk_index;

  app = application_get (ls->app_index);
  if (!is_local)
    app_listener = app_listener_get (app, ls->listener_db_index);
  else
    app_listener = app_local_listener_get (app, ls->listener_db_index);

  wrk_index = clib_bitmap_next_set (app_listener->workers,
				    app_listener->accept_rotor + 1);
  if (wrk_index == ~0)
    wrk_index = clib_bitmap_first_set (app_listener->workers);

  ASSERT (wrk_index != ~0);
  app_listener->accept_rotor = wrk_index;
  return application_get_worker (app, wrk_index);
}

app_worker_t *
app_worker_alloc (application_t * app)
{
  app_worker_t *app_wrk;
  pool_get (app_main.workers, app_wrk);
  clib_memset (app_wrk, 0, sizeof (*app_wrk));
  app_wrk->wrk_index = app_wrk - app_main.workers;
  app_wrk->app_index = app->app_index;
  app_wrk->wrk_map_index = ~0;
  app_wrk->connects_seg_manager = APP_INVALID_SEGMENT_MANAGER_INDEX;
  app_wrk->first_segment_manager = APP_INVALID_SEGMENT_MANAGER_INDEX;
  app_wrk->local_segment_manager = APP_INVALID_SEGMENT_MANAGER_INDEX;
  APP_DBG ("New app %v worker %u", app_get_name (app), app_wrk->wrk_index);
  return app_wrk;
}

app_worker_t *
app_worker_get (u32 wrk_index)
{
  return pool_elt_at_index (app_main.workers, wrk_index);
}

app_worker_t *
app_worker_get_if_valid (u32 wrk_index)
{
  if (pool_is_free_index (app_main.workers, wrk_index))
    return 0;
  return pool_elt_at_index (app_main.workers, wrk_index);
}

void
app_worker_free (app_worker_t * app_wrk)
{
  application_t *app = application_get (app_wrk->app_index);
  vnet_unbind_args_t _a, *a = &_a;
  u64 handle, *handles = 0;
  segment_manager_t *sm;
  u32 sm_index;
  int i;

  /*
   *  Listener cleanup
   */

  /* *INDENT-OFF* */
  hash_foreach (handle, sm_index, app_wrk->listeners_table,
  ({
    vec_add1 (handles, handle);
    sm = segment_manager_get (sm_index);
    sm->app_wrk_index = SEGMENT_MANAGER_INVALID_APP_INDEX;
  }));
  /* *INDENT-ON* */

  for (i = 0; i < vec_len (handles); i++)
    {
      a->app_index = app->app_index;
      a->wrk_map_index = app_wrk->wrk_map_index;
      a->handle = handles[i];
      /* seg manager is removed when unbind completes */
      vnet_unbind (a);
    }

  /*
   * Connects segment manager cleanup
   */

  if (app_wrk->connects_seg_manager != APP_INVALID_SEGMENT_MANAGER_INDEX)
    {
      sm = segment_manager_get (app_wrk->connects_seg_manager);
      sm->app_wrk_index = SEGMENT_MANAGER_INVALID_APP_INDEX;
      segment_manager_init_del (sm);
    }

  /* If first segment manager is used by a listener */
  if (app_wrk->first_segment_manager != APP_INVALID_SEGMENT_MANAGER_INDEX
      && app_wrk->first_segment_manager != app_wrk->connects_seg_manager)
    {
      sm = segment_manager_get (app_wrk->first_segment_manager);
      sm->first_is_protected = 0;
      sm->app_wrk_index = SEGMENT_MANAGER_INVALID_APP_INDEX;
      /* .. and has no fifos, e.g. it might be used for redirected sessions,
       * remove it */
      if (!segment_manager_has_fifos (sm))
	segment_manager_del (sm);
    }

  /*
   * Local sessions
   */
  app_worker_local_sessions_free (app_wrk);

  pool_put (app_main.workers, app_wrk);
  if (CLIB_DEBUG)
    clib_memset (app_wrk, 0xfe, sizeof (*app_wrk));
}

int
app_worker_alloc_and_init (application_t * app, app_worker_t ** wrk)
{
  app_worker_map_t *wrk_map;
  app_worker_t *app_wrk;
  segment_manager_t *sm;
  int rv;

  app_wrk = app_worker_alloc (app);
  wrk_map = app_worker_map_alloc (app);
  wrk_map->wrk_index = app_wrk->wrk_index;
  app_wrk->wrk_map_index = app_worker_map_index (app, wrk_map);

  /*
   * Setup first segment manager
   */
  sm = segment_manager_new ();
  sm->app_wrk_index = app_wrk->wrk_index;

  if ((rv = segment_manager_init (sm, app->sm_properties.segment_size,
				  app->sm_properties.prealloc_fifos)))
    {
      app_worker_free (app_wrk);
      return rv;
    }
  sm->first_is_protected = 1;

  /*
   * Setup app worker
   */
  app_wrk->first_segment_manager = segment_manager_index (sm);
  app_wrk->listeners_table = hash_create (0, sizeof (u64));
  app_wrk->event_queue = segment_manager_event_queue (sm);
  app_wrk->app_is_builtin = application_is_builtin (app);

  /*
   * Segment manager for local sessions
   */
  sm = segment_manager_new ();
  sm->app_wrk_index = app_wrk->wrk_index;
  app_wrk->local_segment_manager = segment_manager_index (sm);
  app_wrk->local_connects = hash_create (0, sizeof (u64));

  *wrk = app_wrk;

  return 0;
}

application_t *
app_worker_get_app (u32 wrk_index)
{
  app_worker_t *app_wrk;
  app_wrk = app_worker_get_if_valid (wrk_index);
  if (!app_wrk)
    return 0;
  return application_get_if_valid (app_wrk->app_index);
}

static segment_manager_t *
app_worker_alloc_segment_manager (app_worker_t * app_wrk)
{
  segment_manager_t *sm = 0;

  /* If the first segment manager is not in use, don't allocate a new one */
  if (app_wrk->first_segment_manager != APP_INVALID_SEGMENT_MANAGER_INDEX
      && app_wrk->first_segment_manager_in_use == 0)
    {
      sm = segment_manager_get (app_wrk->first_segment_manager);
      app_wrk->first_segment_manager_in_use = 1;
      return sm;
    }

  sm = segment_manager_new ();
  sm->app_wrk_index = app_wrk->wrk_index;

  return sm;
}

int
app_worker_start_listen (app_worker_t * app_wrk, stream_session_t * ls)
{
  segment_manager_t *sm;

  /* Allocate segment manager. All sessions derived out of a listen session
   * have fifos allocated by the same segment manager. */
  if (!(sm = app_worker_alloc_segment_manager (app_wrk)))
    return -1;

  /* Add to app's listener table. Useful to find all child listeners
   * when app goes down, although, just for unbinding this is not needed */
  hash_set (app_wrk->listeners_table, listen_session_get_handle (ls),
	    segment_manager_index (sm));

  if (!ls->server_rx_fifo
      && session_transport_service_type (ls) == TRANSPORT_SERVICE_CL)
    {
      if (session_alloc_fifos (sm, ls))
	return -1;
    }
  return 0;
}

int
app_worker_stop_listen (app_worker_t * app_wrk, session_handle_t handle)
{
  segment_manager_t *sm;
  uword *sm_indexp;

  sm_indexp = hash_get (app_wrk->listeners_table, handle);
  if (PREDICT_FALSE (!sm_indexp))
    {
      clib_warning ("listener handle was removed %llu!", handle);
      return -1;
    }

  sm = segment_manager_get (*sm_indexp);
  if (app_wrk->first_segment_manager == *sm_indexp)
    {
      /* Delete sessions but don't remove segment manager */
      app_wrk->first_segment_manager_in_use = 0;
      segment_manager_del_sessions (sm);
    }
  else
    {
      segment_manager_init_del (sm);
    }
  hash_unset (app_wrk->listeners_table, handle);

  return 0;
}

/**
 * Start listening local transport endpoint for requested transport.
 *
 * Creates a 'dummy' stream session with state LISTENING to be used in session
 * lookups, prior to establishing connection. Requests transport to build
 * it's own specific listening connection.
 */
int
application_start_listen (application_t * app,
			  session_endpoint_extended_t * sep_ext,
			  session_handle_t * res)
{
  app_listener_t *app_listener;
  u32 table_index, fib_proto;
  session_endpoint_t *sep;
  app_worker_t *app_wrk;
  stream_session_t *ls;
  session_handle_t lh;
  session_type_t sst;

  /*
   * Check if sep is already listened on
   */
  sep = (session_endpoint_t *) sep_ext;
  fib_proto = session_endpoint_fib_proto (sep);
  table_index = application_session_table (app, fib_proto);
  lh = session_lookup_endpoint_listener (table_index, sep, 1);
  if (lh != SESSION_INVALID_HANDLE)
    {
      ls = listen_session_get_from_handle (lh);
      if (ls->app_index != app->app_index)
	return VNET_API_ERROR_ADDRESS_IN_USE;

      app_wrk = app_worker_get (sep_ext->app_wrk_index);
      if (ls->app_wrk_index == app_wrk->wrk_index)
	return VNET_API_ERROR_ADDRESS_IN_USE;

      if (app_worker_start_listen (app_wrk, ls))
	return -1;

      app_listener = app_listener_get (app, ls->listener_db_index);
      app_listener->workers = clib_bitmap_set (app_listener->workers,
					       app_wrk->wrk_map_index, 1);

      *res = listen_session_get_handle (ls);
      return 0;
    }

  /*
   * Allocate new listener for application
   */
  sst = session_type_from_proto_and_ip (sep_ext->transport_proto,
					sep_ext->is_ip4);
  ls = listen_session_new (0, sst);
  ls->app_index = app->app_index;
  lh = listen_session_get_handle (ls);
  if (session_listen (ls, sep_ext))
    goto err;


  ls = listen_session_get_from_handle (lh);
  app_listener = app_listener_alloc (app);
  ls->listener_db_index = app_listener->al_index;

  /*
   * Setup app worker as a listener
   */
  app_wrk = app_worker_get (sep_ext->app_wrk_index);
  ls->app_wrk_index = app_wrk->wrk_index;
  if (app_worker_start_listen (app_wrk, ls))
    goto err;
  app_listener->workers = clib_bitmap_set (app_listener->workers,
					   app_wrk->wrk_map_index, 1);

  *res = lh;
  return 0;

err:
  listen_session_del (ls);
  return -1;
}

/**
 * Stop listening on session associated to handle
 *
 * @param handle	listener handle
 * @param app_index	index of the app owning the handle.
 * @param app_wrk_index	index of the worker requesting the stop
 */
int
application_stop_listen (u32 app_index, u32 app_wrk_index,
			 session_handle_t handle)
{
  app_listener_t *app_listener;
  stream_session_t *listener;
  app_worker_t *app_wrk;
  application_t *app;

  listener = listen_session_get_from_handle (handle);
  app = application_get (app_index);
  if (PREDICT_FALSE (!app || app->app_index != listener->app_index))
    {
      clib_warning ("app doesn't own handle %llu!", handle);
      return -1;
    }

  app_listener = app_listener_get (app, listener->listener_db_index);
  if (!clib_bitmap_get (app_listener->workers, app_wrk_index))
    {
      clib_warning ("worker not listening on handle %lu", handle);
      return 0;
    }

  app_wrk = application_get_worker (app, app_wrk_index);
  app_worker_stop_listen (app_wrk, handle);
  clib_bitmap_set_no_check (app_listener->workers, app_wrk_index, 0);

  if (clib_bitmap_is_zero (app_listener->workers))
    {
      session_stop_listen (listener);
      app_listener_free (app, app_listener);
      listen_session_del (listener);
    }

  return 0;
}

int
app_worker_open_session (app_worker_t * app, session_endpoint_t * sep,
			 u32 api_context)
{
  int rv;

  /* Make sure we have a segment manager for connects */
  app_worker_alloc_connects_segment_manager (app);

  if ((rv = session_open (app->wrk_index, sep, api_context)))
    return rv;

  return 0;
}

int
app_worker_alloc_connects_segment_manager (app_worker_t * app_wrk)
{
  segment_manager_t *sm;

  if (app_wrk->connects_seg_manager == APP_INVALID_SEGMENT_MANAGER_INDEX)
    {
      sm = app_worker_alloc_segment_manager (app_wrk);
      if (sm == 0)
	return -1;
      app_wrk->connects_seg_manager = segment_manager_index (sm);
    }
  return 0;
}

segment_manager_t *
app_worker_get_connect_segment_manager (app_worker_t * app)
{
  ASSERT (app->connects_seg_manager != (u32) ~ 0);
  return segment_manager_get (app->connects_seg_manager);
}

segment_manager_t *
app_worker_get_listen_segment_manager (app_worker_t * app,
				       stream_session_t * listener)
{
  uword *smp;
  smp = hash_get (app->listeners_table, listen_session_get_handle (listener));
  ASSERT (smp != 0);
  return segment_manager_get (*smp);
}

clib_error_t *
vnet_app_worker_add_del (vnet_app_worker_add_del_args_t * a)
{
  svm_fifo_segment_private_t *fs;
  app_worker_map_t *wrk_map;
  app_worker_t *app_wrk;
  segment_manager_t *sm;
  application_t *app;
  int rv;

  app = application_get (a->app_index);
  if (!app)
    return clib_error_return_code (0, VNET_API_ERROR_INVALID_VALUE, 0,
				   "App %u does not exist", a->app_index);

  if (a->is_add)
    {
      if ((rv = app_worker_alloc_and_init (app, &app_wrk)))
	return clib_error_return_code (0, rv, 0, "app wrk init: %d", rv);
      sm = segment_manager_get (app_wrk->first_segment_manager);
      fs = segment_manager_get_segment_w_lock (sm, 0);
      a->segment = &fs->ssvm;
      segment_manager_segment_reader_unlock (sm);
      a->evt_q = app_wrk->event_queue;
      a->wrk_index = app_wrk->wrk_map_index;
    }
  else
    {
      wrk_map = app_worker_map_get (app, a->wrk_index);
      if (!wrk_map)
	return clib_error_return_code (0, VNET_API_ERROR_INVALID_VALUE, 0,
				       "App %u does not have worker %u",
				       app->app_index, a->wrk_index);
      app_wrk = app_worker_get (wrk_map->wrk_index);
      app_worker_map_free (app, wrk_map);
      if (!app_wrk)
	return clib_error_return_code (0, VNET_API_ERROR_INVALID_VALUE, 0,
				       "No worker %u", a->wrk_index);
      app_worker_free (app_wrk);
    }
  return 0;
}

segment_manager_t *
application_get_local_segment_manager (app_worker_t * app)
{
  return segment_manager_get (app->local_segment_manager);
}

segment_manager_t *
application_get_local_segment_manager_w_session (app_worker_t * app,
						 local_session_t * ls)
{
  stream_session_t *listener;
  if (application_local_session_listener_has_transport (ls))
    {
      listener = listen_session_get (ls->listener_index);
      return app_worker_get_listen_segment_manager (app, listener);
    }
  return segment_manager_get (app->local_segment_manager);
}

int
application_is_proxy (application_t * app)
{
  return (app->flags & APP_OPTIONS_FLAGS_IS_PROXY);
}

int
application_is_builtin (application_t * app)
{
  return (app->flags & APP_OPTIONS_FLAGS_IS_BUILTIN);
}

int
application_is_builtin_proxy (application_t * app)
{
  return (application_is_proxy (app) && application_is_builtin (app));
}

u8
application_has_local_scope (application_t * app)
{
  return app->flags & APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
}

u8
application_has_global_scope (application_t * app)
{
  return app->flags & APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
}

u8
application_use_mq_for_ctrl (application_t * app)
{
  return app->flags & APP_OPTIONS_FLAGS_USE_MQ_FOR_CTRL_MSGS;
}

/**
 * Send an API message to the external app, to map new segment
 */
int
app_worker_add_segment_notify (u32 app_wrk_index, ssvm_private_t * fs)
{
  app_worker_t *app_wrk = app_worker_get (app_wrk_index);
  application_t *app = application_get (app_wrk->app_index);
  return app->cb_fns.add_segment_callback (app->api_client_index, fs);
}

u32
application_n_listeners (app_worker_t * app)
{
  return hash_elts (app->listeners_table);
}

stream_session_t *
app_worker_first_listener (app_worker_t * app, u8 fib_proto,
			   u8 transport_proto)
{
  stream_session_t *listener;
  u64 handle;
  u32 sm_index;
  u8 sst;

  sst = session_type_from_proto_and_ip (transport_proto,
					fib_proto == FIB_PROTOCOL_IP4);

  /* *INDENT-OFF* */
   hash_foreach (handle, sm_index, app->listeners_table, ({
     listener = listen_session_get_from_handle (handle);
     if (listener->session_type == sst
	 && listener->enqueue_epoch != SESSION_PROXY_LISTENER_INDEX)
       return listener;
   }));
  /* *INDENT-ON* */

  return 0;
}

u8
app_worker_application_is_builtin (app_worker_t * app_wrk)
{
  return app_wrk->app_is_builtin;
}

stream_session_t *
application_proxy_listener (app_worker_t * app, u8 fib_proto,
			    u8 transport_proto)
{
  stream_session_t *listener;
  u64 handle;
  u32 sm_index;
  u8 sst;

  sst = session_type_from_proto_and_ip (transport_proto,
					fib_proto == FIB_PROTOCOL_IP4);

  /* *INDENT-OFF* */
   hash_foreach (handle, sm_index, app->listeners_table, ({
     listener = listen_session_get_from_handle (handle);
     if (listener->session_type == sst
	 && listener->enqueue_epoch == SESSION_PROXY_LISTENER_INDEX)
       return listener;
   }));
  /* *INDENT-ON* */

  return 0;
}

static clib_error_t *
application_start_stop_proxy_fib_proto (application_t * app, u8 fib_proto,
					u8 transport_proto, u8 is_start)
{
  app_namespace_t *app_ns = app_namespace_get (app->ns_index);
  u8 is_ip4 = (fib_proto == FIB_PROTOCOL_IP4);
  session_endpoint_extended_t sep = SESSION_ENDPOINT_EXT_NULL;
  transport_connection_t *tc;
  app_worker_t *app_wrk;
  stream_session_t *s;
  u64 handle;

  /* TODO decide if we want proxy to be enabled for all workers */
  app_wrk = application_get_default_worker (app);
  if (is_start)
    {
      s = app_worker_first_listener (app_wrk, fib_proto, transport_proto);
      if (!s)
	{
	  sep.is_ip4 = is_ip4;
	  sep.fib_index = app_namespace_get_fib_index (app_ns, fib_proto);
	  sep.sw_if_index = app_ns->sw_if_index;
	  sep.transport_proto = transport_proto;
	  sep.app_wrk_index = app_wrk->wrk_index;	/* only default */
	  application_start_listen (app, &sep, &handle);
	  s = listen_session_get_from_handle (handle);
	  s->enqueue_epoch = SESSION_PROXY_LISTENER_INDEX;
	}
    }
  else
    {
      s = application_proxy_listener (app_wrk, fib_proto, transport_proto);
      ASSERT (s);
    }

  tc = listen_session_get_transport (s);

  if (!ip_is_zero (&tc->lcl_ip, 1))
    {
      u32 sti;
      sep.is_ip4 = is_ip4;
      sep.fib_index = app_namespace_get_fib_index (app_ns, fib_proto);
      sep.transport_proto = transport_proto;
      sep.port = 0;
      sti = session_lookup_get_index_for_fib (fib_proto, sep.fib_index);
      if (is_start)
	session_lookup_add_session_endpoint (sti,
					     (session_endpoint_t *) & sep,
					     s->session_index);
      else
	session_lookup_del_session_endpoint (sti,
					     (session_endpoint_t *) & sep);
    }

  return 0;
}

static void
application_start_stop_proxy_local_scope (application_t * app,
					  u8 transport_proto, u8 is_start)
{
  session_endpoint_t sep = SESSION_ENDPOINT_NULL;
  app_namespace_t *app_ns;
  app_ns = app_namespace_get (app->ns_index);
  sep.is_ip4 = 1;
  sep.transport_proto = transport_proto;
  sep.port = 0;

  if (is_start)
    {
      session_lookup_add_session_endpoint (app_ns->local_table_index, &sep,
					   app->app_index);
      sep.is_ip4 = 0;
      session_lookup_add_session_endpoint (app_ns->local_table_index, &sep,
					   app->app_index);
    }
  else
    {
      session_lookup_del_session_endpoint (app_ns->local_table_index, &sep);
      sep.is_ip4 = 0;
      session_lookup_del_session_endpoint (app_ns->local_table_index, &sep);
    }
}

void
application_start_stop_proxy (application_t * app,
			      transport_proto_t transport_proto, u8 is_start)
{
  if (application_has_local_scope (app))
    application_start_stop_proxy_local_scope (app, transport_proto, is_start);

  if (application_has_global_scope (app))
    {
      application_start_stop_proxy_fib_proto (app, FIB_PROTOCOL_IP4,
					      transport_proto, is_start);
      application_start_stop_proxy_fib_proto (app, FIB_PROTOCOL_IP6,
					      transport_proto, is_start);
    }
}

void
application_setup_proxy (application_t * app)
{
  u16 transports = app->proxied_transports;
  transport_proto_t tp;

  ASSERT (application_is_proxy (app));

  /* *INDENT-OFF* */
  transport_proto_foreach (tp, ({
    if (transports & (1 << tp))
      application_start_stop_proxy (app, tp, 1);
  }));
  /* *INDENT-ON* */
}

void
application_remove_proxy (application_t * app)
{
  u16 transports = app->proxied_transports;
  transport_proto_t tp;

  ASSERT (application_is_proxy (app));

  /* *INDENT-OFF* */
  transport_proto_foreach (tp, ({
    if (transports & (1 << tp))
      application_start_stop_proxy (app, tp, 0);
  }));
  /* *INDENT-ON* */
}

segment_manager_properties_t *
application_segment_manager_properties (application_t * app)
{
  return &app->sm_properties;
}

segment_manager_properties_t *
application_get_segment_manager_properties (u32 app_index)
{
  application_t *app = application_get (app_index);
  return &app->sm_properties;
}

static inline int
app_enqueue_evt (svm_msg_q_t * mq, svm_msg_q_msg_t * msg, u8 lock)
{
  if (PREDICT_FALSE (svm_msg_q_is_full (mq)))
    {
      clib_warning ("evt q full");
      svm_msg_q_free_msg (mq, msg);
      if (lock)
	svm_msg_q_unlock (mq);
      return -1;
    }

  if (lock)
    {
      svm_msg_q_add_and_unlock (mq, msg);
      return 0;
    }

  /* Even when not locking the ring, we must wait for queue mutex */
  if (svm_msg_q_add (mq, msg, SVM_Q_WAIT))
    {
      clib_warning ("msg q add returned");
      return -1;
    }
  return 0;
}

static inline int
app_send_io_evt_rx (app_worker_t * app_wrk, stream_session_t * s, u8 lock)
{
  session_event_t *evt;
  svm_msg_q_msg_t msg;
  svm_msg_q_t *mq;

  if (PREDICT_FALSE (s->session_state != SESSION_STATE_READY
		     && s->session_state != SESSION_STATE_LISTENING))
    {
      /* Session is closed so app will never clean up. Flush rx fifo */
      if (s->session_state == SESSION_STATE_CLOSED)
	svm_fifo_dequeue_drop_all (s->server_rx_fifo);
      return 0;
    }

  if (app_worker_application_is_builtin (app_wrk))
    {
      application_t *app = application_get (app_wrk->app_index);
      return app->cb_fns.builtin_app_rx_callback (s);
    }

  if (svm_fifo_has_event (s->server_rx_fifo)
      || svm_fifo_is_empty (s->server_rx_fifo))
    return 0;

  mq = app_wrk->event_queue;
  if (lock)
    svm_msg_q_lock (mq);

  if (PREDICT_FALSE (svm_msg_q_ring_is_full (mq, SESSION_MQ_IO_EVT_RING)))
    {
      clib_warning ("evt q rings full");
      if (lock)
	svm_msg_q_unlock (mq);
      return -1;
    }

  msg = svm_msg_q_alloc_msg_w_ring (mq, SESSION_MQ_IO_EVT_RING);
  ASSERT (!svm_msg_q_msg_is_invalid (&msg));

  evt = (session_event_t *) svm_msg_q_msg_data (mq, &msg);
  evt->fifo = s->server_rx_fifo;
  evt->event_type = FIFO_EVENT_APP_RX;

  (void) svm_fifo_set_event (s->server_rx_fifo);

  if (app_enqueue_evt (mq, &msg, lock))
    return -1;
  return 0;
}

static inline int
app_send_io_evt_tx (app_worker_t * app_wrk, stream_session_t * s, u8 lock)
{
  svm_msg_q_t *mq;
  session_event_t *evt;
  svm_msg_q_msg_t msg;

  if (app_worker_application_is_builtin (app_wrk))
    return 0;

  mq = app_wrk->event_queue;
  if (lock)
    svm_msg_q_lock (mq);

  if (PREDICT_FALSE (svm_msg_q_ring_is_full (mq, SESSION_MQ_IO_EVT_RING)))
    {
      clib_warning ("evt q rings full");
      if (lock)
	svm_msg_q_unlock (mq);
      return -1;
    }

  msg = svm_msg_q_alloc_msg_w_ring (mq, SESSION_MQ_IO_EVT_RING);
  ASSERT (!svm_msg_q_msg_is_invalid (&msg));

  evt = (session_event_t *) svm_msg_q_msg_data (mq, &msg);
  evt->event_type = FIFO_EVENT_APP_TX;
  evt->fifo = s->server_tx_fifo;

  return app_enqueue_evt (mq, &msg, lock);
}

/* *INDENT-OFF* */
typedef int (app_send_evt_handler_fn) (app_worker_t *app,
				       stream_session_t *s,
				       u8 lock);
static app_send_evt_handler_fn * const app_send_evt_handler_fns[3] = {
    app_send_io_evt_rx,
    0,
    app_send_io_evt_tx,
};
/* *INDENT-ON* */

/**
 * Send event to application
 *
 * Logic from queue perspective is non-blocking. If there's
 * not enough space to enqueue a message, we return.
 */
int
app_worker_send_event (app_worker_t * app, stream_session_t * s, u8 evt_type)
{
  ASSERT (app && evt_type <= FIFO_EVENT_APP_TX);
  return app_send_evt_handler_fns[evt_type] (app, s, 0 /* lock */ );
}

/**
 * Send event to application
 *
 * Logic from queue perspective is blocking. However, if queue is full,
 * we return.
 */
int
app_worker_lock_and_send_event (app_worker_t * app, stream_session_t * s,
				u8 evt_type)
{
  return app_send_evt_handler_fns[evt_type] (app, s, 1 /* lock */ );
}

local_session_t *
application_local_session_alloc (app_worker_t * app_wrk)
{
  local_session_t *s;
  pool_get (app_wrk->local_sessions, s);
  clib_memset (s, 0, sizeof (*s));
  s->app_wrk_index = app_wrk->wrk_index;
  s->session_index = s - app_wrk->local_sessions;
  s->session_type = session_type_from_proto_and_ip (TRANSPORT_PROTO_NONE, 0);
  return s;
}

void
application_local_session_free (app_worker_t * app, local_session_t * s)
{
  pool_put (app->local_sessions, s);
  if (CLIB_DEBUG)
    clib_memset (s, 0xfc, sizeof (*s));
}

local_session_t *
application_get_local_session (app_worker_t * app_wrk, u32 session_index)
{
  if (pool_is_free_index (app_wrk->local_sessions, session_index))
    return 0;
  return pool_elt_at_index (app_wrk->local_sessions, session_index);
}

local_session_t *
application_get_local_session_from_handle (session_handle_t handle)
{
  app_worker_t *server_wrk;
  u32 session_index, server_wrk_index;
  local_session_parse_handle (handle, &server_wrk_index, &session_index);
  server_wrk = app_worker_get_if_valid (server_wrk_index);
  if (!server_wrk)
    return 0;
  return application_get_local_session (server_wrk, session_index);
}

local_session_t *
application_local_listen_session_alloc (application_t * app)
{
  local_session_t *ll;
  pool_get (app->local_listen_sessions, ll);
  clib_memset (ll, 0, sizeof (*ll));
  return ll;
}

u32
application_local_listener_index (application_t * app, local_session_t * ll)
{
  return (ll - app->local_listen_sessions);
}

void
application_local_listen_session_free (application_t * app,
				       local_session_t * ll)
{
  pool_put (app->local_listen_sessions, ll);
  if (CLIB_DEBUG)
    clib_memset (ll, 0xfb, sizeof (*ll));
}

int
application_start_local_listen (application_t * app,
				session_endpoint_extended_t * sep_ext,
				session_handle_t * handle)
{
  app_listener_t *app_listener;
  session_endpoint_t *sep;
  app_worker_t *app_wrk;
  session_handle_t lh;
  local_session_t *ll;
  u32 table_index;

  sep = (session_endpoint_t *) sep_ext;
  table_index = application_local_session_table (app);
  app_wrk = app_worker_get (sep_ext->app_wrk_index);

  /* An exact sep match, as opposed to session_lookup_local_listener */
  lh = session_lookup_endpoint_listener (table_index, sep, 1);
  if (lh != SESSION_INVALID_HANDLE)
    {
      ll = application_get_local_listener_w_handle (lh);
      if (ll->app_index != app->app_index)
	return VNET_API_ERROR_ADDRESS_IN_USE;

      if (ll->app_wrk_index == app_wrk->wrk_index)
	return VNET_API_ERROR_ADDRESS_IN_USE;

      app_listener = app_local_listener_get (app, ll->listener_db_index);
      app_listener->workers = clib_bitmap_set (app_listener->workers,
					       app_wrk->wrk_map_index, 1);
      *handle = application_local_session_handle (ll);
      return 0;
    }

  ll = application_local_listen_session_alloc (app);
  ll->session_type = session_type_from_proto_and_ip (TRANSPORT_PROTO_NONE, 0);
  ll->app_wrk_index = app_wrk->app_index;
  ll->session_index = application_local_listener_index (app, ll);
  ll->port = sep_ext->port;
  /* Store the original session type for the unbind */
  ll->listener_session_type =
    session_type_from_proto_and_ip (sep_ext->transport_proto,
				    sep_ext->is_ip4);
  ll->transport_listener_index = ~0;
  ll->app_index = app->app_index;

  app_listener = app_local_listener_alloc (app);
  ll->listener_db_index = app_listener->al_index;
  app_listener->workers = clib_bitmap_set (app_listener->workers,
					   app_wrk->wrk_map_index, 1);

  *handle = application_local_session_handle (ll);
  session_lookup_add_session_endpoint (table_index, sep, *handle);

  return 0;
}

/**
 * Clean up local session table. If we have a listener session use it to
 * find the port and proto. If not, the handle must be a local table handle
 * so parse it.
 */
int
application_stop_local_listen (u32 app_index, u32 wrk_map_index,
			       session_handle_t lh)
{
  session_endpoint_t sep = SESSION_ENDPOINT_NULL;
  u32 table_index, ll_index, server_index;
  app_listener_t *app_listener;
  app_worker_t *server_wrk;
  stream_session_t *sl = 0;
  local_session_t *ll, *ls;
  application_t *server;

  server = application_get (app_index);
  table_index = application_local_session_table (server);

  /* We have both local and global table binds. Figure from global what
   * the sep we should be cleaning up is.
   */
  if (!session_handle_is_local (lh))
    {
      sl = listen_session_get_from_handle (lh);
      if (!sl || listen_session_get_local_session_endpoint (sl, &sep))
	{
	  clib_warning ("broken listener");
	  return -1;
	}
      lh = session_lookup_endpoint_listener (table_index, &sep, 0);
      if (lh == SESSION_INVALID_HANDLE)
	return -1;
    }

  local_session_parse_handle (lh, &server_index, &ll_index);
  if (PREDICT_FALSE (server_index != app_index))
    {
      clib_warning ("app %u does not own local handle 0x%lx", app_index, lh);
      return -1;
    }

  ll = application_get_local_listen_session (server, ll_index);
  if (PREDICT_FALSE (!ll))
    {
      clib_warning ("no local listener");
      return -1;
    }

  app_listener = app_local_listener_get (server, ll->listener_db_index);
  if (!clib_bitmap_get (app_listener->workers, wrk_map_index))
    {
      clib_warning ("app wrk %u not listening on handle %lu", wrk_map_index,
		    lh);
      return -1;
    }

  server_wrk = application_get_worker (server, wrk_map_index);
  /* *INDENT-OFF* */
  pool_foreach (ls, server_wrk->local_sessions, ({
    if (ls->listener_index == ll->session_index)
      application_local_session_disconnect (server_wrk->app_index, ls);
  }));
  /* *INDENT-ON* */

  clib_bitmap_set_no_check (app_listener->workers, wrk_map_index, 0);
  if (clib_bitmap_is_zero (app_listener->workers))
    {
      app_local_listener_free (server, app_listener);
      application_local_listener_session_endpoint (ll, &sep);
      session_lookup_del_session_endpoint (table_index, &sep);
      application_local_listen_session_free (server, ll);
    }

  return 0;
}

static void
application_local_session_fix_eventds (svm_msg_q_t * sq, svm_msg_q_t * cq)
{
  int fd;

  /*
   * segment manager initializes only the producer eventds, since vpp is
   * typically the producer. But for local sessions, we also pass to the
   * apps the mqs they listen on for events from peer apps, so they are also
   * consumer fds.
   */
  fd = svm_msg_q_get_producer_eventfd (sq);
  svm_msg_q_set_consumer_eventfd (sq, fd);
  fd = svm_msg_q_get_producer_eventfd (cq);
  svm_msg_q_set_consumer_eventfd (cq, fd);
}

int
application_local_session_connect (app_worker_t * client_wrk,
				   app_worker_t * server_wrk,
				   local_session_t * ll, u32 opaque)
{
  u32 seg_size, evt_q_sz, evt_q_elts, margin = 16 << 10;
  segment_manager_properties_t *props, *cprops;
  u32 round_rx_fifo_sz, round_tx_fifo_sz;
  int rv, has_transport, seg_index;
  svm_fifo_segment_private_t *seg;
  application_t *server, *client;
  segment_manager_t *sm;
  local_session_t *ls;
  svm_msg_q_t *sq, *cq;

  ls = application_local_session_alloc (server_wrk);
  server = application_get (server_wrk->app_index);
  client = application_get (client_wrk->app_index);

  props = application_segment_manager_properties (server);
  cprops = application_segment_manager_properties (client);
  evt_q_elts = props->evt_q_size + cprops->evt_q_size;
  evt_q_sz = segment_manager_evt_q_expected_size (evt_q_elts);
  round_rx_fifo_sz = 1 << max_log2 (props->rx_fifo_size);
  round_tx_fifo_sz = 1 << max_log2 (props->tx_fifo_size);
  seg_size = round_rx_fifo_sz + round_tx_fifo_sz + evt_q_sz + margin;

  has_transport = session_has_transport ((stream_session_t *) ll);
  if (!has_transport)
    {
      /* Local sessions don't have backing transport */
      ls->port = ll->port;
      sm = application_get_local_segment_manager (server_wrk);
    }
  else
    {
      stream_session_t *sl = (stream_session_t *) ll;
      transport_connection_t *tc;
      tc = listen_session_get_transport (sl);
      ls->port = tc->lcl_port;
      sm = app_worker_get_listen_segment_manager (server_wrk, sl);
    }

  seg_index = segment_manager_add_segment (sm, seg_size);
  if (seg_index < 0)
    {
      clib_warning ("failed to add new cut-through segment");
      return seg_index;
    }
  seg = segment_manager_get_segment_w_lock (sm, seg_index);
  sq = segment_manager_alloc_queue (seg, props);
  cq = segment_manager_alloc_queue (seg, cprops);

  if (props->use_mq_eventfd)
    application_local_session_fix_eventds (sq, cq);

  ls->server_evt_q = pointer_to_uword (sq);
  ls->client_evt_q = pointer_to_uword (cq);
  rv = segment_manager_try_alloc_fifos (seg, props->rx_fifo_size,
					props->tx_fifo_size,
					&ls->server_rx_fifo,
					&ls->server_tx_fifo);
  if (rv)
    {
      clib_warning ("failed to add fifos in cut-through segment");
      segment_manager_segment_reader_unlock (sm);
      goto failed;
    }
  ls->server_rx_fifo->ct_session_index = ls->session_index;
  ls->server_tx_fifo->ct_session_index = ls->session_index;
  ls->svm_segment_index = seg_index;
  ls->listener_index = ll->session_index;
  ls->client_wrk_index = client_wrk->wrk_index;
  ls->client_opaque = opaque;
  ls->listener_session_type = ll->session_type;
  ls->session_state = SESSION_STATE_READY;

  if ((rv = server->cb_fns.add_segment_callback (server->api_client_index,
						 &seg->ssvm)))
    {
      clib_warning ("failed to notify server of new segment");
      segment_manager_segment_reader_unlock (sm);
      goto failed;
    }
  segment_manager_segment_reader_unlock (sm);
  if ((rv = server->cb_fns.session_accept_callback ((stream_session_t *) ls)))
    {
      clib_warning ("failed to send accept cut-through notify to server");
      goto failed;
    }
  if (server->flags & APP_OPTIONS_FLAGS_IS_BUILTIN)
    application_local_session_connect_notify (ls);

  return 0;

failed:
  if (!has_transport)
    segment_manager_del_segment (sm, seg);
  return rv;
}

static uword
application_client_local_connect_key (local_session_t * ls)
{
  return ((uword) ls->app_wrk_index << 32 | (uword) ls->session_index);
}

static void
application_client_local_connect_key_parse (uword key, u32 * app_wrk_index,
					    u32 * session_index)
{
  *app_wrk_index = key >> 32;
  *session_index = key & 0xFFFFFFFF;
}

int
application_local_session_connect_notify (local_session_t * ls)
{
  svm_fifo_segment_private_t *seg;
  app_worker_t *client_wrk, *server_wrk;
  segment_manager_t *sm;
  application_t *client;
  int rv, is_fail = 0;
  uword client_key;

  client_wrk = app_worker_get (ls->client_wrk_index);
  server_wrk = app_worker_get (ls->app_wrk_index);
  client = application_get (client_wrk->app_index);

  sm = application_get_local_segment_manager_w_session (server_wrk, ls);
  seg = segment_manager_get_segment_w_lock (sm, ls->svm_segment_index);
  if ((rv = client->cb_fns.add_segment_callback (client->api_client_index,
						 &seg->ssvm)))
    {
      clib_warning ("failed to notify client %u of new segment",
		    ls->client_wrk_index);
      segment_manager_segment_reader_unlock (sm);
      application_local_session_disconnect (ls->client_wrk_index, ls);
      is_fail = 1;
    }
  else
    {
      segment_manager_segment_reader_unlock (sm);
    }

  client->cb_fns.session_connected_callback (client_wrk->wrk_index,
					     ls->client_opaque,
					     (stream_session_t *) ls,
					     is_fail);

  client_key = application_client_local_connect_key (ls);
  hash_set (client_wrk->local_connects, client_key, client_key);
  return 0;
}

int
application_local_session_cleanup (app_worker_t * client_wrk,
				   app_worker_t * server_wrk,
				   local_session_t * ls)
{
  svm_fifo_segment_private_t *seg;
  stream_session_t *listener;
  segment_manager_t *sm;
  uword client_key;
  u8 has_transport;

  /* Retrieve listener transport type as it is the one that decides where
   * the fifos are allocated */
  has_transport = application_local_session_listener_has_transport (ls);
  if (!has_transport)
    sm = application_get_local_segment_manager_w_session (server_wrk, ls);
  else
    {
      listener = listen_session_get (ls->listener_index);
      sm = app_worker_get_listen_segment_manager (server_wrk, listener);
    }

  seg = segment_manager_get_segment (sm, ls->svm_segment_index);
  if (client_wrk)
    {
      client_key = application_client_local_connect_key (ls);
      hash_unset (client_wrk->local_connects, client_key);
    }

  if (!has_transport)
    {
      application_t *server = application_get (server_wrk->app_index);
      server->cb_fns.del_segment_callback (server->api_client_index,
					   &seg->ssvm);
      if (client_wrk)
	{
	  application_t *client = application_get (client_wrk->app_index);
	  client->cb_fns.del_segment_callback (client->api_client_index,
					       &seg->ssvm);
	}
      segment_manager_del_segment (sm, seg);
    }

  application_local_session_free (server_wrk, ls);

  return 0;
}

int
application_local_session_disconnect (u32 app_index, local_session_t * ls)
{
  app_worker_t *client_wrk, *server_wrk;
  u8 is_server = 0, is_client = 0;
  application_t *app;

  app = application_get_if_valid (app_index);
  if (!app)
    return 0;

  client_wrk = app_worker_get_if_valid (ls->client_wrk_index);
  server_wrk = app_worker_get (ls->app_wrk_index);

  if (server_wrk->app_index == app_index)
    is_server = 1;
  else if (client_wrk && client_wrk->app_index == app_index)
    is_client = 1;

  if (!is_server && !is_client)
    {
      clib_warning ("app %u is neither client nor server for session 0x%lx",
		    app_index, application_local_session_handle (ls));
      return VNET_API_ERROR_INVALID_VALUE;
    }

  if (ls->session_state == SESSION_STATE_CLOSED)
    return application_local_session_cleanup (client_wrk, server_wrk, ls);

  if (app_index == ls->client_wrk_index)
    {
      mq_send_local_session_disconnected_cb (ls->app_wrk_index, ls);
    }
  else
    {
      if (!client_wrk)
	{
	  return application_local_session_cleanup (client_wrk, server_wrk,
						    ls);
	}
      else if (ls->session_state < SESSION_STATE_READY)
	{
	  application_t *client = application_get (client_wrk->app_index);
	  client->cb_fns.session_connected_callback (client_wrk->wrk_index,
						     ls->client_opaque,
						     (stream_session_t *) ls,
						     1 /* is_fail */ );
	  ls->session_state = SESSION_STATE_CLOSED;
	  return application_local_session_cleanup (client_wrk, server_wrk,
						    ls);
	}
      else
	{
	  mq_send_local_session_disconnected_cb (client_wrk->wrk_index, ls);
	}
    }

  ls->session_state = SESSION_STATE_CLOSED;

  return 0;
}

int
application_local_session_disconnect_w_index (u32 app_wrk_index, u32 ls_index)
{
  app_worker_t *app_wrk;
  local_session_t *ls;
  app_wrk = app_worker_get (app_wrk_index);
  ls = application_get_local_session (app_wrk, ls_index);
  return application_local_session_disconnect (app_wrk_index, ls);
}

void
app_worker_local_sessions_free (app_worker_t * app_wrk)
{
  u32 index, server_wrk_index, session_index;
  u64 handle, *handles = 0;
  app_worker_t *server_wrk;
  segment_manager_t *sm;
  local_session_t *ls;
  int i;

  /*
   * Local sessions
   */
  if (app_wrk->local_sessions)
    {
      /* *INDENT-OFF* */
      pool_foreach (ls, app_wrk->local_sessions, ({
	application_local_session_disconnect (app_wrk->wrk_index, ls);
      }));
      /* *INDENT-ON* */
    }

  /*
   * Local connects
   */
  vec_reset_length (handles);
  /* *INDENT-OFF* */
  hash_foreach (handle, index, app_wrk->local_connects, ({
    vec_add1 (handles, handle);
  }));
  /* *INDENT-ON* */

  for (i = 0; i < vec_len (handles); i++)
    {
      application_client_local_connect_key_parse (handles[i],
						  &server_wrk_index,
						  &session_index);
      server_wrk = app_worker_get_if_valid (server_wrk_index);
      if (server_wrk)
	{
	  ls = application_get_local_session (server_wrk, session_index);
	  application_local_session_disconnect (app_wrk->wrk_index, ls);
	}
    }

  sm = segment_manager_get (app_wrk->local_segment_manager);
  sm->app_wrk_index = SEGMENT_MANAGER_INVALID_APP_INDEX;
  segment_manager_del (sm);
}

clib_error_t *
vnet_app_add_tls_cert (vnet_app_add_tls_cert_args_t * a)
{
  application_t *app;
  app = application_get (a->app_index);
  if (!app)
    return clib_error_return_code (0, VNET_API_ERROR_APPLICATION_NOT_ATTACHED,
				   0, "app %u doesn't exist", a->app_index);
  app->tls_cert = vec_dup (a->cert);
  return 0;
}

clib_error_t *
vnet_app_add_tls_key (vnet_app_add_tls_key_args_t * a)
{
  application_t *app;
  app = application_get (a->app_index);
  if (!app)
    return clib_error_return_code (0, VNET_API_ERROR_APPLICATION_NOT_ATTACHED,
				   0, "app %u doesn't exist", a->app_index);
  app->tls_key = vec_dup (a->key);
  return 0;
}

u8 *
format_app_worker_listener (u8 * s, va_list * args)
{
  app_worker_t *app_wrk = va_arg (*args, app_worker_t *);
  u64 handle = va_arg (*args, u64);
  u32 sm_index = va_arg (*args, u32);
  int verbose = va_arg (*args, int);
  stream_session_t *listener;
  application_t *app;
  u8 *app_name, *str;

  if (!app_wrk)
    {
      if (verbose)
	s = format (s, "%-40s%-25s%=10s%-15s%-15s%-10s", "Connection", "App",
		    "Wrk", "API Client", "ListenerID", "SegManager");
      else
	s = format (s, "%-40s%-25s%=10s", "Connection", "App", "Wrk");

      return s;
    }

  app = application_get (app_wrk->app_index);
  app_name = app_get_name_from_reg_index (app);
  listener = listen_session_get_from_handle (handle);
  str = format (0, "%U", format_stream_session, listener, verbose);

  if (verbose)
    {
      char buf[32];
      sprintf (buf, "%u(%u)", app_wrk->wrk_map_index, app_wrk->wrk_index);
      s = format (s, "%-40s%-25s%=10s%-15u%-15u%-10u", str, app_name,
		  buf, app->api_client_index, handle, sm_index);
    }
  else
    s = format (s, "%-40s%-25s%=10u", str, app_name, app_wrk->wrk_map_index);

  vec_free (app_name);
  return s;
}

static void
application_format_listeners (application_t * app, int verbose)
{
  vlib_main_t *vm = vlib_get_main ();
  app_worker_map_t *wrk_map;
  app_worker_t *app_wrk;
  u32 sm_index;
  u64 handle;

  if (!app)
    {
      vlib_cli_output (vm, "%U", format_app_worker_listener, 0 /* header */ ,
		       0, 0, verbose);
      return;
    }

  /* *INDENT-OFF* */
  pool_foreach (wrk_map, app->worker_maps, ({
    app_wrk = app_worker_get (wrk_map->wrk_index);
    if (hash_elts (app_wrk->listeners_table) == 0)
      continue;
    hash_foreach (handle, sm_index, app_wrk->listeners_table, ({
      vlib_cli_output (vm, "%U", format_app_worker_listener, app_wrk,
                       handle, sm_index, verbose);
    }));
  }));
  /* *INDENT-ON* */
}

static void
app_worker_format_connects (app_worker_t * app_wrk, int verbose)
{
  svm_fifo_segment_private_t *fifo_segment;
  vlib_main_t *vm = vlib_get_main ();
  segment_manager_t *sm;
  u8 *app_name, *s = 0;
  application_t *app;

  /* Header */
  if (!app_wrk)
    {
      if (verbose)
	vlib_cli_output (vm, "%-40s%-20s%-15s%-10s", "Connection", "App",
			 "API Client", "SegManager");
      else
	vlib_cli_output (vm, "%-40s%-20s", "Connection", "App");
      return;
    }

  app = application_get (app_wrk->app_index);
  if (app_wrk->connects_seg_manager == (u32) ~ 0)
    return;

  app_name = app_get_name_from_reg_index (app);

  /* Across all fifo segments */
  sm = segment_manager_get (app_wrk->connects_seg_manager);

  /* *INDENT-OFF* */
  segment_manager_foreach_segment_w_lock (fifo_segment, sm, ({
    svm_fifo_t *fifo;
    u8 *str;

    fifo = svm_fifo_segment_get_fifo_list (fifo_segment);
    while (fifo)
	{
	  u32 session_index, thread_index;
	  stream_session_t *session;

	  session_index = fifo->master_session_index;
	  thread_index = fifo->master_thread_index;

	  session = session_get (session_index, thread_index);
	  str = format (0, "%U", format_stream_session, session, verbose);

	  if (verbose)
	    s = format (s, "%-40s%-20s%-15u%-10u", str, app_name,
			app->api_client_index, app_wrk->connects_seg_manager);
	  else
	    s = format (s, "%-40s%-20s", str, app_name);

	  vlib_cli_output (vm, "%v", s);
	  vec_reset_length (s);
	  vec_free (str);

	  fifo = fifo->next;
	}
    vec_free (s);
  }));
  /* *INDENT-ON* */

  vec_free (app_name);
}

static void
application_format_connects (application_t * app, int verbose)
{
  app_worker_map_t *wrk_map;
  app_worker_t *app_wrk;

  if (!app)
    {
      app_worker_format_connects (0, verbose);
      return;
    }

  /* *INDENT-OFF* */
  pool_foreach (wrk_map, app->worker_maps, ({
    app_wrk = app_worker_get (wrk_map->wrk_index);
    app_worker_format_connects (app_wrk, verbose);
  }));
  /* *INDENT-ON* */
}

static void
app_worker_format_local_sessions (app_worker_t * app_wrk, int verbose)
{
  vlib_main_t *vm = vlib_get_main ();
  local_session_t *ls;
  transport_proto_t tp;
  u8 *conn = 0;

  /* Header */
  if (app_wrk == 0)
    {
      vlib_cli_output (vm, "%-40s%-15s%-20s", "Connection", "ServerApp",
		       "ClientApp");
      return;
    }

  if (!pool_elts (app_wrk->local_sessions)
      && !pool_elts (app_wrk->local_connects))
    return;

  /* *INDENT-OFF* */
  pool_foreach (ls, app_wrk->local_sessions, ({
    tp = session_type_transport_proto(ls->listener_session_type);
    conn = format (0, "[L][%U] *:%u", format_transport_proto_short, tp,
                   ls->port);
    vlib_cli_output (vm, "%-40v%-15u%-20u", conn, ls->app_wrk_index,
                     ls->client_wrk_index);
    vec_reset_length (conn);
  }));
  /* *INDENT-ON* */

  vec_free (conn);
}

static void
application_format_local_sessions (application_t * app, int verbose)
{
  vlib_main_t *vm = vlib_get_main ();
  app_worker_map_t *wrk_map;
  app_worker_t *app_wrk;
  transport_proto_t tp;
  local_session_t *ls;
  u8 *conn = 0;

  if (!app)
    {
      app_worker_format_local_sessions (0, verbose);
      return;
    }

  /*
   * Format local listeners
   */

  /* *INDENT-OFF* */
  pool_foreach (ls, app->local_listen_sessions, ({
    tp = session_type_transport_proto (ls->listener_session_type);
    conn = format (0, "[L][%U] *:%u", format_transport_proto_short, tp,
                   ls->port);
    vlib_cli_output (vm, "%-40v%-15u%-20s", conn, ls->app_wrk_index, "*");
    vec_reset_length (conn);
  }));
  /* *INDENT-ON* */

  /*
   * Format local accepted/connected sessions
   */
  /* *INDENT-OFF* */
  pool_foreach (wrk_map, app->worker_maps, ({
    app_wrk = app_worker_get (wrk_map->wrk_index);
    app_worker_format_local_sessions (app_wrk, verbose);
  }));
  /* *INDENT-ON* */
}

static void
app_worker_format_local_connects (app_worker_t * app, int verbose)
{
  vlib_main_t *vm = vlib_get_main ();
  u32 app_wrk_index, session_index;
  app_worker_t *server_wrk;
  local_session_t *ls;
  uword client_key;
  u64 value;

  /* Header */
  if (app == 0)
    {
      if (verbose)
	vlib_cli_output (vm, "%-40s%-15s%-20s%-10s", "Connection", "App",
			 "Peer App", "SegManager");
      else
	vlib_cli_output (vm, "%-40s%-15s%-20s", "Connection", "App",
			 "Peer App");
      return;
    }

  if (!app->local_connects)
    return;

  /* *INDENT-OFF* */
  hash_foreach (client_key, value, app->local_connects, ({
    application_client_local_connect_key_parse (client_key, &app_wrk_index,
                                                &session_index);
    server_wrk = app_worker_get (app_wrk_index);
    ls = application_get_local_session (server_wrk, session_index);
    vlib_cli_output (vm, "%-40s%-15s%-20s", "TODO", ls->app_wrk_index,
                     ls->client_wrk_index);
  }));
  /* *INDENT-ON* */
}

static void
application_format_local_connects (application_t * app, int verbose)
{
  app_worker_map_t *wrk_map;
  app_worker_t *app_wrk;

  if (!app)
    {
      app_worker_format_local_connects (0, verbose);
      return;
    }

  /* *INDENT-OFF* */
  pool_foreach (wrk_map, app->worker_maps, ({
    app_wrk = app_worker_get (wrk_map->wrk_index);
    app_worker_format_local_connects (app_wrk, verbose);
  }));
  /* *INDENT-ON* */
}

u8 *
format_application (u8 * s, va_list * args)
{
  application_t *app = va_arg (*args, application_t *);
  CLIB_UNUSED (int verbose) = va_arg (*args, int);
  segment_manager_properties_t *props;
  const u8 *app_ns_name;
  u8 *app_name;

  if (app == 0)
    {
      if (verbose)
	s = format (s, "%-10s%-20s%-15s%-15s%-15s%-15s%-15s", "Index", "Name",
		    "API Client", "Namespace", "Add seg size", "Rx-f size",
		    "Tx-f size");
      else
	s = format (s, "%-10s%-20s%-15s%-40s", "Index", "Name", "API Client",
		    "Namespace");
      return s;
    }

  app_name = app_get_name (app);
  app_ns_name = app_namespace_id_from_index (app->ns_index);
  props = application_segment_manager_properties (app);
  if (verbose)
    s = format (s, "%-10u%-20s%-15d%-15u%-15U%-15U%-15U", app->app_index,
		app_name, app->api_client_index, app->ns_index,
		format_memory_size, props->add_segment_size,
		format_memory_size, props->rx_fifo_size, format_memory_size,
		props->tx_fifo_size);
  else
    s = format (s, "%-10u%-20s%-15d%-40s", app->app_index, app_name,
		app->api_client_index, app_ns_name);
  return s;
}

void
application_format_all_listeners (vlib_main_t * vm, int do_local, int verbose)
{
  application_t *app;

  if (!pool_elts (app_main.app_pool))
    {
      vlib_cli_output (vm, "No active server bindings");
      return;
    }

  if (do_local)
    {
      application_format_local_sessions (0, verbose);
      /* *INDENT-OFF* */
      pool_foreach (app, app_main.app_pool, ({
        application_format_local_sessions (app, verbose);
      }));
      /* *INDENT-ON* */
    }
  else
    {
      application_format_listeners (0, verbose);

      /* *INDENT-OFF* */
      pool_foreach (app, app_main.app_pool, ({
        application_format_listeners (app, verbose);
      }));
      /* *INDENT-ON* */
    }
}

void
application_format_all_clients (vlib_main_t * vm, int do_local, int verbose)
{
  application_t *app;

  if (!pool_elts (app_main.app_pool))
    {
      vlib_cli_output (vm, "No active apps");
      return;
    }

  if (do_local)
    {
      application_format_local_connects (0, verbose);

      /* *INDENT-OFF* */
      pool_foreach (app, app_main.app_pool, ({
	application_format_local_connects (app, verbose);
      }));
      /* *INDENT-ON* */
    }
  else
    {
      application_format_connects (0, verbose);

      /* *INDENT-OFF* */
      pool_foreach (app, app_main.app_pool, ({
        application_format_connects (app, verbose);
      }));
      /* *INDENT-ON* */
    }
}

static clib_error_t *
show_app_command_fn (vlib_main_t * vm, unformat_input_t * input,
		     vlib_cli_command_t * cmd)
{
  int do_server = 0, do_client = 0, do_local = 0;
  application_t *app;
  int verbose = 0;

  session_cli_return_if_not_enabled ();

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "server"))
	do_server = 1;
      else if (unformat (input, "client"))
	do_client = 1;
      else if (unformat (input, "local"))
	do_local = 1;
      else if (unformat (input, "verbose"))
	verbose = 1;
      else
	break;
    }

  if (do_server)
    application_format_all_listeners (vm, do_local, verbose);

  if (do_client)
    application_format_all_clients (vm, do_local, verbose);

  /* Print app related info */
  if (!do_server && !do_client)
    {
      vlib_cli_output (vm, "%U", format_application, 0, verbose);
      /* *INDENT-OFF* */
      pool_foreach (app, app_main.app_pool, ({
	vlib_cli_output (vm, "%U", format_application, app, verbose);
      }));
      /* *INDENT-ON* */
    }

  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_app_command, static) =
{
  .path = "show app",
  .short_help = "show app [server|client] [verbose]",
  .function = show_app_command_fn,
};
/* *INDENT-ON* */

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