vcl/ldp: add locked sessions shim layer

Moves LDP logic that allows sharing of sessions between multi-process
app workers into a separate VCL shim layer. Also refactors LDP to use
the new layer.

Change-Id: I8198b51eae7d099a8c486e36b29e3a0cb8cee8e9
Signed-off-by: Florin Coras <fcoras@cisco.com>
diff --git a/src/vcl/CMakeLists.txt b/src/vcl/CMakeLists.txt
index abe1bf0..cbf954f 100644
--- a/src/vcl/CMakeLists.txt
+++ b/src/vcl/CMakeLists.txt
@@ -20,6 +20,7 @@
   vcl_bapi.c
   vcl_cfg.c
   vcl_private.c
+  vcl_locked.c
 
   LINK_LIBRARIES
   vppinfra svm vlibmemoryclient rt pthread
@@ -43,6 +44,7 @@
   ldp_glibc_socket.h
   vcl_test.h
   vppcom.h
+  vcl_locked.h
   ldp_socket_wrapper.h
 )
 
diff --git a/src/vcl/ldp.c b/src/vcl/ldp.c
index a61acb9..1c038b0 100644
--- a/src/vcl/ldp.c
+++ b/src/vcl/ldp.c
@@ -26,7 +26,7 @@
 #include <vcl/ldp.h>
 #include <sys/time.h>
 
-#include <vcl/vppcom.h>
+#include <vcl/vcl_locked.h>
 #include <vppinfra/time.h>
 #include <vppinfra/bitmap.h>
 #include <vppinfra/lock.h>
@@ -51,19 +51,6 @@
 
 #define LDP_MAX_NWORKERS 32
 
-#define LDP_F_SHUT_RD	(1 << 0)
-#define LDP_F_SHUT_WR	(1 << 1)
-
-typedef struct ldp_fd_entry_
-{
-  u32 session_index;
-  u32 worker_index;
-  u32 fd;
-  u32 fd_index;
-  u32 flags;
-  clib_spinlock_t lock;
-} ldp_fd_entry_t;
-
 typedef struct ldp_worker_ctx_
 {
   u8 *io_buffer;
@@ -103,12 +90,9 @@
   ldp_worker_ctx_t *workers;
   int init;
   char app_name[LDP_APP_NAME_MAX];
-  u32 sh_bit_val;
-  u32 sid_bit_mask;
+  u32 vlsh_bit_val;
+  u32 vlsh_bit_mask;
   u32 debug;
-  ldp_fd_entry_t *fd_pool;
-  clib_rwlock_t fd_table_lock;
-  uword *session_index_to_fd_table;
 
   /** vcl needs next epoll_create to go to libc_epoll */
   u8 vcl_needs_real_epoll;
@@ -121,8 +105,8 @@
     clib_warning ("ldp<%d>: " _fmt, getpid(), ##_args)
 
 static ldp_main_t ldp_main = {
-  .sh_bit_val = (1 << LDP_SID_BIT_MIN),
-  .sid_bit_mask = (1 << LDP_SID_BIT_MIN) - 1,
+  .vlsh_bit_val = (1 << LDP_SID_BIT_MIN),
+  .vlsh_bit_mask = (1 << LDP_SID_BIT_MIN) - 1,
   .debug = LDP_DEBUG_INIT,
 };
 
@@ -156,138 +140,19 @@
   return ldp->app_name;
 }
 
-static inline vcl_session_handle_t
-ldp_fd_entry_sh (ldp_fd_entry_t * fde)
-{
-  return vppcom_session_handle (fde->session_index);
-}
-
-static int
-ldp_fd_alloc (vcl_session_handle_t sh)
-{
-  ldp_fd_entry_t *fde;
-
-  clib_rwlock_writer_lock (&ldp->fd_table_lock);
-  if (pool_elts (ldp->fd_pool) >= (1ULL << 32) - ldp->sh_bit_val)
-    {
-      clib_rwlock_writer_unlock (&ldp->fd_table_lock);
-      return -1;
-    }
-  pool_get (ldp->fd_pool, fde);
-  fde->session_index = vppcom_session_index (sh);
-  fde->worker_index = vppcom_session_worker (sh);
-  fde->fd_index = fde - ldp->fd_pool;
-  fde->fd = fde->fd_index + ldp->sh_bit_val;
-  hash_set (ldp->session_index_to_fd_table, fde->session_index, fde->fd);
-  clib_spinlock_init (&fde->lock);
-  clib_rwlock_writer_unlock (&ldp->fd_table_lock);
-  return fde->fd;
-}
-
-static ldp_fd_entry_t *
-ldp_fd_entry_get (u32 fd_index)
-{
-  if (pool_is_free_index (ldp->fd_pool, fd_index))
-    return 0;
-  return pool_elt_at_index (ldp->fd_pool, fd_index);
-}
-
-static ldp_fd_entry_t *
-ldp_fd_entry_lock (u32 fd_index)
-{
-  ldp_fd_entry_t *fe;
-  clib_rwlock_reader_lock (&ldp->fd_table_lock);
-  if (pool_is_free_index (ldp->fd_pool, fd_index))
-    {
-      clib_rwlock_reader_unlock (&ldp->fd_table_lock);
-      return 0;
-    }
-
-  fe = pool_elt_at_index (ldp->fd_pool, fd_index);
-  clib_spinlock_lock (&fe->lock);
-  return fe;
-}
-
-static void
-ldp_fd_entry_unlock (ldp_fd_entry_t * fde)
-{
-  clib_spinlock_unlock (&fde->lock);
-  clib_rwlock_reader_unlock (&ldp->fd_table_lock);
-}
-
 static inline int
-ldp_fd_from_sh (vcl_session_handle_t sh)
+ldp_vlsh_to_fd (vls_handle_t vlsh)
 {
-  uword *fdp;
-  int fd;
-
-  clib_rwlock_reader_lock (&ldp->fd_table_lock);
-  fdp = hash_get (ldp->session_index_to_fd_table, vppcom_session_index (sh));
-  fd = fdp ? *fdp : -EMFILE;
-  clib_rwlock_reader_unlock (&ldp->fd_table_lock);
-
-  return fd;
+  return (vlsh + ldp->vlsh_bit_val);
 }
 
-static inline int
-ldp_fd_is_sh (int fd)
+static inline vls_handle_t
+ldp_fd_to_vlsh (int fd)
 {
-  return fd >= ldp->sh_bit_val;
-}
+  if (fd < ldp->vlsh_bit_val)
+    return VLS_INVALID_HANDLE;
 
-static inline u32
-ldp_sh_from_fd (int fd)
-{
-  u32 fd_index, session_index;
-  ldp_fd_entry_t *fde;
-
-  if (!ldp_fd_is_sh (fd))
-    return INVALID_SESSION_ID;
-
-  fd_index = fd - ldp->sh_bit_val;
-  fde = ldp_fd_entry_lock (fd_index);
-  if (!fde)
-    {
-      LDBG (0, "unknown fd %d", fd);
-      return INVALID_SESSION_ID;
-    }
-  session_index = fde->session_index;
-  ldp_fd_entry_unlock (fde);
-
-  return vppcom_session_handle (session_index);
-}
-
-static ldp_fd_entry_t *
-ldp_fd_entry_lock_w_fd (int fd)
-{
-  u32 fd_index;
-
-  if (!ldp_fd_is_sh (fd))
-    return 0;
-
-  fd_index = fd - ldp->sh_bit_val;
-  return ldp_fd_entry_lock (fd_index);
-}
-
-static void
-ldp_fd_free_w_sh (vcl_session_handle_t sh)
-{
-  ldp_fd_entry_t *fde;
-  u32 fd_index;
-  int fd;
-
-  fd = ldp_fd_from_sh (sh);
-  if (!fd)
-    return;
-
-  fd_index = fd - ldp->sh_bit_val;
-  clib_rwlock_writer_lock (&ldp->fd_table_lock);
-  fde = ldp_fd_entry_get (fd_index);
-  ASSERT (fde != 0);
-  hash_unset (ldp->session_index_to_fd_table, fde->session_index);
-  clib_spinlock_free (&fde->lock);
-  pool_put (ldp->fd_pool, fde);
-  clib_rwlock_writer_unlock (&ldp->fd_table_lock);
+  return (fd - ldp->vlsh_bit_val);
 }
 
 static inline int
@@ -301,7 +166,7 @@
 
   ldp->init = 1;
   ldp->vcl_needs_real_epoll = 1;
-  rv = vppcom_app_create (ldp_get_app_name ());
+  rv = vls_app_create (ldp_get_app_name ());
   if (rv != VPPCOM_OK)
     {
       ldp->vcl_needs_real_epoll = 0;
@@ -349,43 +214,42 @@
 	  clib_warning ("LDP<%d>: WARNING: Invalid LDP sid bit specified in"
 			" the env var " LDP_ENV_SID_BIT " (%s)! sid bit "
 			"value %d (0x%x)", getpid (), env_var_str,
-			ldp->sh_bit_val, ldp->sh_bit_val);
+			ldp->vlsh_bit_val, ldp->vlsh_bit_val);
 	}
       else if (sb < LDP_SID_BIT_MIN)
 	{
-	  ldp->sh_bit_val = (1 << LDP_SID_BIT_MIN);
-	  ldp->sid_bit_mask = ldp->sh_bit_val - 1;
+	  ldp->vlsh_bit_val = (1 << LDP_SID_BIT_MIN);
+	  ldp->vlsh_bit_mask = ldp->vlsh_bit_val - 1;
 
 	  clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) specified in the"
 			" env var " LDP_ENV_SID_BIT " (%s) is too small. "
 			"Using LDP_SID_BIT_MIN (%d)! sid bit value %d (0x%x)",
 			getpid (), sb, env_var_str, LDP_SID_BIT_MIN,
-			ldp->sh_bit_val, ldp->sh_bit_val);
+			ldp->vlsh_bit_val, ldp->vlsh_bit_val);
 	}
       else if (sb > LDP_SID_BIT_MAX)
 	{
-	  ldp->sh_bit_val = (1 << LDP_SID_BIT_MAX);
-	  ldp->sid_bit_mask = ldp->sh_bit_val - 1;
+	  ldp->vlsh_bit_val = (1 << LDP_SID_BIT_MAX);
+	  ldp->vlsh_bit_mask = ldp->vlsh_bit_val - 1;
 
 	  clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) specified in the"
 			" env var " LDP_ENV_SID_BIT " (%s) is too big. Using"
 			" LDP_SID_BIT_MAX (%d)! sid bit value %d (0x%x)",
 			getpid (), sb, env_var_str, LDP_SID_BIT_MAX,
-			ldp->sh_bit_val, ldp->sh_bit_val);
+			ldp->vlsh_bit_val, ldp->vlsh_bit_val);
 	}
       else
 	{
-	  ldp->sh_bit_val = (1 << sb);
-	  ldp->sid_bit_mask = ldp->sh_bit_val - 1;
+	  ldp->vlsh_bit_val = (1 << sb);
+	  ldp->vlsh_bit_mask = ldp->vlsh_bit_val - 1;
 
 	  LDBG (0, "configured LDP sid bit (%u) from "
 		LDP_ENV_SID_BIT "!  sid bit value %d (0x%x)", sb,
-		ldp->sh_bit_val, ldp->sh_bit_val);
+		ldp->vlsh_bit_val, ldp->vlsh_bit_val);
 	}
     }
 
   clib_time_init (&ldpw->clib_time);
-  clib_rwlock_init (&ldp->fd_table_lock);
   LDBG (0, "LDP initialization: done!");
 
   return 0;
@@ -394,22 +258,19 @@
 int
 close (int fd)
 {
-  int rv, refcnt, epfd;
-  ldp_fd_entry_t *fde;
-  u32 sh;
+  vls_handle_t vlsh;
+  int rv, epfd;
 
   if ((errno = -ldp_init ()))
     return -1;
 
-  fde = ldp_fd_entry_lock_w_fd (fd);
-  if (fde)
+  vlsh = ldp_fd_to_vlsh (fd);
+  if (vlsh != VLS_INVALID_HANDLE)
     {
-      sh = ldp_fd_entry_sh (fde);
-      epfd = vppcom_session_attr (sh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
+      epfd = vls_attr (vlsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
       if (epfd > 0)
 	{
-	  LDBG (0, "fd %d (0x%x): calling libc_close: epfd %u (0x%x)",
-		fd, fd, epfd, epfd);
+	  LDBG (0, "fd %d: calling libc_close: epfd %u", fd, epfd);
 
 	  rv = libc_close (epfd);
 	  if (rv < 0)
@@ -417,114 +278,87 @@
 	      u32 size = sizeof (epfd);
 	      epfd = 0;
 
-	      (void) vppcom_session_attr (sh, VPPCOM_ATTR_SET_LIBC_EPFD,
-					  &epfd, &size);
+	      (void) vls_attr (vlsh, VPPCOM_ATTR_SET_LIBC_EPFD, &epfd, &size);
 	    }
 	}
       else if (PREDICT_FALSE (epfd < 0))
 	{
 	  errno = -epfd;
 	  rv = -1;
-	  ldp_fd_entry_unlock (fde);
 	  goto done;
 	}
 
-      LDBG (0, "fd %d (0x%x): calling vppcom_session_close: sid %u (0x%x)",
-	    fd, fd, sh, sh);
+      LDBG (0, "fd %d: calling vls_close: vlsh %u", fd, vlsh);
 
-      refcnt = vppcom_session_attr (sh, VPPCOM_ATTR_GET_REFCNT, 0, 0);
-      rv = vppcom_session_close (sh);
+      rv = vls_close (vlsh);
       if (rv != VPPCOM_OK)
 	{
 	  errno = -rv;
 	  rv = -1;
 	}
-
-      ldp_fd_entry_unlock (fde);
-      if (refcnt <= 1)
-	ldp_fd_free_w_sh (sh);
     }
   else
     {
-      LDBG (0, "fd %d (0x%x): calling libc_close", fd, fd);
+      LDBG (0, "fd %d: calling libc_close", fd);
       rv = libc_close (fd);
     }
 
 done:
-
-  LDBG (1, "fd %d (0x%x): returning %d (0x%x)", fd, fd, rv, rv);
   return rv;
 }
 
 ssize_t
 read (int fd, void *buf, size_t nbytes)
 {
-  vcl_session_handle_t sh;
-  ldp_fd_entry_t *fde;
+  vls_handle_t vlsh;
   ssize_t size;
 
   if ((errno = -ldp_init ()))
     return -1;
 
-  fde = ldp_fd_entry_lock_w_fd (fd);
-  if (fde)
+  vlsh = ldp_fd_to_vlsh (fd);
+  if (vlsh != VLS_INVALID_HANDLE)
     {
-      sh = ldp_fd_entry_sh (fde);
-      LDBG (2, "fd %d (0x%x): calling vppcom_session_read(): sid %u (0x%x),"
-	    " buf %p, nbytes %u", fd, fd, sh, sh, buf, nbytes);
-
-      size = vppcom_session_read (sh, buf, nbytes);
+      size = vls_read (vlsh, buf, nbytes);
       if (size < 0)
 	{
 	  errno = -size;
 	  size = -1;
 	}
-      ldp_fd_entry_unlock (fde);
     }
   else
     {
-      LDBG (2, "fd %d (0x%x): calling libc_read(): buf %p, nbytes %u",
-	    fd, fd, buf, nbytes);
-
       size = libc_read (fd, buf, nbytes);
     }
 
-  LDBG (2, "fd %d (0x%x): returning %d (0x%x)", fd, fd, size, size);
   return size;
 }
 
 ssize_t
 readv (int fd, const struct iovec * iov, int iovcnt)
 {
-  ssize_t size = 0;
-  u32 sid = ldp_sh_from_fd (fd);
   int rv = 0, i, total = 0;
+  vls_handle_t vlsh;
+  ssize_t size = 0;
 
   if ((errno = -ldp_init ()))
     return -1;
 
-  if (sid != INVALID_SESSION_ID)
+  vlsh = ldp_fd_to_vlsh (fd);
+  if (vlsh != VLS_INVALID_HANDLE)
     {
       do
 	{
 	  for (i = 0; i < iovcnt; ++i)
 	    {
-	      LDBG (2, "fd %d (0x%x): calling vppcom_session_read() [%d]:"
-		    " sid %u (0x%x), iov %p, iovcnt %d, total %d", fd, fd, i,
-		    sid, sid, iov, iovcnt, total);
-
-	      rv = vppcom_session_read (sid, iov[i].iov_base, iov[i].iov_len);
+	      rv = vls_read (vlsh, iov[i].iov_base, iov[i].iov_len);
 	      if (rv < 0)
 		break;
 	      else
 		{
 		  total += rv;
 		  if (rv < iov[i].iov_len)
-		    {
-		      LDBG (2, "fd %d (0x%x): rv (%d) < iov[%d].iov_len (%d)",
-			    fd, fd, rv, i, iov[i].iov_len);
-		      break;
-		    }
+		    break;
 		}
 	    }
 	}
@@ -540,51 +374,36 @@
     }
   else
     {
-      LDBG (2, "fd %d (0x%x): calling libc_readv(): iov %p, iovcnt %d", fd,
-	    fd, iov, iovcnt);
-
       size = libc_readv (fd, iov, iovcnt);
     }
 
-
-  LDBG (2, "fd %d (0x%x): returning %d (0x%x)", fd, fd, size, size);
   return size;
 }
 
 ssize_t
 write (int fd, const void *buf, size_t nbytes)
 {
-  vcl_session_handle_t sh;
-  ldp_fd_entry_t *fde;
+  vls_handle_t vlsh;
   ssize_t size = 0;
 
   if ((errno = -ldp_init ()))
     return -1;
 
-  fde = ldp_fd_entry_lock_w_fd (fd);
-  if (fde)
+  vlsh = ldp_fd_to_vlsh (fd);
+  if (vlsh != VLS_INVALID_HANDLE)
     {
-      sh = ldp_fd_entry_sh (fde);
-      LDBG (2, "fd %d (0x%x): calling vppcom_session_write(): sid %u (0x%x), "
-	    "buf %p, nbytes %u", fd, fd, sh, sh, buf, nbytes);
-
-      size = vppcom_session_write_msg (sh, (void *) buf, nbytes);
+      size = vls_write_msg (vlsh, (void *) buf, nbytes);
       if (size < 0)
 	{
 	  errno = -size;
 	  size = -1;
 	}
-      ldp_fd_entry_unlock (fde);
     }
   else
     {
-      LDBG (2, "fd %d (0x%x): calling libc_write(): buf %p, nbytes %u",
-	    fd, fd, buf, nbytes);
-
       size = libc_write (fd, buf, nbytes);
     }
 
-  LDBG (2, "fd %d (0x%x): returning %d (0x%x)", fd, fd, size, size);
   return size;
 }
 
@@ -592,24 +411,20 @@
 writev (int fd, const struct iovec * iov, int iovcnt)
 {
   ssize_t size = 0, total = 0;
-  u32 sid = ldp_sh_from_fd (fd);
+  vls_handle_t vlsh;
   int i, rv = 0;
 
-  /*
-   * Use [f]printf() instead of clib_warning() to prevent recursion SIGSEGV.
-   */
-
   if ((errno = -ldp_init ()))
     return -1;
 
-  if (sid != INVALID_SESSION_ID)
+  vlsh = ldp_fd_to_vlsh (fd);
+  if (vlsh != VLS_INVALID_HANDLE)
     {
       do
 	{
 	  for (i = 0; i < iovcnt; ++i)
 	    {
-	      rv = vppcom_session_write_msg (sid, iov[i].iov_base,
-					     iov[i].iov_len);
+	      rv = vls_write_msg (vlsh, iov[i].iov_base, iov[i].iov_len);
 	      if (rv < 0)
 		break;
 	      else
@@ -641,16 +456,18 @@
 int
 fcntl (int fd, int cmd, ...)
 {
-  const char *func_str = __func__;
+  vls_handle_t vlsh;
   int rv = 0;
   va_list ap;
-  u32 sid = ldp_sh_from_fd (fd);
 
   if ((errno = -ldp_init ()))
     return -1;
 
   va_start (ap, cmd);
-  if (sid != INVALID_SESSION_ID)
+
+  vlsh = ldp_fd_to_vlsh (fd);
+  LDBG (0, "fd %u vlsh %d, cmd %u", fd, vlsh, cmd);
+  if (vlsh != VLS_INVALID_HANDLE)
     {
       int flags = va_arg (ap, int);
       u32 size;
@@ -660,30 +477,13 @@
       switch (cmd)
 	{
 	case F_SETFL:
-	  func_str = "vppcom_session_attr[SET_FLAGS]";
-	  LDBG (2, "fd %d (0x%x): calling %s(): sid %u (0x%x) "
-		"flags %d (0x%x), size %d", fd, fd, func_str, sid,
-		sid, flags, flags, size);
-
-	  rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_FLAGS, &flags,
-				    &size);
+	  rv = vls_attr (vlsh, VPPCOM_ATTR_SET_FLAGS, &flags, &size);
 	  break;
 
 	case F_GETFL:
-	  func_str = "vppcom_session_attr[GET_FLAGS]";
-	  LDBG (2, "fd %d (0x%x): calling %s(): sid %u (0x%x), "
-		"flags %d (0x%x), size %d", fd, fd, func_str, sid,
-		sid, flags, flags, size);
-
-	  rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_FLAGS, &flags,
-				    &size);
+	  rv = vls_attr (vlsh, VPPCOM_ATTR_GET_FLAGS, &flags, &size);
 	  if (rv == VPPCOM_OK)
-	    {
-	      LDBG (2, "fd %d (0x%x), cmd %d (F_GETFL): %s() "
-		    "returned flags %d (0x%x)", fd, fd, cmd,
-		    func_str, flags, flags);
-	      rv = flags;
-	    }
+	    rv = flags;
 	  break;
 	case F_SETFD:
 	  /* TODO handle this */
@@ -702,58 +502,33 @@
     }
   else
     {
-      func_str = "libc_vfcntl";
-
-      LDBG (2, "fd %d (0x%x): calling %s(): cmd %d", fd, fd, func_str, cmd);
-
       rv = libc_vfcntl (fd, cmd, ap);
     }
 
   va_end (ap);
 
-  if (LDP_DEBUG > 2)
-    {
-      if (rv < 0)
-	{
-	  int errno_val = errno;
-	  perror (func_str);
-	  clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
-			"rv %d, errno = %d", getpid (), fd, fd,
-			func_str, rv, errno_val);
-	  errno = errno_val;
-	}
-      else
-	clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
-		      getpid (), fd, fd, rv, rv);
-    }
   return rv;
 }
 
 int
 ioctl (int fd, unsigned long int cmd, ...)
 {
-  const char *func_str;
-  int rv;
+  vls_handle_t vlsh;
   va_list ap;
-  u32 sid = ldp_sh_from_fd (fd);
+  int rv;
 
   if ((errno = -ldp_init ()))
     return -1;
 
   va_start (ap, cmd);
-  if (sid != INVALID_SESSION_ID)
-    {
-      func_str = "vppcom_session_attr[GET_NREAD]";
 
+  vlsh = ldp_fd_to_vlsh (fd);
+  if (vlsh != VLS_INVALID_HANDLE)
+    {
       switch (cmd)
 	{
 	case FIONREAD:
-	  if (LDP_DEBUG > 2)
-	    clib_warning
-	      ("LDP<%d>: fd %d (0x%x): calling  %s(): sid %u (0x%x)",
-	       getpid (), fd, fd, func_str, sid, sid);
-
-	  rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_NREAD, 0, 0);
+	  rv = vls_attr (vlsh, VPPCOM_ATTR_GET_NREAD, 0, 0);
 	  break;
 
 	case FIONBIO:
@@ -765,14 +540,7 @@
 	     *      non-blocking, the flags should be read here and merged
 	     *      with O_NONBLOCK.
 	     */
-	    if (LDP_DEBUG > 2)
-	      clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-			    "sid %u (0x%x), flags %d (0x%x), size %d",
-			    getpid (), fd, fd, func_str, sid, sid,
-			    flags, flags, size);
-
-	    rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_FLAGS, &flags,
-				      &size);
+	    rv = vls_attr (vlsh, VPPCOM_ATTR_SET_FLAGS, &flags, &size);
 	  }
 	  break;
 
@@ -788,30 +556,9 @@
     }
   else
     {
-      func_str = "libc_vioctl";
-
-      if (LDP_DEBUG > 2)
-	clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): cmd %d",
-		      getpid (), fd, fd, func_str, cmd);
-
       rv = libc_vioctl (fd, cmd, ap);
     }
 
-  if (LDP_DEBUG > 2)
-    {
-      if (rv < 0)
-	{
-	  int errno_val = errno;
-	  perror (func_str);
-	  clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
-			"rv %d, errno = %d", getpid (), fd, fd,
-			func_str, rv, errno_val);
-	  errno = errno_val;
-	}
-      else
-	clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
-		      getpid (), fd, fd, rv, rv);
-    }
   va_end (ap);
   return rv;
 }
@@ -825,8 +572,8 @@
 {
   uword sid_bits, sid_bits_set, libc_bits, libc_bits_set;
   ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
-  u32 minbits = clib_max (nfds, BITS (uword)), sid;
-  char *func_str = "##";
+  u32 minbits = clib_max (nfds, BITS (uword)), si;
+  vls_handle_t vlsh;
   f64 time_out;
   int rv, fd;
 
@@ -839,14 +586,11 @@
   if (timeout)
     {
       time_out = (timeout->tv_sec == 0 && timeout->tv_nsec == 0) ?
-	(f64) 0 : (f64) timeout->tv_sec +
-	(f64) timeout->tv_nsec / (f64) 1000000000;
+	(f64) 0 : (f64) timeout->tv_sec + (f64) timeout->tv_nsec / (f64) 1e9;
 
       /* select as fine grained sleep */
       if (!nfds)
 	{
-	  LDBG (3, "sleeping for %.02f seconds", time_out);
-
 	  time_out += clib_time_now (&ldpw->clib_time);
 	  while (clib_time_now (&ldpw->clib_time) < time_out)
 	    ;
@@ -862,31 +606,24 @@
     time_out = -1;
 
 
-  if (nfds <= ldp->sh_bit_val)
+  if (nfds <= ldp->vlsh_bit_val)
     {
-      func_str = "libc_pselect";
-
-      LDBG (3, "calling %s(): nfds %d, readfds %p, writefds %p, "
-	    "exceptfds %p, timeout %p, sigmask %p", func_str, nfds,
-	    readfds, writefds, exceptfds, timeout, sigmask);
-
       rv = libc_pselect (nfds, readfds, writefds, exceptfds,
 			 timeout, sigmask);
       goto done;
     }
 
-  if (PREDICT_FALSE (ldp->sh_bit_val > FD_SETSIZE / 2))
+  if (PREDICT_FALSE (ldp->vlsh_bit_val > FD_SETSIZE / 2))
     {
-      clib_warning ("LDP<%d>: ERROR: LDP sid bit value %d (0x%x) > "
-		    "FD_SETSIZE/2 %d (0x%x)!", getpid (),
-		    ldp->sh_bit_val, ldp->sh_bit_val,
-		    FD_SETSIZE / 2, FD_SETSIZE / 2);
+      LDBG (0, "ERROR: LDP sid bit value %d > FD_SETSIZE/2 %d!",
+	    ldp->vlsh_bit_val, FD_SETSIZE / 2);
       errno = EOVERFLOW;
       return -1;
     }
 
   sid_bits = libc_bits = 0;
   u32 n_bytes = nfds / 8 + ((nfds % 8) ? 1 : 0);
+
   if (readfds)
     {
       clib_bitmap_validate (ldpw->sid_rd_bitmap, minbits);
@@ -899,13 +636,12 @@
       clib_bitmap_foreach (fd, ldpw->rd_bitmap, ({
 	if (fd > nfds)
 	  break;
-        sid = ldp_sh_from_fd (fd);
-        LDBG (3, "readfds: fd %d (0x%x), sid %u (0x%x)", fd, fd, sid, sid);
-        if (sid == INVALID_SESSION_ID)
+        vlsh = ldp_fd_to_vlsh (fd);
+        if (vlsh == VLS_INVALID_HANDLE)
           clib_bitmap_set_no_check (ldpw->libc_rd_bitmap, fd, 1);
         else
           clib_bitmap_set_no_check (ldpw->sid_rd_bitmap,
-                                    vppcom_session_index (sid), 1);
+                                    vlsh_to_session_index (vlsh), 1);
       }));
       /* *INDENT-ON* */
 
@@ -914,10 +650,6 @@
 
       libc_bits_set = clib_bitmap_last_set (ldpw->libc_rd_bitmap) + 1;
       libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
-
-      LDBG (3, "readfds: sid_bits_set %d, sid_bits %d, "
-	    "libc_bits_set %d, libc_bits %d", sid_bits_set,
-	    sid_bits, libc_bits_set, libc_bits);
     }
   if (writefds)
     {
@@ -931,13 +663,12 @@
       clib_bitmap_foreach (fd, ldpw->wr_bitmap, ({
 	if (fd > nfds)
 	  break;
-        sid = ldp_sh_from_fd (fd);
-        LDBG (3, "writefds: fd %d (0x%x), sid %u (0x%x)", fd, fd, sid, sid);
-        if (sid == INVALID_SESSION_ID)
+        vlsh = ldp_fd_to_vlsh (fd);
+        if (vlsh == VLS_INVALID_HANDLE)
           clib_bitmap_set_no_check (ldpw->libc_wr_bitmap, fd, 1);
         else
           clib_bitmap_set_no_check (ldpw->sid_wr_bitmap,
-                                    vppcom_session_index (sid), 1);
+                                    vlsh_to_session_index (vlsh), 1);
       }));
       /* *INDENT-ON* */
 
@@ -947,9 +678,6 @@
       libc_bits_set = clib_bitmap_last_set (ldpw->libc_wr_bitmap) + 1;
       libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
 
-      LDBG (3, "writefds: sid_bits_set %d, sid_bits %d, "
-	    "libc_bits_set %d, libc_bits %d",
-	    sid_bits_set, sid_bits, libc_bits_set, libc_bits);
     }
   if (exceptfds)
     {
@@ -963,13 +691,12 @@
       clib_bitmap_foreach (fd, ldpw->ex_bitmap, ({
 	if (fd > nfds)
 	  break;
-        sid = ldp_sh_from_fd (fd);
-        LDBG (3, "exceptfds: fd %d (0x%x), sid %u (0x%x)", fd, fd, sid, sid);
-        if (sid == INVALID_SESSION_ID)
+        vlsh = ldp_fd_to_vlsh (fd);
+        if (vlsh == VLS_INVALID_HANDLE)
           clib_bitmap_set_no_check (ldpw->libc_ex_bitmap, fd, 1);
         else
           clib_bitmap_set_no_check (ldpw->sid_ex_bitmap,
-                                    vppcom_session_index (sid), 1);
+                                    vlsh_to_session_index (vlsh), 1);
       }));
       /* *INDENT-ON* */
 
@@ -978,10 +705,6 @@
 
       libc_bits_set = clib_bitmap_last_set (ldpw->libc_ex_bitmap) + 1;
       libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
-
-      LDBG (3, "exceptfds: sid_bits_set %d, sid_bits %d, "
-	    "libc_bits_set %d, libc_bits %d",
-	    sid_bits_set, sid_bits, libc_bits_set, libc_bits);
     }
 
   if (PREDICT_FALSE (!sid_bits && !libc_bits))
@@ -997,8 +720,6 @@
 	{
 	  if (!ldpw->select_vcl)
 	    {
-	      func_str = "vppcom_select";
-
 	      if (readfds)
 		clib_memcpy_fast (ldpw->rd_bitmap, ldpw->sid_rd_bitmap,
 				  vec_len (ldpw->rd_bitmap) *
@@ -1029,49 +750,49 @@
 		  if (readfds)
 		    {
                       /* *INDENT-OFF* */
-                      clib_bitmap_foreach (sid, ldpw->rd_bitmap,
-                        ({
-                          fd = ldp_fd_from_sh (vppcom_session_handle (sid));
-                          if (PREDICT_FALSE (fd < 0))
-                            {
-                              errno = EBADFD;
-                              rv = -1;
-                              goto done;
-                            }
-                          FD_SET (fd, readfds);
-                        }));
+                      clib_bitmap_foreach (si, ldpw->rd_bitmap, ({
+                	vlsh = vls_session_index_to_vlsh (si);
+                        fd = ldp_vlsh_to_fd (vlsh);
+                        if (PREDICT_FALSE (fd < 0))
+                          {
+                            errno = EBADFD;
+                            rv = -1;
+                            goto done;
+                          }
+                        FD_SET (fd, readfds);
+                      }));
                       /* *INDENT-ON* */
 		    }
 		  if (writefds)
 		    {
                       /* *INDENT-OFF* */
-                      clib_bitmap_foreach (sid, ldpw->wr_bitmap,
-                        ({
-                          fd = ldp_fd_from_sh (vppcom_session_handle (sid));
-                          if (PREDICT_FALSE (fd < 0))
-                            {
-                              errno = EBADFD;
-                              rv = -1;
-                              goto done;
-                            }
-                          FD_SET (fd, writefds);
-                        }));
+                      clib_bitmap_foreach (si, ldpw->wr_bitmap, ({
+                	vlsh = vls_session_index_to_vlsh (si);
+                        fd = ldp_vlsh_to_fd (vlsh);
+                        if (PREDICT_FALSE (fd < 0))
+                          {
+                            errno = EBADFD;
+                            rv = -1;
+                            goto done;
+                          }
+                        FD_SET (fd, writefds);
+                      }));
                       /* *INDENT-ON* */
 		    }
 		  if (exceptfds)
 		    {
                       /* *INDENT-OFF* */
-                      clib_bitmap_foreach (sid, ldpw->ex_bitmap,
-                        ({
-                          fd = ldp_fd_from_sh (vppcom_session_handle (sid));
-                          if (PREDICT_FALSE (fd < 0))
-                            {
-                              errno = EBADFD;
-                              rv = -1;
-                              goto done;
-                            }
-                          FD_SET (fd, exceptfds);
-                        }));
+                      clib_bitmap_foreach (si, ldpw->ex_bitmap, ({
+                	vlsh = vls_session_index_to_vlsh (si);
+                        fd = ldp_vlsh_to_fd (vlsh);
+                        if (PREDICT_FALSE (fd < 0))
+                          {
+                            errno = EBADFD;
+                            rv = -1;
+                            goto done;
+                          }
+                        FD_SET (fd, exceptfds);
+                      }));
                       /* *INDENT-ON* */
 		    }
 		  ldpw->select_vcl = 1;
@@ -1085,8 +806,6 @@
 	{
 	  struct timespec tspec;
 
-	  func_str = "libc_pselect";
-
 	  if (readfds)
 	    clib_memcpy_fast (readfds, ldpw->libc_rd_bitmap,
 			      vec_len (ldpw->rd_bitmap) *
@@ -1123,20 +842,6 @@
   clib_bitmap_zero (ldpw->sid_ex_bitmap);
   clib_bitmap_zero (ldpw->libc_ex_bitmap);
 
-  if (LDP_DEBUG > 3)
-    {
-      if (rv < 0)
-	{
-	  int errno_val = errno;
-	  perror (func_str);
-	  clib_warning ("LDP<%d>: ERROR: %s() failed! "
-			"rv %d, errno = %d", getpid (),
-			func_str, rv, errno_val);
-	  errno = errno_val;
-	}
-      else
-	clib_warning ("LDP<%d>: returning %d (0x%x)", getpid (), rv, rv);
-    }
   return rv;
 }
 
@@ -1171,10 +876,9 @@
 int
 socket (int domain, int type, int protocol)
 {
-  const char *func_str;
-  int rv;
+  int rv, sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
   u8 is_nonblocking = type & SOCK_NONBLOCK ? 1 : 0;
-  int sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
+  vls_handle_t vlsh;
 
   if ((errno = -ldp_init ()))
     return -1;
@@ -1182,56 +886,29 @@
   if (((domain == AF_INET) || (domain == AF_INET6)) &&
       ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
     {
-      int sid;
       u8 proto = ((sock_type == SOCK_DGRAM) ?
 		  VPPCOM_PROTO_UDP : VPPCOM_PROTO_TCP);
 
-      func_str = "vppcom_session_create";
+      LDBG (0, "calling vls_create: proto %u (%s), is_nonblocking %u",
+	    proto, vppcom_proto_str (proto), is_nonblocking);
 
-      LDBG (0, "calling %s(): proto %u (%s), is_nonblocking %u",
-	    func_str, proto, vppcom_proto_str (proto), is_nonblocking);
-
-      sid = vppcom_session_create (proto, is_nonblocking);
-      if (sid < 0)
+      vlsh = vls_create (proto, is_nonblocking);
+      if (vlsh < 0)
 	{
-	  errno = -sid;
+	  errno = -vlsh;
 	  rv = -1;
 	}
       else
 	{
-	  func_str = "ldp_fd_from_sid";
-	  rv = ldp_fd_alloc (sid);
-	  if (rv < 0)
-	    {
-	      (void) vppcom_session_close (sid);
-	      errno = -rv;
-	      rv = -1;
-	    }
+	  rv = ldp_vlsh_to_fd (vlsh);
 	}
     }
   else
     {
-      func_str = "libc_socket";
-
-      LDBG (0, "calling %s()", func_str);
-
+      LDBG (0, "calling libc_socket");
       rv = libc_socket (domain, type, protocol);
     }
 
-  if (LDP_DEBUG > 0)
-    {
-      if (rv < 0)
-	{
-	  int errno_val = errno;
-	  perror (func_str);
-	  clib_warning ("LDP<%d>: ERROR: %s() failed! "
-			"rv %d, errno = %d",
-			getpid (), func_str, rv, errno_val);
-	  errno = errno_val;
-	}
-      else
-	clib_warning ("returning fd %d (0x%x)", getpid (), rv, rv);
-    }
   return rv;
 }
 
@@ -1245,9 +922,7 @@
 int
 socketpair (int domain, int type, int protocol, int fds[2])
 {
-  const char *func_str;
-  int rv;
-  int sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
+  int rv, sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
 
   if ((errno = -ldp_init ()))
     return -1;
@@ -1255,48 +930,30 @@
   if (((domain == AF_INET) || (domain == AF_INET6)) &&
       ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
     {
-      func_str = __func__;
-
-      clib_warning ("LDP<%d>: LDP-TBD", getpid ());
+      LDBG (0, "LDP-TBD");
       errno = ENOSYS;
       rv = -1;
     }
   else
     {
-      func_str = "libc_socket";
-
-      LDBG (1, "calling %s()", func_str);
-
+      LDBG (1, "calling libc_socketpair");
       rv = libc_socketpair (domain, type, protocol, fds);
     }
 
-  if (LDP_DEBUG > 1)
-    {
-      if (rv < 0)
-	{
-	  int errno_val = errno;
-	  perror (func_str);
-	  clib_warning ("LDP<%d>: ERROR: %s() failed! "
-			"rv %d, errno = %d",
-			getpid (), func_str, rv, errno_val);
-	  errno = errno_val;
-	}
-      else
-	clib_warning ("LDP<%d>: : returning fd %d (0x%x)", getpid (), rv, rv);
-    }
   return rv;
 }
 
 int
 bind (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
 {
+  vls_handle_t vlsh;
   int rv;
-  u32 sid = ldp_sh_from_fd (fd);
 
   if ((errno = -ldp_init ()))
     return -1;
 
-  if (sid != INVALID_SESSION_ID)
+  vlsh = ldp_fd_to_vlsh (fd);
+  if (vlsh != VLS_INVALID_HANDLE)
     {
       vppcom_endpt_t ep;
 
@@ -1305,9 +962,8 @@
 	case AF_INET:
 	  if (len != sizeof (struct sockaddr_in))
 	    {
-	      clib_warning
-		("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): Invalid "
-		 "AF_INET addr len %u!", getpid (), fd, fd, sid, sid, len);
+	      LDBG (0, "ERROR: fd %d: vlsh %u: Invalid AF_INET addr len %u!",
+		    fd, vlsh, len);
 	      errno = EINVAL;
 	      rv = -1;
 	      goto done;
@@ -1320,9 +976,8 @@
 	case AF_INET6:
 	  if (len != sizeof (struct sockaddr_in6))
 	    {
-	      clib_warning
-		("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): Invalid "
-		 "AF_INET6 addr len %u!", getpid (), fd, fd, sid, sid, len);
+	      LDBG (0, "ERROR: fd %d: vlsh %u: Invalid AF_INET6 addr len %u!",
+		    fd, vlsh, len);
 	      errno = EINVAL;
 	      rv = -1;
 	      goto done;
@@ -1333,17 +988,16 @@
 	  break;
 
 	default:
-	  clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): "
-			"Unsupported address family %u!",
-			getpid (), fd, fd, sid, sid, addr->sa_family);
+	  LDBG (0, "ERROR: fd %d: vlsh %u: Unsupported address family %u!",
+		fd, vlsh, addr->sa_family);
 	  errno = EAFNOSUPPORT;
 	  rv = -1;
 	  goto done;
 	}
-      LDBG (0, "fd %d (0x%x): calling vppcom_session_bind(): "
-	    "sid %u (0x%x), addr %p, len %u", fd, fd, sid, sid, addr, len);
+      LDBG (0, "fd %d: calling vls_bind: vlsh %u, addr %p, len %u", fd, vlsh,
+	    addr, len);
 
-      rv = vppcom_session_bind (sid, &ep);
+      rv = vls_bind (vlsh, &ep);
       if (rv != VPPCOM_OK)
 	{
 	  errno = -rv;
@@ -1352,14 +1006,12 @@
     }
   else
     {
-      LDBG (0, "fd %d (0x%x): calling libc_bind(): addr %p, len %u",
-	    fd, fd, addr, len);
-
+      LDBG (0, "fd %d: calling libc_bind: addr %p, len %u", fd, addr, len);
       rv = libc_bind (fd, addr, len);
     }
 
 done:
-  LDBG (1, "fd %d (0x%x): returning %d", fd, fd, rv);
+  LDBG (1, "fd %d: returning %d", fd, rv);
 
   return rv;
 }
@@ -1413,28 +1065,22 @@
 int
 getsockname (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
 {
+  vls_handle_t vlsh;
   int rv;
-  const char *func_str;
-  u32 sid = ldp_sh_from_fd (fd);
 
   if ((errno = -ldp_init ()))
     return -1;
 
-  if (sid != INVALID_SESSION_ID)
+  vlsh = ldp_fd_to_vlsh (fd);
+  if (vlsh != VLS_INVALID_HANDLE)
     {
       vppcom_endpt_t ep;
       u8 addr_buf[sizeof (struct in6_addr)];
       u32 size = sizeof (ep);
 
       ep.ip = addr_buf;
-      func_str = "vppcom_session_attr[GET_LCL_ADDR]";
 
-      if (LDP_DEBUG > 2)
-	clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
-		      "addr %p, len %u",
-		      getpid (), fd, fd, func_str, sid, sid, addr, len);
-
-      rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LCL_ADDR, &ep, &size);
+      rv = vls_attr (vlsh, VPPCOM_ATTR_GET_LCL_ADDR, &ep, &size);
       if (rv != VPPCOM_OK)
 	{
 	  errno = -rv;
@@ -1452,53 +1098,31 @@
     }
   else
     {
-      func_str = "libc_getsockname";
-
-      if (LDP_DEBUG > 2)
-	clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-		      "addr %p, len %u",
-		      getpid (), fd, fd, func_str, addr, len);
-
       rv = libc_getsockname (fd, addr, len);
     }
 
-  if (LDP_DEBUG > 2)
-    {
-      if (rv < 0)
-	{
-	  int errno_val = errno;
-	  perror (func_str);
-	  clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
-			"rv %d, errno = %d", getpid (), fd, fd,
-			func_str, rv, errno_val);
-	  errno = errno_val;
-	}
-      else
-	clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
-		      getpid (), fd, fd, rv, rv);
-    }
   return rv;
 }
 
 int
 connect (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
 {
+  vls_handle_t vlsh;
   int rv;
-  u32 sid = ldp_sh_from_fd (fd);
 
   if ((errno = -ldp_init ()))
     return -1;
 
   if (!addr)
     {
-      clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): NULL addr, len %u",
-		    getpid (), fd, fd, len);
+      LDBG (0, "ERROR: fd %d: NULL addr, len %u", fd, len);
       errno = EINVAL;
       rv = -1;
       goto done;
     }
 
-  if (sid != INVALID_SESSION_ID)
+  vlsh = ldp_fd_to_vlsh (fd);
+  if (vlsh != VLS_INVALID_HANDLE)
     {
       vppcom_endpt_t ep;
 
@@ -1507,9 +1131,8 @@
 	case AF_INET:
 	  if (len != sizeof (struct sockaddr_in))
 	    {
-	      clib_warning
-		("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): Invalid "
-		 "AF_INET addr len %u!", getpid (), fd, fd, sid, sid, len);
+	      LDBG (0, "fd %d: ERROR vlsh %u: Invalid AF_INET addr len %u!",
+		    fd, vlsh, len);
 	      errno = EINVAL;
 	      rv = -1;
 	      goto done;
@@ -1522,9 +1145,8 @@
 	case AF_INET6:
 	  if (len != sizeof (struct sockaddr_in6))
 	    {
-	      clib_warning
-		("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): Invalid "
-		 "AF_INET6 addr len %u!", getpid (), fd, fd, sid, sid, len);
+	      LDBG (0, "fd %d: ERROR vlsh %u: Invalid AF_INET6 addr len %u!",
+		    fd, vlsh, len);
 	      errno = EINVAL;
 	      rv = -1;
 	      goto done;
@@ -1535,17 +1157,16 @@
 	  break;
 
 	default:
-	  clib_warning ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): "
-			"Unsupported address family %u!",
-			getpid (), fd, fd, sid, sid, addr->sa_family);
+	  LDBG (0, "fd %d: ERROR vlsh %u: Unsupported address family %u!",
+		fd, vlsh, addr->sa_family);
 	  errno = EAFNOSUPPORT;
 	  rv = -1;
 	  goto done;
 	}
-      LDBG (0, "fd %d (0x%x): calling vppcom_session_connect(): sid %u (0x%x)"
-	    " addr %p len %u", fd, fd, sid, sid, addr, len);
+      LDBG (0, "fd %d: calling vls_connect(): vlsh %u addr %p len %u", fd,
+	    vlsh, addr, len);
 
-      rv = vppcom_session_connect (sid, &ep);
+      rv = vls_connect (vlsh, &ep);
       if (rv != VPPCOM_OK)
 	{
 	  errno = -rv;
@@ -1554,42 +1175,35 @@
     }
   else
     {
-      LDBG (0, "fd %d (0x%x): calling libc_connect(): addr %p, len %u",
-	    fd, fd, addr, len);
+      LDBG (0, "fd %d: calling libc_connect(): addr %p, len %u",
+	    fd, addr, len);
 
       rv = libc_connect (fd, addr, len);
     }
 
 done:
-  LDBG (1, "fd %d (0x%x): returning %d (0x%x)", fd, fd, rv, rv);
+  LDBG (1, "fd %d: returning %d (0x%x)", fd, rv, rv);
   return rv;
 }
 
 int
 getpeername (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
 {
+  vls_handle_t vlsh;
   int rv;
-  const char *func_str;
-  u32 sid = ldp_sh_from_fd (fd);
 
   if ((errno = -ldp_init ()))
     return -1;
 
-  if (sid != INVALID_SESSION_ID)
+  vlsh = ldp_fd_to_vlsh (fd);
+  if (vlsh != VLS_INVALID_HANDLE)
     {
       vppcom_endpt_t ep;
       u8 addr_buf[sizeof (struct in6_addr)];
       u32 size = sizeof (ep);
 
       ep.ip = addr_buf;
-      func_str = "vppcom_session_attr[GET_PEER_ADDR]";
-
-      if (LDP_DEBUG > 2)
-	clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
-		      "addr %p, len %u",
-		      getpid (), fd, fd, func_str, sid, sid, addr, len);
-
-      rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_PEER_ADDR, &ep, &size);
+      rv = vls_attr (vlsh, VPPCOM_ATTR_GET_PEER_ADDR, &ep, &size);
       if (rv != VPPCOM_OK)
 	{
 	  errno = -rv;
@@ -1607,55 +1221,24 @@
     }
   else
     {
-      func_str = "libc_getpeername";
-
-      if (LDP_DEBUG > 2)
-	clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-		      "addr %p, len %u",
-		      getpid (), fd, fd, func_str, addr, len);
-
       rv = libc_getpeername (fd, addr, len);
     }
 
-  if (LDP_DEBUG > 2)
-    {
-      if (rv < 0)
-	{
-	  int errno_val = errno;
-	  perror (func_str);
-	  clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
-			"rv %d, errno = %d", getpid (), fd, fd,
-			func_str, rv, errno_val);
-	  errno = errno_val;
-	}
-      else
-	clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
-		      getpid (), fd, fd, rv, rv);
-    }
   return rv;
 }
 
 ssize_t
 send (int fd, const void *buf, size_t n, int flags)
 {
+  vls_handle_t vlsh = ldp_fd_to_vlsh (fd);
   ssize_t size;
-  const char *func_str;
-  u32 sid = ldp_sh_from_fd (fd);
 
   if ((errno = -ldp_init ()))
     return -1;
 
-  if (sid != INVALID_SESSION_ID)
+  if (vlsh != VLS_INVALID_HANDLE)
     {
-
-      func_str = "vppcom_session_sendto";
-
-      if (LDP_DEBUG > 2)
-	clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
-		      "buf %p, n %u, flags 0x%x",
-		      getpid (), fd, fd, func_str, sid, sid, buf, n, flags);
-
-      size = vppcom_session_sendto (sid, (void *) buf, n, flags, NULL);
+      size = vls_sendto (vlsh, (void *) buf, n, flags, NULL);
       if (size < VPPCOM_OK)
 	{
 	  errno = -size;
@@ -1664,31 +1247,9 @@
     }
   else
     {
-      func_str = "libc_send";
-
-      if (LDP_DEBUG > 2)
-	clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-		      "buf %p, n %u, flags 0x%x",
-		      getpid (), fd, fd, func_str, buf, n, flags);
-
       size = libc_send (fd, buf, n, flags);
     }
 
-  if (LDP_DEBUG > 2)
-    {
-      if (size < 0)
-	{
-	  int errno_val = errno;
-	  perror (func_str);
-	  clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
-			"rv %d, errno = %d", getpid (), fd, fd,
-			func_str, size, errno_val);
-	  errno = errno_val;
-	}
-      else
-	clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
-		      getpid (), fd, fd, size, size);
-    }
   return size;
 }
 
@@ -1696,33 +1257,28 @@
 sendfile (int out_fd, int in_fd, off_t * offset, size_t len)
 {
   ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
+  vls_handle_t vlsh;
   ssize_t size = 0;
-  const char *func_str;
-  u32 sid = ldp_sh_from_fd (out_fd);
 
   if ((errno = -ldp_init ()))
     return -1;
 
-  if (sid != INVALID_SESSION_ID)
+  vlsh = ldp_fd_to_vlsh (out_fd);
+  if (vlsh != VLS_INVALID_HANDLE)
     {
       int rv;
       ssize_t results = 0;
       size_t n_bytes_left = len;
       size_t bytes_to_read;
       int nbytes;
-      int errno_val;
       u8 eagain = 0;
       u32 flags, flags_len = sizeof (flags);
 
-      func_str = "vppcom_session_attr[GET_FLAGS]";
-      rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_FLAGS, &flags,
-				&flags_len);
+      rv = vls_attr (vlsh, VPPCOM_ATTR_GET_FLAGS, &flags, &flags_len);
       if (PREDICT_FALSE (rv != VPPCOM_OK))
 	{
-	  clib_warning ("LDP<%d>: ERROR: out fd %d (0x%x): %s(): "
-			"sid %u (0x%x), returned %d (%s)!", getpid (),
-			out_fd, out_fd, func_str, sid, sid, rv,
-			vppcom_retval_str (rv));
+	  LDBG (0, "ERROR: out fd %d: vls_attr: vlsh %u, returned %d (%s)!",
+		out_fd, vlsh, rv, vppcom_retval_str (rv));
 
 	  vec_reset_length (ldpw->io_buffer);
 	  errno = -rv;
@@ -1735,14 +1291,6 @@
 	  off_t off = lseek (in_fd, *offset, SEEK_SET);
 	  if (PREDICT_FALSE (off == -1))
 	    {
-	      func_str = "lseek";
-	      errno_val = errno;
-	      clib_warning ("LDP<%d>: ERROR: out fd %d (0x%x): %s(): "
-			    "SEEK_SET failed: in_fd %d, offset %p, "
-			    "*offset %ld, rv %ld, errno %d", getpid (),
-			    out_fd, out_fd, in_fd, offset, *offset, off,
-			    errno_val);
-	      errno = errno_val;
 	      size = -1;
 	      goto done;
 	    }
@@ -1752,14 +1300,11 @@
 
       do
 	{
-	  func_str = "vppcom_session_attr[GET_NWRITE]";
-	  size = vppcom_session_attr (sid, VPPCOM_ATTR_GET_NWRITE, 0, 0);
+	  size = vls_attr (vlsh, VPPCOM_ATTR_GET_NWRITE, 0, 0);
 	  if (size < 0)
 	    {
-	      clib_warning
-		("LDP<%d>: ERROR: fd %d (0x%x): %s(): sid %u (0x%x), "
-		 "returned %d (%s)!", getpid (), out_fd, out_fd, func_str,
-		 sid, sid, size, vppcom_retval_str (size));
+	      LDBG (0, "ERROR: fd %d: vls_attr: vlsh %u returned %d (%s)!",
+		    out_fd, vlsh, size, vppcom_retval_str (size));
 	      vec_reset_length (ldpw->io_buffer);
 	      errno = -size;
 	      size = -1;
@@ -1767,25 +1312,12 @@
 	    }
 
 	  bytes_to_read = size;
-	  if (LDP_DEBUG > 2)
-	    clib_warning
-	      ("LDP<%d>: fd %d (0x%x): called %s(): sid %u (0x%x), "
-	       "results %ld, n_bytes_left %lu, bytes_to_read %lu", getpid (),
-	       out_fd, out_fd, func_str, sid, sid, results, n_bytes_left,
-	       bytes_to_read);
-
 	  if (bytes_to_read == 0)
 	    {
 	      if (flags & O_NONBLOCK)
 		{
 		  if (!results)
-		    {
-		      if (LDP_DEBUG > 2)
-			clib_warning ("LDP<%d>: fd %d (0x%x): sid %u (0x%x): "
-				      "EAGAIN",
-				      getpid (), out_fd, out_fd, sid, sid);
-		      eagain = 1;
-		    }
+		    eagain = 1;
 		  goto update_offset;
 		}
 	      else
@@ -1796,15 +1328,6 @@
 	  nbytes = libc_read (in_fd, ldpw->io_buffer, bytes_to_read);
 	  if (nbytes < 0)
 	    {
-	      func_str = "libc_read";
-	      errno_val = errno;
-	      clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): in_fd (%d), "
-			    "io_buffer %p, bytes_to_read %lu, rv %d, "
-			    "errno %d", getpid (), out_fd, out_fd, func_str,
-			    in_fd, ldpw->io_buffer, bytes_to_read, nbytes,
-			    errno_val);
-	      errno = errno_val;
-
 	      if (results == 0)
 		{
 		  vec_reset_length (ldpw->io_buffer);
@@ -1813,15 +1336,8 @@
 		}
 	      goto update_offset;
 	    }
-	  func_str = "vppcom_session_write";
-	  if (LDP_DEBUG > 2)
-	    clib_warning
-	      ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
-	       "buf %p, nbytes %u: results %d, n_bytes_left %d", getpid (),
-	       out_fd, out_fd, func_str, sid, sid, ldpw->io_buffer, nbytes,
-	       results, n_bytes_left);
 
-	  size = vppcom_session_write (sid, ldpw->io_buffer, nbytes);
+	  size = vls_write (vlsh, ldpw->io_buffer, nbytes);
 	  if (size < 0)
 	    {
 	      if (size == VPPCOM_EAGAIN)
@@ -1829,27 +1345,12 @@
 		  if (flags & O_NONBLOCK)
 		    {
 		      if (!results)
-			{
-			  if (LDP_DEBUG > 2)
-			    clib_warning
-			      ("LDP<%d>: fd %d (0x%x): sid %u (0x%x): "
-			       "EAGAIN", getpid (), out_fd, out_fd, sid, sid);
-			  eagain = 1;
-			}
+			eagain = 1;
 		      goto update_offset;
 		    }
 		  else
 		    continue;
 		}
-	      else
-		{
-		  clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s():"
-				"sid %u, io_buffer %p, nbytes %u "
-				"returned %d (%s)",
-				getpid (), out_fd, out_fd, func_str,
-				sid, ldpw->io_buffer, nbytes,
-				size, vppcom_retval_str (size));
-		}
 	      if (results == 0)
 		{
 		  vec_reset_length (ldpw->io_buffer);
@@ -1873,13 +1374,6 @@
 	  off_t off = lseek (in_fd, *offset, SEEK_SET);
 	  if (PREDICT_FALSE (off == -1))
 	    {
-	      func_str = "lseek";
-	      errno_val = errno;
-	      clib_warning ("LDP<%d>: ERROR: %s(): SEEK_SET failed: "
-			    "in_fd %d, offset %p, *offset %ld, "
-			    "rv %ld, errno %d", getpid (), in_fd,
-			    offset, *offset, off, errno_val);
-	      errno = errno_val;
 	      size = -1;
 	      goto done;
 	    }
@@ -1897,33 +1391,10 @@
     }
   else
     {
-      func_str = "libc_send";
-
-      if (LDP_DEBUG > 2)
-	clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-		      "in_fd %d, offset %p, len %u",
-		      getpid (), out_fd, out_fd, func_str,
-		      in_fd, offset, len);
-
       size = libc_sendfile (out_fd, in_fd, offset, len);
     }
 
 done:
-  if (LDP_DEBUG > 2)
-    {
-      if (size < 0)
-	{
-	  int errno_val = errno;
-	  perror (func_str);
-	  clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
-			"rv %d, errno = %d", getpid (), out_fd, out_fd,
-			func_str, size, errno_val);
-	  errno = errno_val;
-	}
-      else
-	clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
-		      getpid (), out_fd, out_fd, size, size);
-    }
   return size;
 }
 
@@ -1936,27 +1407,21 @@
 ssize_t
 recv (int fd, void *buf, size_t n, int flags)
 {
+  vls_handle_t vlsh;
   ssize_t size;
-  u32 sid;
 
   if ((errno = -ldp_init ()))
     return -1;
 
-  sid = ldp_sh_from_fd (fd);
-  if (sid != INVALID_SESSION_ID)
+  vlsh = ldp_fd_to_vlsh (fd);
+  if (vlsh != VLS_INVALID_HANDLE)
     {
-      LDBG (2, "fd %d (0x%x): calling vcl recvfrom: sid %u (0x%x), buf %p,"
-	    " n %u, flags 0x%x", fd, fd, sid, sid, buf, n, flags);
-
-      size = vppcom_session_recvfrom (sid, buf, n, flags, NULL);
+      size = vls_recvfrom (vlsh, buf, n, flags, NULL);
       if (size < 0)
 	errno = -size;
     }
   else
     {
-      LDBG (2, "fd %d (0x%x): calling libc_recvfrom(): buf %p, n %u, "
-	    "flags 0x%x", fd, fd, buf, n, flags);
-
       size = libc_recv (fd, buf, n, flags);
     }
 
@@ -1967,14 +1432,14 @@
 sendto (int fd, const void *buf, size_t n, int flags,
 	__CONST_SOCKADDR_ARG addr, socklen_t addr_len)
 {
+  vls_handle_t vlsh;
   ssize_t size;
-  const char *func_str = __func__;
-  u32 sid = ldp_sh_from_fd (fd);
 
   if ((errno = -ldp_init ()))
     return -1;
 
-  if (sid != INVALID_SESSION_ID)
+  vlsh = ldp_fd_to_vlsh (fd);
+  if (vlsh != INVALID_SESSION_ID)
     {
       vppcom_endpt_t *ep = 0;
       vppcom_endpt_t _ep;
@@ -2007,15 +1472,7 @@
 	    }
 	}
 
-      func_str = "vppcom_session_sendto";
-
-      if (LDP_DEBUG > 2)
-	clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-		      "sid %u (0x%x), buf %p, n %u, flags 0x%x, ep %p",
-		      getpid (), fd, fd, func_str, sid, sid, buf, n,
-		      flags, ep);
-
-      size = vppcom_session_sendto (sid, (void *) buf, n, flags, ep);
+      size = vls_sendto (vlsh, (void *) buf, n, flags, ep);
       if (size < 0)
 	{
 	  errno = -size;
@@ -2024,33 +1481,10 @@
     }
   else
     {
-      func_str = "libc_sendto";
-
-      if (LDP_DEBUG > 2)
-	clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-		      "buf %p, n %u, flags 0x%x, addr %p, addr_len %d",
-		      getpid (), fd, fd, func_str, buf, n, flags,
-		      addr, addr_len);
-
       size = libc_sendto (fd, buf, n, flags, addr, addr_len);
     }
 
 done:
-  if (LDP_DEBUG > 2)
-    {
-      if (size < 0)
-	{
-	  int errno_val = errno;
-	  perror (func_str);
-	  clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
-			"rv %d, errno = %d", getpid (), fd, fd,
-			func_str, size, errno_val);
-	  errno = errno_val;
-	}
-      else
-	clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
-		      getpid (), fd, fd, size, size);
-    }
   return size;
 }
 
@@ -2058,35 +1492,28 @@
 recvfrom (int fd, void *__restrict buf, size_t n, int flags,
 	  __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
 {
+  vls_handle_t sid;
   ssize_t size;
-  const char *func_str;
-  u32 sid = ldp_sh_from_fd (fd);
 
   if ((errno = -ldp_init ()))
     return -1;
 
-  if (sid != INVALID_SESSION_ID)
+  sid = ldp_fd_to_vlsh (fd);
+  if (sid != VLS_INVALID_HANDLE)
     {
       vppcom_endpt_t ep;
       u8 src_addr[sizeof (struct sockaddr_in6)];
 
-      func_str = "vppcom_session_recvfrom";
-
-      if (LDP_DEBUG > 2)
-	clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-		      "sid %u (0x%x), buf %p, n %u, flags 0x%x, ep %p",
-		      getpid (), fd, fd, func_str, sid, sid, buf, n,
-		      flags, &ep);
       if (addr)
 	{
 	  ep.ip = src_addr;
-	  size = vppcom_session_recvfrom (sid, buf, n, flags, &ep);
+	  size = vls_recvfrom (sid, buf, n, flags, &ep);
 
 	  if (size > 0)
 	    size = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
 	}
       else
-	size = vppcom_session_recvfrom (sid, buf, n, flags, NULL);
+	size = vls_recvfrom (sid, buf, n, flags, NULL);
 
       if (size < 0)
 	{
@@ -2096,80 +1523,33 @@
     }
   else
     {
-      func_str = "libc_recvfrom";
-
-      if (LDP_DEBUG > 2)
-	clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-		      "buf %p, n %u, flags 0x%x, addr %p, addr_len %d",
-		      getpid (), fd, fd, func_str, buf, n, flags,
-		      addr, addr_len);
-
       size = libc_recvfrom (fd, buf, n, flags, addr, addr_len);
     }
 
-  if (LDP_DEBUG > 2)
-    {
-      if (size < 0)
-	{
-	  int errno_val = errno;
-	  perror (func_str);
-	  clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
-			"rv %d, errno = %d", getpid (), fd, fd,
-			func_str, size, errno_val);
-	  errno = errno_val;
-	}
-      else
-	clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
-		      getpid (), fd, fd, size, size);
-    }
   return size;
 }
 
 ssize_t
 sendmsg (int fd, const struct msghdr * message, int flags)
 {
+  vls_handle_t vlsh;
   ssize_t size;
-  const char *func_str;
-  u32 sid = ldp_sh_from_fd (fd);
 
   if ((errno = -ldp_init ()))
     return -1;
 
-  if (sid != INVALID_SESSION_ID)
+  vlsh = ldp_fd_to_vlsh (fd);
+  if (vlsh != VLS_INVALID_HANDLE)
     {
-      func_str = __func__;
-
-      clib_warning ("LDP<%d>: LDP-TBD", getpid ());
+      LDBG (0, "LDP-TBD");
       errno = ENOSYS;
       size = -1;
     }
   else
     {
-      func_str = "libc_sendmsg";
-
-      if (LDP_DEBUG > 2)
-	clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-		      "message %p, flags 0x%x",
-		      getpid (), fd, fd, func_str, message, flags);
-
       size = libc_sendmsg (fd, message, flags);
     }
 
-  if (LDP_DEBUG > 2)
-    {
-      if (size < 0)
-	{
-	  int errno_val = errno;
-	  perror (func_str);
-	  clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
-			"rv %d, errno = %d", getpid (), fd, fd,
-			func_str, size, errno_val);
-	  errno = errno_val;
-	}
-      else
-	clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
-		      getpid (), fd, fd, size, size);
-    }
   return size;
 }
 
@@ -2179,12 +1559,12 @@
 {
   ssize_t size;
   const char *func_str;
-  u32 sid = ldp_sh_from_fd (fd);
+  u32 sh = ldp_fd_to_vlsh (fd);
 
   if ((errno = -ldp_init ()))
     return -1;
 
-  if (sid != INVALID_SESSION_ID)
+  if (sh != INVALID_SESSION_ID)
     {
       clib_warning ("LDP<%d>: LDP-TBD", getpid ());
       errno = ENOSYS;
@@ -2224,48 +1604,24 @@
 ssize_t
 recvmsg (int fd, struct msghdr * message, int flags)
 {
+  vls_handle_t vlsh;
   ssize_t size;
-  const char *func_str;
-  u32 sid = ldp_sh_from_fd (fd);
 
   if ((errno = -ldp_init ()))
     return -1;
 
-  if (sid != INVALID_SESSION_ID)
+  vlsh = ldp_fd_to_vlsh (fd);
+  if (vlsh != VLS_INVALID_HANDLE)
     {
-      func_str = __func__;
-
-      clib_warning ("LDP<%d>: LDP-TBD", getpid ());
+      LDBG (0, "LDP-TBD");
       errno = ENOSYS;
       size = -1;
     }
   else
     {
-      func_str = "libc_recvmsg";
-
-      if (LDP_DEBUG > 2)
-	clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-		      "message %p, flags 0x%x",
-		      getpid (), fd, fd, func_str, message, flags);
-
       size = libc_recvmsg (fd, message, flags);
     }
 
-  if (LDP_DEBUG > 2)
-    {
-      if (size < 0)
-	{
-	  int errno_val = errno;
-	  perror (func_str);
-	  clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
-			"rv %d, errno = %d", getpid (), fd, fd,
-			func_str, size, errno_val);
-	  errno = errno_val;
-	}
-      else
-	clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
-		      getpid (), fd, fd, size, size);
-    }
   return size;
 }
 
@@ -2276,12 +1632,12 @@
 {
   ssize_t size;
   const char *func_str;
-  u32 sid = ldp_sh_from_fd (fd);
+  u32 sh = ldp_fd_to_vlsh (fd);
 
   if ((errno = -ldp_init ()))
     return -1;
 
-  if (sid != INVALID_SESSION_ID)
+  if (sh != INVALID_SESSION_ID)
     {
       clib_warning ("LDP<%d>: LDP-TBD", getpid ());
       errno = ENOSYS;
@@ -2323,15 +1679,14 @@
 getsockopt (int fd, int level, int optname,
 	    void *__restrict optval, socklen_t * __restrict optlen)
 {
+  vls_handle_t vlsh;
   int rv;
-  const char *func_str = __func__;
-  u32 sid = ldp_sh_from_fd (fd);
-  u32 buflen = optlen ? (u32) * optlen : 0;
 
   if ((errno = -ldp_init ()))
     return -1;
 
-  if (sid != INVALID_SESSION_ID)
+  vlsh = ldp_fd_to_vlsh (fd);
+  if (vlsh != VLS_INVALID_HANDLE)
     {
       rv = -EOPNOTSUPP;
 
@@ -2341,50 +1696,26 @@
 	  switch (optname)
 	    {
 	    case TCP_NODELAY:
-	      func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_NODELAY]";
-	      if (LDP_DEBUG > 1)
-		clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-			      "sid %u (0x%x)",
-			      getpid (), fd, fd, func_str, sid, sid);
-	      rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_NODELAY,
-					optval, optlen);
+	      rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_NODELAY,
+			     optval, optlen);
 	      break;
 	    case TCP_MAXSEG:
-	      func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_USER_MSS]";
-	      if (LDP_DEBUG > 1)
-		clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-			      "sid %u (0x%x)",
-			      getpid (), fd, fd, func_str, sid, sid);
-	      rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_USER_MSS,
-					optval, optlen);
+	      rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_USER_MSS,
+			     optval, optlen);
 	      break;
 	    case TCP_KEEPIDLE:
-	      func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_KEEPIDLE]";
-	      if (LDP_DEBUG > 1)
-		clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-			      "sid %u (0x%x)",
-			      getpid (), fd, fd, func_str, sid, sid);
-	      rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_KEEPIDLE,
-					optval, optlen);
+	      rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_KEEPIDLE,
+			     optval, optlen);
 	      break;
 	    case TCP_KEEPINTVL:
-	      func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_KEEPINTVL]";
-	      if (LDP_DEBUG > 1)
-		clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-			      "sid %u (0x%x), SOL_TCP",
-			      getpid (), fd, fd, func_str, sid, sid);
-	      rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_KEEPINTVL,
-					optval, optlen);
+	      rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_KEEPINTVL,
+			     optval, optlen);
 	      break;
 	    case TCP_INFO:
 	      if (optval && optlen && (*optlen == sizeof (struct tcp_info)))
 		{
-		  if (LDP_DEBUG > 1)
-		    clib_warning ("LDP<%d>: fd %d (0x%x): sid %u (0x%x), "
-				  "SOL_TCP, TCP_INFO, optval %p, "
-				  "optlen %d: #LDP-NOP#",
-				  getpid (), fd, fd, sid, sid,
-				  optval, *optlen);
+		  LDBG (1, "fd %d: vlsh %u SOL_TCP, TCP_INFO, optval %p, "
+			"optlen %d: #LDP-NOP#", fd, vlsh, optval, *optlen);
 		  memset (optval, 0, *optlen);
 		  rv = VPPCOM_OK;
 		}
@@ -2392,11 +1723,8 @@
 		rv = -EFAULT;
 	      break;
 	    default:
-	      if (LDP_DEBUG > 1)
-		clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
-			      "sid %u (0x%x), SOL_TCP, "
-			      "optname %d unsupported!",
-			      getpid (), fd, fd, func_str, sid, sid, optname);
+	      LDBG (0, "ERROR: fd %d: getsockopt SOL_TCP: sid %u, "
+		    "optname %d unsupported!", fd, vlsh, optname);
 	      break;
 	    }
 	  break;
@@ -2404,20 +1732,11 @@
 	  switch (optname)
 	    {
 	    case IPV6_V6ONLY:
-	      func_str = "vppcom_session_attr[SOL_IPV6,GET_V6ONLY]";
-	      if (LDP_DEBUG > 1)
-		clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-			      "sid %u (0x%x)",
-			      getpid (), fd, fd, func_str, sid, sid);
-	      rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_V6ONLY,
-					optval, optlen);
+	      rv = vls_attr (vlsh, VPPCOM_ATTR_GET_V6ONLY, optval, optlen);
 	      break;
 	    default:
-	      if (LDP_DEBUG > 1)
-		clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
-			      "sid %u (0x%x), SOL_IPV6, "
-			      "optname %d unsupported!",
-			      getpid (), fd, fd, func_str, sid, sid, optname);
+	      LDBG (0, "ERROR: fd %d: getsockopt SOL_IPV6: vlsh %u "
+		    "optname %d unsupported!", fd, vlsh, optname);
 	      break;
 	    }
 	  break;
@@ -2425,84 +1744,35 @@
 	  switch (optname)
 	    {
 	    case SO_ACCEPTCONN:
-	      func_str = "vppcom_session_attr[SOL_SOCKET,GET_ACCEPTCONN]";
-	      if (LDP_DEBUG > 1)
-		clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-			      "sid %u (0x%x)",
-			      getpid (), fd, fd, func_str, sid, sid);
-	      rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LISTEN,
-					optval, optlen);
+	      rv = vls_attr (vlsh, VPPCOM_ATTR_GET_LISTEN, optval, optlen);
 	      break;
 	    case SO_KEEPALIVE:
-	      func_str = "vppcom_session_attr[SOL_SOCKET,GET_KEEPALIVE]";
-	      if (LDP_DEBUG > 1)
-		clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-			      "sid %u (0x%x)",
-			      getpid (), fd, fd, func_str, sid, sid);
-	      rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_KEEPALIVE,
-					optval, optlen);
+	      rv = vls_attr (vlsh, VPPCOM_ATTR_GET_KEEPALIVE, optval, optlen);
 	      break;
 	    case SO_PROTOCOL:
-	      func_str = "vppcom_session_attr[SOL_SOCKET,GET_PROTOCOL]";
-	      if (LDP_DEBUG > 1)
-		clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-			      "sid %u (0x%x)",
-			      getpid (), fd, fd, func_str, sid, sid);
-	      rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_PROTOCOL,
-					optval, optlen);
+	      rv = vls_attr (vlsh, VPPCOM_ATTR_GET_PROTOCOL, optval, optlen);
 	      *(int *) optval = *(int *) optval ? SOCK_DGRAM : SOCK_STREAM;
 	      break;
 	    case SO_SNDBUF:
-	      func_str = "vppcom_session_attr[SOL_SOCKET,GET_TX_FIFO_LEN]";
-	      if (LDP_DEBUG > 1)
-		clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-			      "sid %u (0x%x), optlen %d",
-			      getpid (), fd, fd, func_str, sid, sid, buflen);
-	      rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TX_FIFO_LEN,
-					optval, optlen);
+	      rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TX_FIFO_LEN,
+			     optval, optlen);
 	      break;
 	    case SO_RCVBUF:
-	      func_str = "vppcom_session_attr[SOL_SOCKET,GET_RX_FIFO_LEN]";
-	      if (LDP_DEBUG > 1)
-		clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-			      "sid %u (0x%x), optlen %d",
-			      getpid (), fd, fd, func_str, sid, sid, buflen);
-	      rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_RX_FIFO_LEN,
-					optval, optlen);
+	      rv = vls_attr (vlsh, VPPCOM_ATTR_GET_RX_FIFO_LEN,
+			     optval, optlen);
 	      break;
 	    case SO_REUSEADDR:
-	      func_str = "vppcom_session_attr[SOL_SOCKET,GET_REUSEADDR]";
-	      if (LDP_DEBUG > 1)
-		clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-			      "sid %u (0x%x)",
-			      getpid (), fd, fd, func_str, sid, sid);
-	      rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_REUSEADDR,
-					optval, optlen);
+	      rv = vls_attr (vlsh, VPPCOM_ATTR_GET_REUSEADDR, optval, optlen);
 	      break;
 	    case SO_BROADCAST:
-	      func_str = "vppcom_session_attr[SOL_SOCKET,GET_BROADCAST]";
-	      if (LDP_DEBUG > 1)
-		clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-			      "sid %u (0x%x)",
-			      getpid (), fd, fd, func_str, sid, sid);
-	      rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_BROADCAST,
-					optval, optlen);
+	      rv = vls_attr (vlsh, VPPCOM_ATTR_GET_BROADCAST, optval, optlen);
 	      break;
 	    case SO_ERROR:
-	      func_str = "vppcom_session_attr[SOL_SOCKET,GET_ERROR]";
-	      if (LDP_DEBUG > 1)
-		clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-			      "sid %u (0x%x)",
-			      getpid (), fd, fd, func_str, sid, sid);
-	      rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_ERROR,
-					optval, optlen);
+	      rv = vls_attr (vlsh, VPPCOM_ATTR_GET_ERROR, optval, optlen);
 	      break;
 	    default:
-	      if (LDP_DEBUG > 1)
-		clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
-			      "sid %u (0x%x), SOL_SOCKET, "
-			      "optname %d unsupported!",
-			      getpid (), fd, fd, func_str, sid, sid, optname);
+	      LDBG (0, "ERROR: fd %d: getsockopt SOL_SOCKET: vlsh %u "
+		    "optname %d unsupported!", fd, vlsh, optname);
 	      break;
 	    }
 	  break;
@@ -2518,32 +1788,9 @@
     }
   else
     {
-      func_str = "libc_getsockopt";
-
-      if (LDP_DEBUG > 1)
-	clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): level %d, "
-		      "optname %d, optval %p, optlen %d",
-		      getpid (), fd, fd, func_str, level, optname,
-		      optval, optlen);
-
       rv = libc_getsockopt (fd, level, optname, optval, optlen);
     }
 
-  if (LDP_DEBUG > 1)
-    {
-      if (rv < 0)
-	{
-	  int errno_val = errno;
-	  perror (func_str);
-	  clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
-			"rv %d, errno = %d", getpid (), fd, fd,
-			func_str, rv, errno_val);
-	  errno = errno_val;
-	}
-      else
-	clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
-		      getpid (), fd, fd, rv, rv);
-    }
   return rv;
 }
 
@@ -2551,14 +1798,14 @@
 setsockopt (int fd, int level, int optname,
 	    const void *optval, socklen_t optlen)
 {
+  vls_handle_t vlsh;
   int rv;
-  const char *func_str = __func__;
-  u32 sid = ldp_sh_from_fd (fd);
 
   if ((errno = -ldp_init ()))
     return -1;
 
-  if (sid != INVALID_SESSION_ID)
+  vlsh = ldp_fd_to_vlsh (fd);
+  if (vlsh != VLS_INVALID_HANDLE)
     {
       rv = -EOPNOTSUPP;
 
@@ -2568,47 +1815,24 @@
 	  switch (optname)
 	    {
 	    case TCP_NODELAY:
-	      func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_NODELAY]";
-	      if (LDP_DEBUG > 1)
-		clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-			      "sid %u (0x%x)",
-			      getpid (), fd, fd, func_str, sid, sid);
-	      rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_NODELAY,
-					(void *) optval, &optlen);
+	      rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_NODELAY,
+			     (void *) optval, &optlen);
 	      break;
 	    case TCP_MAXSEG:
-	      func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_USER_MSS]";
-	      if (LDP_DEBUG > 1)
-		clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-			      "sid %u (0x%x)",
-			      getpid (), fd, fd, func_str, sid, sid);
-	      rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_USER_MSS,
-					(void *) optval, &optlen);
+	      rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_USER_MSS,
+			     (void *) optval, &optlen);
 	      break;
 	    case TCP_KEEPIDLE:
-	      func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_KEEPIDLE]";
-	      if (LDP_DEBUG > 1)
-		clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-			      "sid %u (0x%x)",
-			      getpid (), fd, fd, func_str, sid, sid);
-	      rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_KEEPIDLE,
-					(void *) optval, &optlen);
+	      rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_KEEPIDLE,
+			     (void *) optval, &optlen);
 	      break;
 	    case TCP_KEEPINTVL:
-	      func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_KEEPINTVL]";
-	      if (LDP_DEBUG > 1)
-		clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-			      "sid %u (0x%x), SOL_TCP",
-			      getpid (), fd, fd, func_str, sid, sid);
-	      rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_KEEPINTVL,
-					(void *) optval, &optlen);
+	      rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_KEEPINTVL,
+			     (void *) optval, &optlen);
 	      break;
 	    default:
-	      if (LDP_DEBUG > 1)
-		clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
-			      "sid %u (0x%x), SOL_TCP, "
-			      "optname %d unsupported!",
-			      getpid (), fd, fd, func_str, sid, sid, optname);
+	      LDBG (0, "ERROR: fd %d: setsockopt() SOL_TCP: vlsh %u"
+		    "optname %d unsupported!", fd, vlsh, optname);
 	      break;
 	    }
 	  break;
@@ -2616,20 +1840,12 @@
 	  switch (optname)
 	    {
 	    case IPV6_V6ONLY:
-	      func_str = "vppcom_session_attr[SOL_IPV6,SET_V6ONLY]";
-	      if (LDP_DEBUG > 1)
-		clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-			      "sid %u (0x%x)",
-			      getpid (), fd, fd, func_str, sid, sid);
-	      rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_V6ONLY,
-					(void *) optval, &optlen);
+	      rv = vls_attr (vlsh, VPPCOM_ATTR_SET_V6ONLY,
+			     (void *) optval, &optlen);
 	      break;
 	    default:
-	      if (LDP_DEBUG > 1)
-		clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
-			      "sid %u (0x%x), SOL_IPV6, "
-			      "optname %d unsupported!",
-			      getpid (), fd, fd, func_str, sid, sid, optname);
+	      LDBG (0, "ERROR: fd %d: setsockopt SOL_IPV6: vlsh %u"
+		    "optname %d unsupported!", fd, vlsh, optname);
 	      break;
 	    }
 	  break;
@@ -2637,38 +1853,20 @@
 	  switch (optname)
 	    {
 	    case SO_KEEPALIVE:
-	      func_str = "vppcom_session_attr[SOL_SOCKET,SET_KEEPALIVE]";
-	      if (LDP_DEBUG > 1)
-		clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-			      "sid %u (0x%x)",
-			      getpid (), fd, fd, func_str, sid, sid);
-	      rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_KEEPALIVE,
-					(void *) optval, &optlen);
+	      rv = vls_attr (vlsh, VPPCOM_ATTR_SET_KEEPALIVE,
+			     (void *) optval, &optlen);
 	      break;
 	    case SO_REUSEADDR:
-	      func_str = "vppcom_session_attr[SOL_SOCKET,SET_REUSEADDR]";
-	      if (LDP_DEBUG > 1)
-		clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-			      "sid %u (0x%x)",
-			      getpid (), fd, fd, func_str, sid, sid);
-	      rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_REUSEADDR,
-					(void *) optval, &optlen);
+	      rv = vls_attr (vlsh, VPPCOM_ATTR_SET_REUSEADDR,
+			     (void *) optval, &optlen);
 	      break;
 	    case SO_BROADCAST:
-	      func_str = "vppcom_session_attr[SOL_SOCKET,SET_BROADCAST]";
-	      if (LDP_DEBUG > 1)
-		clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
-			      "sid %u (0x%x)",
-			      getpid (), fd, fd, func_str, sid, sid);
-	      rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_BROADCAST,
-					(void *) optval, &optlen);
+	      rv = vls_attr (vlsh, VPPCOM_ATTR_SET_BROADCAST,
+			     (void *) optval, &optlen);
 	      break;
 	    default:
-	      if (LDP_DEBUG > 1)
-		clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
-			      "sid %u (0x%x), SOL_SOCKET, "
-			      "optname %d unsupported!",
-			      getpid (), fd, fd, func_str, sid, sid, optname);
+	      LDBG (0, "ERROR: fd %d: setsockopt SOL_SOCKET: vlsh %u "
+		    "optname %d unsupported!", fd, vlsh, optname);
 	      break;
 	    }
 	  break;
@@ -2684,50 +1882,27 @@
     }
   else
     {
-      func_str = "libc_setsockopt";
-
-      if (LDP_DEBUG > 1)
-	clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): level %d, "
-		      "optname %d, optval %p, optlen %d",
-		      getpid (), fd, fd, func_str, level, optname,
-		      optval, optlen);
-
       rv = libc_setsockopt (fd, level, optname, optval, optlen);
     }
 
-  if (LDP_DEBUG > 1)
-    {
-      if (rv < 0)
-	{
-	  int errno_val = errno;
-	  perror (func_str);
-	  clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
-			"rv %d, errno = %d", getpid (), fd, fd,
-			func_str, rv, errno_val);
-	  errno = errno_val;
-	}
-      else
-	clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
-		      getpid (), fd, fd, rv, rv);
-    }
   return rv;
 }
 
 int
 listen (int fd, int n)
 {
+  vls_handle_t vlsh;
   int rv;
-  u32 sid = ldp_sh_from_fd (fd);
 
   if ((errno = -ldp_init ()))
     return -1;
 
-  if (sid != INVALID_SESSION_ID)
+  vlsh = ldp_fd_to_vlsh (fd);
+  if (vlsh != VLS_INVALID_HANDLE)
     {
-      LDBG (0, "fd %d (0x%x): calling vppcom_session_listen():"
-	    " sid %u (0x%x), n %d", fd, fd, sid, sid, n);
+      LDBG (0, "fd %d: calling vls_listen: vlsh %u, n %d", fd, vlsh, n);
 
-      rv = vppcom_session_listen (sid, n);
+      rv = vls_listen (vlsh, n);
       if (rv != VPPCOM_OK)
 	{
 	  errno = -rv;
@@ -2736,12 +1911,11 @@
     }
   else
     {
-      LDBG (0, "fd %d (0x%x): calling libc_listen(): n %d", fd, fd, n);
-
+      LDBG (0, "fd %d: calling libc_listen(): n %d", fd, n);
       rv = libc_listen (fd, n);
     }
 
-  LDBG (1, "fd %d (0x%x): returning %d (0x%x)", fd, fd, rv, rv);
+  LDBG (1, "fd %d: returning %d", fd, rv);
   return rv;
 }
 
@@ -2749,29 +1923,27 @@
 ldp_accept4 (int listen_fd, __SOCKADDR_ARG addr,
 	     socklen_t * __restrict addr_len, int flags)
 {
+  vls_handle_t listen_vlsh, accept_vlsh;
   int rv;
-  u32 listen_sh;
-  int accept_sh;
 
   if ((errno = -ldp_init ()))
     return -1;
 
-  listen_sh = ldp_sh_from_fd (listen_fd);
-  if (listen_sh != INVALID_SESSION_ID)
+  listen_vlsh = ldp_fd_to_vlsh (listen_fd);
+  if (listen_vlsh != VLS_INVALID_HANDLE)
     {
       vppcom_endpt_t ep;
       u8 src_addr[sizeof (struct sockaddr_in6)];
       memset (&ep, 0, sizeof (ep));
       ep.ip = src_addr;
 
-      LDBG (0, "listen fd %d (0x%x): calling vppcom_session_accept:"
-	    " listen sid %u (0x%x), ep %p, flags 0x%x", listen_fd,
-	    listen_fd, listen_sh, listen_sh, ep, flags);
+      LDBG (0, "listen fd %d: calling vppcom_session_accept: listen sid %u,"
+	    " ep %p, flags 0x%x", listen_fd, listen_vlsh, ep, flags);
 
-      accept_sh = vppcom_session_accept (listen_sh, &ep, flags);
-      if (accept_sh < 0)
+      accept_vlsh = vls_accept (listen_vlsh, &ep, flags);
+      if (accept_vlsh < 0)
 	{
-	  errno = -accept_sh;
+	  errno = -accept_vlsh;
 	  rv = -1;
 	}
       else
@@ -2779,33 +1951,25 @@
 	  rv = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
 	  if (rv != VPPCOM_OK)
 	    {
-	      (void) vppcom_session_close ((u32) accept_sh);
+	      (void) vls_close (accept_vlsh);
 	      errno = -rv;
 	      rv = -1;
 	    }
 	  else
 	    {
-	      rv = ldp_fd_alloc ((u32) accept_sh);
-	      if (rv < 0)
-		{
-		  (void) vppcom_session_close ((u32) accept_sh);
-		  errno = -rv;
-		  rv = -1;
-		}
+	      rv = ldp_vlsh_to_fd (accept_vlsh);
 	    }
 	}
     }
   else
     {
-      LDBG (0, "listen fd %d (0x%x): calling libc_accept4(): "
-	    "addr %p, addr_len %p, flags 0x%x", listen_fd,
-	    listen_fd, addr, addr_len, flags);
+      LDBG (0, "listen fd %d: calling libc_accept4(): addr %p, addr_len %p,"
+	    " flags 0x%x", listen_fd, addr, addr_len, flags);
 
       rv = libc_accept4 (listen_fd, addr, addr_len, flags);
     }
 
-  LDBG (1, "listen fd %d (0x%x): returning %d (0x%x)", listen_fd, listen_fd,
-	rv, rv);
+  LDBG (1, "listen fd %d: accept returning %d", listen_fd, rv);
 
   return rv;
 }
@@ -2826,39 +1990,36 @@
 int
 shutdown (int fd, int how)
 {
-  int rv = 0;
+  vls_handle_t vlsh;
+  int rv = 0, flags;
+  u32 flags_len = sizeof (flags);
 
   if ((errno = -ldp_init ()))
     return -1;
 
-  if (ldp_fd_is_sh (fd))
+  vlsh = ldp_fd_to_vlsh (fd);
+  if (vlsh != VLS_INVALID_HANDLE)
     {
-      u32 fd_index = fd - ldp->sh_bit_val;
-      ldp_fd_entry_t *fde;
+      LDBG (0, "called shutdown: fd %u vlsh %u how %d", fd, vlsh, how);
 
-      fde = ldp_fd_entry_lock (fd_index);
-      if (!fde)
+      if (vls_attr (vlsh, VPPCOM_ATTR_SET_SHUT, &how, &flags_len))
 	{
-	  errno = ENOTCONN;
+	  close (fd);
 	  return -1;
 	}
 
-      if (how == SHUT_RD)
-	fde->flags |= LDP_F_SHUT_RD;
-      else if (how == SHUT_WR)
-	fde->flags |= LDP_F_SHUT_WR;
-      else if (how == SHUT_RDWR)
-	fde->flags |= (LDP_F_SHUT_RD | LDP_F_SHUT_WR);
+      if (vls_attr (vlsh, VPPCOM_ATTR_GET_SHUT, &flags, &flags_len))
+	{
+	  close (fd);
+	  return -1;
+	}
 
-      if ((fde->flags & LDP_F_SHUT_RD) && (fde->flags & LDP_F_SHUT_WR))
+      if (flags == SHUT_RDWR)
 	rv = close (fd);
-
-      ldp_fd_entry_unlock (fde);
-      LDBG (0, "fd %d (0x%x): calling vcl shutdown: how %d", fd, fd, how);
     }
   else
     {
-      LDBG (1, "fd %d (0x%x): calling libc_shutdown: how %d", fd, fd, how);
+      LDBG (0, "fd %d: calling libc_shutdown: how %d", fd, how);
       rv = libc_shutdown (fd, how);
     }
 
@@ -2869,7 +2030,7 @@
 epoll_create1 (int flags)
 {
   ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
-  const char *func_str;
+  vls_handle_t vlsh;
   int rv;
 
   if ((errno = -ldp_init ()))
@@ -2883,34 +2044,18 @@
       LDBG (0, "created vcl epfd %u", rv);
       return rv;
     }
-  func_str = "vppcom_epoll_create";
 
-  LDBG (1, "calling %s()", func_str);
-
-  rv = vppcom_epoll_create ();
-
-  if (PREDICT_FALSE (rv < 0))
+  vlsh = vls_epoll_create ();
+  if (PREDICT_FALSE (vlsh == VLS_INVALID_HANDLE))
     {
-      errno = -rv;
+      errno = -vlsh;
       rv = -1;
     }
   else
-    rv = ldp_fd_alloc ((u32) rv);
-
-  if (LDP_DEBUG > 1)
     {
-      if (rv < 0)
-	{
-	  int errno_val = errno;
-	  perror (func_str);
-	  clib_warning ("LDP<%d>: ERROR: %s() failed! "
-			"rv %d, errno = %d",
-			getpid (), func_str, rv, errno_val);
-	  errno = errno_val;
-	}
-      else
-	clib_warning ("LDP<%d>: returning epfd %d (0x%x)", getpid (), rv, rv);
+      rv = ldp_vlsh_to_fd (vlsh);
     }
+  LDBG (0, "epoll_create epfd %u vlsh %u", rv, vlsh);
   return rv;
 }
 
@@ -2923,43 +2068,38 @@
 int
 epoll_ctl (int epfd, int op, int fd, struct epoll_event *event)
 {
-  u32 vep_idx = ldp_sh_from_fd (epfd), sid;
-  const char *func_str;
+  vls_handle_t vep_vlsh, vlsh;
   int rv;
 
   if ((errno = -ldp_init ()))
     return -1;
 
-  if (PREDICT_FALSE (vep_idx == INVALID_SESSION_ID))
+  vep_vlsh = ldp_fd_to_vlsh (epfd);
+  if (PREDICT_FALSE (vep_vlsh == VLS_INVALID_HANDLE))
     {
       /* The LDP epoll_create1 always creates VCL epfd's.
        * The app should never have a kernel base epoll fd unless it
        * was acquired outside of the LD_PRELOAD process context.
        * In any case, if we get one, punt it to libc_epoll_ctl.
        */
-      func_str = "libc_epoll_ctl";
-
-      LDBG (1, "epfd %d (0x%x): calling %s(): op %d, fd %d (0x%x),"
-	    " event %p", epfd, epfd, func_str, op, fd, fd, event);
+      LDBG (1, "epfd %d: calling libc_epoll_ctl: op %d, fd %d"
+	    " event %p", epfd, op, fd, event);
 
       rv = libc_epoll_ctl (epfd, op, fd, event);
       goto done;
     }
 
-  sid = ldp_sh_from_fd (fd);
+  vlsh = ldp_fd_to_vlsh (fd);
 
-  LDBG (0, "epfd %d (0x%x), vep_idx %d (0x%x), sid %d (0x%x)",
-	epfd, epfd, vep_idx, vep_idx, sid, sid);
+  LDBG (0, "epfd %d ep_vlsh %d, fd %u vlsh %d, op %u", epfd, vep_vlsh, fd,
+	vlsh, op);
 
-  if (sid != INVALID_SESSION_ID)
+  if (vlsh != VLS_INVALID_HANDLE)
     {
-      func_str = "vppcom_epoll_ctl";
+      LDBG (1, "epfd %d: calling vls_epoll_ctl: ep_vlsh %d op %d, vlsh %u,"
+	    " event %p", epfd, vep_vlsh, vlsh, event);
 
-      LDBG (1, "epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
-	    " op %d, sid %u (0x%x), event %p", epfd, epfd,
-	    func_str, vep_idx, vep_idx, sid, sid, event);
-
-      rv = vppcom_epoll_ctl (vep_idx, op, sid, event);
+      rv = vls_epoll_ctl (vep_vlsh, op, vlsh, event);
       if (rv != VPPCOM_OK)
 	{
 	  errno = -rv;
@@ -2971,20 +2111,11 @@
       int libc_epfd;
       u32 size = sizeof (epfd);
 
-      func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
-      libc_epfd = vppcom_session_attr (vep_idx, VPPCOM_ATTR_GET_LIBC_EPFD, 0,
-				       0);
-      LDBG (1, "epfd %d (0x%x), vep_idx %d (0x%x): %s() "
-	    "returned libc_epfd %d (0x%x)", epfd, epfd,
-	    vep_idx, vep_idx, func_str, libc_epfd, libc_epfd);
-
+      libc_epfd = vls_attr (vep_vlsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
       if (!libc_epfd)
 	{
-	  func_str = "libc_epoll_create1";
-
-	  LDBG (1, "epfd %d (0x%x), vep_idx %d (0x%x): "
-		"calling %s(): EPOLL_CLOEXEC", epfd, epfd,
-		vep_idx, vep_idx, func_str);
+	  LDBG (1, "epfd %d, vep_vlsh %d calling libc_epoll_create1: "
+		"EPOLL_CLOEXEC", epfd, vep_vlsh);
 
 	  libc_epfd = libc_epoll_create1 (EPOLL_CLOEXEC);
 	  if (libc_epfd < 0)
@@ -2993,14 +2124,8 @@
 	      goto done;
 	    }
 
-	  func_str = "vppcom_session_attr[SET_LIBC_EPFD]";
-	  LDBG (1, "epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
-		" VPPCOM_ATTR_SET_LIBC_EPFD, libc_epfd %d (0x%x), size %d",
-		epfd, epfd, func_str, vep_idx, vep_idx, libc_epfd,
-		libc_epfd, size);
-
-	  rv = vppcom_session_attr (vep_idx, VPPCOM_ATTR_SET_LIBC_EPFD,
-				    &libc_epfd, &size);
+	  rv = vls_attr (vep_vlsh, VPPCOM_ATTR_SET_LIBC_EPFD, &libc_epfd,
+			 &size);
 	  if (rv < 0)
 	    {
 	      errno = -rv;
@@ -3015,31 +2140,13 @@
 	  goto done;
 	}
 
-      func_str = "libc_epoll_ctl";
-
-      LDBG (1, "epfd %d (0x%x): calling %s(): libc_epfd %d (0x%x), "
-	    "op %d, fd %d (0x%x), event %p", epfd, epfd, func_str,
-	    libc_epfd, libc_epfd, op, fd, fd, event);
+      LDBG (1, "epfd %d: calling libc_epoll_ctl: libc_epfd %d, op %d, fd %d,"
+	    " event %p", epfd, libc_epfd, op, fd, event);
 
       rv = libc_epoll_ctl (libc_epfd, op, fd, event);
     }
 
 done:
-  if (LDP_DEBUG > 1)
-    {
-      if (rv < 0)
-	{
-	  int errno_val = errno;
-	  perror (func_str);
-	  clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
-			"rv %d, errno = %d", getpid (), fd, fd,
-			func_str, rv, errno_val);
-	  errno = errno_val;
-	}
-      else
-	clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
-		      getpid (), fd, fd, rv, rv);
-    }
   return rv;
 }
 
@@ -3049,8 +2156,8 @@
 {
   ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
   double time_to_wait = (double) 0, time_out, now = 0;
-  u32 vep_idx = ldp_sh_from_fd (epfd);
   int libc_epfd, rv = 0;
+  vls_handle_t ep_vlsh;
 
   if ((errno = -ldp_init ()))
     return -1;
@@ -3064,10 +2171,10 @@
   if (epfd == ldpw->vcl_mq_epfd)
     return libc_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
 
-  if (PREDICT_FALSE (vep_idx == INVALID_SESSION_ID))
+  ep_vlsh = ldp_fd_to_vlsh (epfd);
+  if (PREDICT_FALSE (ep_vlsh == VLS_INVALID_HANDLE))
     {
-      LDBG (0, "epfd %d (0x%x): bad vep_idx %d (0x%x)!", epfd, epfd, vep_idx,
-	    vep_idx);
+      LDBG (0, "epfd %d: bad ep_vlsh %d!", epfd, ep_vlsh);
       errno = EBADFD;
       return -1;
     }
@@ -3075,7 +2182,7 @@
   time_to_wait = ((timeout >= 0) ? (double) timeout / 1000 : 0);
   time_out = clib_time_now (&ldpw->clib_time) + time_to_wait;
 
-  libc_epfd = vppcom_session_attr (vep_idx, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
+  libc_epfd = vls_attr (ep_vlsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
   if (PREDICT_FALSE (libc_epfd < 0))
     {
       errno = -libc_epfd;
@@ -3083,19 +2190,15 @@
       goto done;
     }
 
-  LDBG (2, "epfd %d (0x%x): vep_idx %d (0x%x), libc_epfd %d (0x%x), "
-	"events %p, maxevents %d, timeout %d, sigmask %p: time_to_wait %.02f",
-	epfd, epfd, vep_idx, vep_idx, libc_epfd, libc_epfd, events,
-	maxevents, timeout, sigmask, time_to_wait, time_out);
+  LDBG (2, "epfd %d: vep_idx %d, libc_epfd %d, events %p, maxevents %d, "
+	"timeout %d, sigmask %p: time_to_wait %.02f", epfd, ep_vlsh,
+	libc_epfd, events, maxevents, timeout, sigmask, time_to_wait,
+	time_out);
   do
     {
       if (!ldpw->epoll_wait_vcl)
 	{
-	  LDBG (3, "epfd %d (0x%x): calling vcl_epoll_wait: vep_idx %d (0x%x)"
-		" events %p, maxevents %d", epfd, epfd, vep_idx, vep_idx,
-		events, maxevents);
-
-	  rv = vppcom_epoll_wait (vep_idx, events, maxevents, 0);
+	  rv = vls_epoll_wait (ep_vlsh, events, maxevents, 0);
 	  if (rv > 0)
 	    {
 	      ldpw->epoll_wait_vcl = 1;
@@ -3113,10 +2216,6 @@
 
       if (libc_epfd > 0)
 	{
-	  LDBG (3, "epfd %d (0x%x): calling libc_epoll_wait: libc_epfd %d "
-		"(0x%x), events %p, maxevents %d, sigmask %p", epfd, epfd,
-		libc_epfd, libc_epfd, events, maxevents, sigmask);
-
 	  rv = libc_epoll_pwait (libc_epfd, events, maxevents, 0, sigmask);
 	  if (rv != 0)
 	    goto done;
@@ -3148,9 +2247,8 @@
 poll (struct pollfd *fds, nfds_t nfds, int timeout)
 {
   ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
-  const char *func_str = __func__;
   int rv, i, n_revents = 0;
-  u32 sid;
+  vls_handle_t vlsh;
   vcl_poll_t *vp;
   double wait_for_time;
 
@@ -3166,16 +2264,13 @@
       if (fds[i].fd < 0)
 	continue;
 
-      LDBG (3, "fds[%d] fd %d (0x%0x) events = 0x%x revents = 0x%x",
-	    i, fds[i].fd, fds[i].fd, fds[i].events, fds[i].revents);
-
-      sid = ldp_sh_from_fd (fds[i].fd);
-      if (sid != INVALID_SESSION_ID)
+      vlsh = ldp_fd_to_vlsh (fds[i].fd);
+      if (vlsh != VLS_INVALID_HANDLE)
 	{
 	  fds[i].fd = -fds[i].fd;
 	  vec_add2 (ldpw->vcl_poll, vp, 1);
 	  vp->fds_ndx = i;
-	  vp->sid = sid;
+	  vp->sh = vlsh_to_sh (vlsh);
 	  vp->events = fds[i].events;
 #ifdef __USE_XOPEN2K
 	  if (fds[i].events & POLLRDNORM)
@@ -3196,13 +2291,6 @@
     {
       if (vec_len (ldpw->vcl_poll))
 	{
-	  func_str = "vppcom_poll";
-
-	  LDBG (3, "calling %s(): vcl_poll %p, n_sids %u (0x%x): "
-		"n_libc_fds %u", func_str, ldpw->vcl_poll,
-		vec_len (ldpw->vcl_poll), vec_len (ldpw->vcl_poll),
-		vec_len (ldpw->libc_poll));
-
 	  rv = vppcom_poll (ldpw->vcl_poll, vec_len (ldpw->vcl_poll), 0);
 	  if (rv < 0)
 	    {
@@ -3216,11 +2304,6 @@
 
       if (vec_len (ldpw->libc_poll))
 	{
-	  func_str = "libc_poll";
-
-	  LDBG (3, "calling %s(): fds %p, nfds %u: n_sids %u",
-		fds, nfds, vec_len (ldpw->vcl_poll));
-
 	  rv = libc_poll (ldpw->libc_poll, vec_len (ldpw->libc_poll), 0);
 	  if (rv < 0)
 	    goto done;
@@ -3261,37 +2344,6 @@
   vec_reset_length (ldpw->libc_poll_idxs);
   vec_reset_length (ldpw->libc_poll);
 
-  if (LDP_DEBUG > 3)
-    {
-      if (rv < 0)
-	{
-	  int errno_val = errno;
-	  perror (func_str);
-	  clib_warning ("LDP<%d>: ERROR: %s() failed! "
-			"rv %d, errno = %d", getpid (),
-			func_str, rv, errno_val);
-	  errno = errno_val;
-	}
-      else
-	{
-	  clib_warning ("LDP<%d>: returning %d (0x%x): n_sids %u, "
-			"n_libc_fds %d", getpid (), rv, rv,
-			vec_len (ldpw->vcl_poll), vec_len (ldpw->libc_poll));
-
-	  for (i = 0; i < nfds; i++)
-	    {
-	      if (fds[i].fd >= 0)
-		{
-		  if (LDP_DEBUG > 3)
-		    clib_warning ("LDP<%d>: fds[%d].fd %d (0x%0x), "
-				  ".events = 0x%x, .revents = 0x%x",
-				  getpid (), i, fds[i].fd, fds[i].fd,
-				  fds[i].events, fds[i].revents);
-		}
-	    }
-	}
-    }
-
   return rv;
 }
 
diff --git a/src/vcl/vcl_locked.c b/src/vcl/vcl_locked.c
new file mode 100644
index 0000000..6254bad
--- /dev/null
+++ b/src/vcl/vcl_locked.c
@@ -0,0 +1,457 @@
+/*
+ * Copyright (c) 2019 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 <vcl/vcl_locked.h>
+#include <vcl/vcl_private.h>
+
+typedef struct vcl_locked_session_
+{
+  u32 session_index;
+  u32 worker_index;
+  u32 vls_index;
+  u32 flags;
+  clib_spinlock_t lock;
+} vcl_locked_session_t;
+
+typedef struct vcl_main_
+{
+  vcl_locked_session_t *vls_pool;
+  clib_rwlock_t vls_table_lock;
+  uword *session_index_to_vlsh_table;
+} vls_main_t;
+
+vls_main_t vls_main;
+vls_main_t *vlsm = &vls_main;
+
+static inline void
+vls_table_rlock (void)
+{
+  clib_rwlock_reader_lock (&vlsm->vls_table_lock);
+}
+
+static inline void
+vls_table_runlock (void)
+{
+  clib_rwlock_reader_unlock (&vlsm->vls_table_lock);
+}
+
+static inline void
+vls_table_wlock (void)
+{
+  clib_rwlock_writer_lock (&vlsm->vls_table_lock);
+}
+
+static inline void
+vls_table_wunlock (void)
+{
+  clib_rwlock_writer_unlock (&vlsm->vls_table_lock);
+}
+
+static inline vcl_session_handle_t
+vls_to_sh (vcl_locked_session_t * vls)
+{
+  return vppcom_session_handle (vls->session_index);
+}
+
+static inline vcl_session_handle_t
+vls_to_sh_tu (vcl_locked_session_t * vls)
+{
+  vcl_session_handle_t sh;
+  sh = vls_to_sh (vls);
+  vls_table_runlock ();
+  return sh;
+}
+
+static vls_handle_t
+vls_alloc (vcl_session_handle_t sh)
+{
+  vcl_locked_session_t *vls;
+
+  vls_table_wlock ();
+  pool_get (vlsm->vls_pool, vls);
+  vls->session_index = vppcom_session_index (sh);
+  vls->worker_index = vppcom_session_worker (sh);
+  vls->vls_index = vls - vlsm->vls_pool;
+  hash_set (vlsm->session_index_to_vlsh_table, vls->session_index,
+	    vls->vls_index);
+  clib_spinlock_init (&vls->lock);
+  vls_table_wunlock ();
+  return vls->vls_index;
+}
+
+static vcl_locked_session_t *
+vls_get (vls_handle_t vlsh)
+{
+  if (pool_is_free_index (vlsm->vls_pool, vlsh))
+    return 0;
+  return pool_elt_at_index (vlsm->vls_pool, vlsh);
+}
+
+static void
+vls_free (vcl_locked_session_t * fde)
+{
+  ASSERT (fde != 0);
+  hash_unset (vlsm->session_index_to_vlsh_table, fde->session_index);
+  clib_spinlock_free (&fde->lock);
+  pool_put (vlsm->vls_pool, fde);
+}
+
+static vcl_locked_session_t *
+vls_get_and_lock (vls_handle_t vlsh)
+{
+  vcl_locked_session_t *vls;
+  if (pool_is_free_index (vlsm->vls_pool, vlsh))
+    return 0;
+  vls = pool_elt_at_index (vlsm->vls_pool, vlsh);
+  clib_spinlock_lock (&vls->lock);
+  return vls;
+}
+
+static vcl_locked_session_t *
+vls_get_w_dlock (vls_handle_t vlsh)
+{
+  vcl_locked_session_t *vls;
+  vls_table_rlock ();
+  vls = vls_get_and_lock (vlsh);
+  if (!vls)
+    vls_table_runlock ();
+  return vls;
+}
+
+static inline void
+vls_unlock (vcl_locked_session_t * vls)
+{
+  clib_spinlock_unlock (&vls->lock);
+}
+
+static inline void
+vls_get_and_unlock (vls_handle_t vlsh)
+{
+  vcl_locked_session_t *vls;
+  vls_table_rlock ();
+  vls = vls_get (vlsh);
+  vls_unlock (vls);
+  vls_table_runlock ();
+}
+
+static inline void
+vls_dunlock (vcl_locked_session_t * vls)
+{
+  vls_unlock (vls);
+  vls_table_runlock ();
+}
+
+static void
+vls_get_and_free (vls_handle_t vlsh)
+{
+  vcl_locked_session_t *vls;
+
+  vls_table_wlock ();
+  vls = vls_get (vlsh);
+  vls_free (vls);
+  vls_table_wunlock ();
+}
+
+int
+vls_write (vls_handle_t vlsh, void *buf, size_t nbytes)
+{
+  vcl_locked_session_t *vls;
+  int rv;
+
+  if (!(vls = vls_get_w_dlock (vlsh)))
+    return VPPCOM_EBADFD;
+  rv = vppcom_session_write (vls_to_sh_tu (vls), buf, nbytes);
+  vls_get_and_unlock (vlsh);
+  return rv;
+}
+
+int
+vls_write_msg (vls_handle_t vlsh, void *buf, size_t nbytes)
+{
+  vcl_locked_session_t *vls;
+  int rv;
+
+  if (!(vls = vls_get_w_dlock (vlsh)))
+    return VPPCOM_EBADFD;
+  rv = vppcom_session_write_msg (vls_to_sh_tu (vls), buf, nbytes);
+  vls_get_and_unlock (vlsh);
+  return rv;
+}
+
+int
+vls_sendto (vls_handle_t vlsh, void *buf, int buflen, int flags,
+	    vppcom_endpt_t * ep)
+{
+  vcl_locked_session_t *vls;
+  int rv;
+
+  if (!(vls = vls_get_w_dlock (vlsh)))
+    return VPPCOM_EBADFD;
+  rv = vppcom_session_sendto (vls_to_sh_tu (vls), buf, buflen, flags, ep);
+  vls_get_and_unlock (vlsh);
+  return rv;
+}
+
+ssize_t
+vls_read (vls_handle_t vlsh, void *buf, size_t nbytes)
+{
+  vcl_locked_session_t *vls;
+  int rv;
+
+  if (!(vls = vls_get_w_dlock (vlsh)))
+    return VPPCOM_EBADFD;
+  rv = vppcom_session_read (vls_to_sh_tu (vls), buf, nbytes);
+  vls_get_and_unlock (vlsh);
+  return rv;
+}
+
+ssize_t
+vls_recvfrom (vls_handle_t vlsh, void *buffer, uint32_t buflen, int flags,
+	      vppcom_endpt_t * ep)
+{
+  vcl_locked_session_t *vls;
+  int rv;
+
+  if (!(vls = vls_get_w_dlock (vlsh)))
+    return VPPCOM_EBADFD;
+  rv = vppcom_session_recvfrom (vls_to_sh_tu (vls), buffer, buflen, flags,
+				ep);
+  vls_get_and_unlock (vlsh);
+  return rv;
+}
+
+int
+vls_attr (vls_handle_t vlsh, uint32_t op, void *buffer, uint32_t * buflen)
+{
+  vcl_locked_session_t *vls;
+  int rv;
+
+  if (!(vls = vls_get_w_dlock (vlsh)))
+    return VPPCOM_EBADFD;
+  rv = vppcom_session_attr (vls_to_sh_tu (vls), op, buffer, buflen);
+  vls_get_and_unlock (vlsh);
+  return rv;
+}
+
+int
+vls_bind (vls_handle_t vlsh, vppcom_endpt_t * ep)
+{
+  vcl_locked_session_t *vls;
+  int rv;
+
+  if (!(vls = vls_get_w_dlock (vlsh)))
+    return VPPCOM_EBADFD;
+  rv = vppcom_session_bind (vls_to_sh_tu (vls), ep);
+  vls_get_and_unlock (vlsh);
+  return rv;
+}
+
+int
+vls_listen (vls_handle_t vlsh, int q_len)
+{
+  vcl_locked_session_t *vls;
+  int rv;
+
+  if (!(vls = vls_get_w_dlock (vlsh)))
+    return VPPCOM_EBADFD;
+  rv = vppcom_session_listen (vls_to_sh_tu (vls), q_len);
+  vls_get_and_unlock (vlsh);
+  return rv;
+}
+
+int
+vls_connect (vls_handle_t vlsh, vppcom_endpt_t * server_ep)
+{
+  vcl_locked_session_t *vls;
+  int rv;
+
+  if (!(vls = vls_get_w_dlock (vlsh)))
+    return VPPCOM_EBADFD;
+  rv = vppcom_session_connect (vls_to_sh_tu (vls), server_ep);
+  vls_get_and_unlock (vlsh);
+  return rv;
+}
+
+vls_handle_t
+vls_accept (vls_handle_t listener_vlsh, vppcom_endpt_t * ep, int flags)
+{
+  vls_handle_t accepted_vlsh;
+  vcl_locked_session_t *vls;
+  int sh;
+
+  if (!(vls = vls_get_w_dlock (listener_vlsh)))
+    return VPPCOM_EBADFD;
+  sh = vppcom_session_accept (vls_to_sh_tu (vls), ep, flags);
+  vls_get_and_unlock (listener_vlsh);
+  if (sh < 0)
+    return sh;
+  accepted_vlsh = vls_alloc (sh);
+  if (PREDICT_FALSE (accepted_vlsh == VLS_INVALID_HANDLE))
+    vppcom_session_close (sh);
+  return accepted_vlsh;
+}
+
+vls_handle_t
+vls_create (uint8_t proto, uint8_t is_nonblocking)
+{
+  vcl_session_handle_t sh;
+  vls_handle_t vlsh;
+
+  sh = vppcom_session_create (proto, is_nonblocking);
+  if (sh == INVALID_SESSION_ID)
+    return VLS_INVALID_HANDLE;
+
+  vlsh = vls_alloc (sh);
+  if (PREDICT_FALSE (vlsh == VLS_INVALID_HANDLE))
+    vppcom_session_close (sh);
+
+  return vlsh;
+}
+
+int
+vls_close (vls_handle_t vlsh)
+{
+  vcl_locked_session_t *vls;
+  vcl_session_handle_t sh;
+  int rv, refcnt;
+
+  if (!(vls = vls_get_w_dlock (vlsh)))
+    return VPPCOM_EBADFD;
+
+  sh = vls_to_sh (vls);
+  refcnt = vppcom_session_attr (sh, VPPCOM_ATTR_GET_REFCNT, 0, 0);
+  if ((rv = vppcom_session_close (sh)))
+    {
+      vls_dunlock (vls);
+      return rv;
+    }
+
+  vls_dunlock (vls);
+  if (refcnt <= 1)
+    vls_get_and_free (vlsh);
+  return rv;
+}
+
+vls_handle_t
+vls_epoll_create (void)
+{
+  vcl_session_handle_t sh;
+  vls_handle_t vlsh;
+
+  sh = vppcom_epoll_create ();
+  if (sh == INVALID_SESSION_ID)
+    return VLS_INVALID_HANDLE;
+
+  vlsh = vls_alloc (sh);
+  if (vlsh == VLS_INVALID_HANDLE)
+    vppcom_session_close (sh);
+
+  return vlsh;
+}
+
+int
+vls_epoll_ctl (vls_handle_t ep_vlsh, int op, vls_handle_t vlsh,
+	       struct epoll_event *event)
+{
+  vcl_locked_session_t *ep_vls, *vls;
+  vcl_session_handle_t ep_sh, sh;
+  int rv;
+
+  vls_table_rlock ();
+  ep_vls = vls_get_and_lock (ep_vlsh);
+  vls = vls_get_and_lock (vlsh);
+  ep_sh = vls_to_sh (ep_vls);
+  sh = vls_to_sh (vls);
+  vls_table_runlock ();
+
+  rv = vppcom_epoll_ctl (ep_sh, op, sh, event);
+
+  vls_table_rlock ();
+  ep_vls = vls_get (ep_vlsh);
+  vls = vls_get (vlsh);
+  vls_unlock (vls);
+  vls_unlock (ep_vls);
+  vls_table_runlock ();
+  return rv;
+}
+
+int
+vls_epoll_wait (vls_handle_t ep_vlsh, struct epoll_event *events,
+		int maxevents, double wait_for_time)
+{
+  vcl_locked_session_t *vls;
+  int rv;
+
+  if (!(vls = vls_get_w_dlock (ep_vlsh)))
+    return VPPCOM_EBADFD;
+  rv = vppcom_epoll_wait (vls_to_sh_tu (vls), events, maxevents,
+			  wait_for_time);
+  vls_get_and_unlock (ep_vlsh);
+  return rv;
+}
+
+vcl_session_handle_t
+vlsh_to_sh (vls_handle_t vlsh)
+{
+  vcl_locked_session_t *vls;
+  int rv;
+
+  vls = vls_get_w_dlock (vlsh);
+  if (!vls)
+    return INVALID_SESSION_ID;
+  rv = vls_to_sh (vls);
+  vls_dunlock (vls);
+  return rv;
+}
+
+vcl_session_handle_t
+vlsh_to_session_index (vls_handle_t vlsh)
+{
+  vcl_session_handle_t sh;
+  sh = vlsh_to_sh (vlsh);
+  return vppcom_session_index (sh);
+}
+
+vls_handle_t
+vls_session_index_to_vlsh (uint32_t session_index)
+{
+  vls_handle_t vlsh;
+  uword *vlshp;
+
+  vls_table_rlock ();
+  vlshp = hash_get (vlsm->session_index_to_vlsh_table, session_index);
+  vlsh = vlshp ? *vlshp : VLS_INVALID_HANDLE;
+  vls_table_runlock ();
+
+  return vlsh;
+}
+
+int
+vls_app_create (char *app_name)
+{
+  int rv;
+  if ((rv = vppcom_app_create (app_name)))
+    return rv;
+  clib_rwlock_init (&vlsm->vls_table_lock);
+  return VPPCOM_OK;
+}
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/src/vcl/vcl_locked.h b/src/vcl/vcl_locked.h
new file mode 100644
index 0000000..4f40f43
--- /dev/null
+++ b/src/vcl/vcl_locked.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2019 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.
+ *
+ * VCL Locked Sessions
+ */
+
+#ifndef SRC_VCL_VCL_LOCKED_H_
+#define SRC_VCL_VCL_LOCKED_H_
+
+#include <vcl/vppcom.h>
+
+#define VLS_INVALID_HANDLE ((int)-1)
+
+typedef int vls_handle_t;
+
+vls_handle_t vls_create (uint8_t proto, uint8_t is_nonblocking);
+int vls_close (vls_handle_t vlsh);
+int vls_bind (vls_handle_t vlsh, vppcom_endpt_t * ep);
+int vls_listen (vls_handle_t vlsh, int q_len);
+int vls_connect (vls_handle_t vlsh, vppcom_endpt_t * server_ep);
+vls_handle_t vls_accept (vls_handle_t vlsh, vppcom_endpt_t * ep, int flags);
+ssize_t vls_read (vls_handle_t vlsh, void *buf, size_t nbytes);
+ssize_t vls_recvfrom (vls_handle_t vlsh, void *buffer, uint32_t buflen,
+		      int flags, vppcom_endpt_t * ep);
+int vls_write (vls_handle_t vlsh, void *buf, size_t nbytes);
+int vls_write_msg (vls_handle_t vlsh, void *buf, size_t nbytes);
+int vls_sendto (vls_handle_t vlsh, void *buf, int buflen, int flags,
+		vppcom_endpt_t * ep);
+int vls_attr (vls_handle_t vlsh, uint32_t op, void *buffer,
+	      uint32_t * buflen);
+vls_handle_t vls_epoll_create (void);
+int vls_epoll_ctl (vls_handle_t ep_vlsh, int op, vls_handle_t vlsh,
+		   struct epoll_event *event);
+int vls_epoll_wait (vls_handle_t ep_vlsh, struct epoll_event *events,
+		    int maxevents, double wait_for_time);
+vcl_session_handle_t vlsh_to_sh (vls_handle_t vlsh);
+vcl_session_handle_t vlsh_to_session_index (vls_handle_t vlsh);
+vls_handle_t vls_session_index_to_vlsh (uint32_t session_index);
+int vls_app_create (char *app_name);
+
+#endif /* SRC_VCL_VCL_LOCKED_H_ */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/src/vcl/vcl_private.h b/src/vcl/vcl_private.h
index 2ae4b72..0315a62 100644
--- a/src/vcl/vcl_private.h
+++ b/src/vcl/vcl_private.h
@@ -125,6 +125,8 @@
   VCL_SESS_ATTR_TCP_NODELAY,	// SOL_TCP,TCP_NODELAY
   VCL_SESS_ATTR_TCP_KEEPIDLE,	// SOL_TCP,TCP_KEEPIDLE
   VCL_SESS_ATTR_TCP_KEEPINTVL,	// SOL_TCP,TCP_KEEPINTVL
+  VCL_SESS_ATTR_SHUT_RD,
+  VCL_SESS_ATTR_SHUT_WR,
   VCL_SESS_ATTR_MAX
 } vppcom_session_attr_t;
 
@@ -583,6 +585,7 @@
 
 u8 *format_api_error (u8 * s, va_list * args);
 
+void vls_init ();
 #endif /* SRC_VCL_VCL_PRIVATE_H_ */
 
 /*
diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c
index 6a1bf1c..2c2cb2c 100644
--- a/src/vcl/vppcom.c
+++ b/src/vcl/vppcom.c
@@ -22,7 +22,6 @@
 
 __thread uword __vcl_worker_index = ~0;
 
-
 static int
 vcl_wait_for_segment (u64 segment_handle)
 {
@@ -1594,9 +1593,9 @@
 
   if (PREDICT_FALSE (session->session_state & CLIENT_STATE_OPEN))
     {
-      VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: session already "
+      VDBG (0, "session handle %u [0x%llx]: session already "
 	    "connected to %s %U port %d proto %s, state 0x%x (%s)",
-	    getpid (), session->vpp_handle, session_handle,
+	    session_handle, session->vpp_handle,
 	    session->transport.is_ip4 ? "IPv4" : "IPv6",
 	    format_ip46_address,
 	    &session->transport.rmt_ip, session->transport.is_ip4 ?
@@ -1616,9 +1615,8 @@
 		      sizeof (ip6_address_t));
   session->transport.rmt_port = server_ep->port;
 
-  VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: connecting to server %s %U "
-	"port %d proto %s",
-	getpid (), session->vpp_handle, session_handle,
+  VDBG (0, "session handle %u [0x%llx]: connecting to server %s %U "
+	"port %d proto %s", session_handle, session->vpp_handle,
 	session->transport.is_ip4 ? "IPv4" : "IPv6",
 	format_ip46_address,
 	&session->transport.rmt_ip, session->transport.is_ip4 ?
@@ -2993,7 +2991,7 @@
   vcl_worker_t *wrk = vcl_worker_get_current ();
   vcl_session_t *session;
   int rv = VPPCOM_OK;
-  u32 *flags = buffer;
+  u32 *flags = buffer, tmp_flags = 0;
   vppcom_endpt_t *ep = buffer;
 
   session = vcl_session_get_w_handle (wrk, session_handle);
@@ -3004,8 +3002,7 @@
     {
     case VPPCOM_ATTR_GET_NREAD:
       rv = vppcom_session_read_ready (session);
-      VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_NREAD: sid %u, nread = %d",
-	    getpid (), rv);
+      VDBG (2, "VPPCOM_ATTR_GET_NREAD: sid %u, nread = %d", rv);
       break;
 
     case VPPCOM_ATTR_GET_NWRITE:
@@ -3514,6 +3511,26 @@
       rv = vcl_session_get_refcnt (session);
       break;
 
+    case VPPCOM_ATTR_SET_SHUT:
+      if (*flags == SHUT_RD || *flags == SHUT_RDWR)
+	VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_SHUT_RD);
+      if (*flags == SHUT_WR || *flags == SHUT_RDWR)
+	VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_SHUT_WR);
+      break;
+
+    case VPPCOM_ATTR_GET_SHUT:
+      if (VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_SHUT_RD))
+	tmp_flags = 1;
+      if (VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_SHUT_WR))
+	tmp_flags |= 2;
+      if (tmp_flags == 1)
+	*(int *) buffer = SHUT_RD;
+      else if (tmp_flags == 2)
+	*(int *) buffer = SHUT_WR;
+      else if (tmp_flags == 3)
+	*(int *) buffer = SHUT_RDWR;
+      *buflen = sizeof (int);
+      break;
     default:
       rv = VPPCOM_EINVAL;
       break;
@@ -3620,7 +3637,7 @@
 
       for (i = 0; i < n_sids; i++)
 	{
-	  session = vcl_session_get (wrk, vp[i].sid);
+	  session = vcl_session_get (wrk, vp[i].sh);
 	  if (!session)
 	    {
 	      vp[i].revents = POLLHUP;
@@ -3695,7 +3712,7 @@
       for (i = 0; i < n_sids; i++)
 	{
 	  clib_warning ("VCL<%d>: vp[%d].sid %d (0x%x), .events 0x%x, "
-			".revents 0x%x", getpid (), i, vp[i].sid, vp[i].sid,
+			".revents 0x%x", getpid (), i, vp[i].sh, vp[i].sh,
 			vp[i].events, vp[i].revents);
 	}
     }
diff --git a/src/vcl/vppcom.h b/src/vcl/vppcom.h
index f2fca09..513947a 100644
--- a/src/vcl/vppcom.h
+++ b/src/vcl/vppcom.h
@@ -31,7 +31,7 @@
 /*
  * VPPCOM Public API Definitions, Enums, and Data Structures
  */
-#define INVALID_SESSION_ID                  	(~0)
+#define INVALID_SESSION_ID                  	((u32)~0)
 #define VPPCOM_CONF_DEFAULT                  	"/etc/vpp/vcl.conf"
 #define VPPCOM_ENV_CONF                      	"VCL_CONFIG"
 #define VPPCOM_ENV_DEBUG                     	"VCL_DEBUG"
@@ -153,12 +153,14 @@
   VPPCOM_ATTR_GET_TCP_USER_MSS,
   VPPCOM_ATTR_SET_TCP_USER_MSS,
   VPPCOM_ATTR_GET_REFCNT,
+  VPPCOM_ATTR_SET_SHUT,
+  VPPCOM_ATTR_GET_SHUT,
 } vppcom_attr_op_t;
 
 typedef struct _vcl_poll
 {
   uint32_t fds_ndx;
-  uint32_t sid;
+  vcl_session_handle_t sh;
   short events;
   short revents;
 } vcl_poll_t;