/*
 * Copyright (c) 2017 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this
 * 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 <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <svm/svm_fifo_segment.h>
#include <vlibmemory/api.h>
#include <vpp/api/vpe_msg_enum.h>
#include <vnet/session/application_interface.h>
#include <vcl/vppcom.h>
#include <vlib/unix/unix.h>
#include <vppinfra/vec_bootstrap.h>

#define vl_typedefs		/* define message structures */
#include <vpp/api/vpe_all_api_h.h>
#undef vl_typedefs

/* declare message handlers for each api */

#define vl_endianfun		/* define message structures */
#include <vpp/api/vpe_all_api_h.h>
#undef vl_endianfun

/* instantiate all the print functions we know about */
#define vl_print(handle, ...)
#define vl_printfun
#include <vpp/api/vpe_all_api_h.h>
#undef vl_printfun

#if (CLIB_DEBUG > 0)
/* Set VPPCOM_DEBUG_INIT 2 for connection debug,
 *                       3 for read/write debug output
 * or
 *    export VCL_DEBUG=<#> to set dynamically.
 */
#define VPPCOM_DEBUG_INIT 1
#else
#define VPPCOM_DEBUG_INIT 0
#endif

#define VPPCOM_DEBUG vcm->debug

/*
 * VPPCOM Private definitions and functions.
 */
typedef enum
{
  STATE_APP_START,
  STATE_APP_CONN_VPP,
  STATE_APP_ENABLED,
  STATE_APP_ATTACHED,
} app_state_t;

typedef enum
{
  STATE_START,
  STATE_CONNECT,
  STATE_LISTEN,
  STATE_ACCEPT,
  STATE_DISCONNECT,
  STATE_FAILED
} session_state_t;

typedef struct epoll_event vppcom_epoll_event_t;

typedef struct
{
  u32 next_sid;
  u32 prev_sid;
  u32 vep_idx;
  vppcom_epoll_event_t ev;
#define VEP_DEFAULT_ET_MASK  (EPOLLIN|EPOLLOUT)
#define VEP_UNSUPPORTED_EVENTS (EPOLLONESHOT|EPOLLEXCLUSIVE)
  u32 et_mask;
} vppcom_epoll_t;

typedef struct
{
  u8 is_ip4;
  ip46_address_t ip46;
} vppcom_ip46_t;

typedef struct
{
  volatile session_state_t state;

  svm_fifo_t *server_rx_fifo;
  svm_fifo_t *server_tx_fifo;
  u8 *segment_name;
  u32 sm_seg_index;
  u32 client_context;
  u64 vpp_handle;
  unix_shared_memory_queue_t *vpp_event_queue;

  /* Socket configuration state */
  /* TBD: covert 'is_*' vars to bit in u8 flags; */
  u8 is_server;
  u8 is_listen;
  u8 is_cut_thru;
  u8 is_nonblocking;
  u8 is_vep;
  u8 is_vep_session;
  u32 wait_cont_idx;
  vppcom_epoll_t vep;
  u32 vrf;
  vppcom_ip46_t lcl_addr;
  vppcom_ip46_t peer_addr;
  u16 lcl_port;			// network order
  u16 peer_port;		// network order
  u8 proto;
  u64 client_queue_address;
  u64 options[16];
} session_t;

typedef struct vppcom_cfg_t_
{
  u64 heapsize;
  u64 segment_baseva;
  u32 segment_size;
  u32 add_segment_size;
  u32 preallocated_fifo_pairs;
  u32 rx_fifo_size;
  u32 tx_fifo_size;
  u32 event_queue_size;
  u32 listen_queue_size;
  u8 app_proxy_transport_tcp;
  u8 app_proxy_transport_udp;
  u8 app_scope_local;
  u8 app_scope_global;
  u8 *namespace_id;
  u64 namespace_secret;
  f64 app_timeout;
  f64 session_timeout;
  f64 accept_timeout;
} vppcom_cfg_t;

typedef struct vppcom_main_t_
{
  u8 init;
  u32 debug;
  u32 *client_session_index_fifo;
  volatile u32 bind_session_index;
  int main_cpu;

  /* vpe input queue */
  unix_shared_memory_queue_t *vl_input_queue;

  /* API client handle */
  u32 my_client_index;

  /* Session pool */
  clib_spinlock_t sessions_lockp;
  session_t *sessions;

  /* Hash table for disconnect processing */
  uword *session_index_by_vpp_handles;

  /* Select bitmaps */
  clib_bitmap_t *rd_bitmap;
  clib_bitmap_t *wr_bitmap;
  clib_bitmap_t *ex_bitmap;

  /* Our event queue */
  unix_shared_memory_queue_t *app_event_queue;

  /* unique segment name counter */
  u32 unique_segment_index;

  /* For deadman timers */
  clib_time_t clib_time;

  /* State of the connection, shared between msg RX thread and main thread */
  volatile app_state_t app_state;

  vppcom_cfg_t cfg;

  /* VNET_API_ERROR_FOO -> "Foo" hash table */
  uword *error_string_by_error_number;
} vppcom_main_t;

/* NOTE: _vppcom_main is only used until the heap is allocated.
 *       Do not access it directly -- use vcm which will point to
 *       the heap allocated copy after init.
 */
static vppcom_main_t _vppcom_main = {
  .debug = VPPCOM_DEBUG_INIT,
  .my_client_index = ~0
};

static vppcom_main_t *vcm = &_vppcom_main;

#define VCL_LOCK_AND_GET_SESSION(I, S)                  \
do {                                                    \
  clib_spinlock_lock (&vcm->sessions_lockp);            \
  rv = vppcom_session_at_index (I, S);                  \
  if (PREDICT_FALSE (rv))                               \
    {                                                   \
      clib_spinlock_unlock (&vcm->sessions_lockp);      \
                                                        \
      if (VPPCOM_DEBUG > 0)                             \
        clib_warning ("[%s] ERROR: Invalid ##I (%u)!",  \
                      getpid (), I);                  \
                                                        \
      goto done;                                        \
    }                                                   \
} while (0)

static const char *
vppcom_app_state_str (app_state_t state)
{
  char *st;

  switch (state)
    {
    case STATE_APP_START:
      st = "STATE_APP_START";
      break;

    case STATE_APP_CONN_VPP:
      st = "STATE_APP_CONN_VPP";
      break;

    case STATE_APP_ENABLED:
      st = "STATE_APP_ENABLED";
      break;

    case STATE_APP_ATTACHED:
      st = "STATE_APP_ATTACHED";
      break;

    default:
      st = "UNKNOWN_APP_STATE";
      break;
    }

  return st;
}

static const char *
vppcom_session_state_str (session_state_t state)
{
  char *st;

  switch (state)
    {
    case STATE_START:
      st = "STATE_START";
      break;

    case STATE_CONNECT:
      st = "STATE_CONNECT";
      break;

    case STATE_LISTEN:
      st = "STATE_LISTEN";
      break;

    case STATE_ACCEPT:
      st = "STATE_ACCEPT";
      break;

    case STATE_DISCONNECT:
      st = "STATE_DISCONNECT";
      break;

    case STATE_FAILED:
      st = "STATE_FAILED";
      break;

    default:
      st = "UNKNOWN_STATE";
      break;
    }

  return st;
}

/*
 * VPPCOM Utility Functions
 */
static inline int
vppcom_session_at_index (u32 session_index, session_t * volatile *sess)
{
  /* Assumes that caller has acquired spinlock: vcm->sessions_lockp */
  if (PREDICT_FALSE ((session_index == ~0) ||
		     pool_is_free_index (vcm->sessions, session_index)))
    {
      clib_warning ("[%d] invalid session, sid (%u) has been closed!",
		    getpid (), session_index);
      return VPPCOM_EBADFD;
    }
  *sess = pool_elt_at_index (vcm->sessions, session_index);
  return VPPCOM_OK;
}

static inline void
vppcom_session_table_add_listener (u64 listener_handle, u32 value)
{
  /* Session and listener handles have different formats. The latter has
   * the thread index in the upper 32 bits while the former has the session
   * type. Knowing that, for listeners we just flip the MSB to 1 */
  listener_handle |= 1ULL << 63;
  hash_set (vcm->session_index_by_vpp_handles, listener_handle, value);
}

static inline session_t *
vppcom_session_table_lookup_listener (u64 listener_handle)
{
  uword *p;
  u64 handle = listener_handle | (1ULL << 63);
  p = hash_get (vcm->session_index_by_vpp_handles, handle);
  if (!p)
    {
      clib_warning ("[%d] couldn't find listen session: unknown vpp "
		    "listener handle %llx", getpid (), listener_handle);
      return 0;
    }
  if (pool_is_free_index (vcm->sessions, p[0]))
    {
      if (VPPCOM_DEBUG > 1)
	clib_warning ("[%d] invalid listen session, sid (%u)", getpid (),
		      p[0]);
      return 0;
    }

  return pool_elt_at_index (vcm->sessions, p[0]);
}

static inline void
vppcom_session_table_del_listener (u64 listener_handle)
{
  listener_handle |= 1ULL << 63;
  hash_unset (vcm->session_index_by_vpp_handles, listener_handle);
}

static int
vppcom_connect_to_vpp (char *app_name)
{
  api_main_t *am = &api_main;

  if (VPPCOM_DEBUG > 0)
    printf ("\nConnecting to VPP api...");
  if (vl_client_connect_to_vlib ("/vpe-api", app_name, 32) < 0)
    {
      clib_warning ("[%d] connect to vpp (%s) failed!", getpid (), app_name);
      return VPPCOM_ECONNREFUSED;
    }

  vcm->vl_input_queue = am->shmem_hdr->vl_input_queue;
  vcm->my_client_index = am->my_client_index;
  if (VPPCOM_DEBUG > 0)
    printf (" connected!\n");

  vcm->app_state = STATE_APP_CONN_VPP;
  return VPPCOM_OK;
}

static u8 *
format_api_error (u8 * s, va_list * args)
{
  i32 error = va_arg (*args, u32);
  uword *p;

  p = hash_get (vcm->error_string_by_error_number, -error);

  if (p)
    s = format (s, "%s (%d)", p[0], error);
  else
    s = format (s, "%d", error);
  return s;
}

static void
vppcom_init_error_string_table (void)
{
  vcm->error_string_by_error_number = hash_create (0, sizeof (uword));

#define _(n,v,s) hash_set (vcm->error_string_by_error_number, -v, s);
  foreach_vnet_api_error;
#undef _

  hash_set (vcm->error_string_by_error_number, 99, "Misc");
}

static inline int
vppcom_wait_for_app_state_change (app_state_t app_state)
{
  f64 timeout = clib_time_now (&vcm->clib_time) + vcm->cfg.app_timeout;

  while (clib_time_now (&vcm->clib_time) < timeout)
    {
      if (vcm->app_state == app_state)
	return VPPCOM_OK;
    }
  if (VPPCOM_DEBUG > 0)
    clib_warning ("[%d] timeout waiting for state %s (%d)", getpid (),
		  vppcom_app_state_str (app_state), app_state);
  return VPPCOM_ETIMEDOUT;
}

static inline int
vppcom_wait_for_session_state_change (u32 session_index,
				      session_state_t state,
				      f64 wait_for_time)
{
  f64 timeout = clib_time_now (&vcm->clib_time) + wait_for_time;
  session_t *volatile session;
  int rv;

  do
    {
      clib_spinlock_lock (&vcm->sessions_lockp);
      rv = vppcom_session_at_index (session_index, &session);
      if (PREDICT_FALSE (rv))
	{
	  clib_spinlock_unlock (&vcm->sessions_lockp);
	  return rv;
	}
      if (session->state == state)
	{
	  clib_spinlock_unlock (&vcm->sessions_lockp);
	  return VPPCOM_OK;
	}
      clib_spinlock_unlock (&vcm->sessions_lockp);
    }
  while (clib_time_now (&vcm->clib_time) < timeout);

  if (VPPCOM_DEBUG > 0)
    clib_warning ("[%d] timeout waiting for state %s (%d)", getpid (),
		  vppcom_session_state_str (state), state);
  return VPPCOM_ETIMEDOUT;
}

static inline int
vppcom_wait_for_client_session_index (f64 wait_for_time)
{
  f64 timeout = clib_time_now (&vcm->clib_time) + wait_for_time;

  do
    {
      if (clib_fifo_elts (vcm->client_session_index_fifo))
	return VPPCOM_OK;
    }
  while (clib_time_now (&vcm->clib_time) < timeout);

  if (wait_for_time == 0)
    return VPPCOM_EAGAIN;

  if (VPPCOM_DEBUG > 0)
    clib_warning ("[%d] timeout waiting for client_session_index", getpid ());
  return VPPCOM_ETIMEDOUT;
}

/*
 * VPP-API message functions
 */
static void
vppcom_send_session_enable_disable (u8 is_enable)
{
  vl_api_session_enable_disable_t *bmp;
  bmp = vl_msg_api_alloc (sizeof (*bmp));
  memset (bmp, 0, sizeof (*bmp));

  bmp->_vl_msg_id = ntohs (VL_API_SESSION_ENABLE_DISABLE);
  bmp->client_index = vcm->my_client_index;
  bmp->context = htonl (0xfeedface);
  bmp->is_enable = is_enable;
  vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & bmp);
}

static int
vppcom_app_session_enable (void)
{
  int rv;

  if (vcm->app_state != STATE_APP_ENABLED)
    {
      vppcom_send_session_enable_disable (1 /* is_enabled == TRUE */ );
      rv = vppcom_wait_for_app_state_change (STATE_APP_ENABLED);
      if (PREDICT_FALSE (rv))
	{
	  if (VPPCOM_DEBUG > 0)
	    clib_warning ("[%d] Session enable timed out, rv = %s (%d)",
			  getpid (), vppcom_retval_str (rv), rv);
	  return rv;
	}
    }
  return VPPCOM_OK;
}

static void
  vl_api_session_enable_disable_reply_t_handler
  (vl_api_session_enable_disable_reply_t * mp)
{
  if (mp->retval)
    {
      clib_warning ("[%d] session_enable_disable failed: %U", getpid (),
		    format_api_error, ntohl (mp->retval));
    }
  else
    vcm->app_state = STATE_APP_ENABLED;
}

static void
vppcom_app_send_attach (void)
{
  vl_api_application_attach_t *bmp;
  u8 nsid_len = vec_len (vcm->cfg.namespace_id);
  u8 app_is_proxy = (vcm->cfg.app_proxy_transport_tcp ||
		     vcm->cfg.app_proxy_transport_udp);

  bmp = vl_msg_api_alloc (sizeof (*bmp));
  memset (bmp, 0, sizeof (*bmp));

  bmp->_vl_msg_id = ntohs (VL_API_APPLICATION_ATTACH);
  bmp->client_index = vcm->my_client_index;
  bmp->context = htonl (0xfeedface);
  bmp->options[APP_OPTIONS_FLAGS] =
    APP_OPTIONS_FLAGS_ACCEPT_REDIRECT | APP_OPTIONS_FLAGS_ADD_SEGMENT |
    (vcm->cfg.app_scope_local ? APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE : 0) |
    (vcm->cfg.app_scope_global ? APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE : 0) |
    (app_is_proxy ? APP_OPTIONS_FLAGS_IS_PROXY : 0);
  bmp->options[APP_OPTIONS_PROXY_TRANSPORT] =
    (vcm->cfg.app_proxy_transport_tcp ? 1 << TRANSPORT_PROTO_TCP : 0) |
    (vcm->cfg.app_proxy_transport_udp ? 1 << TRANSPORT_PROTO_UDP : 0);
  bmp->options[SESSION_OPTIONS_SEGMENT_SIZE] = vcm->cfg.segment_size;
  bmp->options[SESSION_OPTIONS_ADD_SEGMENT_SIZE] = vcm->cfg.add_segment_size;
  bmp->options[SESSION_OPTIONS_RX_FIFO_SIZE] = vcm->cfg.rx_fifo_size;
  bmp->options[SESSION_OPTIONS_TX_FIFO_SIZE] = vcm->cfg.tx_fifo_size;
  if (nsid_len)
    {
      bmp->namespace_id_len = nsid_len;
      clib_memcpy (bmp->namespace_id, vcm->cfg.namespace_id, nsid_len);
      bmp->options[APP_OPTIONS_NAMESPACE_SECRET] = vcm->cfg.namespace_secret;
    }
  vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & bmp);
}

static int
vppcom_app_attach (void)
{
  int rv;

  vppcom_app_send_attach ();
  rv = vppcom_wait_for_app_state_change (STATE_APP_ATTACHED);
  if (PREDICT_FALSE (rv))
    {
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] application attach timed out, rv = %s (%d)",
		      getpid (), vppcom_retval_str (rv), rv);
      return rv;
    }
  return VPPCOM_OK;
}

static void
vppcom_app_detach (void)
{
  vl_api_application_detach_t *bmp;
  bmp = vl_msg_api_alloc (sizeof (*bmp));
  memset (bmp, 0, sizeof (*bmp));

  bmp->_vl_msg_id = ntohs (VL_API_APPLICATION_DETACH);
  bmp->client_index = vcm->my_client_index;
  bmp->context = htonl (0xfeedface);
  vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & bmp);
}

static void
vl_api_application_attach_reply_t_handler (vl_api_application_attach_reply_t *
					   mp)
{
  static svm_fifo_segment_create_args_t _a;
  svm_fifo_segment_create_args_t *a = &_a;
  int rv;

  memset (a, 0, sizeof (*a));
  if (mp->retval)
    {
      clib_warning ("[%d] attach failed: %U", getpid (),
		    format_api_error, ntohl (mp->retval));
      return;
    }

  if (mp->segment_name_length == 0)
    {
      clib_warning ("[%d] segment_name_length zero", getpid ());
      return;
    }

  a->segment_name = (char *) mp->segment_name;
  a->segment_size = mp->segment_size;

  ASSERT (mp->app_event_queue_address);

  /* Attach to the segment vpp created */
  rv = svm_fifo_segment_attach (a);
  vec_reset_length (a->new_segment_indices);
  if (PREDICT_FALSE (rv))
    {
      clib_warning ("[%d] svm_fifo_segment_attach ('%s') failed", getpid (),
		    mp->segment_name);
      return;
    }

  vcm->app_event_queue =
    uword_to_pointer (mp->app_event_queue_address,
		      unix_shared_memory_queue_t *);

  vcm->app_state = STATE_APP_ATTACHED;
}

static void
vl_api_application_detach_reply_t_handler (vl_api_application_detach_reply_t *
					   mp)
{
  if (mp->retval)
    clib_warning ("[%d] detach failed: %U", getpid (), format_api_error,
		  ntohl (mp->retval));

  vcm->app_state = STATE_APP_ENABLED;
}

static void
vl_api_disconnect_session_reply_t_handler (vl_api_disconnect_session_reply_t *
					   mp)
{
  uword *p;
  u32 session_index = ~0;

  p = hash_get (vcm->session_index_by_vpp_handles, mp->handle);
  if (p)
    {
      session_t *session = 0;
      int rv;

      session_index = p[0];
      hash_unset (vcm->session_index_by_vpp_handles, mp->handle);
      clib_spinlock_lock (&vcm->sessions_lockp);
      rv = vppcom_session_at_index (session_index, &session);
      if (PREDICT_FALSE (rv))
	{
	  if (VPPCOM_DEBUG > 1)
	    clib_warning ("[%d] invalid session, sid %u has been closed!",
			  getpid (), session_index);
	}
      else
	{
	  if (VPPCOM_DEBUG > 1)
	    clib_warning ("[%d] vpp handle 0x%llx, sid %u disconnected!",
			  getpid (), mp->handle, session_index);

	  session->state = STATE_DISCONNECT;
	}
      clib_spinlock_unlock (&vcm->sessions_lockp);
    }
  else
    {
      if (VPPCOM_DEBUG > 1)
	clib_warning ("[%d] couldn't find session: unknown vpp handle 0x%llx",
		      getpid (), mp->handle);
    }

  if (mp->retval)
    clib_warning ("[%d] disconnect_session vpp handle 0x%llx, sid %u "
		  "failed: %U", getpid (), mp->handle, session_index,
		  format_api_error, ntohl (mp->retval));
}

static void
vl_api_map_another_segment_t_handler (vl_api_map_another_segment_t * mp)
{
  static svm_fifo_segment_create_args_t _a;
  svm_fifo_segment_create_args_t *a = &_a;
  int rv;

  memset (a, 0, sizeof (*a));
  a->segment_name = (char *) mp->segment_name;
  a->segment_size = mp->segment_size;
  /* Attach to the segment vpp created */
  rv = svm_fifo_segment_attach (a);
  vec_reset_length (a->new_segment_indices);
  if (PREDICT_FALSE (rv))
    {
      clib_warning ("[%d] svm_fifo_segment_attach ('%s') failed",
		    getpid (), mp->segment_name);
      return;
    }
  if (VPPCOM_DEBUG > 1)
    clib_warning ("[%d] mapped new segment '%s' size %d", getpid (),
		  mp->segment_name, mp->segment_size);
}

static void
vl_api_disconnect_session_t_handler (vl_api_disconnect_session_t * mp)
{
  session_t *session = 0;
  vl_api_disconnect_session_reply_t *rmp;
  uword *p;
  int rv = 0, rval;

  p = hash_get (vcm->session_index_by_vpp_handles, mp->handle);
  if (VPPCOM_DEBUG > 0)
    {
      if (!p)
	{
	  clib_warning ("[%d] request to disconnect invalid handle (%u)!",
			getpid (), mp->handle);
	  rv = -11;
	  goto done;
	}
      clib_warning ("[%d] disconnecting handle %u sid (%u)!", getpid (),
		    mp->handle, p[0]);
    }

  goto done;

  if (p)
    {
      clib_spinlock_lock (&vcm->sessions_lockp);
      rval = vppcom_session_at_index (p[0], &session);
      if (PREDICT_FALSE (rval))
	{
	  if (VPPCOM_DEBUG > 1)
	    clib_warning ("[%d] invalid session, sid (%u) has been closed!",
			  getpid (), p[0]);
	}
      else
	pool_put (vcm->sessions, session);
      clib_spinlock_unlock (&vcm->sessions_lockp);
      hash_unset (vcm->session_index_by_vpp_handles, mp->handle);
    }
  else
    {
      clib_warning ("[%d] couldn't find session: unknown vpp handle 0x%llx",
		    getpid (), mp->handle);
      rv = -11;
    }

done:
  rmp = vl_msg_api_alloc (sizeof (*rmp));
  memset (rmp, 0, sizeof (*rmp));

  rmp->_vl_msg_id = ntohs (VL_API_DISCONNECT_SESSION_REPLY);
  rmp->retval = htonl (rv);
  rmp->handle = mp->handle;
  vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & rmp);
}

static void
vl_api_reset_session_t_handler (vl_api_reset_session_t * mp)
{
  session_t *session = 0;
  vl_api_reset_session_reply_t *rmp;
  uword *p;
  int rv = 0;

  p = hash_get (vcm->session_index_by_vpp_handles, mp->handle);
  if (p)
    {
      int rval;
      clib_spinlock_lock (&vcm->sessions_lockp);
      rval = vppcom_session_at_index (p[0], &session);
      if (PREDICT_FALSE (rval))
	{
	  if (VPPCOM_DEBUG > 1)
	    clib_warning ("[%d] invalid session, sid (%u) has been closed!",
			  getpid (), p[0]);
	}
      else
	pool_put (vcm->sessions, session);
      clib_spinlock_unlock (&vcm->sessions_lockp);
      hash_unset (vcm->session_index_by_vpp_handles, mp->handle);
    }
  else
    {
      clib_warning ("[%d] couldn't find session: unknown vpp handle 0x%llx",
		    getpid (), mp->handle);
      rv = -11;
    }

  rmp = vl_msg_api_alloc (sizeof (*rmp));
  memset (rmp, 0, sizeof (*rmp));
  rmp->_vl_msg_id = ntohs (VL_API_RESET_SESSION_REPLY);
  rmp->retval = htonl (rv);
  rmp->handle = mp->handle;
  vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & rmp);
}

static void
vl_api_connect_session_reply_t_handler (vl_api_connect_session_reply_t * mp)
{
  session_t *session;
  u32 session_index;
  svm_fifo_t *rx_fifo, *tx_fifo;
  u8 is_cut_thru = 0;
  int rv;

  if (mp->retval)
    {
      clib_warning ("[%d] connect failed: %U", getpid (), format_api_error,
		    ntohl (mp->retval));
      return;
    }

  session_index = mp->context;
  if (VPPCOM_DEBUG > 1)
    clib_warning ("[%d] session_index = %d 0x%08x", getpid (),
		  session_index, session_index);

  clib_spinlock_lock (&vcm->sessions_lockp);
  if (pool_is_free_index (vcm->sessions, session_index))
    {
      clib_spinlock_unlock (&vcm->sessions_lockp);
      if (VPPCOM_DEBUG > 1)
	clib_warning ("[%d] invalid session, sid %d is closed!",
		      getpid (), session_index);
      return;
    }

  /* We've been redirected */
  if (mp->segment_name_length > 0)
    {
      static svm_fifo_segment_create_args_t _a;
      svm_fifo_segment_create_args_t *a = &_a;

      is_cut_thru = 1;
      memset (a, 0, sizeof (*a));
      a->segment_name = (char *) mp->segment_name;
      if (VPPCOM_DEBUG > 1)
	clib_warning ("[%d] cut-thru segment: %s\n",
		      getpid (), a->segment_name);

      rv = svm_fifo_segment_attach (a);
      vec_reset_length (a->new_segment_indices);
      if (PREDICT_FALSE (rv))
	{
	  clib_spinlock_unlock (&vcm->sessions_lockp);
	  clib_warning ("[%d] sm_fifo_segment_attach ('%s') failed",
			getpid (), a->segment_name);
	  return;
	}
    }

  /*
   * Setup session
   */
  session = pool_elt_at_index (vcm->sessions, session_index);
  session->is_cut_thru = is_cut_thru;
  session->vpp_event_queue = uword_to_pointer (mp->vpp_event_queue_address,
					       unix_shared_memory_queue_t *);

  rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
  rx_fifo->client_session_index = session_index;
  tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
  tx_fifo->client_session_index = session_index;

  session->server_rx_fifo = rx_fifo;
  session->server_tx_fifo = tx_fifo;
  session->vpp_handle = mp->handle;
  session->lcl_addr.is_ip4 = mp->is_ip4;
  clib_memcpy (&session->lcl_addr.ip46, mp->lcl_ip,
	       sizeof (session->peer_addr.ip46));
  session->lcl_port = mp->lcl_port;
  session->state = STATE_CONNECT;

  /* Add it to lookup table */
  hash_set (vcm->session_index_by_vpp_handles, mp->handle, session_index);

  if (VPPCOM_DEBUG > 1)
    clib_warning ("[%d] client sid %d, vpp handle 0x%llx\n"
		  "  session_rx_fifo %p, refcnt %d\n"
		  "  session_tx_fifo %p, refcnt %d",
		  getpid (), session_index, mp->handle,
		  session->server_rx_fifo,
		  session->server_rx_fifo->refcnt,
		  session->server_tx_fifo, session->server_tx_fifo->refcnt);

  clib_spinlock_unlock (&vcm->sessions_lockp);
}

static void
vppcom_send_connect_sock (session_t * session, u32 session_index)
{
  vl_api_connect_sock_t *cmp;

  /* Assumes caller as acquired the spinlock: vcm->sessions_lockp */
  session->is_server = 0;
  cmp = vl_msg_api_alloc (sizeof (*cmp));
  memset (cmp, 0, sizeof (*cmp));
  cmp->_vl_msg_id = ntohs (VL_API_CONNECT_SOCK);
  cmp->client_index = vcm->my_client_index;
  cmp->context = session_index;

  if (VPPCOM_DEBUG > 1)
    clib_warning ("[%d] session_index = %d 0x%08x",
		  getpid (), session_index, session_index);

  cmp->vrf = session->vrf;
  cmp->is_ip4 = session->peer_addr.is_ip4;
  clib_memcpy (cmp->ip, &session->peer_addr.ip46, sizeof (cmp->ip));
  cmp->port = session->peer_port;
  cmp->proto = session->proto;
  clib_memcpy (cmp->options, session->options, sizeof (cmp->options));
  vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & cmp);
}

static inline void
vppcom_send_disconnect (session_t * session)
{
  vl_api_disconnect_session_t *dmp;

  /* Assumes caller as acquired the spinlock: vcm->sessions_lockp */
  dmp = vl_msg_api_alloc (sizeof (*dmp));
  memset (dmp, 0, sizeof (*dmp));
  dmp->_vl_msg_id = ntohs (VL_API_DISCONNECT_SESSION);
  dmp->client_index = vcm->my_client_index;
  dmp->handle = session->vpp_handle;
  vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & dmp);
}

static void
vl_api_bind_sock_reply_t_handler (vl_api_bind_sock_reply_t * mp)
{
  session_t *session = 0;
  int rv;

  if (mp->retval)
    clib_warning ("[%d] bind failed: %U", getpid (), format_api_error,
		  ntohl (mp->retval));

  ASSERT (vcm->bind_session_index != ~0);

  clib_spinlock_lock (&vcm->sessions_lockp);
  rv = vppcom_session_at_index (vcm->bind_session_index, &session);
  if (rv == VPPCOM_OK)
    {
      session->vpp_handle = mp->handle;
      session->lcl_addr.is_ip4 = mp->lcl_is_ip4;
      clib_memcpy (&session->lcl_addr.ip46, mp->lcl_ip,
		   sizeof (session->peer_addr.ip46));
      session->lcl_port = mp->lcl_port;
      vppcom_session_table_add_listener (mp->handle, vcm->bind_session_index);
      session->state = mp->retval ? STATE_FAILED : STATE_LISTEN;
      vcm->bind_session_index = ~0;
    }
  clib_spinlock_unlock (&vcm->sessions_lockp);
}

static void
vl_api_unbind_sock_reply_t_handler (vl_api_unbind_sock_reply_t * mp)
{
  session_t *session = 0;

  clib_spinlock_lock (&vcm->sessions_lockp);
  session = vppcom_session_table_lookup_listener (vcm->bind_session_index);

  if (session)
    {
      if ((VPPCOM_DEBUG > 1) && (mp->retval))
	clib_warning ("[%d] unbind failed: %U", getpid (), format_api_error,
		      ntohl (mp->retval));

      vppcom_session_table_del_listener (vcm->bind_session_index);
      vcm->bind_session_index = ~0;
      session->state = STATE_START;
    }
  clib_spinlock_unlock (&vcm->sessions_lockp);
}

u8 *
format_ip4_address (u8 * s, va_list * args)
{
  u8 *a = va_arg (*args, u8 *);
  return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
}

u8 *
format_ip6_address (u8 * s, va_list * args)
{
  ip6_address_t *a = va_arg (*args, ip6_address_t *);
  u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;

  i_max_n_zero = ARRAY_LEN (a->as_u16);
  max_n_zeros = 0;
  i_first_zero = i_max_n_zero;
  n_zeros = 0;
  for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
    {
      u32 is_zero = a->as_u16[i] == 0;
      if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
	{
	  i_first_zero = i;
	  n_zeros = 0;
	}
      n_zeros += is_zero;
      if ((!is_zero && n_zeros > max_n_zeros)
	  || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
	{
	  i_max_n_zero = i_first_zero;
	  max_n_zeros = n_zeros;
	  i_first_zero = ARRAY_LEN (a->as_u16);
	  n_zeros = 0;
	}
    }

  last_double_colon = 0;
  for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
    {
      if (i == i_max_n_zero && max_n_zeros > 1)
	{
	  s = format (s, "::");
	  i += max_n_zeros - 1;
	  last_double_colon = 1;
	}
      else
	{
	  s = format (s, "%s%x",
		      (last_double_colon || i == 0) ? "" : ":",
		      clib_net_to_host_u16 (a->as_u16[i]));
	  last_double_colon = 0;
	}
    }

  return s;
}

/* Format an IP46 address. */
u8 *
format_ip46_address (u8 * s, va_list * args)
{
  ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
  ip46_type_t type = va_arg (*args, ip46_type_t);
  int is_ip4 = 1;

  switch (type)
    {
    case IP46_TYPE_ANY:
      is_ip4 = ip46_address_is_ip4 (ip46);
      break;
    case IP46_TYPE_IP4:
      is_ip4 = 1;
      break;
    case IP46_TYPE_IP6:
      is_ip4 = 0;
      break;
    }

  return is_ip4 ?
    format (s, "%U", format_ip4_address, &ip46->ip4) :
    format (s, "%U", format_ip6_address, &ip46->ip6);
}

static inline void
vppcom_send_accept_session_reply (u32 handle, int retval)
{
  vl_api_accept_session_reply_t *rmp;

  rmp = vl_msg_api_alloc (sizeof (*rmp));
  memset (rmp, 0, sizeof (*rmp));
  rmp->_vl_msg_id = ntohs (VL_API_ACCEPT_SESSION_REPLY);
  rmp->retval = htonl (retval);
  rmp->handle = handle;
  vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & rmp);
}

static void
vl_api_accept_session_t_handler (vl_api_accept_session_t * mp)
{
  svm_fifo_t *rx_fifo, *tx_fifo;
  session_t *session, *listen_session;
  u32 session_index;

  clib_spinlock_lock (&vcm->sessions_lockp);
  if (!clib_fifo_free_elts (vcm->client_session_index_fifo))
    {
      clib_warning ("[%d] client session queue is full!", getpid ());
      vppcom_send_accept_session_reply (mp->handle,
					VNET_API_ERROR_QUEUE_FULL);
      clib_spinlock_unlock (&vcm->sessions_lockp);
      return;
    }

  listen_session = vppcom_session_table_lookup_listener (mp->listener_handle);
  if (!listen_session)
    {
      clib_warning ("[%d] ERROR: couldn't find listen session: unknown vpp "
		    "listener handle %llx", getpid (), mp->listener_handle);
      clib_spinlock_unlock (&vcm->sessions_lockp);
      return;
    }

  /* Allocate local session and set it up */
  pool_get (vcm->sessions, session);
  memset (session, 0, sizeof (*session));
  session_index = session - vcm->sessions;

  rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
  rx_fifo->client_session_index = session_index;
  tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
  tx_fifo->client_session_index = session_index;

  session->vpp_handle = mp->handle;
  session->server_rx_fifo = rx_fifo;
  session->server_tx_fifo = tx_fifo;
  session->vpp_event_queue = uword_to_pointer (mp->vpp_event_queue_address,
					       unix_shared_memory_queue_t *);
  session->state = STATE_ACCEPT;
  session->is_cut_thru = 0;
  session->is_server = 1;
  session->peer_port = mp->port;
  session->peer_addr.is_ip4 = mp->is_ip4;
  clib_memcpy (&session->peer_addr.ip46, mp->ip,
	       sizeof (session->peer_addr.ip46));

  /* Add it to lookup table */
  hash_set (vcm->session_index_by_vpp_handles, mp->handle, session_index);
  session->lcl_port = listen_session->lcl_port;
  session->lcl_addr = listen_session->lcl_addr;

  /* TBD: move client_session_index_fifo into listener session */
  clib_fifo_add1 (vcm->client_session_index_fifo, session_index);

  clib_spinlock_unlock (&vcm->sessions_lockp);

  if (VPPCOM_DEBUG > 1)
    {
      u8 *ip_str = format (0, "%U", format_ip46_address, &mp->ip, mp->is_ip4);
      clib_warning ("[%d] received request to accept session (sid %d) "
		    "from %s:%d", getpid (), session_index, ip_str,
		    clib_net_to_host_u16 (mp->port));
      vec_free (ip_str);
    }
}

static void
vppcom_send_connect_session_reply (session_t * session, int retval)
{
  vl_api_connect_session_reply_t *rmp;
  u32 len;
  unix_shared_memory_queue_t *client_q;

  rmp = vl_msg_api_alloc (sizeof (*rmp));
  memset (rmp, 0, sizeof (*rmp));

  rmp->_vl_msg_id = ntohs (VL_API_CONNECT_SESSION_REPLY);
  rmp->context = session->client_context;
  rmp->retval = htonl (retval);
  rmp->handle = session->vpp_handle;
  rmp->server_rx_fifo = pointer_to_uword (session->server_rx_fifo);
  rmp->server_tx_fifo = pointer_to_uword (session->server_tx_fifo);
  rmp->vpp_event_queue_address = pointer_to_uword (session->vpp_event_queue);
  rmp->segment_size = vcm->cfg.segment_size;
  len = vec_len (session->segment_name);
  rmp->segment_name_length = clib_min (len, sizeof (rmp->segment_name));
  clib_memcpy (rmp->segment_name, session->segment_name,
	       rmp->segment_name_length - 1);
  clib_memcpy (rmp->lcl_ip, session->lcl_addr.ip46.as_u8,
	       sizeof (rmp->lcl_ip));
  rmp->is_ip4 = session->lcl_addr.is_ip4;
  client_q = uword_to_pointer (session->client_queue_address,
			       unix_shared_memory_queue_t *);
  ASSERT (client_q);
  vl_msg_api_send_shmem (client_q, (u8 *) & rmp);
}

/*
 * Acting as server for redirected connect requests
 */
static void
vl_api_connect_sock_t_handler (vl_api_connect_sock_t * mp)
{
  u32 session_index;
  session_t *session = 0;

  clib_spinlock_lock (&vcm->sessions_lockp);
  if (!clib_fifo_free_elts (vcm->client_session_index_fifo))
    {
      if (VPPCOM_DEBUG > 1)
	clib_warning ("[%d] client session queue is full!", getpid ());
      clib_spinlock_unlock (&vcm->sessions_lockp);
      /* TBD: fix handle */
      vppcom_send_accept_session_reply (0, VNET_API_ERROR_QUEUE_FULL);
      return;
    }

  pool_get (vcm->sessions, session);
  memset (session, 0, sizeof (*session));
  session_index = session - vcm->sessions;

  session->client_context = mp->context;
  session->vpp_handle = session_index;
  session->client_queue_address = mp->client_queue_address;
  session->is_cut_thru = 1;
  session->is_server = 1;
  session->peer_port = mp->port;
  session->peer_addr.is_ip4 = mp->is_ip4;
  clib_memcpy (&session->peer_addr.ip46, mp->ip,
	       sizeof (session->peer_addr.ip46));

  session->state = STATE_ACCEPT;
  clib_fifo_add1 (vcm->client_session_index_fifo, session_index);
  if (VPPCOM_DEBUG > 1)
    clib_warning
      ("[%d] Got a cut-thru connect request to client: "
       "sid %d, clib_fifo_elts %u!\n", getpid (), session_index,
       clib_fifo_elts (vcm->client_session_index_fifo));
  clib_spinlock_unlock (&vcm->sessions_lockp);
}

static void
vppcom_send_bind_sock (session_t * session)
{
  vl_api_bind_sock_t *bmp;

  /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
  session->is_server = 1;
  bmp = vl_msg_api_alloc (sizeof (*bmp));
  memset (bmp, 0, sizeof (*bmp));

  bmp->_vl_msg_id = ntohs (VL_API_BIND_SOCK);
  bmp->client_index = vcm->my_client_index;
  bmp->context = htonl (0xfeedface);
  bmp->vrf = session->vrf;
  bmp->is_ip4 = session->lcl_addr.is_ip4;
  clib_memcpy (bmp->ip, &session->lcl_addr.ip46, sizeof (bmp->ip));
  bmp->port = session->lcl_port;
  bmp->proto = session->proto;
  clib_memcpy (bmp->options, session->options, sizeof (bmp->options));
  vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & bmp);
}

static void
vppcom_send_unbind_sock (u32 session_index)
{
  vl_api_unbind_sock_t *ump;
  session_t *session = 0;
  int rv;

  clib_spinlock_lock (&vcm->sessions_lockp);
  rv = vppcom_session_at_index (session_index, &session);
  if (PREDICT_FALSE (rv))
    {
      clib_spinlock_unlock (&vcm->sessions_lockp);
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] invalid session, sid (%u) has been closed!",
		      getpid (), session_index);
      return;
    }

  ump = vl_msg_api_alloc (sizeof (*ump));
  memset (ump, 0, sizeof (*ump));

  ump->_vl_msg_id = ntohs (VL_API_UNBIND_SOCK);
  ump->client_index = vcm->my_client_index;
  ump->handle = session->vpp_handle;
  clib_spinlock_unlock (&vcm->sessions_lockp);
  vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & ump);
}

static int
vppcom_session_unbind_cut_thru (session_t * session, u32 session_index)
{
  svm_fifo_segment_main_t *sm = &svm_fifo_segment_main;
  svm_fifo_segment_private_t *seg;
  int rv = VPPCOM_OK;

  if (VPPCOM_DEBUG > 1)
    clib_warning ("[%d] sid %d, seg_nxd %d:\n"
		  "  server_rx_fifo %p, refcnt = %d\n"
		  "  server_tx_fifo %p, refcnt = %d",
		  getpid (), session_index, session->sm_seg_index,
		  session->server_rx_fifo, session->server_rx_fifo->refcnt,
		  session->server_tx_fifo, session->server_tx_fifo->refcnt);

  seg = vec_elt_at_index (sm->segments, session->sm_seg_index);
  svm_fifo_segment_free_fifo (seg, session->server_rx_fifo,
			      FIFO_SEGMENT_RX_FREELIST);
  svm_fifo_segment_free_fifo (seg, session->server_tx_fifo,
			      FIFO_SEGMENT_TX_FREELIST);
  svm_fifo_segment_delete (seg);

  return rv;
}

static int
vppcom_session_unbind (u32 session_index)
{
  int rv;

  clib_spinlock_lock (&vcm->sessions_lockp);
  if (PREDICT_FALSE (pool_is_free_index (vcm->sessions, session_index)))
    {
      clib_spinlock_unlock (&vcm->sessions_lockp);
      if (VPPCOM_DEBUG > 1)
	clib_warning ("[%d] invalid session, sid (%u) has been closed!",
		      getpid (), session_index);
      return VPPCOM_EBADFD;
    }
  clib_spinlock_unlock (&vcm->sessions_lockp);

  if (vcm->bind_session_index != session_index)
    clib_warning ("[%d] ERROR: unbinding a not bound listener %u (%u)",
		  session_index, vcm->bind_session_index);
  vcm->bind_session_index = session_index;
  vppcom_send_unbind_sock (session_index);
  rv = vppcom_wait_for_session_state_change (session_index, STATE_START,
					     vcm->cfg.session_timeout);
  if (PREDICT_FALSE (rv))
    {
      vcm->bind_session_index = ~0;
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] server unbind timed out, rv = %s (%d)",
		      getpid (), vppcom_retval_str (rv), rv);
      return rv;
    }
  return VPPCOM_OK;
}

static inline int
vppcom_session_disconnect (u32 session_index)
{
  int rv;
  session_t *session;

  clib_spinlock_lock (&vcm->sessions_lockp);
  rv = vppcom_session_at_index (session_index, &session);
  if (PREDICT_FALSE (rv))
    {
      clib_spinlock_unlock (&vcm->sessions_lockp);
      if (VPPCOM_DEBUG > 1)
	clib_warning ("[%d] invalid session, sid (%u) has been closed!",
		      getpid (), session_index);
      return rv;
    }

  if (!session->is_cut_thru)
    {
      if (VPPCOM_DEBUG > 1)
	clib_warning ("[%d] disconnecting sid (%u)", getpid (),
		      session_index);
      vppcom_send_disconnect (session);
      clib_spinlock_unlock (&vcm->sessions_lockp);

      rv = vppcom_wait_for_session_state_change (session_index,
						 STATE_DISCONNECT, 1.0);
      /* TBD: Force clean up on error/timeout since there is no other
       *      way to recover from a failed disconnect.
       */
      if ((VPPCOM_DEBUG > 0) && (rv < 0))
	clib_warning ("[%d] disconnect (session %d) failed, rv = %s (%d)",
		      getpid (), session_index, vppcom_retval_str (rv), rv);
    }
  else
    {
      /* TBD: Handle cut-thru disconnect */
      clib_spinlock_unlock (&vcm->sessions_lockp);
    }

  return VPPCOM_OK;
}

#define foreach_sock_msg                                        \
_(SESSION_ENABLE_DISABLE_REPLY, session_enable_disable_reply)   \
_(BIND_SOCK_REPLY, bind_sock_reply)                             \
_(UNBIND_SOCK_REPLY, unbind_sock_reply)                         \
_(ACCEPT_SESSION, accept_session)                               \
_(CONNECT_SOCK, connect_sock)                                   \
_(CONNECT_SESSION_REPLY, connect_session_reply)                 \
_(DISCONNECT_SESSION, disconnect_session)                       \
_(DISCONNECT_SESSION_REPLY, disconnect_session_reply)           \
_(RESET_SESSION, reset_session)                                 \
_(APPLICATION_ATTACH_REPLY, application_attach_reply)           \
_(APPLICATION_DETACH_REPLY, application_detach_reply)           \
_(MAP_ANOTHER_SEGMENT, map_another_segment)

static void
vppcom_api_hookup (void)
{
#define _(N,n)                                                  \
    vl_msg_api_set_handlers(VL_API_##N, #n,                     \
                           vl_api_##n##_t_handler,              \
                           vl_noop_handler,                     \
                           vl_api_##n##_t_endian,               \
                           vl_api_##n##_t_print,                \
                           sizeof(vl_api_##n##_t), 1);
  foreach_sock_msg;
#undef _
}

static void
vppcom_cfg_init (vppcom_cfg_t * vcl_cfg)
{
  ASSERT (vcl_cfg);

  vcl_cfg->heapsize = (256ULL << 20);
  vcl_cfg->segment_baseva = 0x200000000ULL;
  vcl_cfg->segment_size = (256 << 20);
  vcl_cfg->add_segment_size = (128 << 20);
  vcl_cfg->preallocated_fifo_pairs = 8;
  vcl_cfg->rx_fifo_size = (1 << 20);
  vcl_cfg->tx_fifo_size = (1 << 20);
  vcl_cfg->event_queue_size = 2048;
  vcl_cfg->listen_queue_size = CLIB_CACHE_LINE_BYTES / sizeof (u32);
  vcl_cfg->app_timeout = 10 * 60.0;
  vcl_cfg->session_timeout = 10 * 60.0;
  vcl_cfg->accept_timeout = 60.0;
}

static void
vppcom_cfg_heapsize (char *conf_fname)
{
  vppcom_cfg_t *vcl_cfg = &vcm->cfg;
  FILE *fp;
  char inbuf[4096];
  int argc = 1;
  char **argv = NULL;
  char *arg = NULL;
  char *p;
  int i;
  u8 *sizep;
  u32 size;
  void *vcl_mem;
  void *heap;

  fp = fopen (conf_fname, "r");
  if (fp == NULL)
    {
      if (VPPCOM_DEBUG > 0)
	fprintf (stderr, "open configuration file '%s' failed\n", conf_fname);
      goto defaulted;
    }
  argv = calloc (1, sizeof (char *));
  if (argv == NULL)
    goto defaulted;

  while (1)
    {
      if (fgets (inbuf, 4096, fp) == 0)
	break;
      p = strtok (inbuf, " \t\n");
      while (p != NULL)
	{
	  if (*p == '#')
	    break;
	  argc++;
	  char **tmp = realloc (argv, argc * sizeof (char *));
	  if (tmp == NULL)
	    goto defaulted;
	  argv = tmp;
	  arg = strndup (p, 1024);
	  if (arg == NULL)
	    goto defaulted;
	  argv[argc - 1] = arg;
	  p = strtok (NULL, " \t\n");
	}
    }

  fclose (fp);
  fp = NULL;

  char **tmp = realloc (argv, (argc + 1) * sizeof (char *));
  if (tmp == NULL)
    goto defaulted;
  argv = tmp;
  argv[argc] = NULL;

  /*
   * Look for and parse the "heapsize" config parameter.
   * Manual since none of the clib infra has been bootstrapped yet.
   *
   * Format: heapsize <nn>[mM][gG]
   */

  for (i = 1; i < (argc - 1); i++)
    {
      if (!strncmp (argv[i], "heapsize", 8))
	{
	  sizep = (u8 *) argv[i + 1];
	  size = 0;
	  while (*sizep >= '0' && *sizep <= '9')
	    {
	      size *= 10;
	      size += *sizep++ - '0';
	    }
	  if (size == 0)
	    {
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] parse error '%s %s', "
			      "using default heapsize %lld (0x%llx)",
			      getpid (), argv[i], argv[i + 1],
			      vcl_cfg->heapsize, vcl_cfg->heapsize);
	      goto defaulted;
	    }

	  if (*sizep == 'g' || *sizep == 'G')
	    vcl_cfg->heapsize = size << 30;
	  else if (*sizep == 'm' || *sizep == 'M')
	    vcl_cfg->heapsize = size << 20;
	  else
	    {
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] parse error '%s %s', "
			      "using default heapsize %lld (0x%llx)",
			      getpid (), argv[i], argv[i + 1],
			      vcl_cfg->heapsize, vcl_cfg->heapsize);
	      goto defaulted;
	    }
	}
    }

defaulted:
  if (fp != NULL)
    fclose (fp);
  if (argv != NULL)
    free (argv);

  vcl_mem = mmap (0, vcl_cfg->heapsize, PROT_READ | PROT_WRITE,
		  MAP_SHARED | MAP_ANONYMOUS, -1, 0);
  if (vcl_mem == MAP_FAILED)
    {
      clib_unix_error ("[%d] ERROR: mmap(0, %lld == 0x%llx, "
		       "PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS, "
		       "-1, 0) failed!",
		       getpid (), vcl_cfg->heapsize, vcl_cfg->heapsize);
      return;
    }
  heap = clib_mem_init (vcl_mem, vcl_cfg->heapsize);
  if (!heap)
    {
      clib_warning ("[%d] ERROR: clib_mem_init() failed!", getpid ());
      return;
    }
  vcl_mem = clib_mem_alloc (sizeof (_vppcom_main));
  if (!vcl_mem)
    {
      clib_warning ("[%d] ERROR: clib_mem_alloc() failed!", getpid ());
      return;
    }

  clib_memcpy (vcl_mem, &_vppcom_main, sizeof (_vppcom_main));
  vcm = vcl_mem;

  if (VPPCOM_DEBUG > 0)
    clib_warning ("[%d] allocated VCL heap = %p, size %lld (0x%llx)",
		  getpid (), heap, vcl_cfg->heapsize, vcl_cfg->heapsize);
}

static void
vppcom_cfg_read (char *conf_fname)
{
  vppcom_cfg_t *vcl_cfg = &vcm->cfg;
  int fd;
  unformat_input_t _input, *input = &_input;
  unformat_input_t _line_input, *line_input = &_line_input;
  u8 vc_cfg_input = 0;
  u8 *chroot_path;
  struct stat s;
  u32 uid, gid;

  fd = open (conf_fname, O_RDONLY);
  if (fd < 0)
    {
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] open configuration file '%s' failed!",
		      getpid (), conf_fname);
      goto file_done;
    }

  if (fstat (fd, &s) < 0)
    {
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] failed to stat `%s'", getpid (), conf_fname);
      goto file_done;
    }

  if (!(S_ISREG (s.st_mode) || S_ISLNK (s.st_mode)))
    {
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] not a regular file `%s'", getpid (), conf_fname);
      goto file_done;
    }

  unformat_init_clib_file (input, fd);

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      (void) unformat_user (input, unformat_line_input, line_input);
      unformat_skip_white_space (line_input);

      if (unformat (line_input, "vcl {"))
	{
	  vc_cfg_input = 1;
	  continue;
	}

      if (vc_cfg_input)
	{
	  if (unformat (line_input, "heapsize %s", &chroot_path))
	    {
	      vec_terminate_c_string (chroot_path);
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] configured heapsize %s, "
			      "actual heapsize %lld (0x%llx)",
			      getpid (), chroot_path, vcl_cfg->heapsize,
			      vcl_cfg->heapsize);
	      vec_free (chroot_path);
	    }
	  else if (unformat (line_input, "api-prefix %s", &chroot_path))
	    {
	      vec_terminate_c_string (chroot_path);
	      vl_set_memory_root_path ((char *) chroot_path);
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] configured api-prefix %s",
			      getpid (), chroot_path);
	      chroot_path = 0;	/* Don't vec_free() it! */
	    }
	  else if (unformat (line_input, "uid %d", &uid))
	    {
	      vl_set_memory_uid (uid);
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] configured uid %d", getpid (), uid);
	    }
	  else if (unformat (line_input, "gid %d", &gid))
	    {
	      vl_set_memory_gid (gid);
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] configured gid %d", getpid (), gid);
	    }
	  else if (unformat (line_input, "segment-baseva 0x%lx",
			     &vcl_cfg->segment_baseva))
	    {
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] configured segment_baseva 0x%lx",
			      getpid (), vcl_cfg->segment_baseva);
	    }
	  else if (unformat (line_input, "segment-size 0x%lx",
			     &vcl_cfg->segment_size))
	    {
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] configured segment_size 0x%lx (%ld)",
			      getpid (), vcl_cfg->segment_size,
			      vcl_cfg->segment_size);
	    }
	  else if (unformat (line_input, "segment-size %ld",
			     &vcl_cfg->segment_size))
	    {
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] configured segment_size %ld (0x%lx)",
			      getpid (), vcl_cfg->segment_size,
			      vcl_cfg->segment_size);
	    }
	  else if (unformat (line_input, "add-segment-size 0x%lx",
			     &vcl_cfg->add_segment_size))
	    {
	      if (VPPCOM_DEBUG > 0)
		clib_warning
		  ("[%d] configured add_segment_size 0x%lx (%ld)",
		   getpid (), vcl_cfg->add_segment_size,
		   vcl_cfg->add_segment_size);
	    }
	  else if (unformat (line_input, "add-segment-size %ld",
			     &vcl_cfg->add_segment_size))
	    {
	      if (VPPCOM_DEBUG > 0)
		clib_warning
		  ("[%d] configured add_segment_size %ld (0x%lx)",
		   getpid (), vcl_cfg->add_segment_size,
		   vcl_cfg->add_segment_size);
	    }
	  else if (unformat (line_input, "preallocated-fifo-pairs %d",
			     &vcl_cfg->preallocated_fifo_pairs))
	    {
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] configured preallocated_fifo_pairs "
			      "%d (0x%x)", getpid (),
			      vcl_cfg->preallocated_fifo_pairs,
			      vcl_cfg->preallocated_fifo_pairs);
	    }
	  else if (unformat (line_input, "rx-fifo-size 0x%lx",
			     &vcl_cfg->rx_fifo_size))
	    {
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] configured rx_fifo_size 0x%lx (%ld)",
			      getpid (), vcl_cfg->rx_fifo_size,
			      vcl_cfg->rx_fifo_size);
	    }
	  else if (unformat (line_input, "rx-fifo-size %ld",
			     &vcl_cfg->rx_fifo_size))
	    {
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] configured rx_fifo_size %ld (0x%lx)",
			      getpid (), vcl_cfg->rx_fifo_size,
			      vcl_cfg->rx_fifo_size);
	    }
	  else if (unformat (line_input, "tx-fifo-size 0x%lx",
			     &vcl_cfg->tx_fifo_size))
	    {
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] configured tx_fifo_size 0x%lx (%ld)",
			      getpid (), vcl_cfg->tx_fifo_size,
			      vcl_cfg->tx_fifo_size);
	    }
	  else if (unformat (line_input, "tx-fifo-size %ld",
			     &vcl_cfg->tx_fifo_size))
	    {
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] configured tx_fifo_size %ld (0x%lx)",
			      getpid (), vcl_cfg->tx_fifo_size,
			      vcl_cfg->tx_fifo_size);
	    }
	  else if (unformat (line_input, "event-queue-size 0x%lx",
			     &vcl_cfg->event_queue_size))
	    {
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] configured event_queue_size 0x%lx (%ld)",
			      getpid (), vcl_cfg->event_queue_size,
			      vcl_cfg->event_queue_size);
	    }
	  else if (unformat (line_input, "event-queue-size %ld",
			     &vcl_cfg->event_queue_size))
	    {
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] configured event_queue_size %ld (0x%lx)",
			      getpid (), vcl_cfg->event_queue_size,
			      vcl_cfg->event_queue_size);
	    }
	  else if (unformat (line_input, "listen-queue-size 0x%lx",
			     &vcl_cfg->listen_queue_size))
	    {
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] configured listen_queue_size 0x%lx (%ld)",
			      getpid (), vcl_cfg->listen_queue_size,
			      vcl_cfg->listen_queue_size);
	    }
	  else if (unformat (line_input, "listen-queue-size %ld",
			     &vcl_cfg->listen_queue_size))
	    {
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] configured listen_queue_size %ld (0x%lx)",
			      getpid (), vcl_cfg->listen_queue_size,
			      vcl_cfg->listen_queue_size);
	    }
	  else if (unformat (line_input, "app-timeout %f",
			     &vcl_cfg->app_timeout))
	    {
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] configured app_timeout %f",
			      getpid (), vcl_cfg->app_timeout);
	    }
	  else if (unformat (line_input, "session-timeout %f",
			     &vcl_cfg->session_timeout))
	    {
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] configured session_timeout %f",
			      getpid (), vcl_cfg->session_timeout);
	    }
	  else if (unformat (line_input, "accept-timeout %f",
			     &vcl_cfg->accept_timeout))
	    {
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] configured accept_timeout %f",
			      getpid (), vcl_cfg->accept_timeout);
	    }
	  else if (unformat (line_input, "app-proxy-transport-tcp"))
	    {
	      vcl_cfg->app_proxy_transport_tcp = 1;
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] configured app_proxy_transport_tcp (%d)",
			      getpid (), vcl_cfg->app_proxy_transport_tcp);
	    }
	  else if (unformat (line_input, "app-proxy-transport-udp"))
	    {
	      vcl_cfg->app_proxy_transport_udp = 1;
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] configured app_proxy_transport_udp (%d)",
			      getpid (), vcl_cfg->app_proxy_transport_udp);
	    }
	  else if (unformat (line_input, "app-scope-local"))
	    {
	      vcl_cfg->app_scope_local = 1;
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] configured app_scope_local (%d)",
			      getpid (), vcl_cfg->app_scope_local);
	    }
	  else if (unformat (line_input, "app-scope-global"))
	    {
	      vcl_cfg->app_scope_global = 1;
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] configured app_scope_global (%d)",
			      getpid (), vcl_cfg->app_scope_global);
	    }
	  else if (unformat (line_input, "namespace-secret %lu",
			     &vcl_cfg->namespace_secret))
	    {
	      if (VPPCOM_DEBUG > 0)
		clib_warning
		  ("[%d] configured namespace_secret %lu (0x%lx)",
		   getpid (), vcl_cfg->namespace_secret,
		   vcl_cfg->namespace_secret);
	    }
	  else if (unformat (line_input, "namespace-id %v",
			     &vcl_cfg->namespace_id))
	    {
	      vl_api_application_attach_t *mp;
	      u32 max_nsid_vec_len = sizeof (mp->namespace_id) - 1;
	      u32 nsid_vec_len = vec_len (vcl_cfg->namespace_id);
	      if (nsid_vec_len > max_nsid_vec_len)
		{
		  _vec_len (vcl_cfg->namespace_id) = max_nsid_vec_len;
		  if (VPPCOM_DEBUG > 0)
		    clib_warning ("[%d] configured namespace_id is too long,"
				  " truncated to %d characters!", getpid (),
				  max_nsid_vec_len);
		}

	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] configured namespace_id %v",
			      getpid (), vcl_cfg->namespace_id);
	    }
	  else if (unformat (line_input, "}"))
	    {
	      vc_cfg_input = 0;
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] completed parsing vppcom config!",
			      getpid ());
	      goto input_done;
	    }
	  else
	    {
	      if (line_input->buffer[line_input->index] != '#')
		{
		  clib_warning ("[%d] Unknown vppcom config option: '%s'",
				getpid (), (char *)
				&line_input->buffer[line_input->index]);
		}
	    }
	}
    }

input_done:
  unformat_free (input);

file_done:
  if (fd >= 0)
    close (fd);
}

/*
 * VPPCOM Public API functions
 */
int
vppcom_app_create (char *app_name)
{
  vppcom_cfg_t *vcl_cfg = &vcm->cfg;
  u8 *heap;
  mheap_t *h;
  int rv;

  if (!vcm->init)
    {
      char *conf_fname;
      char *env_var_str;

      vcm->init = 1;
      vppcom_cfg_init (vcl_cfg);
      env_var_str = getenv (VPPCOM_ENV_DEBUG);
      if (env_var_str)
	{
	  u32 tmp;
	  if (sscanf (env_var_str, "%u", &tmp) != 1)
	    clib_warning ("[%d] Invalid debug level specified in "
			  "the environment variable "
			  VPPCOM_ENV_DEBUG
			  " (%s)!\n", getpid (), env_var_str);
	  else
	    {
	      vcm->debug = tmp;
	      clib_warning ("[%d] configured debug level (%u) from "
			    VPPCOM_ENV_DEBUG "!", getpid (), vcm->debug);
	    }
	}
      conf_fname = getenv (VPPCOM_ENV_CONF);
      if (!conf_fname)
	{
	  conf_fname = VPPCOM_CONF_DEFAULT;
	  if (VPPCOM_DEBUG > 0)
	    clib_warning ("[%d] getenv '%s' failed!", getpid (),
			  VPPCOM_ENV_CONF);
	}
      vppcom_cfg_heapsize (conf_fname);
      clib_fifo_validate (vcm->client_session_index_fifo,
			  vcm->cfg.listen_queue_size);
      vppcom_cfg_read (conf_fname);
      env_var_str = getenv (VPPCOM_ENV_APP_NAMESPACE_ID);
      if (env_var_str)
	{
	  u32 ns_id_vec_len = strlen (env_var_str);

	  vec_reset_length (vcm->cfg.namespace_id);
	  vec_validate (vcm->cfg.namespace_id, ns_id_vec_len - 1);
	  clib_memcpy (vcm->cfg.namespace_id, env_var_str, ns_id_vec_len);

	  if (VPPCOM_DEBUG > 0)
	    clib_warning ("[%d] configured namespace_id (%v) from "
			  VPPCOM_ENV_APP_NAMESPACE_ID "!", getpid (),
			  vcm->cfg.namespace_id);
	}
      env_var_str = getenv (VPPCOM_ENV_APP_NAMESPACE_SECRET);
      if (env_var_str)
	{
	  u64 tmp;
	  if (sscanf (env_var_str, "%lu", &tmp) != 1)
	    clib_warning ("[%d] Invalid namespace secret specified in "
			  "the environment variable "
			  VPPCOM_ENV_APP_NAMESPACE_SECRET
			  " (%s)!\n", getpid (), env_var_str);
	  else
	    {
	      vcm->cfg.namespace_secret = tmp;
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] configured namespace secret (%lu) from "
			      VPPCOM_ENV_APP_NAMESPACE_ID "!", getpid (),
			      vcm->cfg.namespace_secret);
	    }
	}
      if (getenv (VPPCOM_ENV_APP_PROXY_TRANSPORT_TCP))
	{
	  vcm->cfg.app_proxy_transport_tcp = 1;
	  if (VPPCOM_DEBUG > 0)
	    clib_warning ("[%d] configured app_proxy_transport_tcp (%u) from "
			  VPPCOM_ENV_APP_PROXY_TRANSPORT_TCP "!", getpid (),
			  vcm->cfg.app_proxy_transport_tcp);
	}
      if (getenv (VPPCOM_ENV_APP_PROXY_TRANSPORT_UDP))
	{
	  vcm->cfg.app_proxy_transport_udp = 1;
	  if (VPPCOM_DEBUG > 0)
	    clib_warning ("[%d] configured app_proxy_transport_udp (%u) from "
			  VPPCOM_ENV_APP_PROXY_TRANSPORT_UDP "!", getpid (),
			  vcm->cfg.app_proxy_transport_udp);
	}
      if (getenv (VPPCOM_ENV_APP_SCOPE_LOCAL))
	{
	  vcm->cfg.app_scope_local = 1;
	  if (VPPCOM_DEBUG > 0)
	    clib_warning ("[%d] configured app_scope_local (%u) from "
			  VPPCOM_ENV_APP_SCOPE_LOCAL "!", getpid (),
			  vcm->cfg.app_scope_local);
	}
      if (getenv (VPPCOM_ENV_APP_SCOPE_GLOBAL))
	{
	  vcm->cfg.app_scope_global = 1;
	  if (VPPCOM_DEBUG > 0)
	    clib_warning ("[%d] configured app_scope_global (%u) from "
			  VPPCOM_ENV_APP_SCOPE_GLOBAL "!", getpid (),
			  vcm->cfg.app_scope_global);
	}

      vcm->bind_session_index = ~0;
      vcm->main_cpu = os_get_thread_index ();
      heap = clib_mem_get_per_cpu_heap ();
      h = mheap_header (heap);

      /* make the main heap thread-safe */
      h->flags |= MHEAP_FLAG_THREAD_SAFE;

      vcm->session_index_by_vpp_handles = hash_create (0, sizeof (uword));

      clib_time_init (&vcm->clib_time);
      vppcom_init_error_string_table ();
      svm_fifo_segment_init (vcl_cfg->segment_baseva,
			     20 /* timeout in secs */ );
      clib_spinlock_init (&vcm->sessions_lockp);
      vppcom_api_hookup ();
    }

  if (vcm->my_client_index == ~0)
    {
      vcm->app_state = STATE_APP_START;
      rv = vppcom_connect_to_vpp (app_name);
      if (rv)
	{
	  clib_warning ("[%d] couldn't connect to VPP.", getpid ());
	  return rv;
	}

      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] sending session enable", getpid ());

      rv = vppcom_app_session_enable ();
      if (rv)
	{
	  clib_warning ("[%d] vppcom_app_session_enable() failed!",
			getpid ());
	  return rv;
	}

      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] sending app attach", getpid ());

      rv = vppcom_app_attach ();
      if (rv)
	{
	  clib_warning ("[%d] vppcom_app_attach() failed!", getpid ());
	  return rv;
	}

      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] app_name '%s', my_client_index %d (0x%x)",
		      getpid (), app_name, vcm->my_client_index,
		      vcm->my_client_index);
    }

  return VPPCOM_OK;
}

void
vppcom_app_destroy (void)
{
  int rv;

  if (vcm->my_client_index == ~0)
    return;

  if (VPPCOM_DEBUG > 0)
    clib_warning ("[%d] detaching from VPP, my_client_index %d (0x%x)",
		  getpid (), vcm->my_client_index, vcm->my_client_index);

  vppcom_app_detach ();
  rv = vppcom_wait_for_app_state_change (STATE_APP_ENABLED);
  if (PREDICT_FALSE (rv))
    {
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] application detach timed out, rv = %s (%d)",
		      getpid (), vppcom_retval_str (rv), rv);
    }
  vl_client_disconnect_from_vlib ();
  vcm->my_client_index = ~0;
  vcm->app_state = STATE_APP_START;
}

int
vppcom_session_create (u32 vrf, u8 proto, u8 is_nonblocking)
{
  session_t *session;
  u32 session_index;

  clib_spinlock_lock (&vcm->sessions_lockp);
  pool_get (vcm->sessions, session);
  memset (session, 0, sizeof (*session));
  session_index = session - vcm->sessions;

  session->vrf = vrf;
  session->proto = proto;
  session->state = STATE_START;
  session->is_nonblocking = is_nonblocking ? 1 : 0;
  clib_spinlock_unlock (&vcm->sessions_lockp);

  if (VPPCOM_DEBUG > 0)
    clib_warning ("[%d] sid %d", getpid (), session_index);

  return (int) session_index;
}

int
vppcom_session_close (uint32_t session_index)
{
  session_t *session = 0;
  int rv;
  u8 is_server;
  u8 is_listen;
  u8 is_cut_thru;
  u8 is_vep;
  u8 is_vep_session;
  u32 next_sid;
  u32 vep_idx;
  session_state_t state;

  clib_spinlock_lock (&vcm->sessions_lockp);
  rv = vppcom_session_at_index (session_index, &session);
  if (PREDICT_FALSE (rv))
    {
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] invalid session, sid (%u) has been closed!",
		      getpid (), session_index);
      clib_spinlock_unlock (&vcm->sessions_lockp);
      goto done;
    }
  is_server = session->is_server;
  is_listen = session->is_listen;
  is_cut_thru = session->is_cut_thru;
  is_vep = session->is_vep;
  is_vep_session = session->is_vep_session;
  next_sid = session->vep.next_sid;
  vep_idx = session->vep.vep_idx;
  state = session->state;
  clib_spinlock_unlock (&vcm->sessions_lockp);

  if (VPPCOM_DEBUG > 0)
    clib_warning ("[%d] sid %d", getpid (), session_index);

  if (is_vep)
    {
      while (next_sid != ~0)
	{
	  rv = vppcom_epoll_ctl (session_index, EPOLL_CTL_DEL, next_sid, 0);
	  if ((VPPCOM_DEBUG > 0) && (rv < 0))
	    clib_warning ("[%d] EPOLL_CTL_DEL vep_idx %u, sid %u failed, "
			  "rv = %s (%d)", getpid (), vep_idx, next_sid,
			  vppcom_retval_str (rv), rv);

	  clib_spinlock_lock (&vcm->sessions_lockp);
	  rv = vppcom_session_at_index (session_index, &session);
	  if (PREDICT_FALSE (rv))
	    {
	      if (VPPCOM_DEBUG > 0)
		clib_warning
		  ("[%d] invalid session, sid (%u) has been closed!",
		   getpid (), session_index);
	      clib_spinlock_unlock (&vcm->sessions_lockp);
	      goto done;
	    }
	  next_sid = session->vep.next_sid;
	  clib_spinlock_unlock (&vcm->sessions_lockp);
	}
    }
  else
    {
      if (is_vep_session)
	{
	  rv = vppcom_epoll_ctl (vep_idx, EPOLL_CTL_DEL, session_index, 0);
	  if ((VPPCOM_DEBUG > 0) && (rv < 0))
	    clib_warning ("[%d] EPOLL_CTL_DEL vep_idx %u, sid %u failed, "
			  "rv = %s (%d)", getpid (), vep_idx, session_index,
			  vppcom_retval_str (rv), rv);
	}

      if (is_cut_thru && is_server && (state == STATE_ACCEPT))
	{
	  rv = vppcom_session_unbind_cut_thru (session, session_index);
	  if ((VPPCOM_DEBUG > 0) && (rv < 0))
	    clib_warning ("[%d] unbind cut-thru (session %d) failed, "
			  "rv = %s (%d)",
			  getpid (), session_index,
			  vppcom_retval_str (rv), rv);
	}
      else if (is_server && is_listen)
	{
	  rv = vppcom_session_unbind (session_index);
	  if ((VPPCOM_DEBUG > 0) && (rv < 0))
	    clib_warning ("[%d] unbind (session %d) failed, rv = %s (%d)",
			  getpid (), session_index,
			  vppcom_retval_str (rv), rv);
	}
      else if (state == STATE_CONNECT)
	if (vppcom_session_disconnect (session_index))
	  goto done;
    }
  clib_spinlock_lock (&vcm->sessions_lockp);
  pool_put_index (vcm->sessions, session_index);
  clib_spinlock_unlock (&vcm->sessions_lockp);
done:
  return rv;
}

int
vppcom_session_bind (uint32_t session_index, vppcom_endpt_t * ep)
{
  session_t *session = 0;
  int rv;

  if (!ep || !ep->ip)
    return VPPCOM_EINVAL;

  clib_spinlock_lock (&vcm->sessions_lockp);
  rv = vppcom_session_at_index (session_index, &session);
  if (PREDICT_FALSE (rv))
    {
      clib_spinlock_unlock (&vcm->sessions_lockp);
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] invalid session, sid (%u) has been closed!",
		      getpid (), session_index);
      return rv;
    }

  if (session->is_vep)
    {
      clib_spinlock_unlock (&vcm->sessions_lockp);
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] invalid session, sid (%u) is an epoll session!",
		      getpid (), session_index);
      return VPPCOM_EBADFD;
    }

  session->vrf = ep->vrf;
  session->lcl_addr.is_ip4 = ep->is_ip4;
  session->lcl_addr.ip46 = to_ip46 (!ep->is_ip4, ep->ip);
  session->lcl_port = ep->port;

  if (VPPCOM_DEBUG > 0)
    clib_warning ("[%d] sid %d, bound to lcl address %U lcl port %u",
		  getpid (), session_index, format_ip46_address,
		  &session->lcl_addr.ip46, session->lcl_addr.is_ip4,
		  clib_net_to_host_u16 (session->lcl_port));

  clib_spinlock_unlock (&vcm->sessions_lockp);
  return VPPCOM_OK;
}

int
vppcom_session_listen (uint32_t listen_session_index, uint32_t q_len)
{
  session_t *listen_session = 0;
  int rv;

  clib_spinlock_lock (&vcm->sessions_lockp);
  rv = vppcom_session_at_index (listen_session_index, &listen_session);
  if (PREDICT_FALSE (rv))
    {
      clib_spinlock_unlock (&vcm->sessions_lockp);
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] invalid session, sid (%u) has been closed!",
		      getpid (), listen_session_index);
      return rv;
    }

  if (listen_session->is_vep)
    {
      clib_spinlock_unlock (&vcm->sessions_lockp);
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] invalid session, sid (%u) is an epoll session!",
		      getpid (), listen_session_index);
      return VPPCOM_EBADFD;
    }

  if (listen_session->is_listen)
    {
      clib_spinlock_unlock (&vcm->sessions_lockp);
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] sid (%u) is already in listen state!",
		      getpid (), listen_session_index);
      return VPPCOM_OK;
    }

  if (VPPCOM_DEBUG > 0)
    clib_warning ("[%d] sid %d", getpid (), listen_session_index);

  ASSERT (vcm->bind_session_index == ~0);
  vcm->bind_session_index = listen_session_index;
  vppcom_send_bind_sock (listen_session);
  clib_spinlock_unlock (&vcm->sessions_lockp);
  rv =
    vppcom_wait_for_session_state_change (listen_session_index, STATE_LISTEN,
					  vcm->cfg.session_timeout);
  if (PREDICT_FALSE (rv))
    {
      vcm->bind_session_index = ~0;
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] server listen timed out, rv = %d (%d)",
		      getpid (), vppcom_retval_str (rv), rv);
      return rv;
    }

  clib_spinlock_lock (&vcm->sessions_lockp);
  rv = vppcom_session_at_index (listen_session_index, &listen_session);
  if (PREDICT_FALSE (rv))
    {
      clib_spinlock_unlock (&vcm->sessions_lockp);
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] invalid session, sid (%u) has been closed!",
		      getpid (), listen_session_index);
      return rv;
    }
  listen_session->is_listen = 1;
  clib_fifo_validate (vcm->client_session_index_fifo, q_len);
  clib_spinlock_unlock (&vcm->sessions_lockp);

  return VPPCOM_OK;
}

int
vppcom_session_accept (uint32_t listen_session_index, vppcom_endpt_t * ep,
		       uint32_t flags, double wait_for_time)
{
  session_t *listen_session = 0;
  session_t *client_session = 0;
  u32 client_session_index = ~0;
  int rv;
  f64 wait_for;
  char *cut_thru_str;

  clib_spinlock_lock (&vcm->sessions_lockp);
  rv = vppcom_session_at_index (listen_session_index, &listen_session);
  if (PREDICT_FALSE (rv))
    {
      clib_spinlock_unlock (&vcm->sessions_lockp);
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] invalid session, sid (%u) has been closed!",
		      getpid (), listen_session_index);
      return rv;
    }

  if (listen_session->is_vep)
    {
      clib_spinlock_unlock (&vcm->sessions_lockp);
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] invalid session, sid (%u) is an epoll session!",
		      getpid (), listen_session_index);
      return VPPCOM_EBADFD;
    }

  if (listen_session->state != STATE_LISTEN)
    {
      clib_spinlock_unlock (&vcm->sessions_lockp);
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] session not in listen state, state = %s",
		      getpid (),
		      vppcom_session_state_str (listen_session->state));
      return VPPCOM_EBADFD;
    }
  wait_for = listen_session->is_nonblocking ? 0 :
    (wait_for_time < 0) ? vcm->cfg.accept_timeout : wait_for_time;

  if (VPPCOM_DEBUG > 0)
    clib_warning ("[%d] sid %d: %s (%d)", getpid (),
		  listen_session_index,
		  vppcom_session_state_str (listen_session->state),
		  listen_session->state);
  clib_spinlock_unlock (&vcm->sessions_lockp);

  while (1)
    {
      rv = vppcom_wait_for_client_session_index (wait_for);
      if (rv)
	{
	  if ((VPPCOM_DEBUG > 0))
	    clib_warning ("[%d] sid %d, accept timed out, rv = %s (%d)",
			  getpid (), listen_session_index,
			  vppcom_retval_str (rv), rv);
	  if ((wait_for == 0) || (wait_for_time > 0))
	    return rv;
	}
      else
	break;
    }

  clib_spinlock_lock (&vcm->sessions_lockp);
  clib_fifo_sub1 (vcm->client_session_index_fifo, client_session_index);
  rv = vppcom_session_at_index (client_session_index, &client_session);
  ASSERT (rv == VPPCOM_OK);
  ASSERT (client_session->peer_addr.is_ip4 ==
	  listen_session->lcl_addr.is_ip4);

  client_session->is_nonblocking = (flags & O_NONBLOCK) ? 1 : 0;
  if (VPPCOM_DEBUG > 0)
    clib_warning ("[%d] Got a request: client sid %d, flags %d, "
		  " is_nonblocking %u", getpid (), client_session_index,
		  flags, client_session->is_nonblocking);

  ep->vrf = client_session->vrf;
  ep->is_cut_thru = client_session->is_cut_thru;
  ep->is_ip4 = client_session->peer_addr.is_ip4;
  ep->port = client_session->peer_port;
  if (client_session->peer_addr.is_ip4)
    clib_memcpy (ep->ip, &client_session->peer_addr.ip46.ip4,
		 sizeof (ip4_address_t));
  else
    clib_memcpy (ep->ip, &client_session->peer_addr.ip46.ip6,
		 sizeof (ip6_address_t));

  if (client_session->is_server && client_session->is_cut_thru)
    {
      static svm_fifo_segment_create_args_t _a;
      svm_fifo_segment_create_args_t *a = &_a;
      svm_fifo_segment_private_t *seg;

      cut_thru_str = "cut-thru ";

      /* Create the segment */
      memset (a, 0, sizeof (*a));
      a->segment_name = (char *)
	format ((u8 *) a->segment_name, "%d:segment%d%c",
		getpid (), vcm->unique_segment_index++, 0);
      a->segment_size = vcm->cfg.segment_size;
      a->preallocated_fifo_pairs = vcm->cfg.preallocated_fifo_pairs;
      a->rx_fifo_size = vcm->cfg.rx_fifo_size;
      a->tx_fifo_size = vcm->cfg.tx_fifo_size;

      rv = svm_fifo_segment_create (a);
      if (PREDICT_FALSE (rv))
	{
	  if (VPPCOM_DEBUG > 1)
	    clib_warning ("[%d] svm_fifo_segment_create ('%s') failed",
			  getpid (), a->segment_name);
	  vec_reset_length (a->new_segment_indices);
	  rv = VNET_API_ERROR_URI_FIFO_CREATE_FAILED;
	  vppcom_send_connect_session_reply (client_session, rv);
	  clib_spinlock_unlock (&vcm->sessions_lockp);
	  return VPPCOM_ENOMEM;
	}

      client_session->segment_name = vec_dup ((u8 *) a->segment_name);
      client_session->sm_seg_index = a->new_segment_indices[0];
      vec_free (a->new_segment_indices);

      seg = svm_fifo_segment_get_segment (client_session->sm_seg_index);
      client_session->server_rx_fifo =
	svm_fifo_segment_alloc_fifo (seg, vcm->cfg.rx_fifo_size,
				     FIFO_SEGMENT_RX_FREELIST);
      if (PREDICT_FALSE (!client_session->server_rx_fifo))
	{
	  svm_fifo_segment_delete (seg);
	  clib_warning ("[%d] rx fifo alloc failed, size %ld (0x%lx)",
			getpid (), vcm->cfg.rx_fifo_size,
			vcm->cfg.rx_fifo_size);
	  rv = VNET_API_ERROR_URI_FIFO_CREATE_FAILED;
	  vppcom_send_connect_session_reply (client_session, rv);
	  clib_spinlock_unlock (&vcm->sessions_lockp);
	  return VPPCOM_ENOMEM;
	}
      client_session->server_rx_fifo->master_session_index =
	client_session_index;

      client_session->server_tx_fifo =
	svm_fifo_segment_alloc_fifo (seg, vcm->cfg.tx_fifo_size,
				     FIFO_SEGMENT_TX_FREELIST);
      if (PREDICT_FALSE (!client_session->server_tx_fifo))
	{
	  svm_fifo_segment_delete (seg);
	  if (VPPCOM_DEBUG > 1)
	    clib_warning ("[%d] tx fifo alloc failed, size %ld (0x%lx)",
			  getpid (), vcm->cfg.tx_fifo_size,
			  vcm->cfg.tx_fifo_size);
	  rv = VNET_API_ERROR_URI_FIFO_CREATE_FAILED;
	  vppcom_send_connect_session_reply (client_session, rv);
	  clib_spinlock_unlock (&vcm->sessions_lockp);
	  return VPPCOM_ENOMEM;
	}
      client_session->server_tx_fifo->master_session_index =
	client_session_index;

      if (VPPCOM_DEBUG > 1)
	clib_warning ("[%d] created segment '%s': rx_fifo %p, tx_fifo %p",
		      getpid (), client_session->segment_name,
		      client_session->server_rx_fifo,
		      client_session->server_tx_fifo);

#ifdef CUT_THRU_EVENT_QUEUE	/* TBD */
      {
	void *oldheap;
	ssvm_shared_header_t *sh = seg->ssvm.sh;

	ssvm_lock_non_recursive (sh, 1);
	oldheap = ssvm_push_heap (sh);
	event_q = client_session->vpp_event_queue =
	  unix_shared_memory_queue_init (vcm->cfg.event_queue_size,
					 sizeof (session_fifo_event_t),
					 getpid (), 0 /* signal not sent */ );
	ssvm_pop_heap (oldheap);
	ssvm_unlock_non_recursive (sh);
      }
#endif
      vppcom_send_connect_session_reply (client_session, 0);
    }
  else
    {
      cut_thru_str = " ";
      vppcom_send_accept_session_reply (client_session->vpp_handle, 0);
    }

  if (VPPCOM_DEBUG > 0)
    clib_warning ("[%d] sid %d, accepted %sconnection to peer address "
		  "%U peer port %u",
		  getpid (), client_session_index, cut_thru_str,
		  format_ip46_address, &client_session->peer_addr.ip46,
		  client_session->peer_addr.is_ip4,
		  clib_net_to_host_u16 (client_session->peer_port));

  clib_spinlock_unlock (&vcm->sessions_lockp);
  return (int) client_session_index;
}

int
vppcom_session_connect (uint32_t session_index, vppcom_endpt_t * server_ep)
{
  session_t *session = 0;
  int rv;

  clib_spinlock_lock (&vcm->sessions_lockp);
  rv = vppcom_session_at_index (session_index, &session);
  if (PREDICT_FALSE (rv))
    {
      clib_spinlock_unlock (&vcm->sessions_lockp);
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] invalid session, sid (%u) has been closed!",
		      getpid (), session_index);
      return rv;
    }

  if (session->is_vep)
    {
      clib_spinlock_unlock (&vcm->sessions_lockp);
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] invalid session, sid (%u) is an epoll session!",
		      getpid (), session_index);
      return VPPCOM_EBADFD;
    }

  if (session->state == STATE_CONNECT)
    {
      clib_spinlock_unlock (&vcm->sessions_lockp);
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] session, sid (%u) already connected!",
		      getpid (), session_index);
      return VPPCOM_OK;
    }

  session->vrf = server_ep->vrf;
  session->peer_addr.is_ip4 = server_ep->is_ip4;
  session->peer_addr.ip46 = to_ip46 (!server_ep->is_ip4, server_ep->ip);
  session->peer_port = server_ep->port;

  if (VPPCOM_DEBUG > 0)
    {
      u8 *ip_str = format (0, "%U", format_ip46_address,
			   &session->peer_addr.ip46,
			   session->peer_addr.is_ip4);
      clib_warning ("[%d] connect sid %d to %s server port %d proto %s",
		    getpid (), session_index, ip_str,
		    clib_net_to_host_u16 (session->peer_port),
		    session->proto ? "UDP" : "TCP");
      vec_free (ip_str);
    }

  vppcom_send_connect_sock (session, session_index);
  clib_spinlock_unlock (&vcm->sessions_lockp);
  rv = vppcom_wait_for_session_state_change (session_index, STATE_CONNECT,
					     vcm->cfg.session_timeout);
  if (PREDICT_FALSE (rv))
    {
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] connect timed out, rv = %s (%d)",
		      getpid (), vppcom_retval_str (rv), rv);
      return rv;
    }
  if (VPPCOM_DEBUG > 0)
    clib_warning ("[%d] sid %d connected!", getpid (), session_index);

  return VPPCOM_OK;
}

static inline int
vppcom_session_read_internal (uint32_t session_index, void *buf, int n,
			      u8 peek)
{
  session_t *session = 0;
  svm_fifo_t *rx_fifo;
  int n_read = 0;
  int rv;
  char *fifo_str;
  u32 poll_et;

  ASSERT (buf);

  clib_spinlock_lock (&vcm->sessions_lockp);
  rv = vppcom_session_at_index (session_index, &session);
  if (PREDICT_FALSE (rv))
    {
      clib_spinlock_unlock (&vcm->sessions_lockp);
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] invalid session, sid (%u) has been closed!",
		      getpid (), session_index);
      return rv;
    }

  if (session->is_vep)
    {
      clib_spinlock_unlock (&vcm->sessions_lockp);
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] invalid session, sid (%u) is an epoll session!",
		      getpid (), session_index);
      return VPPCOM_EBADFD;
    }

  if (session->state == STATE_DISCONNECT)
    {
      clib_spinlock_unlock (&vcm->sessions_lockp);
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] sid (%u) has been closed by remote peer!",
		      getpid (), session_index);
      return VPPCOM_ECONNRESET;
    }

  rx_fifo = ((!session->is_cut_thru || session->is_server) ?
	     session->server_rx_fifo : session->server_tx_fifo);
  fifo_str = ((!session->is_cut_thru || session->is_server) ?
	      "server_rx_fifo" : "server_tx_fifo");
  poll_et =
    ((EPOLLET | EPOLLIN) & session->vep.ev.events) == (EPOLLET | EPOLLIN);
  clib_spinlock_unlock (&vcm->sessions_lockp);

  do
    {
      if (peek)
	n_read = svm_fifo_peek (rx_fifo, 0, n, buf);
      else
	n_read = svm_fifo_dequeue_nowait (rx_fifo, n, buf);
    }
  while (!session->is_nonblocking && (n_read <= 0));

  if (poll_et && (n_read <= 0))
    {
      clib_spinlock_lock (&vcm->sessions_lockp);
      session->vep.et_mask |= EPOLLIN;
      clib_spinlock_unlock (&vcm->sessions_lockp);
    }

  if ((VPPCOM_DEBUG > 2) && (n_read > 0))
    clib_warning ("[%d] sid %d, read %d bytes from %s (%p)", getpid (),
		  session_index, n_read, fifo_str, rx_fifo);

  return (n_read <= 0) ? VPPCOM_EAGAIN : n_read;
}

int
vppcom_session_read (uint32_t session_index, void *buf, int n)
{
  return (vppcom_session_read_internal (session_index, buf, n, 0));
}

static int
vppcom_session_peek (uint32_t session_index, void *buf, int n)
{
  return (vppcom_session_read_internal (session_index, buf, n, 1));
}

static inline int
vppcom_session_read_ready (session_t * session, u32 session_index)
{
  svm_fifo_t *rx_fifo = 0;
  int ready = 0;
  u32 poll_et;

  /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
  if (session->is_vep)
    {
      clib_spinlock_unlock (&vcm->sessions_lockp);
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] invalid session, sid (%u) is an epoll session!",
		      getpid (), session_index);
      return VPPCOM_EBADFD;
    }

  if (session->state == STATE_DISCONNECT)
    {
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] sid (%u) has been closed by remote peer!",
		      getpid (), session_index);
      return VPPCOM_ECONNRESET;
    }

  if (session->is_listen)
    ready = clib_fifo_elts (vcm->client_session_index_fifo);
  else
    {
      rx_fifo = ((!session->is_cut_thru || session->is_server) ?
		 session->server_rx_fifo : session->server_tx_fifo);

      ready = svm_fifo_max_dequeue (rx_fifo);
    }

  poll_et =
    ((EPOLLET | EPOLLIN) & session->vep.ev.events) == (EPOLLET | EPOLLIN);
  if (poll_et && (ready == 0))
    {
      if (VPPCOM_DEBUG > 11)
	clib_warning ("[%d] sid %d: current vep.et_mask = 0x%x", getpid (),
		      session_index, session->vep.et_mask);
      session->vep.et_mask |= EPOLLIN;
      if (VPPCOM_DEBUG > 11)
	clib_warning ("[%d] sid %d: updated vep.et_mask = 0x%x", getpid (),
		      session_index, session->vep.et_mask);
    }

  if (session->vep.et_mask && (VPPCOM_DEBUG > 11))
    clib_warning ("[%d] sid %d, is_listen %u, peek %s (%p), ready = %d, "
		  "et_mask 0x%x",
		  getpid (), session_index, session->is_listen,
		  session->is_server ? "server_rx_fifo" : "server_tx_fifo",
		  rx_fifo, ready, session->vep.et_mask);
  return ready;
}

int
vppcom_session_write (uint32_t session_index, void *buf, int n)
{
  session_t *session = 0;
  svm_fifo_t *tx_fifo;
  unix_shared_memory_queue_t *q;
  session_fifo_event_t evt;
  int rv, n_write;
  char *fifo_str;
  u32 poll_et;

  ASSERT (buf);

  clib_spinlock_lock (&vcm->sessions_lockp);
  rv = vppcom_session_at_index (session_index, &session);
  if (PREDICT_FALSE (rv))
    {
      clib_spinlock_unlock (&vcm->sessions_lockp);
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] invalid session, sid (%u) has been closed!",
		      getpid (), session_index);
      return rv;
    }

  if (session->is_vep)
    {
      clib_spinlock_unlock (&vcm->sessions_lockp);
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] invalid session, sid (%u) is an epoll session!",
		      getpid (), session_index);
      return VPPCOM_EBADFD;
    }

  if (session->state == STATE_DISCONNECT)
    {
      clib_spinlock_unlock (&vcm->sessions_lockp);
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] sid (%u) has been closed by remote peer!",
		      getpid (), session_index);
      return VPPCOM_ECONNRESET;
    }

  tx_fifo = ((!session->is_cut_thru || session->is_server) ?
	     session->server_tx_fifo : session->server_rx_fifo);
  fifo_str = ((!session->is_cut_thru || session->is_server) ?
	      "server_tx_fifo" : "server_rx_fifo");
  q = session->vpp_event_queue;
  poll_et = (((EPOLLET | EPOLLOUT) & session->vep.ev.events) ==
	     (EPOLLET | EPOLLOUT));
  clib_spinlock_unlock (&vcm->sessions_lockp);

  do
    {
      n_write = svm_fifo_enqueue_nowait (tx_fifo, n, buf);
    }
  while (!session->is_nonblocking && (n_write <= 0));

  /* If event wasn't set, add one */
  if (!session->is_cut_thru && (n_write > 0) && svm_fifo_set_event (tx_fifo))
    {
      int rval;

      /* Fabricate TX event, send to vpp */
      evt.fifo = tx_fifo;
      evt.event_type = FIFO_EVENT_APP_TX;

      rval = vppcom_session_at_index (session_index, &session);
      if (PREDICT_FALSE (rval))
	{
	  if (VPPCOM_DEBUG > 1)
	    clib_warning ("[%d] invalid session, sid (%u) has been closed!",
			  getpid (), session_index);
	  return rval;
	}
      ASSERT (q);
      unix_shared_memory_queue_add (q, (u8 *) & evt,
				    0 /* do wait for mutex */ );
    }

  if (poll_et && (n_write <= 0))
    {
      clib_spinlock_lock (&vcm->sessions_lockp);
      session->vep.et_mask |= EPOLLOUT;
      clib_spinlock_unlock (&vcm->sessions_lockp);
    }

  if (VPPCOM_DEBUG > 2)
    {
      if (n_write == -2)
	clib_warning ("[%d] sid %d, FIFO-FULL %s (%p)", getpid (),
		      session_index, fifo_str, tx_fifo);
      else
	clib_warning ("[%d] sid %d, wrote %d bytes to %s (%p)", getpid (),
		      session_index, n_write, fifo_str, tx_fifo);
    }
  return (n_write < 0) ? VPPCOM_EAGAIN : n_write;
}

static inline int
vppcom_session_write_ready (session_t * session, u32 session_index)
{
  svm_fifo_t *tx_fifo;
  char *fifo_str;
  int ready;
  u32 poll_et;

  /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
  if (session->is_vep)
    {
      clib_spinlock_unlock (&vcm->sessions_lockp);
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] invalid session, sid (%u) is an epoll session!",
		      getpid (), session_index);
      return VPPCOM_EBADFD;
    }

  if (session->state == STATE_DISCONNECT)
    {
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] sid (%u) has been closed by remote peer!",
		      getpid (), session_index);
      return VPPCOM_ECONNRESET;
    }

  tx_fifo = ((!session->is_cut_thru || session->is_server) ?
	     session->server_tx_fifo : session->server_rx_fifo);
  fifo_str = ((!session->is_cut_thru || session->is_server) ?
	      "server_tx_fifo" : "server_rx_fifo");

  ready = svm_fifo_max_enqueue (tx_fifo);

  if (VPPCOM_DEBUG > 3)
    clib_warning ("[%d] sid %d, peek %s (%p), ready = %d", getpid (),
		  session_index, fifo_str, tx_fifo, ready);
  poll_et = (((EPOLLET | EPOLLOUT) & session->vep.ev.events) ==
	     (EPOLLET | EPOLLOUT));
  if (poll_et && (ready == 0))
    session->vep.et_mask |= EPOLLOUT;

  return ready;
}

int
vppcom_select (unsigned long n_bits, unsigned long *read_map,
	       unsigned long *write_map, unsigned long *except_map,
	       double time_to_wait)
{
  u32 session_index;
  session_t *session = 0;
  int rv, bits_set = 0;
  f64 timeout = clib_time_now (&vcm->clib_time) + time_to_wait;
  u32 minbits = clib_max (n_bits, BITS (uword));

  ASSERT (sizeof (clib_bitmap_t) == sizeof (long int));

  if (n_bits && read_map)
    {
      clib_bitmap_validate (vcm->rd_bitmap, minbits);
      clib_memcpy (vcm->rd_bitmap, read_map, vec_len (vcm->rd_bitmap));
      memset (read_map, 0, vec_len (vcm->rd_bitmap));
    }
  if (n_bits && write_map)
    {
      clib_bitmap_validate (vcm->wr_bitmap, minbits);
      clib_memcpy (vcm->wr_bitmap, write_map, vec_len (vcm->wr_bitmap));
      memset (write_map, 0, vec_len (vcm->wr_bitmap));
    }
  if (n_bits && except_map)
    {
      clib_bitmap_validate (vcm->ex_bitmap, minbits);
      clib_memcpy (vcm->ex_bitmap, except_map, vec_len (vcm->ex_bitmap));
      memset (except_map, 0, vec_len (vcm->ex_bitmap));
    }

  do
    {
      /* *INDENT-OFF* */
      if (n_bits)
        {
          if (read_map)
            {
              clib_bitmap_foreach (session_index, vcm->rd_bitmap,
                ({
                  clib_spinlock_lock (&vcm->sessions_lockp);
                  rv = vppcom_session_at_index (session_index, &session);
                  if (rv < 0)
                    {
                      clib_spinlock_unlock (&vcm->sessions_lockp);
                      if (VPPCOM_DEBUG > 1)
                        clib_warning ("[%d] session %d specified in "
                                      "read_map is closed.", getpid (),
                                      session_index);
                      bits_set = VPPCOM_EBADFD;
                      goto select_done;
                    }

                  rv = vppcom_session_read_ready (session, session_index);
                  clib_spinlock_unlock (&vcm->sessions_lockp);
                  if (except_map && vcm->ex_bitmap &&
                      clib_bitmap_get (vcm->ex_bitmap, session_index) &&
                      (rv < 0))
                    {
                      // TBD: clib_warning
                      clib_bitmap_set_no_check (except_map, session_index, 1);
                      bits_set++;
                    }
                  else if (rv > 0)
                    {
                      // TBD: clib_warning
                      clib_bitmap_set_no_check (read_map, session_index, 1);
                      bits_set++;
                    }
                }));
            }

          if (write_map)
            {
              clib_bitmap_foreach (session_index, vcm->wr_bitmap,
                ({
                  clib_spinlock_lock (&vcm->sessions_lockp);
                  rv = vppcom_session_at_index (session_index, &session);
                  if (rv < 0)
                    {
                      clib_spinlock_unlock (&vcm->sessions_lockp);
                      if (VPPCOM_DEBUG > 0)
                        clib_warning ("[%d] session %d specified in "
                                      "write_map is closed.", getpid (),
                                      session_index);
                      bits_set = VPPCOM_EBADFD;
                      goto select_done;
                    }

                  rv = vppcom_session_write_ready (session, session_index);
                  clib_spinlock_unlock (&vcm->sessions_lockp);
                  if (write_map && (rv > 0))
                    {
                      // TBD: clib_warning
                      clib_bitmap_set_no_check (write_map, session_index, 1);
                      bits_set++;
                    }
                }));
            }

          if (except_map)
            {
              clib_bitmap_foreach (session_index, vcm->ex_bitmap,
                ({
                  clib_spinlock_lock (&vcm->sessions_lockp);
                  rv = vppcom_session_at_index (session_index, &session);
                  if (rv < 0)
                    {
                      clib_spinlock_unlock (&vcm->sessions_lockp);
                      if (VPPCOM_DEBUG > 1)
                        clib_warning ("[%d] session %d specified in "
                                      "except_map is closed.", getpid (),
                                      session_index);
                      bits_set = VPPCOM_EBADFD;
                      goto select_done;
                    }

                  rv = vppcom_session_read_ready (session, session_index);
                  clib_spinlock_unlock (&vcm->sessions_lockp);
                  if (rv < 0)
                    {
                      // TBD: clib_warning
                      clib_bitmap_set_no_check (except_map, session_index, 1);
                      bits_set++;
                    }
                }));
            }
        }
      /* *INDENT-ON* */
    }
  while (clib_time_now (&vcm->clib_time) < timeout);

select_done:
  return (bits_set);
}

static inline void
vep_verify_epoll_chain (u32 vep_idx)
{
  session_t *session;
  vppcom_epoll_t *vep;
  int rv;
  u32 sid = vep_idx;

  if (VPPCOM_DEBUG <= 1)
    return;

  /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
  rv = vppcom_session_at_index (vep_idx, &session);
  if (PREDICT_FALSE (rv))
    {
      clib_warning ("[%d] ERROR: Invalid vep_idx (%u)!", getpid (), vep_idx);
      goto done;
    }
  if (PREDICT_FALSE (!session->is_vep))
    {
      clib_warning ("[%d] ERROR: vep_idx (%u) is not a vep!", getpid (),
		    vep_idx);
      goto done;
    }
  clib_warning ("[%d] vep_idx (%u): Dumping epoll chain\n"
		"{\n"
		"   is_vep         = %u\n"
		"   is_vep_session = %u\n"
		"   wait_cont_idx  = 0x%x (%u)\n"
		"}\n", getpid (),
		vep_idx, session->is_vep, session->is_vep_session,
		session->wait_cont_idx, session->wait_cont_idx);
  do
    {
      vep = &session->vep;
      sid = vep->next_sid;
      if (sid != ~0)
	{
	  rv = vppcom_session_at_index (sid, &session);
	  if (PREDICT_FALSE (rv))
	    {
	      clib_warning ("[%d] ERROR: Invalid sid (%u)!", getpid (), sid);
	      goto done;
	    }
	  if (PREDICT_FALSE (session->is_vep))
	    clib_warning ("[%d] ERROR: sid (%u) is a vep!",
			  getpid (), vep_idx);
	  else if (PREDICT_FALSE (!session->is_vep_session))
	    {
	      clib_warning ("[%d] ERROR: session (%u) is not a vep session!",
			    getpid (), sid);
	      goto done;
	    }
	  if (PREDICT_FALSE (session->vep.vep_idx != vep_idx))
	    clib_warning ("[%d] ERROR: session (%u) vep_idx (%u) != "
			  "vep_idx (%u)!", getpid (),
			  sid, session->vep.vep_idx, vep_idx);
	  if (session->is_vep_session)
	    {
	      clib_warning ("vep_idx[%u]: sid 0x%x (%u)\n"
			    "{\n"
			    "   next_sid       = 0x%x (%u)\n"
			    "   prev_sid       = 0x%x (%u)\n"
			    "   vep_idx        = 0x%x (%u)\n"
			    "   ev.events      = 0x%x\n"
			    "   ev.data.u64    = 0x%llx\n"
			    "   et_mask        = 0x%x\n"
			    "}\n",
			    vep_idx, sid, sid,
			    vep->next_sid, vep->next_sid,
			    vep->prev_sid, vep->prev_sid,
			    vep->vep_idx, vep->vep_idx,
			    vep->ev.events, vep->ev.data.u64, vep->et_mask);
	    }
	}
    }
  while (sid != ~0);

done:
  clib_warning ("[%d] vep_idx (%u): Dump complete!\n", getpid (), vep_idx);
}

int
vppcom_epoll_create (void)
{
  session_t *vep_session;
  u32 vep_idx;

  clib_spinlock_lock (&vcm->sessions_lockp);
  pool_get (vcm->sessions, vep_session);
  memset (vep_session, 0, sizeof (*vep_session));
  vep_idx = vep_session - vcm->sessions;

  vep_session->is_vep = 1;
  vep_session->vep.vep_idx = ~0;
  vep_session->vep.next_sid = ~0;
  vep_session->vep.prev_sid = ~0;
  vep_session->wait_cont_idx = ~0;
  clib_spinlock_unlock (&vcm->sessions_lockp);

  if (VPPCOM_DEBUG > 0)
    clib_warning ("[%d] Created vep_idx %u!", getpid (), vep_idx);

  return (vep_idx);
}

int
vppcom_epoll_ctl (uint32_t vep_idx, int op, uint32_t session_index,
		  struct epoll_event *event)
{
  session_t *vep_session;
  session_t *session;
  int rv;

  if (vep_idx == session_index)
    {
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] ERROR: vep_idx == session_index (%u)!",
		      getpid (), vep_idx);
      return VPPCOM_EINVAL;
    }

  clib_spinlock_lock (&vcm->sessions_lockp);
  rv = vppcom_session_at_index (vep_idx, &vep_session);
  if (PREDICT_FALSE (rv))
    {
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] ERROR: Invalid vep_idx (%u)!", vep_idx);
      goto done;
    }
  if (PREDICT_FALSE (!vep_session->is_vep))
    {
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] ERROR: vep_idx (%u) is not a vep!",
		      getpid (), vep_idx);
      rv = VPPCOM_EINVAL;
      goto done;
    }

  ASSERT (vep_session->vep.vep_idx == ~0);
  ASSERT (vep_session->vep.prev_sid == ~0);

  rv = vppcom_session_at_index (session_index, &session);
  if (PREDICT_FALSE (rv))
    {
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] ERROR: Invalid session_index (%u)!",
		      getpid (), session_index);
      goto done;
    }
  if (PREDICT_FALSE (session->is_vep))
    {
      if (VPPCOM_DEBUG > 0)
	clib_warning ("ERROR: session_index (%u) is a vep!", vep_idx);
      rv = VPPCOM_EINVAL;
      goto done;
    }

  switch (op)
    {
    case EPOLL_CTL_ADD:
      if (PREDICT_FALSE (!event))
	{
	  clib_warning ("[%d] ERROR: EPOLL_CTL_ADD: NULL pointer to "
			"epoll_event structure!", getpid ());
	  rv = VPPCOM_EINVAL;
	  goto done;
	}
      if (vep_session->vep.next_sid != ~0)
	{
	  session_t *next_session;
	  rv = vppcom_session_at_index (vep_session->vep.next_sid,
					&next_session);
	  if (PREDICT_FALSE (rv))
	    {
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] ERROR: EPOLL_CTL_ADD: Invalid "
			      "vep.next_sid (%u) on vep_idx (%u)!",
			      getpid (), vep_session->vep.next_sid, vep_idx);
	      goto done;
	    }
	  ASSERT (next_session->vep.prev_sid == vep_idx);
	  next_session->vep.prev_sid = session_index;
	}
      session->vep.next_sid = vep_session->vep.next_sid;
      session->vep.prev_sid = vep_idx;
      session->vep.vep_idx = vep_idx;
      session->vep.et_mask = VEP_DEFAULT_ET_MASK;
      session->vep.ev = *event;
      session->is_vep_session = 1;
      vep_session->vep.next_sid = session_index;
      if (VPPCOM_DEBUG > 1)
	clib_warning ("[%d] EPOLL_CTL_ADD: vep_idx %u, sid %u, events 0x%x,"
		      " data 0x%llx!", getpid (), vep_idx, session_index,
		      event->events, event->data.u64);
      break;

    case EPOLL_CTL_MOD:
      if (PREDICT_FALSE (!event))
	{
	  clib_warning ("[%d] ERROR: EPOLL_CTL_MOD: NULL pointer to "
			"epoll_event structure!", getpid ());
	  rv = VPPCOM_EINVAL;
	  goto done;
	}
      if (PREDICT_FALSE (!session->is_vep_session &&
			 (session->vep.vep_idx != vep_idx)))
	{
	  if (VPPCOM_DEBUG > 0)
	    {
	      if (!session->is_vep_session)
		clib_warning ("[%d] ERROR: EPOLL_CTL_MOD: session (%u) "
			      "is not a vep session!",
			      getpid (), session_index);
	      else
		clib_warning ("[%d] ERROR: EPOLL_CTL_MOD: session (%u) "
			      "vep_idx (%u) != vep_idx (%u)!",
			      getpid (), session_index,
			      session->vep.vep_idx, vep_idx);
	    }
	  rv = VPPCOM_EINVAL;
	  goto done;
	}
      session->vep.et_mask = VEP_DEFAULT_ET_MASK;
      session->vep.ev = *event;
      if (VPPCOM_DEBUG > 1)
	clib_warning ("[%d] EPOLL_CTL_MOD: vep_idx %u, sid %u, events 0x%x,"
		      " data 0x%llx!", getpid (), vep_idx, session_index,
		      event->events, event->data.u64);
      break;

    case EPOLL_CTL_DEL:
      if (PREDICT_FALSE (!session->is_vep_session &&
			 (session->vep.vep_idx != vep_idx)))
	{
	  if (VPPCOM_DEBUG > 0)
	    {
	      if (!session->is_vep_session)
		clib_warning ("[%d] ERROR: EPOLL_CTL_DEL: session (%u) "
			      "is not a vep session!",
			      getpid (), session_index);
	      else
		clib_warning ("[%d] ERROR: EPOLL_CTL_DEL: session (%u) "
			      "vep_idx (%u) != vep_idx (%u)!",
			      getpid (), session_index,
			      session->vep.vep_idx, vep_idx);
	    }
	  rv = VPPCOM_EINVAL;
	  goto done;
	}

      vep_session->wait_cont_idx =
	(vep_session->wait_cont_idx == session_index) ?
	session->vep.next_sid : vep_session->wait_cont_idx;

      if (session->vep.prev_sid == vep_idx)
	vep_session->vep.next_sid = session->vep.next_sid;
      else
	{
	  session_t *prev_session;
	  rv = vppcom_session_at_index (session->vep.prev_sid, &prev_session);
	  if (PREDICT_FALSE (rv))
	    {
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] ERROR: EPOLL_CTL_DEL: Invalid "
			      "vep.prev_sid (%u) on sid (%u)!",
			      getpid (), session->vep.prev_sid,
			      session_index);
	      goto done;
	    }
	  ASSERT (prev_session->vep.next_sid == session_index);
	  prev_session->vep.next_sid = session->vep.next_sid;
	}
      if (session->vep.next_sid != ~0)
	{
	  session_t *next_session;
	  rv = vppcom_session_at_index (session->vep.next_sid, &next_session);
	  if (PREDICT_FALSE (rv))
	    {
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] ERROR: EPOLL_CTL_DEL: Invalid "
			      "vep.next_sid (%u) on sid (%u)!",
			      getpid (), session->vep.next_sid,
			      session_index);
	      goto done;
	    }
	  ASSERT (next_session->vep.prev_sid == session_index);
	  next_session->vep.prev_sid = session->vep.prev_sid;
	}

      memset (&session->vep, 0, sizeof (session->vep));
      session->vep.next_sid = ~0;
      session->vep.prev_sid = ~0;
      session->vep.vep_idx = ~0;
      session->is_vep_session = 0;
      if (VPPCOM_DEBUG > 1)
	clib_warning ("[%d] EPOLL_CTL_DEL: vep_idx %u, sid %u!",
		      getpid (), vep_idx, session_index);
      break;

    default:
      clib_warning ("[%d] ERROR: Invalid operation (%d)!", getpid (), op);
      rv = VPPCOM_EINVAL;
    }

  vep_verify_epoll_chain (vep_idx);

done:
  clib_spinlock_unlock (&vcm->sessions_lockp);
  return rv;
}

int
vppcom_epoll_wait (uint32_t vep_idx, struct epoll_event *events,
		   int maxevents, double wait_for_time)
{
  session_t *vep_session;
  int rv;
  f64 timeout = clib_time_now (&vcm->clib_time) + wait_for_time;
  u32 keep_trying = 1;
  int num_ev = 0;
  u32 vep_next_sid, wait_cont_idx;
  u8 is_vep;

  if (PREDICT_FALSE (maxevents <= 0))
    {
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] ERROR: Invalid maxevents (%d)!",
		      getpid (), maxevents);
      return VPPCOM_EINVAL;
    }
  memset (events, 0, sizeof (*events) * maxevents);

  VCL_LOCK_AND_GET_SESSION (vep_idx, &vep_session);
  vep_next_sid = vep_session->vep.next_sid;
  is_vep = vep_session->is_vep;
  wait_cont_idx = vep_session->wait_cont_idx;
  clib_spinlock_unlock (&vcm->sessions_lockp);

  if (PREDICT_FALSE (!is_vep))
    {
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] ERROR: vep_idx (%u) is not a vep!",
		      getpid (), vep_idx);
      rv = VPPCOM_EINVAL;
      goto done;
    }
  if (PREDICT_FALSE (vep_next_sid == ~0))
    {
      if (VPPCOM_DEBUG > 0)
	clib_warning ("[%d] WARNING: vep_idx (%u) is empty!",
		      getpid (), vep_idx);
      goto done;
    }

  do
    {
      u32 sid;
      u32 next_sid = ~0;
      session_t *session;

      for (sid = (wait_cont_idx == ~0) ? vep_next_sid : wait_cont_idx;
	   sid != ~0; sid = next_sid)
	{
	  u32 session_events, et_mask, clear_et_mask, session_vep_idx;
	  u8 add_event, is_vep_session;
	  int ready;
	  u64 session_ev_data;

	  VCL_LOCK_AND_GET_SESSION (sid, &session);
	  next_sid = session->vep.next_sid;
	  session_events = session->vep.ev.events;
	  et_mask = session->vep.et_mask;
	  is_vep = session->is_vep;
	  is_vep_session = session->is_vep_session;
	  session_vep_idx = session->vep.vep_idx;
	  session_ev_data = session->vep.ev.data.u64;
	  clib_spinlock_unlock (&vcm->sessions_lockp);

	  if (PREDICT_FALSE (is_vep))
	    {
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] ERROR: sid (%u) is a vep!",
			      getpid (), vep_idx);
	      rv = VPPCOM_EINVAL;
	      goto done;
	    }
	  if (PREDICT_FALSE (!is_vep_session))
	    {
	      if (VPPCOM_DEBUG > 0)
		clib_warning ("[%d] ERROR: session (%u) is not "
			      "a vep session!", getpid (), sid);
	      rv = VPPCOM_EINVAL;
	      goto done;
	    }
	  if (PREDICT_FALSE (session_vep_idx != vep_idx))
	    {
	      clib_warning ("[%d] ERROR: session (%u) "
			    "vep_idx (%u) != vep_idx (%u)!",
			    getpid (), sid, session->vep.vep_idx, vep_idx);
	      rv = VPPCOM_EINVAL;
	      goto done;
	    }

	  add_event = clear_et_mask = 0;

	  if (EPOLLIN & session_events)
	    {
	      VCL_LOCK_AND_GET_SESSION (sid, &session);
	      ready = vppcom_session_read_ready (session, sid);
	      clib_spinlock_unlock (&vcm->sessions_lockp);
	      if ((ready > 0) && (EPOLLIN & et_mask))
		{
		  add_event = 1;
		  events[num_ev].events |= EPOLLIN;
		  if (((EPOLLET | EPOLLIN) & session_events) ==
		      (EPOLLET | EPOLLIN))
		    clear_et_mask |= EPOLLIN;
		}
	      else if (ready < 0)
		{
		  add_event = 1;
		  switch (ready)
		    {
		    case VPPCOM_ECONNRESET:
		      events[num_ev].events |= EPOLLHUP | EPOLLRDHUP;
		      break;

		    default:
		      events[num_ev].events |= EPOLLERR;
		      break;
		    }
		}
	    }

	  if (EPOLLOUT & session_events)
	    {
	      VCL_LOCK_AND_GET_SESSION (sid, &session);
	      ready = vppcom_session_write_ready (session, sid);
	      clib_spinlock_unlock (&vcm->sessions_lockp);
	      if ((ready > 0) && (EPOLLOUT & et_mask))
		{
		  add_event = 1;
		  events[num_ev].events |= EPOLLOUT;
		  if (((EPOLLET | EPOLLOUT) & session_events) ==
		      (EPOLLET | EPOLLOUT))
		    clear_et_mask |= EPOLLOUT;
		}
	      else if (ready < 0)
		{
		  add_event = 1;
		  switch (ready)
		    {
		    case VPPCOM_ECONNRESET:
		      events[num_ev].events |= EPOLLHUP;
		      break;

		    default:
		      events[num_ev].events |= EPOLLERR;
		      break;
		    }
		}
	    }

	  if (add_event)
	    {
	      events[num_ev].data.u64 = session_ev_data;
	      if (EPOLLONESHOT & session_events)
		{
		  VCL_LOCK_AND_GET_SESSION (sid, &session);
		  session->vep.ev.events = 0;
		  clib_spinlock_unlock (&vcm->sessions_lockp);
		}
	      num_ev++;
	      if (num_ev == maxevents)
		{
		  VCL_LOCK_AND_GET_SESSION (vep_idx, &vep_session);
		  vep_session->wait_cont_idx = next_sid;
		  clib_spinlock_unlock (&vcm->sessions_lockp);
		  goto done;
		}
	    }
	  if (wait_cont_idx != ~0)
	    {
	      if (next_sid == ~0)
		next_sid = vep_next_sid;
	      else if (next_sid == wait_cont_idx)
		next_sid = ~0;
	    }
	}
      if (wait_for_time != -1)
	keep_trying = (clib_time_now (&vcm->clib_time) <= timeout) ? 1 : 0;
    }
  while ((num_ev == 0) && keep_trying);

  if (wait_cont_idx != ~0)
    {
      VCL_LOCK_AND_GET_SESSION (vep_idx, &vep_session);
      vep_session->wait_cont_idx = ~0;
      clib_spinlock_unlock (&vcm->sessions_lockp);
    }
done:
  return (rv != VPPCOM_OK) ? rv : num_ev;
}

int
vppcom_session_attr (uint32_t session_index, uint32_t op,
		     void *buffer, uint32_t * buflen)
{
  session_t *session;
  int rv = VPPCOM_OK;
  u32 *flags = buffer;
  vppcom_endpt_t *ep = buffer;

  VCL_LOCK_AND_GET_SESSION (session_index, &session);
  switch (op)
    {
    case VPPCOM_ATTR_GET_NREAD:
      rv = vppcom_session_read_ready (session, session_index);
      if (VPPCOM_DEBUG > 2)
	clib_warning ("[%d] VPPCOM_ATTR_GET_NREAD: sid %u, nread = %d",
		      getpid (), rv);

      break;

    case VPPCOM_ATTR_GET_NWRITE:
      rv = vppcom_session_write_ready (session, session_index);
      if (VPPCOM_DEBUG > 2)
	clib_warning ("[%d] VPPCOM_ATTR_GET_NWRITE: sid %u, nwrite = %d",
		      getpid (), session_index, rv);

      break;

    case VPPCOM_ATTR_GET_FLAGS:
      if (buffer && buflen && (*buflen >= sizeof (*flags)))
	{
	  *flags = O_RDWR | ((session->is_nonblocking) ? O_NONBLOCK : 0);
	  *buflen = sizeof (*flags);
	  if (VPPCOM_DEBUG > 2)
	    clib_warning ("[%d] VPPCOM_ATTR_GET_FLAGS: sid %u, "
			  "flags = 0x%08x, is_nonblocking = %u", getpid (),
			  session_index, *flags, session->is_nonblocking);
	}
      else
	rv = VPPCOM_EINVAL;
      break;

    case VPPCOM_ATTR_SET_FLAGS:
      if (buffer && buflen && (*buflen >= sizeof (*flags)))
	{
	  session->is_nonblocking = (*flags & O_NONBLOCK) ? 1 : 0;
	  if (VPPCOM_DEBUG > 2)
	    clib_warning ("[%d] VPPCOM_ATTR_SET_FLAGS: sid %u, "
			  "flags = 0x%08x, is_nonblocking = %u",
			  getpid (), *flags, session->is_nonblocking);
	}
      else
	rv = VPPCOM_EINVAL;
      break;

    case VPPCOM_ATTR_GET_PEER_ADDR:
      if (buffer && buflen && (*buflen >= sizeof (*ep)))
	{
	  ep->vrf = session->vrf;
	  ep->is_ip4 = session->peer_addr.is_ip4;
	  ep->port = session->peer_port;
	  if (session->peer_addr.is_ip4)
	    clib_memcpy (ep->ip, &session->peer_addr.ip46.ip4,
			 sizeof (ip4_address_t));
	  else
	    clib_memcpy (ep->ip, &session->peer_addr.ip46.ip6,
			 sizeof (ip6_address_t));
	  *buflen = sizeof (*ep);
	  if (VPPCOM_DEBUG > 1)
	    clib_warning ("[%d] VPPCOM_ATTR_GET_PEER_ADDR: sid %u, is_ip4 = "
			  "%u, addr = %U, port %u", getpid (),
			  session_index, ep->is_ip4, format_ip46_address,
			  &session->peer_addr.ip46, ep->is_ip4,
			  clib_net_to_host_u16 (ep->port));
	}
      else
	rv = VPPCOM_EINVAL;
      break;

    case VPPCOM_ATTR_GET_LCL_ADDR:
      if (buffer && buflen && (*buflen >= sizeof (*ep)))
	{
	  ep->vrf = session->vrf;
	  ep->is_ip4 = session->lcl_addr.is_ip4;
	  ep->port = session->lcl_port;
	  if (session->lcl_addr.is_ip4)
	    clib_memcpy (ep->ip, &session->lcl_addr.ip46.ip4,
			 sizeof (ip4_address_t));
	  else
	    clib_memcpy (ep->ip, &session->lcl_addr.ip46.ip6,
			 sizeof (ip6_address_t));
	  *buflen = sizeof (*ep);
	  if (VPPCOM_DEBUG > 1)
	    clib_warning ("[%d] VPPCOM_ATTR_GET_LCL_ADDR: sid %u, is_ip4 = "
			  "%u, addr = %U port %d", getpid (),
			  session_index, ep->is_ip4, format_ip46_address,
			  &session->lcl_addr.ip46, ep->is_ip4,
			  clib_net_to_host_u16 (ep->port));
	}
      else
	rv = VPPCOM_EINVAL;
      break;

    case VPPCOM_ATTR_SET_REUSEADDR:
      break;

    case VPPCOM_ATTR_SET_BROADCAST:
      break;

    case VPPCOM_ATTR_SET_V6ONLY:
      break;

    case VPPCOM_ATTR_SET_KEEPALIVE:
      break;

    case VPPCOM_ATTR_SET_TCP_KEEPIDLE:
      break;

    case VPPCOM_ATTR_SET_TCP_KEEPINTVL:
      break;

    default:
      rv = VPPCOM_EINVAL;
      break;
    }

done:
  clib_spinlock_unlock (&vcm->sessions_lockp);
  return rv;
}

int
vppcom_session_recvfrom (uint32_t session_index, void *buffer,
			 uint32_t buflen, int flags, vppcom_endpt_t * ep)
{
  int rv = VPPCOM_OK;
  session_t *session = 0;

  if (ep)
    {
      clib_spinlock_lock (&vcm->sessions_lockp);
      rv = vppcom_session_at_index (session_index, &session);
      if (PREDICT_FALSE (rv))
	{
	  clib_spinlock_unlock (&vcm->sessions_lockp);
	  if (VPPCOM_DEBUG > 0)
	    clib_warning ("[%d] invalid session, sid (%u) has been closed!",
			  getpid (), session_index);
	  rv = VPPCOM_EBADFD;
	  clib_spinlock_unlock (&vcm->sessions_lockp);
	  goto done;
	}
      ep->vrf = session->vrf;
      ep->is_ip4 = session->peer_addr.is_ip4;
      ep->port = session->peer_port;
      if (session->peer_addr.is_ip4)
	clib_memcpy (ep->ip, &session->peer_addr.ip46.ip4,
		     sizeof (ip4_address_t));
      else
	clib_memcpy (ep->ip, &session->peer_addr.ip46.ip6,
		     sizeof (ip6_address_t));
      clib_spinlock_unlock (&vcm->sessions_lockp);
    }

  if (flags == 0)
    rv = vppcom_session_read (session_index, buffer, buflen);
  else if (flags & MSG_PEEK)
    rv = vppcom_session_peek (session_index, buffer, buflen);
  else
    {
      clib_warning ("[%d] Unsupport flags for recvfrom %d", getpid (), flags);
      rv = VPPCOM_EAFNOSUPPORT;
    }

done:
  return rv;
}

int
vppcom_session_sendto (uint32_t session_index, void *buffer,
		       uint32_t buflen, int flags, vppcom_endpt_t * ep)
{
  if (!buffer)
    return VPPCOM_EINVAL;

  if (ep)
    {
      // TBD
      return VPPCOM_EINVAL;
    }

  if (flags)
    {
      // TBD check the flags and do the right thing
      if (VPPCOM_DEBUG > 2)
	clib_warning ("[%d] handling flags 0x%u (%d) not implemented yet.",
		      getpid (), flags, flags);
    }

  return (vppcom_session_write (session_index, buffer, buflen));
}

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