LD_PRELOAD: stateless LDP
[vpp.git] / src / vcl / vcom_socket.c
diff --git a/src/vcl/vcom_socket.c b/src/vcl/vcom_socket.c
deleted file mode 100644 (file)
index 13e008c..0000000
+++ /dev/null
@@ -1,3733 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <unistd.h>
-#include <stdio.h>
-#include <sys/uio.h>
-#include <limits.h>
-#define __need_IOV_MAX
-#include <bits/stdio_lim.h>
-#include <netinet/tcp.h>
-
-#include <vppinfra/types.h>
-#include <vppinfra/time.h>
-#include <vppinfra/hash.h>
-#include <vppinfra/pool.h>
-
-#include <vcl/vcom_socket.h>
-#include <vcl/vcom_socket_wrapper.h>
-#include <vcl/vcom.h>
-
-#include <vcl/vppcom.h>
-
-#ifndef IOV_MAX
-#define IOV_MAX __IOV_MAX
-#endif
-
-/*
- * VCOM_SOCKET Private definitions and functions.
- */
-
-typedef struct vcom_socket_main_t_
-{
-  u8 init;
-  clib_time_t clib_time;
-  pid_t my_pid;
-
-  /* vcom_socket pool */
-  vcom_socket_t *vsockets;
-
-  /* Hash table for socketidx to fd mapping */
-  uword *sockidx_by_fd;
-
-  /* vcom_epoll pool */
-  vcom_epoll_t *vepolls;
-
-  /* Hash table for epollidx to epfd mapping */
-  uword *epollidx_by_epfd;
-
-  /* common epitem poll for all epfd */
-  /* TBD: epitem poll per epfd */
-  /* vcom_epitem pool */
-  vcom_epitem_t *vepitems;
-
-  /* Hash table for epitemidx to epfdfd mapping */
-  uword *epitemidx_by_epfdfd;
-
-  /* Hash table - key:epfd, value:vec of epitemidx */
-  uword *epitemidxs_by_epfd;
-  /* Hash table - key:fd, value:vec of epitemidx */
-  uword *epitemidxs_by_fd;
-
-  u8 *io_buffer;
-} vcom_socket_main_t;
-
-vcom_socket_main_t vcom_socket_main;
-
-
-static int
-vcom_socket_open_socket (int domain, int type, int protocol)
-{
-  int rv = -1;
-
-  /* handle domains implemented by vpp */
-  switch (domain)
-    {
-    case AF_INET:
-    case AF_INET6:
-      /* get socket type and
-       * handle the socket types supported by vpp */
-      switch (type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
-       {
-       case SOCK_STREAM:
-       case SOCK_DGRAM:
-         /* the type argument serves a second purpose,
-          * in addition to specifying a socket type,
-          * it may include the bitwise OR of any of
-          * SOCK_NONBLOCK and SOCK_CLOEXEC, to modify
-          * the behavior of socket. */
-         rv = libc_socket (domain, type, protocol);
-         if (rv == -1)
-           rv = -errno;
-         break;
-
-       default:
-         break;
-       }
-
-      break;
-
-    default:
-      break;
-    }
-
-  return rv;
-}
-
-static int
-vcom_socket_open_epoll (int flags)
-{
-  int rv = -1;
-
-  if (flags < 0)
-    {
-      return -EINVAL;
-    }
-  if (flags && (flags & ~EPOLL_CLOEXEC))
-    {
-      return -EINVAL;
-    }
-
-  /* flags can be either zero or EPOLL_CLOEXEC */
-  rv = libc_epoll_create1 (flags);
-  if (rv == -1)
-    rv = -errno;
-
-  return rv;
-}
-
-static int
-vcom_socket_close_socket (int fd)
-{
-  int rv;
-
-  rv = libc_close (fd);
-  if (rv == -1)
-    rv = -errno;
-
-  return rv;
-}
-
-static int
-vcom_socket_close_epoll (int epfd)
-{
-  int rv;
-
-  rv = libc_close (epfd);
-  if (rv == -1)
-    rv = -errno;
-
-  return rv;
-}
-
-/*
- * Public API functions
- */
-
-
-int
-vcom_socket_is_vcom_fd (int fd)
-{
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  uword *p;
-  vcom_socket_t *vsock;
-
-  p = hash_get (vsm->sockidx_by_fd, fd);
-
-  if (p)
-    {
-      vsock = pool_elt_at_index (vsm->vsockets, p[0]);
-      if (vsock && vsock->type == SOCKET_TYPE_VPPCOM_BOUND)
-       return 1;
-    }
-  return 0;
-}
-
-int
-vcom_socket_is_vcom_epfd (int epfd)
-{
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  uword *p;
-  vcom_epoll_t *vepoll;
-
-  p = hash_get (vsm->epollidx_by_epfd, epfd);
-
-  if (p)
-    {
-      vepoll = pool_elt_at_index (vsm->vepolls, p[0]);
-      if (vepoll && vepoll->type == EPOLL_TYPE_VPPCOM_BOUND)
-       return 1;
-    }
-  return 0;
-}
-
-static inline int
-vcom_socket_get_sid (int fd)
-{
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  uword *p;
-  vcom_socket_t *vsock;
-
-  p = hash_get (vsm->sockidx_by_fd, fd);
-
-  if (p)
-    {
-      vsock = pool_elt_at_index (vsm->vsockets, p[0]);
-      if (vsock && vsock->type == SOCKET_TYPE_VPPCOM_BOUND)
-       return vsock->sid;
-    }
-  return INVALID_SESSION_ID;
-}
-
-static inline int
-vcom_socket_get_vep_idx (int epfd)
-{
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  uword *p;
-  vcom_epoll_t *vepoll;
-
-  p = hash_get (vsm->epollidx_by_epfd, epfd);
-
-  if (p)
-    {
-      vepoll = pool_elt_at_index (vsm->vepolls, p[0]);
-      if (vepoll && vepoll->type == EPOLL_TYPE_VPPCOM_BOUND)
-       return vepoll->vep_idx;
-    }
-  return INVALID_VEP_IDX;
-}
-
-static inline int
-vcom_socket_get_sid_and_vsock (int fd, vcom_socket_t ** vsockp)
-{
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  uword *p;
-  vcom_socket_t *vsock;
-
-  p = hash_get (vsm->sockidx_by_fd, fd);
-
-  if (p)
-    {
-      vsock = pool_elt_at_index (vsm->vsockets, p[0]);
-      if (vsock && vsock->type == SOCKET_TYPE_VPPCOM_BOUND)
-       {
-         *vsockp = vsock;
-         return vsock->sid;
-       }
-    }
-  return INVALID_SESSION_ID;
-}
-
-static inline int
-vcom_socket_get_vep_idx_and_vepoll (int epfd, vcom_epoll_t ** vepollp)
-{
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  uword *p;
-  vcom_epoll_t *vepoll;
-
-  p = hash_get (vsm->epollidx_by_epfd, epfd);
-
-  if (p)
-    {
-      vepoll = pool_elt_at_index (vsm->vepolls, p[0]);
-      if (vepoll && vepoll->type == EPOLL_TYPE_VPPCOM_BOUND)
-       {
-         *vepollp = vepoll;
-         return vepoll->vep_idx;
-       }
-    }
-  return INVALID_VEP_IDX;
-}
-
-
-static int
-vcom_socket_close_vepoll (int epfd)
-{
-  int rv = -1;
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  uword *p;
-  vcom_epoll_t *vepoll;
-
-  p = hash_get (vsm->epollidx_by_epfd, epfd);
-  if (!p)
-    return -EBADF;
-
-  vepoll = pool_elt_at_index (vsm->vepolls, p[0]);
-  if (!vepoll)
-    return -EBADF;
-
-  if (vepoll->type != EPOLL_TYPE_VPPCOM_BOUND)
-    return -EINVAL;
-
-  if (vepoll->count)
-    {
-      if (!vepoll->close)
-       {
-         vepoll->close = 1;
-         return 0;
-       }
-      else
-       {
-         return -EBADF;
-       }
-    }
-
-  /* count is zero */
-  rv = vppcom_session_close (vepoll->vep_idx);
-  rv = vcom_socket_close_epoll (vepoll->epfd);
-
-  vepoll_init (vepoll);
-  hash_unset (vsm->epollidx_by_epfd, epfd);
-  pool_put (vsm->vepolls, vepoll);
-
-  return rv;
-}
-
-static int
-vcom_socket_close_vsock (int fd)
-{
-  int rv = -1;
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  uword *p;
-  vcom_socket_t *vsock;
-
-  vcom_epitem_t *vepitem;
-
-  i32 *vepitemidxs = 0;
-  i32 *vepitemidxs_var = 0;
-
-  p = hash_get (vsm->sockidx_by_fd, fd);
-  if (!p)
-    return -EBADF;
-
-  vsock = pool_elt_at_index (vsm->vsockets, p[0]);
-  if (!vsock)
-    return -ENOTSOCK;
-
-  if (vsock->type != SOCKET_TYPE_VPPCOM_BOUND)
-    return -EINVAL;
-
-  rv = vppcom_session_close (vsock->sid);
-  rv = vcom_socket_close_socket (vsock->fd);
-
-  vsocket_init (vsock);
-  hash_unset (vsm->sockidx_by_fd, fd);
-  pool_put (vsm->vsockets, vsock);
-
-  /*
-   * NOTE:
-   * Before calling close(), user should remove
-   * this fd from the epoll-set of all epoll instances,
-   * otherwise resource(epitems) leaks ensues.
-   */
-
-  /*
-   * 00. close all epoll instances that are marked as "close"
-   *     of which this fd is the "last" remaining member.
-   * 01. epitems associated with this fd are intentionally
-   *     not removed, see NOTE: above.
-   * */
-
-  /* does this fd participate in epoll */
-  p = hash_get (vsm->epitemidxs_by_fd, fd);
-  if (p)
-    {
-      vepitemidxs = *(i32 **) p;
-      vec_foreach (vepitemidxs_var, vepitemidxs)
-      {
-       vepitem = pool_elt_at_index (vsm->vepitems, vepitemidxs_var[0]);
-       if (vepitem && vepitem->fd == fd &&
-           vepitem->type == FD_TYPE_VCOM_SOCKET)
-         {
-           i32 vep_idx;
-           vcom_epoll_t *vepoll;
-           if ((vep_idx =
-                vcom_socket_get_vep_idx_and_vepoll (vepitem->epfd,
-                                                    &vepoll)) !=
-               INVALID_VEP_IDX)
-             {
-               if (vepoll->close)
-                 {
-                   if (vepoll->count == 1)
-                     {
-                       /*
-                        * force count to zero and
-                        * close this epoll instance
-                        * */
-                       vepoll->count = 0;
-                       vcom_socket_close_vepoll (vepoll->epfd);
-                     }
-                   else
-                     {
-                       vepoll->count -= 1;
-                     }
-                 }
-             }
-         }
-
-      }
-    }
-
-  return rv;
-}
-
-int
-vcom_socket_close (int __fd)
-{
-  int rv;
-
-  if (vcom_socket_is_vcom_fd (__fd))
-    {
-      rv = vcom_socket_close_vsock (__fd);
-    }
-  else if (vcom_socket_is_vcom_epfd (__fd))
-    {
-      rv = vcom_socket_close_vepoll (__fd);
-    }
-  else
-    {
-      rv = -EBADF;
-    }
-
-  return rv;
-}
-
-ssize_t
-vcom_socket_read (int __fd, void *__buf, size_t __nbytes)
-{
-  int rv = -1;
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  uword *p;
-  vcom_socket_t *vsock;
-
-  p = hash_get (vsm->sockidx_by_fd, __fd);
-  if (!p)
-    return -EBADF;
-
-  vsock = pool_elt_at_index (vsm->vsockets, p[0]);
-  if (!vsock)
-    return -ENOTSOCK;
-
-  if (vsock->type != SOCKET_TYPE_VPPCOM_BOUND)
-    return -EINVAL;
-
-  if (!__buf)
-    {
-      return -EINVAL;
-    }
-
-  rv = vcom_fcntl (__fd, F_GETFL, 0);
-  if (rv < 0)
-    {
-      return rv;
-
-    }
-
-  /* is blocking */
-  if (!(rv & O_NONBLOCK))
-    {
-      do
-       {
-         rv = vppcom_session_read (vsock->sid, __buf, __nbytes);
-       }
-      /* coverity[CONSTANT_EXPRESSION_RESULT] */
-      while (rv == -EAGAIN || rv == -EWOULDBLOCK);
-      return rv;
-    }
-  /* The file descriptor refers to a socket and has been
-   * marked nonblocking(O_NONBLOCK) and the read would
-   * block.
-   * */
-  /* is non blocking */
-  rv = vppcom_session_read (vsock->sid, __buf, __nbytes);
-  return rv;
-}
-
-ssize_t
-vcom_socket_readv (int __fd, const struct iovec * __iov, int __iovcnt)
-{
-  int rv;
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  uword *p;
-  vcom_socket_t *vsock;
-  ssize_t total = 0, len = 0;
-  int i;
-
-  p = hash_get (vsm->sockidx_by_fd, __fd);
-  if (!p)
-    return -EBADF;
-
-  vsock = pool_elt_at_index (vsm->vsockets, p[0]);
-  if (!vsock)
-    return -ENOTSOCK;
-
-  if (vsock->type != SOCKET_TYPE_VPPCOM_BOUND)
-    return -EINVAL;
-
-  if (__iov == 0 || __iovcnt == 0 || __iovcnt > IOV_MAX)
-    return -EINVAL;
-
-  /* Sanity check */
-  for (i = 0; i < __iovcnt; ++i)
-    {
-      if (SSIZE_MAX - len < __iov[i].iov_len)
-       return -EINVAL;
-      len += __iov[i].iov_len;
-    }
-
-  rv = vcom_fcntl (__fd, F_GETFL, 0);
-  if (rv < 0)
-    {
-      return rv;
-    }
-
-  /* is blocking */
-  if (!(rv & O_NONBLOCK))
-    {
-      do
-       {
-         for (i = 0; i < __iovcnt; ++i)
-           {
-             rv = vppcom_session_read (vsock->sid, __iov[i].iov_base,
-                                       __iov[i].iov_len);
-             if (rv < 0)
-               break;
-             else
-               {
-                 total += rv;
-                 if (rv < __iov[i].iov_len)
-                   /* Read less than buffer provided, no point to continue */
-                   break;
-               }
-           }
-       }
-      /* coverity[CONSTANT_EXPRESSION_RESULT] */
-      while ((rv == -EAGAIN || rv == -EWOULDBLOCK) && total == 0);
-      return total;
-    }
-
-  /* is non blocking */
-  for (i = 0; i < __iovcnt; ++i)
-    {
-      rv = vppcom_session_read (vsock->sid, __iov[i].iov_base,
-                               __iov[i].iov_len);
-      if (rv < 0)
-       {
-         if (total > 0)
-           break;
-         else
-           {
-             errno = rv;
-             return rv;
-           }
-       }
-      else
-       {
-         total += rv;
-         if (rv < __iov[i].iov_len)
-           /* Read less than buffer provided, no point to continue */
-           break;
-       }
-    }
-  return total;
-}
-
-ssize_t
-vcom_socket_write (int __fd, const void *__buf, size_t __n)
-{
-  int rv = -1;
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  uword *p;
-  vcom_socket_t *vsock;
-
-  if (!__buf)
-    {
-      return -EINVAL;
-    }
-
-  p = hash_get (vsm->sockidx_by_fd, __fd);
-  if (!p)
-    return -EBADF;
-
-  vsock = pool_elt_at_index (vsm->vsockets, p[0]);
-  if (!vsock)
-    return -ENOTSOCK;
-
-  if (vsock->type != SOCKET_TYPE_VPPCOM_BOUND)
-    return -EINVAL;
-
-  rv = vppcom_session_write (vsock->sid, (void *) __buf, __n);
-  return rv;
-}
-
-ssize_t
-vcom_socket_writev (int __fd, const struct iovec * __iov, int __iovcnt)
-{
-  int rv = -1;
-  ssize_t total = 0;
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  uword *p;
-  vcom_socket_t *vsock;
-  int i;
-
-  p = hash_get (vsm->sockidx_by_fd, __fd);
-  if (!p)
-    return -EBADF;
-
-  vsock = pool_elt_at_index (vsm->vsockets, p[0]);
-  if (!vsock)
-    return -ENOTSOCK;
-
-  if (vsock->type != SOCKET_TYPE_VPPCOM_BOUND)
-    return -EINVAL;
-
-  if (__iov == 0 || __iovcnt == 0 || __iovcnt > IOV_MAX)
-    return -EINVAL;
-
-  for (i = 0; i < __iovcnt; ++i)
-    {
-      rv = vppcom_session_write (vsock->sid, __iov[i].iov_base,
-                                __iov[i].iov_len);
-      if (rv < 0)
-       {
-         if (total > 0)
-           break;
-         else
-           return rv;
-       }
-      else
-       total += rv;
-    }
-  return total;
-}
-
-/*
- * RETURN:  0 - invalid cmd
- *          1 - cmd not handled by vcom and vppcom
- *          2 - cmd handled by vcom socket resource
- *          3 - cmd handled by vppcom
- * */
-/* TBD: incomplete list of cmd */
-static int
-vcom_socket_check_fcntl_cmd (int __cmd)
-{
-  switch (__cmd)
-    {
-      /*cmd not handled by vcom and vppcom */
-      /* Fallthrough */
-    case F_DUPFD:
-    case F_DUPFD_CLOEXEC:
-      return 1;
-
-      /* cmd handled by vcom socket resource */
-      /* Fallthrough */
-    case F_GETFD:
-    case F_SETFD:
-    case F_GETLK:
-    case F_SETLK:
-    case F_SETLKW:
-    case F_GETOWN:
-    case F_SETOWN:
-      return 2;
-
-      /* cmd handled by vcom and vppcom */
-    case F_SETFL:
-    case F_GETFL:
-      return 3;
-
-      /* cmd not handled by vcom and vppcom */
-    default:
-      return 1;
-    }
-  return 0;
-}
-
-static inline int
-vcom_session_fcntl_va (int __sid, int __cmd, va_list __ap)
-{
-  int flags = va_arg (__ap, int);
-  int rv = -EOPNOTSUPP;
-  uint32_t size;
-
-  size = sizeof (flags);
-  if (__cmd == F_SETFL)
-    {
-      rv = vppcom_session_attr (__sid, VPPCOM_ATTR_SET_FLAGS, &flags, &size);
-    }
-  else if (__cmd == F_GETFL)
-    {
-      rv = vppcom_session_attr (__sid, VPPCOM_ATTR_GET_FLAGS, &flags, &size);
-      if (rv == VPPCOM_OK)
-       rv = flags;
-    }
-
-  return rv;
-}
-
-int
-vcom_socket_fcntl_va (int __fd, int __cmd, va_list __ap)
-{
-  int rv = -EBADF;
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  uword *p;
-  vcom_socket_t *vsock;
-
-  p = hash_get (vsm->sockidx_by_fd, __fd);
-  if (!p)
-    return -EBADF;
-
-  vsock = pool_elt_at_index (vsm->vsockets, p[0]);
-  if (!vsock)
-    return -ENOTSOCK;
-
-  if (vsock->type != SOCKET_TYPE_VPPCOM_BOUND)
-    return -EINVAL;
-
-  switch (vcom_socket_check_fcntl_cmd (__cmd))
-    {
-      /* invalid cmd */
-    case 0:
-      rv = -EBADF;
-      break;
-      /*cmd not handled by vcom and vppcom */
-    case 1:
-      rv = libc_vfcntl (vsock->fd, __cmd, __ap);
-      break;
-      /* cmd handled by vcom socket resource */
-    case 2:
-      rv = libc_vfcntl (vsock->fd, __cmd, __ap);
-      break;
-      /* cmd handled by vppcom */
-    case 3:
-      rv = vcom_session_fcntl_va (vsock->sid, __cmd, __ap);
-      break;
-
-    default:
-      rv = -EINVAL;
-      break;
-    }
-
-  return rv;
-}
-
-/*
- * RETURN:  0 - invalid cmd
- *          1 - cmd not handled by vcom and vppcom
- *          2 - cmd handled by vcom socket resource
- *          3 - cmd handled by vppcom
- */
-static int
-vcom_socket_check_ioctl_cmd (unsigned long int __cmd)
-{
-  int rc;
-
-  switch (__cmd)
-    {
-      /* cmd handled by vppcom */
-    case FIONREAD:
-      rc = 3;
-      break;
-
-      /* cmd not handled by vcom and vppcom */
-    default:
-      rc = 1;
-      break;
-    }
-  return rc;
-}
-
-static inline int
-vcom_session_ioctl_va (int __sid, int __cmd, va_list __ap)
-{
-  int rv;
-
-  switch (__cmd)
-    {
-    case FIONREAD:
-      rv = vppcom_session_attr (__sid, VPPCOM_ATTR_GET_NREAD, 0, 0);
-      break;
-
-    case FIONBIO:
-      {
-       u32 flags = va_arg (__ap, int) ? O_NONBLOCK : 0;
-       u32 len = sizeof (flags);
-       rv = vppcom_session_attr (__sid, VPPCOM_ATTR_SET_FLAGS, &flags, &len);
-      }
-      break;
-
-    default:
-      rv = -EOPNOTSUPP;
-      break;
-    }
-  return rv;
-}
-
-int
-vcom_socket_ioctl_va (int __fd, unsigned long int __cmd, va_list __ap)
-{
-  int rv = -EBADF;
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  uword *p;
-  vcom_socket_t *vsock;
-
-  p = hash_get (vsm->sockidx_by_fd, __fd);
-  if (!p)
-    return -EBADF;
-
-  vsock = pool_elt_at_index (vsm->vsockets, p[0]);
-  if (!vsock)
-    return -ENOTSOCK;
-
-  if (vsock->type != SOCKET_TYPE_VPPCOM_BOUND)
-    return -EINVAL;
-
-  switch (vcom_socket_check_ioctl_cmd (__cmd))
-    {
-      /* Not supported cmd */
-    case 0:
-      rv = -EOPNOTSUPP;
-      break;
-
-      /* cmd not handled by vcom and vppcom */
-    case 1:
-      rv = libc_vioctl (vsock->fd, __cmd, __ap);
-      break;
-
-      /* cmd handled by vcom socket resource */
-    case 2:
-      rv = libc_vioctl (vsock->fd, __cmd, __ap);
-      break;
-
-      /* cmd handled by vppcom */
-    case 3:
-      rv = vcom_session_ioctl_va (vsock->sid, __cmd, __ap);
-      break;
-
-    default:
-      rv = -EINVAL;
-      break;
-    }
-
-  return rv;
-}
-
-static inline int
-vcom_socket_fds_2_sid_fds (
-                           /* dest */
-                           int *vcom_nsid_fds,
-                           fd_set * __restrict vcom_rd_sid_fds,
-                           fd_set * __restrict vcom_wr_sid_fds,
-                           fd_set * __restrict vcom_ex_sid_fds,
-                           /* src */
-                           int vcom_nfds,
-                           fd_set * __restrict vcom_readfds,
-                           fd_set * __restrict vcom_writefds,
-                           fd_set * __restrict vcom_exceptfds)
-{
-  int rv = 0;
-  int fd;
-  int sid;
-  /* invalid max_sid is -1 */
-  int max_sid = -1;
-  int nsid = 0;
-
-  /*
-   *  set sid in sid sets corresponding to fd's in fd sets
-   *  compute nsid and vcom_nsid_fds from sid sets
-   */
-
-  for (fd = 0; fd < vcom_nfds; fd++)
-    {
-      /*
-       * F fd set, src
-       * S sid set, dest
-       */
-#define _(S,F)                              \
-      if ((F) && (S) && FD_ISSET (fd, (F))) \
-        {                                   \
-          sid = vcom_socket_get_sid (fd);   \
-          if (sid != INVALID_SESSION_ID)    \
-            {                               \
-              FD_SET (sid, (S));            \
-              if (sid > max_sid)            \
-                {                           \
-                  max_sid = sid;            \
-                }                           \
-              ++nsid;                       \
-            }                               \
-          else                              \
-            {                               \
-              rv = -EBADFD;                 \
-              goto done;                    \
-            }                               \
-        }
-
-
-      _(vcom_rd_sid_fds, vcom_readfds);
-      _(vcom_wr_sid_fds, vcom_writefds);
-      _(vcom_ex_sid_fds, vcom_exceptfds);
-#undef _
-    }
-
-  *vcom_nsid_fds = max_sid != -1 ? max_sid + 1 : 0;
-  rv = nsid;
-
-done:
-  return rv;
-}
-
-/*
- * PRE: 00. sid sets were derived from fd sets
- *      01. sid sets were updated with sids that actually changed
- *          status
- *      02. fd sets still has watched fds
- *
- * This function will modify in place fd sets to indicate which fd's
- * actually changed status(inferred from sid sets)
- */
-static inline int
-vcom_socket_sid_fds_2_fds (
-                           /* dest */
-                           int *new_vcom_nfds,
-                           int vcom_nfds,
-                           fd_set * __restrict vcom_readfds,
-                           fd_set * __restrict vcom_writefds,
-                           fd_set * __restrict vcom_exceptfds,
-                           /* src */
-                           int vcom_nsid_fds,
-                           fd_set * __restrict vcom_rd_sid_fds,
-                           fd_set * __restrict vcom_wr_sid_fds,
-                           fd_set * __restrict vcom_ex_sid_fds)
-{
-  int rv = 0;
-  int fd;
-  int sid;
-  /* invalid max_fd is -1 */
-  int max_fd = -1;
-  int nfd = 0;
-
-
-  /*
-   *  modify in place fd sets to indicate which fd's
-   * actually changed status(inferred from sid sets)
-   */
-  for (fd = 0; fd < vcom_nfds; fd++)
-    {
-      /*
-       * F fd set, dest
-       * S sid set, src
-       */
-#define _(S,F)                              \
-      if ((F) && (S) && FD_ISSET (fd, (F))) \
-        {                                   \
-          sid = vcom_socket_get_sid (fd);   \
-          if (sid != INVALID_SESSION_ID)    \
-            {                               \
-              if (!FD_ISSET (sid, (S)))     \
-                {                           \
-                   FD_CLR(fd, (F));         \
-                }                           \
-            }                               \
-          else                              \
-            {                               \
-              rv = -EBADFD;                 \
-              goto done;                    \
-            }                               \
-        }
-
-
-      _(vcom_rd_sid_fds, vcom_readfds);
-      _(vcom_wr_sid_fds, vcom_writefds);
-      _(vcom_ex_sid_fds, vcom_exceptfds);
-#undef _
-    }
-
-  /*
-   *  compute nfd and new_vcom_nfds from fd sets
-   */
-  for (fd = 0; fd < vcom_nfds; fd++)
-    {
-
-#define _(F)                                \
-      if ((F) && FD_ISSET (fd, (F)))        \
-        {                                   \
-          if (fd > max_fd)                  \
-            {                               \
-              max_fd = fd;                  \
-            }                               \
-          ++nfd;                            \
-        }
-
-
-      _(vcom_readfds);
-      _(vcom_writefds);
-      _(vcom_exceptfds);
-#undef _
-
-    }
-
-  *new_vcom_nfds = max_fd != -1 ? max_fd + 1 : 0;
-  rv = nfd;
-
-done:
-  return rv;
-}
-
-/*
- * PRE:
- * vom_socket_select is always called with
- * timeout->tv_sec and timeout->tv_usec set to zero.
- * hence vppcom_select return immediately.
- */
-/*
- * TBD: do{body;} while(timeout conditional); timeout loop
- */
-int
-vcom_socket_select (int vcom_nfds, fd_set * __restrict vcom_readfds,
-                   fd_set * __restrict vcom_writefds,
-                   fd_set * __restrict vcom_exceptfds,
-                   struct timeval *__restrict timeout)
-{
-  static unsigned long vcom_nsid_fds = 0;
-  int vcom_nsid = 0;
-  int rv = -EBADF;
-
-  int new_vcom_nfds = 0;
-  int new_vcom_nfd = 0;
-
-  /* vcom sid fds */
-  fd_set vcom_rd_sid_fds;
-  fd_set vcom_wr_sid_fds;
-  fd_set vcom_ex_sid_fds;
-
-  /* in seconds eg. 3.123456789 seconds */
-  double time_to_wait = (double) 0;
-
-  /* validate inputs */
-  if (vcom_nfds < 0)
-    {
-      return -EINVAL;
-    }
-
-  /* convert timeval timeout to double time_to_wait */
-  if (timeout)
-    {
-      if (timeout->tv_sec == 0 && timeout->tv_usec == 0)
-       {
-         /* polling: vppcom_select returns immediately */
-         time_to_wait = (double) 0;
-       }
-      else
-       {
-         /*TBD:  use timeval api */
-         time_to_wait = (double) timeout->tv_sec +
-           (double) timeout->tv_usec / (double) 1000000 +
-           (double) (timeout->tv_usec % 1000000) / (double) 1000000;
-       }
-    }
-  else
-    {
-      /*
-       * no timeout: vppcom_select can block indefinitely
-       * waiting for a file descriptor to become ready
-       * */
-      /* set to a phantom value */
-      time_to_wait = ~0;
-    }
-
-  /* zero the sid_sets */
-  /*
-   * F fd set
-   * S sid set
-   */
-#define _(S,F)                          \
-  if ((F))                              \
-    {                                   \
-      FD_ZERO ((S));                    \
-    }
-
-
-  _(&vcom_rd_sid_fds, vcom_readfds);
-  _(&vcom_wr_sid_fds, vcom_writefds);
-  _(&vcom_ex_sid_fds, vcom_exceptfds);
-#undef _
-
-  if (vcom_nfds == 0)
-    {
-      if (time_to_wait > 0)
-       {
-         if (VCOM_DEBUG > 0)
-           fprintf (stderr,
-                    "[%d] vcom_socket_select called to "
-                    "emulate delay_ns()!\n", getpid ());
-         rv = vppcom_select (0, NULL, NULL, NULL, time_to_wait);
-       }
-      else
-       {
-         fprintf (stderr, "[%d] vcom_socket_select called vcom_nfds = 0 "
-                  "and invalid time_to_wait (%f)!\n",
-                  getpid (), time_to_wait);
-       }
-      return 0;
-    }
-
-  /* populate read, write and except sid_sets */
-  vcom_nsid = vcom_socket_fds_2_sid_fds (
-                                         /* dest */
-                                         vcom_readfds || vcom_writefds
-                                         || vcom_exceptfds ? (int *)
-                                         &vcom_nsid_fds : NULL,
-                                         vcom_readfds ? &vcom_rd_sid_fds :
-                                         NULL,
-                                         vcom_writefds ? &vcom_wr_sid_fds :
-                                         NULL,
-                                         vcom_exceptfds ? &vcom_ex_sid_fds :
-                                         NULL,
-                                         /* src */
-                                         vcom_nfds,
-                                         vcom_readfds,
-                                         vcom_writefds, vcom_exceptfds);
-  if (vcom_nsid < 0)
-    {
-      return vcom_nsid;
-    }
-
-  rv = vppcom_select (vcom_nsid_fds,
-                     vcom_readfds ? (unsigned long *) &vcom_rd_sid_fds :
-                     NULL,
-                     vcom_writefds ? (unsigned long *) &vcom_wr_sid_fds :
-                     NULL,
-                     vcom_exceptfds ? (unsigned long *) &vcom_ex_sid_fds :
-                     NULL, time_to_wait);
-  if (VCOM_DEBUG > 2)
-    fprintf (stderr, "[%d] called vppcom_select(): "
-            "'%04d'='%04d'\n", getpid (), rv, (int) vcom_nsid_fds);
-
-  /* check if any file descriptors changed status */
-  if (rv > 0)
-    {
-      /*
-       * on exit, sets are modified in place to indicate which
-       * file descriptors actually changed status
-       * */
-
-      /*
-       * comply with pre-condition
-       * do not clear vcom fd sets befor calling
-       * vcom_socket_sid_fds_2_fds
-       */
-      new_vcom_nfd = vcom_socket_sid_fds_2_fds (
-                                                /* dest */
-                                                &new_vcom_nfds,
-                                                vcom_nfds,
-                                                vcom_readfds,
-                                                vcom_writefds,
-                                                vcom_exceptfds,
-                                                /* src */
-                                                vcom_nsid_fds,
-                                                vcom_readfds ?
-                                                &vcom_rd_sid_fds : NULL,
-                                                vcom_writefds ?
-                                                &vcom_wr_sid_fds : NULL,
-                                                vcom_exceptfds ?
-                                                &vcom_ex_sid_fds : NULL);
-      if (new_vcom_nfd < 0)
-       {
-         return new_vcom_nfd;
-       }
-      if (new_vcom_nfds < 0)
-       {
-         return -EINVAL;
-       }
-      rv = new_vcom_nfd;
-    }
-  return rv;
-}
-
-
-int
-vcom_socket_socket (int __domain, int __type, int __protocol)
-{
-  int rv = -1;
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  vcom_socket_t *vsock;
-
-  i32 fd;
-  i32 sid;
-  i32 sockidx;
-  u8 is_nonblocking = __type & SOCK_NONBLOCK ? 1 : 0;
-  int type = __type & ~(SOCK_NONBLOCK | SOCK_CLOEXEC);
-
-  fd = vcom_socket_open_socket (__domain, __type, __protocol);
-  if (fd < 0)
-    {
-      rv = fd;
-      goto out;
-    }
-
-  sid = vppcom_session_create (VPPCOM_VRF_DEFAULT,
-                              (type == SOCK_DGRAM) ?
-                              VPPCOM_PROTO_UDP : VPPCOM_PROTO_TCP,
-                              is_nonblocking);
-  if (sid < 0)
-    {
-      rv = sid;
-      goto out_close_socket;
-    }
-
-  pool_get (vsm->vsockets, vsock);
-  vsocket_init (vsock);
-
-  sockidx = vsock - vsm->vsockets;
-  hash_set (vsm->sockidx_by_fd, fd, sockidx);
-
-  vsocket_set (vsock, fd, sid, SOCKET_TYPE_VPPCOM_BOUND);
-  return fd;
-
-out_close_socket:
-  vcom_socket_close_socket (fd);
-out:
-  return rv;
-}
-
-int
-vcom_socket_socketpair (int __domain, int __type, int __protocol,
-                       int __fds[2])
-{
-/* TBD: */
-  return 0;
-}
-
-int
-vcom_socket_bind (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len)
-{
-  int rv = -1;
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  uword *p;
-  vcom_socket_t *vsock;
-
-  vppcom_endpt_t ep;
-
-  p = hash_get (vsm->sockidx_by_fd, __fd);
-  if (!p)
-    return -EBADF;
-
-  vsock = pool_elt_at_index (vsm->vsockets, p[0]);
-  if (!vsock)
-    return -ENOTSOCK;
-
-  if (vsock->type != SOCKET_TYPE_VPPCOM_BOUND)
-    return -EINVAL;
-
-  if (!__addr)
-    {
-      return -EINVAL;
-    }
-
-  ep.vrf = VPPCOM_VRF_DEFAULT;
-  switch (__addr->sa_family)
-    {
-    case AF_INET:
-      if (__len != sizeof (struct sockaddr_in))
-       {
-         return -EINVAL;
-       }
-      ep.is_ip4 = VPPCOM_IS_IP4;
-      ep.ip = (u8 *) & ((const struct sockaddr_in *) __addr)->sin_addr;
-      ep.port = (u16) ((const struct sockaddr_in *) __addr)->sin_port;
-      break;
-
-    case AF_INET6:
-      if (__len != sizeof (struct sockaddr_in6))
-       {
-         return -EINVAL;
-       }
-      ep.is_ip4 = VPPCOM_IS_IP6;
-      ep.ip = (u8 *) & ((const struct sockaddr_in6 *) __addr)->sin6_addr;
-      ep.port = (u16) ((const struct sockaddr_in6 *) __addr)->sin6_port;
-      break;
-
-    default:
-      return -1;
-      break;
-    }
-
-  rv = vppcom_session_bind (vsock->sid, &ep);
-  return rv;
-}
-
-static inline int
-vcom_socket_copy_ep_to_sockaddr (__SOCKADDR_ARG __addr,
-                                socklen_t * __restrict __len,
-                                vppcom_endpt_t * ep)
-{
-  int rv = 0;
-  int sa_len, copy_len;
-
-  __addr->sa_family = (ep->is_ip4 == VPPCOM_IS_IP4) ? AF_INET : AF_INET6;
-  switch (__addr->sa_family)
-    {
-    case AF_INET:
-      ((struct sockaddr_in *) __addr)->sin_port = ep->port;
-      if (*__len > sizeof (struct sockaddr_in))
-       *__len = sizeof (struct sockaddr_in);
-      sa_len = sizeof (struct sockaddr_in) - sizeof (struct in_addr);
-      copy_len = *__len - sa_len;
-      if (copy_len > 0)
-       memcpy (&((struct sockaddr_in *) __addr)->sin_addr, ep->ip, copy_len);
-      break;
-
-    case AF_INET6:
-      ((struct sockaddr_in6 *) __addr)->sin6_port = ep->port;
-      if (*__len > sizeof (struct sockaddr_in6))
-       *__len = sizeof (struct sockaddr_in6);
-      sa_len = sizeof (struct sockaddr_in6) - sizeof (struct in6_addr);
-      copy_len = *__len - sa_len;
-      if (copy_len > 0)
-       memcpy (((struct sockaddr_in6 *) __addr)->sin6_addr.
-               __in6_u.__u6_addr8, ep->ip, copy_len);
-      break;
-
-    default:
-      /* Not possible */
-      rv = -EAFNOSUPPORT;
-      break;
-    }
-
-  return rv;
-}
-
-int
-vcom_socket_getsockname (int __fd, __SOCKADDR_ARG __addr,
-                        socklen_t * __restrict __len)
-{
-  int rv = -1;
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  uword *p;
-  vcom_socket_t *vsock;
-  vppcom_endpt_t ep;
-  u8 addr_buf[sizeof (struct in6_addr)];
-  uint32_t size = sizeof (ep);
-
-  if (!__addr || !__len)
-    return -EFAULT;
-
-  p = hash_get (vsm->sockidx_by_fd, __fd);
-  if (!p)
-    return -EBADF;
-
-  vsock = pool_elt_at_index (vsm->vsockets, p[0]);
-  if (!vsock)
-    return -ENOTSOCK;
-
-  if (vsock->type != SOCKET_TYPE_VPPCOM_BOUND)
-    return -EINVAL;
-
-  ep.ip = addr_buf;
-  rv = vppcom_session_attr (vsock->sid, VPPCOM_ATTR_GET_LCL_ADDR, &ep, &size);
-  if (rv == VPPCOM_OK)
-    rv = vcom_socket_copy_ep_to_sockaddr (__addr, __len, &ep);
-
-  return rv;
-}
-
-int
-vcom_socket_connect (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len)
-{
-  int rv = -1;
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  uword *p;
-  vcom_socket_t *vsock;
-
-  vppcom_endpt_t ep;
-
-  p = hash_get (vsm->sockidx_by_fd, __fd);
-  if (p)
-    {
-      vsock = pool_elt_at_index (vsm->vsockets, p[0]);
-
-      ep.vrf = VPPCOM_VRF_DEFAULT;
-      switch (__addr->sa_family)
-       {
-       case AF_INET:
-         ep.is_ip4 = VPPCOM_IS_IP4;
-         ep.ip =
-           (uint8_t *) & ((const struct sockaddr_in *) __addr)->sin_addr;
-         ep.port =
-           (uint16_t) ((const struct sockaddr_in *) __addr)->sin_port;
-         break;
-
-       case AF_INET6:
-         ep.is_ip4 = VPPCOM_IS_IP6;
-         ep.ip =
-           (uint8_t *) & ((const struct sockaddr_in6 *) __addr)->sin6_addr;
-         ep.port =
-           (uint16_t) ((const struct sockaddr_in6 *) __addr)->sin6_port;
-         break;
-
-       default:
-         return -1;
-         break;
-       }
-
-      rv = vppcom_session_connect (vsock->sid, &ep);
-    }
-  return rv;
-}
-
-static inline int
-vcom_session_getpeername (int sid, vppcom_endpt_t * ep)
-{
-  int rv;
-  uint32_t size = sizeof (*ep);
-
-  rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_PEER_ADDR, ep, &size);
-  return rv;
-}
-
-int
-vcom_socket_getpeername (int __fd, __SOCKADDR_ARG __addr,
-                        socklen_t * __restrict __len)
-{
-  int rv = -1;
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  uword *p;
-  vcom_socket_t *vsock;
-  u8 src_addr[sizeof (struct sockaddr_in6)];
-  vppcom_endpt_t ep;
-
-  p = hash_get (vsm->sockidx_by_fd, __fd);
-  if (!p)
-    return -EBADF;
-
-  vsock = pool_elt_at_index (vsm->vsockets, p[0]);
-  if (!vsock)
-    return -ENOTSOCK;
-
-  if (vsock->type != SOCKET_TYPE_VPPCOM_BOUND)
-    return -EINVAL;
-
-  if (!__addr || !__len)
-    return -EFAULT;
-
-  ep.ip = src_addr;
-  rv = vcom_session_getpeername (vsock->sid, &ep);
-  if (rv == 0)
-    rv = vcom_socket_copy_ep_to_sockaddr (__addr, __len, &ep);
-
-  return rv;
-}
-
-ssize_t
-vcom_socket_send (int __fd, const void *__buf, size_t __n, int __flags)
-{
-  return vcom_socket_sendto (__fd, __buf, __n, __flags, NULL, 0);
-}
-
-/* NOTE: this function is not thread safe or 32-bit friendly */
-ssize_t
-vcom_socket_sendfile (int __out_fd, int __in_fd, off_t * __offset,
-                     size_t __len)
-{
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  uword *p;
-  vcom_socket_t *vsock;
-  size_t n_bytes_left = __len;
-  u32 out_sockidx, out_sid = ~0;
-  size_t bytes_to_read;
-  int nbytes;
-  int rv, errno_val;
-  ssize_t results = 0;
-  u8 eagain = 0;
-
-  if (VCOM_DEBUG > 2)
-    clib_warning ("[%d] __out_fd %d, __in_fd %d, __offset %p, __len %lu",
-                 getpid (), __out_fd, __in_fd, __offset, __len);
-
-  p = hash_get (vsm->sockidx_by_fd, __out_fd);
-  if (!p)
-    {
-      clib_warning ("[%d] ERROR: invalid __out_fd (%d), fd lookup failed!",
-                   getpid (), __len);
-      return -EBADF;
-    }
-  out_sockidx = p[0];
-  vsock = pool_elt_at_index (vsm->vsockets, out_sockidx);
-  if (!vsock)
-    {
-      clib_warning ("[%d] ERROR: invalid __out_fd (%d) / out_sockidx %u, "
-                   "missing vsock pool element!",
-                   getpid (), __len, out_sockidx);
-      return -ENOTSOCK;
-    }
-  out_sid = vsock->sid;
-  if (vsock->type != SOCKET_TYPE_VPPCOM_BOUND)
-    {
-      clib_warning ("[%d] ERROR: __out_fd (%d), socket (sid %u) "
-                   "is not VCL bound!", getpid (), __out_fd, out_sid);
-      return -EINVAL;
-    }
-
-  if (__offset)
-    {
-      off_t offset = lseek (__in_fd, *__offset, SEEK_SET);
-      if (offset == -1)
-       {
-         errno_val = errno;
-         perror ("lseek()");
-         clib_warning ("[%d] ERROR: lseek SEEK_SET failed: "
-                       "in_fd %d, offset %p (%ld), rv %ld, errno %d",
-                       getpid (), __in_fd, __offset, *__offset, offset,
-                       errno_val);
-         return -errno_val;
-       }
-
-      ASSERT (offset == *__offset);
-    }
-
-  do
-    {
-      rv = vppcom_session_attr (out_sid, VPPCOM_ATTR_GET_NWRITE, 0, 0);
-      if (rv < 0)
-       {
-         clib_warning ("[%d] ERROR: vppcom_session_attr (out_sid (%u), "
-                       "VPPCOM_ATTR_GET_NWRITE, 0, 0) returned %d (%s)!",
-                       getpid (), out_sid, rv, vppcom_retval_str (rv));
-         vec_reset_length (vsm->io_buffer);
-         return rv;
-       }
-
-      bytes_to_read = (size_t) rv;
-      if (VCOM_DEBUG > 2)
-       clib_warning ("[%d] results %ld, n_bytes_left %lu, "
-                     "bytes_to_read %lu", getpid (), results,
-                     n_bytes_left, bytes_to_read);
-      if (bytes_to_read == 0)
-       {
-         u32 flags, flags_len = sizeof (flags);
-         rv = vppcom_session_attr (out_sid, VPPCOM_ATTR_GET_FLAGS, &flags,
-                                   &flags_len);
-         ASSERT (rv == VPPCOM_OK);
-
-         if (flags & O_NONBLOCK)
-           {
-             if (!results)
-               {
-                 if (VCOM_DEBUG > 2)
-                   clib_warning ("[%d] EAGAIN", getpid ());
-                 eagain = 1;
-               }
-             goto update_offset;
-           }
-         else
-           continue;
-       }
-      bytes_to_read = clib_min (n_bytes_left, bytes_to_read);
-      vec_validate (vsm->io_buffer, bytes_to_read);
-      nbytes = libc_read (__in_fd, vsm->io_buffer, bytes_to_read);
-      if (nbytes < 0)
-       {
-         errno_val = errno;
-         perror ("read()");
-         clib_warning ("[%d] ERROR: libc_read (__in_fd (%d), "
-                       "io_buffer %p, bytes_to_read %lu) returned "
-                       "errno %d",
-                       getpid (), __in_fd, vsm->io_buffer,
-                       bytes_to_read, errno_val);
-         if (results == 0)
-           {
-             vec_reset_length (vsm->io_buffer);
-             return -errno_val;
-           }
-         goto update_offset;
-       }
-      rv = vppcom_session_write (out_sid, vsm->io_buffer, nbytes);
-      if (rv < 0)
-       {
-         clib_warning ("[%d] ERROR: vppcom_session_write ("
-                       "out_sid %u, io_buffer %p, nbytes %d) "
-                       "returned %d (%s)",
-                       getpid (), out_sid, vsm->io_buffer, nbytes,
-                       rv, vppcom_retval_str (rv));
-         if (results == 0)
-           {
-             vec_reset_length (vsm->io_buffer);
-             return rv;
-           }
-         goto update_offset;
-       }
-
-      results += nbytes;
-      ASSERT (n_bytes_left >= nbytes);
-      n_bytes_left = n_bytes_left - nbytes;
-    }
-  while (n_bytes_left > 0);
-
-update_offset:
-  if (__offset)
-    {
-      off_t offset = lseek (__in_fd, *__offset, SEEK_SET);
-      if (offset == -1)
-       {
-         errno_val = errno;
-         perror ("lseek()");
-         clib_warning ("[%d] ERROR: lseek (__in_fd %d, __offset %p "
-                       "(%ld), SEEK_SET) returned errno %d",
-                       getpid (), __in_fd, __offset, *__offset, errno_val);
-         vec_reset_length (vsm->io_buffer);
-         return -errno_val;
-       }
-
-      *__offset += results + 1;
-    }
-
-  vec_reset_length (vsm->io_buffer);
-  return eagain ? -EAGAIN : results;
-}
-
-ssize_t
-vcom_socket_recv (int __fd, void *__buf, size_t __n, int __flags)
-{
-  int rv = -1;
-  rv = vcom_socket_recvfrom (__fd, __buf, __n, __flags, NULL, 0);
-  return rv;
-}
-
-/*
- * RETURN   1 if __fd is (SOCK_STREAM, SOCK_SEQPACKET),
- * 0 otherwise
- * */
-int
-vcom_socket_is_connection_mode_socket (int __fd)
-{
-  int rv = -1;
-  /* TBD define new vppcom api */
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  uword *p;
-  vcom_socket_t *vsock;
-
-  int type;
-  socklen_t optlen;
-
-  p = hash_get (vsm->sockidx_by_fd, __fd);
-
-  if (p)
-    {
-      vsock = pool_elt_at_index (vsm->vsockets, p[0]);
-      if (vsock && vsock->type == SOCKET_TYPE_VPPCOM_BOUND)
-       {
-         optlen = sizeof (type);
-         rv = libc_getsockopt (__fd, SOL_SOCKET, SO_TYPE, &type, &optlen);
-         if (rv != 0)
-           {
-             return 0;
-           }
-         /* get socket type */
-         switch (type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
-           {
-           case SOCK_STREAM:
-           case SOCK_SEQPACKET:
-             return 1;
-             break;
-
-           default:
-             return 0;
-             break;
-           }
-       }
-    }
-  return 0;
-}
-
-static inline ssize_t
-vcom_session_sendto (int __sid, void *__buf, size_t __n,
-                    int __flags, __CONST_SOCKADDR_ARG __addr,
-                    socklen_t __addr_len)
-{
-  vppcom_endpt_t *ep = 0;
-  vppcom_endpt_t _ep;
-
-  if (__addr)
-    {
-      ep = &_ep;
-      ep->vrf = VPPCOM_VRF_DEFAULT;
-      switch (__addr->sa_family)
-       {
-       case AF_INET:
-         ep->is_ip4 = VPPCOM_IS_IP4;
-         ep->ip =
-           (uint8_t *) & ((const struct sockaddr_in *) __addr)->sin_addr;
-         ep->port =
-           (uint16_t) ((const struct sockaddr_in *) __addr)->sin_port;
-         break;
-
-       case AF_INET6:
-         ep->is_ip4 = VPPCOM_IS_IP6;
-         ep->ip =
-           (uint8_t *) & ((const struct sockaddr_in6 *) __addr)->sin6_addr;
-         ep->port =
-           (uint16_t) ((const struct sockaddr_in6 *) __addr)->sin6_port;
-         break;
-
-       default:
-         return -EAFNOSUPPORT;
-       }
-    }
-
-  return vppcom_session_sendto (__sid, __buf, __n, __flags, ep);;
-}
-
-ssize_t
-vcom_socket_sendto (int __fd, const void *__buf, size_t __n,
-                   int __flags, __CONST_SOCKADDR_ARG __addr,
-                   socklen_t __addr_len)
-{
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  uword *p;
-  vcom_socket_t *vsock;
-
-  if (!__buf)
-    {
-      return -EINVAL;
-    }
-
-  p = hash_get (vsm->sockidx_by_fd, __fd);
-  if (!p)
-    return -EBADF;
-
-  vsock = pool_elt_at_index (vsm->vsockets, p[0]);
-  if (!vsock)
-    return -ENOTSOCK;
-
-  if (vsock->type != SOCKET_TYPE_VPPCOM_BOUND)
-    {
-      return -EINVAL;
-    }
-
-  if (vcom_socket_is_connection_mode_socket (__fd))
-    {
-      /* ignore __addr and _addr_len */
-      /* and EISCONN may be returned when they are not NULL and 0 */
-      if ((__addr != NULL) || (__addr_len != 0))
-       {
-         return -EISCONN;
-       }
-    }
-  else
-    {
-      if (!__addr)
-       {
-         return -EDESTADDRREQ;
-       }
-      /* not a vppcom supported address family */
-      if (!((__addr->sa_family == AF_INET) ||
-           (__addr->sa_family == AF_INET6)))
-       {
-         return -EINVAL;
-       }
-    }
-
-  return vcom_session_sendto (vsock->sid, (void *) __buf, (int) __n,
-                             __flags, __addr, __addr_len);
-}
-
-static inline ssize_t
-vcom_session_recvfrom (int __sid, void *__restrict __buf, size_t __n,
-                      int __flags, __SOCKADDR_ARG __addr,
-                      socklen_t * __restrict __addr_len)
-{
-  int rv;
-  vppcom_endpt_t ep;
-  u8 src_addr[sizeof (struct sockaddr_in6)];
-
-  if (__addr)
-    {
-      ep.ip = src_addr;
-      rv = vppcom_session_recvfrom (__sid, __buf, __n, __flags, &ep);
-
-      if (rv > 0)
-       rv = vcom_socket_copy_ep_to_sockaddr (__addr, __addr_len, &ep);
-    }
-  else
-    rv = vppcom_session_recvfrom (__sid, __buf, __n, __flags, NULL);
-
-  return rv;
-}
-
-ssize_t
-vcom_socket_recvfrom (int __fd, void *__restrict __buf, size_t __n,
-                     int __flags, __SOCKADDR_ARG __addr,
-                     socklen_t * __restrict __addr_len)
-{
-  int rv = -1;
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  uword *p;
-  vcom_socket_t *vsock;
-
-  if (__addr && !__addr_len)
-    return -EINVAL;
-
-  p = hash_get (vsm->sockidx_by_fd, __fd);
-  if (!p)
-    return -EBADF;
-
-  vsock = pool_elt_at_index (vsm->vsockets, p[0]);
-  if (!vsock)
-    return -ENOTSOCK;
-
-  if (vsock->type != SOCKET_TYPE_VPPCOM_BOUND)
-    {
-      return -EINVAL;
-    }
-
-  rv = vcom_session_recvfrom (vsock->sid, __buf, __n,
-                             __flags, __addr, __addr_len);
-  return rv;
-}
-
-/* TBD: move it to vppcom */
-static inline ssize_t
-vcom_session_sendmsg (int __sid, const struct msghdr *__message, int __flags)
-{
-  int rv = -1;
-  /* rv = vppcom_session_write (__sid, (void *) __message->__buf,
-     (int)__n); */
-  return rv;
-}
-
-ssize_t
-vcom_socket_sendmsg (int __fd, const struct msghdr * __message, int __flags)
-{
-  int rv = -1;
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  uword *p;
-  vcom_socket_t *vsock;
-
-  p = hash_get (vsm->sockidx_by_fd, __fd);
-  if (!p)
-    return -EBADF;
-
-  vsock = pool_elt_at_index (vsm->vsockets, p[0]);
-  if (!vsock)
-    return -ENOTSOCK;
-
-  if (vcom_socket_is_connection_mode_socket (__fd))
-    {
-      /* ignore __addr and _addr_len */
-      /* and EISCONN may be returned when they are not NULL and 0 */
-      if ((__message->msg_name != NULL) || (__message->msg_namelen != 0))
-       {
-         return -EISCONN;
-       }
-    }
-  else
-    {
-      /* TBD: validate __message->msg_name and __message->msg_namelen
-       * and return -EINVAL on validation error
-       * */
-      ;
-    }
-
-  rv = vcom_session_sendmsg (vsock->sid, __message, __flags);
-
-  return rv;
-}
-
-#ifdef __USE_GNU
-int
-vcom_socket_sendmmsg (int __fd, struct mmsghdr *__vmessages,
-                     unsigned int __vlen, int __flags)
-{
-
-  /* TBD: define a new vppcom api */
-  return 0;
-}
-#endif
-
-/* TBD: move it to vppcom */
-static inline ssize_t
-vcom_session_recvmsg (int __sid, struct msghdr *__message, int __flags)
-{
-  int rv = -1;
-  /* rv = vppcom_session_read (__sid, (void *) __message->__buf,
-     (int)__n); */
-  rv = -EOPNOTSUPP;
-  return rv;
-}
-
-ssize_t
-vcom_socket_recvmsg (int __fd, struct msghdr * __message, int __flags)
-{
-  int rv = -1;
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  uword *p;
-  vcom_socket_t *vsock;
-
-  p = hash_get (vsm->sockidx_by_fd, __fd);
-  if (!p)
-    return -EBADF;
-
-  vsock = pool_elt_at_index (vsm->vsockets, p[0]);
-  if (!vsock)
-    return -ENOTSOCK;
-
-  if (vsock->type != SOCKET_TYPE_VPPCOM_BOUND)
-    return -EINVAL;
-
-  if (!__message)
-    {
-      return -EINVAL;
-    }
-
-  /* validate __flags */
-
-  rv = vcom_session_recvmsg (vsock->sid, __message, __flags);
-  return rv;
-}
-
-#ifdef __USE_GNU
-int
-vcom_socket_recvmmsg (int __fd, struct mmsghdr *__vmessages,
-                     unsigned int __vlen, int __flags,
-                     struct timespec *__tmo)
-{
-  /* TBD: define a new vppcom api */
-  return 0;
-}
-#endif
-
-/* TBD: move it to vppcom */
-static inline int
-vcom_session_get_sockopt (int __sid, int __level, int __optname,
-                         void *__restrict __optval,
-                         socklen_t * __restrict __optlen)
-{
-  int rv = 0;
-
-  /* 1. for socket level options that are NOT socket attributes
-   *    and that has corresponding vpp options get from vppcom */
-  switch (__level)
-    {
-    case SOL_SOCKET:
-      switch (__optname)
-       {
-       case SO_ERROR:
-         *(int *) __optval = 0;
-         break;
-       default:
-         break;
-       }
-    default:
-      break;
-    }
-  /* 2. unhandled options */
-  return rv;
-}
-
-int
-vcom_socket_getsockopt (int __fd, int __level, int __optname,
-                       void *__restrict __optval,
-                       socklen_t * __restrict __optlen)
-{
-  int rv = -1;
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  uword *p;
-  vcom_socket_t *vsock;
-
-  if (!__optval || !__optlen)
-    return -EINVAL;
-
-  p = hash_get (vsm->sockidx_by_fd, __fd);
-  if (!p)
-    return -EBADF;
-
-  vsock = pool_elt_at_index (vsm->vsockets, p[0]);
-  if (!vsock)
-    return -ENOTSOCK;
-
-  if (vsock->type != SOCKET_TYPE_VPPCOM_BOUND)
-    return -EINVAL;
-
-  switch (__level)
-    {
-    case SOL_SOCKET:
-      switch (__optname)
-       {
-/*
- *  1. for socket level options that are socket attributes,
- *     get from libc_getsockopt.
- *  2. for socket level options that are NOT socket
- *     attributes and that has corresponding vpp options
- *     get from vppcom.
- *  3. for socket level options unimplemented
- *     return -ENOPROTOOPT */
-       case SO_DEBUG:
-       case SO_DONTROUTE:
-       case SO_BROADCAST:
-       case SO_SNDBUF:
-       case SO_RCVBUF:
-       case SO_REUSEADDR:
-       case SO_REUSEPORT:
-       case SO_KEEPALIVE:
-       case SO_TYPE:
-       case SO_PROTOCOL:
-       case SO_DOMAIN:
-       case SO_OOBINLINE:
-       case SO_NO_CHECK:
-       case SO_PRIORITY:
-       case SO_LINGER:
-       case SO_BSDCOMPAT:
-       case SO_TIMESTAMP:
-       case SO_TIMESTAMPNS:
-       case SO_TIMESTAMPING:
-       case SO_RCVTIMEO:
-       case SO_SNDTIMEO:
-       case SO_RCVLOWAT:
-       case SO_SNDLOWAT:
-       case SO_PASSCRED:
-       case SO_PEERCRED:
-       case SO_PEERNAME:
-       case SO_ACCEPTCONN:
-       case SO_PASSSEC:
-       case SO_PEERSEC:
-       case SO_MARK:
-       case SO_RXQ_OVFL:
-       case SO_WIFI_STATUS:
-       case SO_PEEK_OFF:
-       case SO_NOFCS:
-       case SO_BINDTODEVICE:
-       case SO_GET_FILTER:
-       case SO_LOCK_FILTER:
-       case SO_BPF_EXTENSIONS:
-       case SO_SELECT_ERR_QUEUE:
-#ifdef CONFIG_NET_RX_BUSY_POLL
-       case SO_BUSY_POLL:
-#endif
-       case SO_MAX_PACING_RATE:
-#ifdef SO_INCOMING_CPU
-       case SO_INCOMING_CPU:
-#endif
-         rv = libc_getsockopt (__fd, __level, __optname, __optval, __optlen);
-         if (rv != 0)
-           {
-             rv = -errno;
-             return rv;
-           }
-         break;
-
-       case SO_ERROR:
-         rv = vcom_session_get_sockopt (vsock->sid, __level, __optname,
-                                        __optval, __optlen);
-         break;
-
-       default:
-         /* We implement the SO_SNDLOWAT etc to not be settable
-          * (1003.1g 7).
-          */
-         return -ENOPROTOOPT;
-       }
-
-      break;
-
-    default:
-      /* 1. handle options that are NOT socket level options,
-       *    but have corresponding vpp otions. */
-      rv = vcom_session_get_sockopt (vsock->sid, __level, __optname,
-                                    __optval, __optlen);
-      break;
-    }
-
-  return rv;
-}
-
-/* TBD: move it to vppcom */
-static inline int
-vcom_session_setsockopt (int __sid, int __level, int __optname,
-                        const void *__optval, socklen_t __optlen)
-{
-  int rv = -EOPNOTSUPP;
-
-  switch (__level)
-    {
-    case SOL_TCP:
-      switch (__optname)
-       {
-       case TCP_KEEPIDLE:
-         rv =
-           vppcom_session_attr (__sid, VPPCOM_ATTR_SET_TCP_KEEPIDLE, 0, 0);
-         break;
-       case TCP_KEEPINTVL:
-         rv =
-           vppcom_session_attr (__sid, VPPCOM_ATTR_SET_TCP_KEEPINTVL, 0, 0);
-         break;
-       default:
-         break;
-       }
-      break;
-    case SOL_IPV6:
-      switch (__optname)
-       {
-       case IPV6_V6ONLY:
-         rv = vppcom_session_attr (__sid, VPPCOM_ATTR_SET_V6ONLY, 0, 0);
-         break;
-       default:
-         break;
-       }
-      break;
-    case SOL_SOCKET:
-      switch (__optname)
-       {
-       case SO_KEEPALIVE:
-         rv = vppcom_session_attr (__sid, VPPCOM_ATTR_SET_KEEPALIVE, 0, 0);
-         break;
-       case SO_REUSEADDR:
-         rv = vppcom_session_attr (__sid, VPPCOM_ATTR_SET_REUSEADDR, 0, 0);
-         break;
-       case SO_BROADCAST:
-         rv = vppcom_session_attr (__sid, VPPCOM_ATTR_SET_BROADCAST, 0, 0);
-         break;
-       default:
-         break;
-       }
-      break;
-    default:
-      break;
-    }
-
-  return rv;
-}
-
-int
-vcom_socket_setsockopt (int __fd, int __level, int __optname,
-                       const void *__optval, socklen_t __optlen)
-{
-  int rv = -1;
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  uword *p;
-  vcom_socket_t *vsock;
-
-  p = hash_get (vsm->sockidx_by_fd, __fd);
-  if (!p)
-    return -EBADF;
-
-  vsock = pool_elt_at_index (vsm->vsockets, p[0]);
-  if (!vsock)
-    return -ENOTSOCK;
-
-  if (vsock->type != SOCKET_TYPE_VPPCOM_BOUND)
-    return -EINVAL;
-
-  /*
-   *      Options without arguments
-   */
-
-  if (__optname == SO_BINDTODEVICE)
-    {
-      rv = libc_setsockopt (__fd, __level, __optname, __optval, __optlen);
-      if (rv != 0)
-       {
-         rv = -errno;
-       }
-      return rv;
-    }
-
-  if (!__optval)
-    return -EFAULT;
-
-  if (__optlen < sizeof (int))
-    return -EINVAL;
-
-  switch (__level)
-    {
-    case SOL_IPV6:
-      switch (__optname)
-       {
-       case IPV6_V6ONLY:
-         rv = vcom_session_setsockopt (vsock->sid, __level, __optname,
-                                       __optval, __optlen);
-         break;
-       default:
-         return -EOPNOTSUPP;
-       }
-      break;
-    case SOL_TCP:
-      switch (__optname)
-       {
-       case TCP_NODELAY:
-         return 0;
-       case TCP_KEEPIDLE:
-       case TCP_KEEPINTVL:
-         rv = vcom_session_setsockopt (vsock->sid, __level, __optname,
-                                       __optval, __optlen);
-         break;
-       default:
-         return -EOPNOTSUPP;
-       }
-      break;
-      /* handle options at socket level */
-    case SOL_SOCKET:
-      switch (__optname)
-       {
-       case SO_REUSEADDR:
-       case SO_BROADCAST:
-       case SO_KEEPALIVE:
-         rv = vcom_session_setsockopt (vsock->sid, __level, __optname,
-                                       __optval, __optlen);
-         break;
-
-         /*
-          * 1. for socket level options that are socket attributes,
-          *    set it from libc_getsockopt
-          * 2. for socket level options that are NOT socket
-          *    attributes and that has corresponding vpp options
-          *    set it from vppcom
-          * 3. for socket level options unimplemented
-          *    return -ENOPROTOOPT */
-       case SO_DEBUG:
-       case SO_DONTROUTE:
-       case SO_SNDBUF:
-       case SO_RCVBUF:
-       case SO_REUSEPORT:
-       case SO_TYPE:
-       case SO_PROTOCOL:
-       case SO_DOMAIN:
-       case SO_ERROR:
-       case SO_OOBINLINE:
-       case SO_NO_CHECK:
-       case SO_PRIORITY:
-       case SO_LINGER:
-       case SO_BSDCOMPAT:
-       case SO_TIMESTAMP:
-       case SO_TIMESTAMPNS:
-       case SO_TIMESTAMPING:
-       case SO_RCVTIMEO:
-       case SO_SNDTIMEO:
-       case SO_RCVLOWAT:
-       case SO_SNDLOWAT:
-       case SO_PASSCRED:
-       case SO_PEERCRED:
-       case SO_PEERNAME:
-       case SO_ACCEPTCONN:
-       case SO_PASSSEC:
-       case SO_PEERSEC:
-       case SO_MARK:
-       case SO_RXQ_OVFL:
-       case SO_WIFI_STATUS:
-       case SO_PEEK_OFF:
-       case SO_NOFCS:
-         /*
-          * SO_BINDTODEVICE already handled as
-          * "Options without arguments" */
-         /* case SO_BINDTODEVICE: */
-       case SO_GET_FILTER:
-       case SO_LOCK_FILTER:
-       case SO_BPF_EXTENSIONS:
-       case SO_SELECT_ERR_QUEUE:
-#ifdef CONFIG_NET_RX_BUSY_POLL
-       case SO_BUSY_POLL:
-#endif
-       case SO_MAX_PACING_RATE:
-#ifdef SO_INCOMING_CPU
-       case SO_INCOMING_CPU:
-#endif
-         rv = libc_setsockopt (__fd, __level, __optname, __optval, __optlen);
-         if (rv != 0)
-           {
-             rv = -errno;
-             return rv;
-           }
-         break;
-
-       default:
-         /* We implement the SO_SNDLOWAT etc to not be settable
-          * (1003.1g 7).
-          */
-         return -ENOPROTOOPT;
-       }
-
-      break;
-
-    default:
-      return -ENOPROTOOPT;
-    }
-
-  return rv;
-}
-
-int
-vcom_socket_listen (int __fd, int __n)
-{
-  int rv = -1;
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  uword *p;
-  vcom_socket_t *vsock;
-
-  p = hash_get (vsm->sockidx_by_fd, __fd);
-  if (p)
-    {
-      vsock = pool_elt_at_index (vsm->vsockets, p[0]);
-
-      /* TBD vppcom to accept __n parameter */
-      rv = vppcom_session_listen (vsock->sid, __n);
-    }
-
-  return rv;
-}
-
-static int
-vcom_socket_connected_socket (int __fd, int __sid,
-                             int *__domain,
-                             int *__type, int *__protocol, int flags)
-{
-  int rv = -1;
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  vcom_socket_t *vsock;
-
-  i32 fd;
-  i32 sockidx;
-
-  socklen_t optlen;
-
-  optlen = sizeof (*__domain);
-  rv = libc_getsockopt (__fd, SOL_SOCKET, SO_DOMAIN, __domain, &optlen);
-  if (rv != 0)
-    {
-      rv = -errno;
-      goto out;
-    }
-
-  optlen = sizeof (*__type);
-  rv = libc_getsockopt (__fd, SOL_SOCKET, SO_TYPE, __type, &optlen);
-  if (rv != 0)
-    {
-      rv = -errno;
-      goto out;
-    }
-
-  optlen = sizeof (*__protocol);
-  rv = libc_getsockopt (__fd, SOL_SOCKET, SO_PROTOCOL, __protocol, &optlen);
-  if (rv != 0)
-    {
-      rv = -errno;
-      goto out;
-    }
-
-  fd = vcom_socket_open_socket (*__domain, *__type | flags, *__protocol);
-  if (fd < 0)
-    {
-      rv = fd;
-      goto out;
-    }
-
-  pool_get (vsm->vsockets, vsock);
-  vsocket_init (vsock);
-
-  sockidx = vsock - vsm->vsockets;
-  hash_set (vsm->sockidx_by_fd, fd, sockidx);
-
-  vsocket_set (vsock, fd, __sid, SOCKET_TYPE_VPPCOM_BOUND);
-  return fd;
-
-out:
-  return rv;
-}
-
-/* If flag is 0, then accept4() is the same as accept().
- * SOCK_NONBLOCK and SOCK_CLOEXEC can be bitwise ORed in flags
- */
-static int
-vcom_socket_accept_flags (int __fd, __SOCKADDR_ARG __addr,
-                         socklen_t * __restrict __addr_len, int flags)
-{
-  int rv = -1;
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  uword *p;
-  vcom_socket_t *vsock;
-
-  int fd;
-  int sid;
-  int domain;
-  int type;
-  int protocol;
-
-  uint8_t addr8[sizeof (struct in6_addr)];
-  vppcom_endpt_t ep;
-
-  ep.ip = addr8;
-
-  /* validate flags */
-
-  /*
-   * for documentation
-   *  switch (flags)
-   *   {
-   *   case 0:
-   *   case SOCK_NONBLOCK:
-   *   case SOCK_CLOEXEC:
-   *   case SOCK_NONBLOCK | SOCK_CLOEXEC:
-   *     break;
-   *
-   *   default:
-   *     return -1;
-   *   }
-   */
-  /* flags can be 0 or can be bitwise OR
-   * of any of SOCK_NONBLOCK and SOCK_CLOEXEC */
-
-  if (VCOM_DEBUG > 2)
-    fprintf (stderr, "[%d] vcom_socket_accept_flags: "
-            "fd = %d, __addr = %p, __addr_len = %p  flags = %d (0x%x)\n",
-            getpid (), __fd, __addr, __addr_len, flags, flags);
-
-  if (!(!flags || (flags & (SOCK_NONBLOCK | SOCK_CLOEXEC))))
-    {
-      /* TBD: return proper error code */
-      fprintf (stderr, "[%d] ERROR: vcom_socket_accept_flags: "
-              "invalid flags = %d (0x%x)\n", getpid (), flags, flags);
-
-      return -1;
-    }
-
-  /* TBD: return proper error code */
-
-  if (!vcom_socket_is_connection_mode_socket (__fd))
-    {
-      fprintf (stderr, "[%d] ERROR: vcom_socket_accept_flags: "
-              "connection mode socket support TBD!\n", getpid ());
-      return -EOPNOTSUPP;
-    }
-
-  p = hash_get (vsm->sockidx_by_fd, __fd);
-  if (p)
-    {
-      vsock = pool_elt_at_index (vsm->vsockets, p[0]);
-
-
-      rv = vcom_fcntl (vsock->fd, F_GETFL, 0);
-      if (rv < 0)
-       {
-         fprintf (stderr, "[%d] ERROR: vcom_socket_accept_flags: "
-                  "vcom_fcnt() returned %d!\n", getpid (), rv);
-         return rv;
-       }
-
-      /* is blocking */
-      if (!(rv & O_NONBLOCK))
-       {
-         /* socket is not marked as nonblocking
-          * and no pending connections are present
-          * on the queue, accept () blocks the caller
-          * until a connection is present.
-          */
-         rv = vppcom_session_accept (vsock->sid, &ep, flags,
-                                     -1.0 /* wait forever */ );
-       }
-      else
-       {
-         /* The file descriptor refers to a socket and has been
-          * marked nonblocking(O_NONBLOCK) and the accept would
-          * block.
-          * */
-         /* is non blocking */
-         rv = vppcom_session_accept (vsock->sid, &ep, flags, 0);
-         /* If the socket is marked nonblocking and
-          * no pending connections are present on the
-          * queue, accept fails with the error
-          * EAGAIN or EWOULDBLOCK
-          */
-         if (rv == VPPCOM_ETIMEDOUT)
-           {
-             rv = VPPCOM_EAGAIN;
-           }
-       }
-      if (rv < 0)
-       {
-         if (rv != VPPCOM_EAGAIN)
-           fprintf (stderr, "[%d] ERROR: vcom_socket_accept_flags: "
-                    "vppcom_session_accept() returned %d!", getpid (), rv);
-         return rv;
-       }
-
-      sid = rv;
-
-      /* create a new connected socket resource and set flags
-       * on the new file descriptor.
-       * update vsockets and sockidx_by_fd table
-       * */
-      fd = vcom_socket_connected_socket (__fd, sid,
-                                        &domain, &type, &protocol, flags);
-      if (fd < 0)
-       {
-         fprintf (stderr, "[%d] ERROR: vcom_socket_accept_flags: "
-                  "vcom_socket_connected_socket() returned %d!",
-                  getpid (), rv);
-         return fd;
-       }
-
-      rv = fd;
-
-      /* TBD populate __addr and __addr_len */
-      /* TBD: The returned address is truncated if the buffer
-       * provided is too small, in this case, __addr_len will
-       * return a value greater than was supplied to the call.*/
-      if (__addr)
-       {
-         if (ep.is_cut_thru)
-           {
-             /* TBD populate __addr and __addr_len */
-             switch (domain)
-               {
-               case AF_INET:
-                 ((struct sockaddr_in *) __addr)->sin_family = AF_INET;
-                 ((struct sockaddr_in *) __addr)->sin_port = ep.port;
-                 memcpy (&((struct sockaddr_in *) __addr)->sin_addr,
-                         addr8, sizeof (struct in_addr));
-                 /* TBD: populate __addr_len */
-                 if (__addr_len)
-                   {
-                     *__addr_len = sizeof (struct sockaddr_in);
-                   }
-                 break;
-
-               case AF_INET6:
-                 ((struct sockaddr_in6 *) __addr)->sin6_family = AF_INET6;
-                 ((struct sockaddr_in6 *) __addr)->sin6_port = ep.port;
-                 memcpy (((struct sockaddr_in6 *) __addr)->sin6_addr.
-                         __in6_u.__u6_addr8, addr8,
-                         sizeof (struct in6_addr));
-                 /* TBD: populate __addr_len */
-                 if (__addr_len)
-                   {
-                     *__addr_len = sizeof (struct sockaddr_in6);
-                   }
-                 break;
-
-               default:
-                 return -EAFNOSUPPORT;
-               }
-           }
-         else
-           {
-             switch (ep.is_ip4)
-               {
-               case VPPCOM_IS_IP4:
-                 ((struct sockaddr_in *) __addr)->sin_family = AF_INET;
-                 ((struct sockaddr_in *) __addr)->sin_port = ep.port;
-                 memcpy (&((struct sockaddr_in *) __addr)->sin_addr,
-                         addr8, sizeof (struct in_addr));
-                 /* TBD: populate __addr_len */
-                 if (__addr_len)
-                   {
-                     *__addr_len = sizeof (struct sockaddr_in);
-                   }
-                 break;
-
-               case VPPCOM_IS_IP6:
-                 ((struct sockaddr_in6 *) __addr)->sin6_family = AF_INET6;
-                 ((struct sockaddr_in6 *) __addr)->sin6_port = ep.port;
-                 memcpy (((struct sockaddr_in6 *) __addr)->sin6_addr.
-                         __in6_u.__u6_addr8, addr8,
-                         sizeof (struct in6_addr));
-                 /* TBD: populate __addr_len */
-                 if (__addr_len)
-                   {
-                     *__addr_len = sizeof (struct sockaddr_in6);
-                   }
-                 break;
-
-               default:
-                 return -EAFNOSUPPORT;
-               }
-           }
-       }
-    }
-
-  return rv;
-}
-
-int
-vcom_socket_accept (int __fd, __SOCKADDR_ARG __addr,
-                   socklen_t * __restrict __addr_len)
-{
-  /* set flags to 0 for accept() */
-  return vcom_socket_accept_flags (__fd, __addr, __addr_len, 0);
-}
-
-int
-vcom_socket_accept4 (int __fd, __SOCKADDR_ARG __addr,
-                    socklen_t * __restrict __addr_len, int __flags)
-{
-  /*  SOCK_NONBLOCK and SOCK_CLOEXEC can be bitwise ORed in flags */
-  return vcom_socket_accept_flags (__fd, __addr, __addr_len, __flags);
-}
-
-/* TBD: move it to vppcom */
-static inline int
-vcom_session_shutdown (int __fd, int __how)
-{
-  return 0;
-}
-
-int
-vcom_socket_shutdown (int __fd, int __how)
-{
-  int rv = -1;
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  uword *p;
-  vcom_socket_t *vsock;
-
-  p = hash_get (vsm->sockidx_by_fd, __fd);
-  if (p)
-    {
-      vsock = pool_elt_at_index (vsm->vsockets, p[0]);
-      switch (__how)
-       {
-       case SHUT_RD:
-       case SHUT_WR:
-       case SHUT_RDWR:
-         rv = vcom_session_shutdown (vsock->sid, __how);
-         return rv;
-         break;
-
-       default:
-         return -EINVAL;
-         break;
-       }
-    }
-
-  return rv;
-}
-
-int
-vcom_socket_epoll_create1 (int __flags)
-{
-  int rv = -1;
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  vcom_epoll_t *vepoll;
-
-  i32 epfd;
-  i32 vep_idx;
-  i32 epollidx;
-
-  epfd = vcom_socket_open_epoll (__flags);
-  if (epfd < 0)
-    {
-      rv = epfd;
-      goto out;
-    }
-
-  vep_idx = vppcom_epoll_create ();
-  if (vep_idx < 0)
-    {
-      rv = vep_idx;
-      goto out_close_epoll;
-    }
-
-  pool_get (vsm->vepolls, vepoll);
-  vepoll_init (vepoll);
-
-  epollidx = vepoll - vsm->vepolls;
-  hash_set (vsm->epollidx_by_epfd, epfd, epollidx);
-
-  vepoll_set (vepoll, epfd, vep_idx, EPOLL_TYPE_VPPCOM_BOUND, __flags, 0, 0);
-
-  return epfd;
-
-out_close_epoll:
-  vcom_socket_close_epoll (epfd);
-out:
-  return rv;
-}
-
-/*
- * PRE: vppcom_epoll_ctl() is successful
- * free_vepitem_on_del : 0 - no_pool_put, 1 - pool_put
- */
-int
-vcom_socket_ctl_vepitem (int __epfd, int __op, int __fd,
-                        struct epoll_event *__event,
-                        i32 vep_idx, vcom_epoll_t * vepoll,
-                        i32 vfd_id, void *vfd, vcom_fd_type_t type,
-                        int free_vepitem_on_del)
-{
-  int rv = -1;
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  vcom_epitem_t *vepitem;
-
-  vcom_epitem_key_t epfdfd = {.epfd = __epfd,.fd = __fd };
-  uword *p;
-  i32 vepitemidx;
-
-  i32 *vepitemidxs = 0;
-
-  struct epoll_event revent = {.events = 0,.data.fd = INVALID_FD };
-
-  i32 vec_idx;
-
-  /* perform control operations on the epoll instance */
-  switch (__op)
-    {
-    case EPOLL_CTL_ADD:
-      /*
-       * supplied file descriptor is already
-       * registered with this epoll instance
-       * */
-      /* vepitem exists */
-      p = hash_get (vsm->epitemidx_by_epfdfd, epfdfd.key);
-      if (p)
-       {
-         rv = -EEXIST;
-         goto out;
-       }
-
-      /* add a new vepitem */
-      pool_get (vsm->vepitems, vepitem);
-      vepitem_init (vepitem);
-
-      vepitemidx = vepitem - vsm->vepitems;
-      hash_set (vsm->epitemidx_by_epfdfd, epfdfd.key, vepitemidx);
-      vepitem_set (vepitem, __epfd, __fd, __fd, __fd, type, *__event, revent);
-
-      /* update epitemidxs */
-      /* by_epfd */
-      p = hash_get (vsm->epitemidxs_by_epfd, __epfd);
-      if (!p)                  /*  not exist */
-       {
-         vepitemidxs = 0;
-         vec_add1 (vepitemidxs, vepitemidx);
-         hash_set (vsm->epitemidxs_by_epfd, __epfd, vepitemidxs);
-       }
-      else                     /*  exists */
-       {
-         vepitemidxs = *(i32 **) p;
-         vec_add1 (vepitemidxs, vepitemidx);
-         hash_set3 (vsm->epitemidxs_by_epfd, __epfd, vepitemidxs, 0);
-       }
-      /* update epitemidxs */
-      /* by_fd */
-      p = hash_get (vsm->epitemidxs_by_fd, __fd);
-      if (!p)                  /*  not exist */
-       {
-         vepitemidxs = 0;
-         vec_add1 (vepitemidxs, vepitemidx);
-         hash_set (vsm->epitemidxs_by_fd, __fd, vepitemidxs);
-       }
-      else                     /*  exists */
-       {
-         vepitemidxs = *(i32 **) p;
-         vec_add1 (vepitemidxs, vepitemidx);
-         hash_set3 (vsm->epitemidxs_by_fd, __fd, vepitemidxs, 0);
-       }
-
-      /* increment vepoll fd count by 1 */
-      vepoll->count += 1;
-
-      rv = 0;
-      goto out;
-      break;
-
-    case EPOLL_CTL_MOD:
-      /*
-       * supplied file descriptor is not
-       * registered with this epoll instance
-       * */
-      /* vepitem not exist */
-      p = hash_get (vsm->epitemidx_by_epfdfd, epfdfd.key);
-      if (!p)
-       {
-         rv = -ENOENT;
-         goto out;
-       }
-      vepitem = pool_elt_at_index (vsm->vepitems, p[0]);
-      if (vepitem)
-       {
-         vepitem->event = *__event;
-         vepitem->revent = revent;
-       }
-
-      rv = 0;
-      goto out;
-      break;
-
-    case EPOLL_CTL_DEL:
-      /*
-       * supplied file descriptor is not
-       * registered with this epoll instance
-       * */
-      /* vepitem not exist */
-      p = hash_get (vsm->epitemidx_by_epfdfd, epfdfd.key);
-      if (!p)
-       {
-         rv = -ENOENT;
-         goto out;
-       }
-      vepitemidx = *(i32 *) p;
-      hash_unset (vsm->epitemidx_by_epfdfd, epfdfd.key);
-
-      /* update epitemidxs */
-      /* by_epfd */
-      p = hash_get (vsm->epitemidxs_by_epfd, __epfd);
-      if (!p)                  /*  not exist */
-       {
-         rv = -ENOENT;
-         goto out;
-       }
-      else                     /*  exists */
-       {
-         vepitemidxs = *(i32 **) p;
-         vec_idx = vec_search (vepitemidxs, vepitemidx);
-         if (vec_idx != ~0)
-           {
-             vec_del1 (vepitemidxs, vec_idx);
-             if (!vec_len (vepitemidxs))
-               {
-                 vec_free (vepitemidxs);
-                 hash_unset (vsm->epitemidxs_by_epfd, __epfd);
-               }
-           }
-       }
-
-      /* update epitemidxs */
-      /* by_fd */
-      p = hash_get (vsm->epitemidxs_by_fd, __fd);
-      if (!p)                  /*  not exist */
-       {
-         rv = -ENOENT;
-         goto out;
-       }
-      else                     /*  exists */
-       {
-         vepitemidxs = *(i32 **) p;
-         vec_idx = vec_search (vepitemidxs, vepitemidx);
-         if (vec_idx != ~0)
-           {
-             vec_del1 (vepitemidxs, vec_idx);
-             if (!vec_len (vepitemidxs))
-               {
-                 vec_free (vepitemidxs);
-                 hash_unset (vsm->epitemidxs_by_fd, __fd);
-               }
-           }
-       }
-
-      /* pool put vepitem */
-      vepitem = pool_elt_at_index (vsm->vepitems, vepitemidx);
-      if (free_vepitem_on_del)
-       {
-         if (!vepitem)
-           {
-             rv = -ENOENT;
-             goto out;
-           }
-         vepitem_init (vepitem);
-         pool_put (vsm->vepitems, vepitem);
-       }
-      else
-       {
-         if (!vepitem)
-           {
-             vepitem_init (vepitem);
-           }
-       }
-
-      /* decrement vepoll fd count by 1 */
-      vepoll->count -= 1;
-
-      rv = 0;
-      goto out;
-      break;
-
-    default:
-      rv = -EINVAL;
-      goto out;
-      break;
-    }
-
-out:
-  return rv;
-}
-
-/*
- * PRE: 00. null pointer check on __event
- *      01. all other parameters are validated
- */
-
-static int
-vcom_socket_epoll_ctl_internal (int __epfd, int __op, int __fd,
-                               struct epoll_event *__event,
-                               int free_vepitem_on_del)
-{
-  int rv = -1;
-  i32 cnt;
-  vcom_epoll_t *vepoll;
-  vcom_socket_t *vfd_vsock;
-  i32 vep_idx;
-  i32 sid;
-
-  /* get vep_idx and vepoll */
-  vep_idx = vcom_socket_get_vep_idx_and_vepoll (__epfd, &vepoll);
-  if (vep_idx == INVALID_VEP_IDX)
-    {
-      return -EBADF;
-    }
-
-  /* get vcom fd type, vfd_id and vfd */
-  sid = vcom_socket_get_sid_and_vsock (__fd, &vfd_vsock);
-  if ((sid != INVALID_SESSION_ID) &&
-      vcom_socket_type_is_vppcom_bound (vfd_vsock->type))
-    {
-      rv = vppcom_epoll_ctl (vep_idx, __op, sid, __event);
-      if (rv == VPPCOM_OK)
-       {
-         cnt = ((__op == EPOLL_CTL_ADD) ? 1 :
-                (__op == EPOLL_CTL_DEL) ? -1 : 0);
-         vepoll->count += cnt;
-         vepoll->vcl_cnt += cnt;
-       }
-      if (VCOM_DEBUG > 0)
-       fprintf (stderr,
-                "[%d] vcom_socket_epoll_ctl_i: vppcom_epoll_ctl() "
-                "returned %d\n\tepfd %d, vep_idx %d, fd %d sid %d op %d"
-                "\n\tcount %d, vcl_cnt %d, libc_cnt %d\n",
-                getpid (), rv, __epfd, vep_idx, __fd, sid, __op,
-                vepoll->count, vepoll->vcl_cnt, vepoll->libc_cnt);
-    }
-  else
-    {
-      rv = libc_epoll_ctl (__epfd, __op, __fd, __event);
-      if (rv == 0)
-       {
-         cnt = ((__op == EPOLL_CTL_ADD) ? 1 :
-                (__op == EPOLL_CTL_DEL) ? -1 : 0);
-         vepoll->count += cnt;
-         vepoll->libc_cnt += cnt;
-       }
-      if (VCOM_DEBUG > 0)
-       fprintf (stderr,
-                "[%d] vcom_socket_epoll_ctl_i: libc_epoll_ctl() "
-                "returned %d\n\tepfd %d, vep_idx %d, fd %d sid %d op %d"
-                "\n\tcount %d, vcl_cnt %d, libc_cnt %d\n",
-                getpid (), rv, __epfd, vep_idx, __fd, sid, __op,
-                vepoll->count, vepoll->vcl_cnt, vepoll->libc_cnt);
-    }
-
-  return rv;
-}
-
-int
-vcom_socket_epoll_ctl (int __epfd, int __op, int __fd,
-                      struct epoll_event *__event)
-{
-  int rv = -1;
-
-  rv = vcom_socket_epoll_ctl_internal (__epfd, __op, __fd, __event, 1);
-  return rv;
-}
-
-static int
-vcom_socket_epoll_ctl1 (int __epfd, int __op, int __fd,
-                       struct epoll_event *__event)
-{
-  int rv = -1;
-
-  rv = vcom_socket_epoll_ctl_internal (__epfd, __op, __fd, __event, 0);
-  return rv;
-}
-
-int
-vcom_socket_epoll_pwait (int __epfd, struct epoll_event *__events,
-                        int __maxevents, int __timeout,
-                        const __sigset_t * __ss)
-{
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  int rv = -EBADF;
-  double time_to_wait = (double) 0;
-  double timeout, now = 0;
-  vcom_epoll_t *vepoll;
-  i32 vep_idx;
-
-  /* validate __event */
-  if (!__events || (__timeout < -1))
-    {
-      fprintf (stderr, "[%d] ERROR: vcom_socket_epoll_pwait: "
-              "Bad args __events %p, __timeout %d\n", getpid (),
-              __events, __timeout);
-      rv = -EFAULT;
-      goto out;
-    }
-
-  time_to_wait = ((__timeout >= 0) ? (double) __timeout / (double) 1000 : 0);
-
-  vep_idx = vcom_socket_get_vep_idx_and_vepoll (__epfd, &vepoll);
-  if (vep_idx == INVALID_VEP_IDX)
-    {
-      fprintf (stderr, "[%d] ERROR: vcom_socket_epoll_pwait: "
-              "Bad epoll fd %d\n", getpid (), __epfd);
-      return -EBADF;
-    }
-
-  if (vepoll->count <= 0)
-    {
-      fprintf (stderr, "[%d] ERROR: vcom_socket_epoll_pwait: No events"
-              " in epfd!\n\tcount %d, vcl_cnt %d, libc_cnt %d\n",
-              getpid (), vepoll->count, vepoll->vcl_cnt, vepoll->libc_cnt);
-      rv = -EINVAL;
-      goto out;
-    }
-
-  if (vepoll->libc_cnt == 0)
-    {
-      if (VCOM_DEBUG > 2)
-       fprintf (stderr, "[%d] vcom_socket_epoll_pwait: libc_cnt = 0, "
-                "calling vppcom_epoll_wait() time_to_wait = %f\n",
-                getpid (), time_to_wait);
-      rv = vppcom_epoll_wait (vep_idx, __events, __maxevents, time_to_wait);
-    }
-  else if (vepoll->vcl_cnt == 0)
-    {
-      if (VCOM_DEBUG > 2)
-       fprintf (stderr, "[%d] vcom_socket_epoll_pwait: vcl_cnt = 0, "
-                "calling libc_epoll_pwait()\n", getpid ());
-      rv = libc_epoll_pwait (__epfd, __events, __maxevents, __timeout, __ss);
-    }
-  else
-    {
-      if (VCOM_DEBUG > 2)
-       fprintf (stderr, "[%d] vcom_socket_epoll_pwait: vcl_cnt = %d, "
-                "libc_cnt = %d -> mixed polling (time_to_wait = %f, "
-                "__timeout = %d)\n",
-                getpid (), vepoll->vcl_cnt, vepoll->libc_cnt,
-                time_to_wait, __timeout);
-      timeout = clib_time_now (&vsm->clib_time) + time_to_wait;
-      do
-       {
-         rv = vppcom_epoll_wait (vep_idx, __events, __maxevents, 0);
-         if (rv > 0)
-           {
-             if (VCOM_DEBUG > 2)
-               fprintf (stderr, "[%d] vcom_socket_epoll_pwait: "
-                        "vppcom_epoll_wait() returned %d\n", getpid (), rv);
-             goto out;
-           }
-         else if (rv < 0)
-           {
-             if (VCOM_DEBUG > 2)
-               fprintf (stderr, "[%d] ERROR: vcom_socket_epoll_pwait: "
-                        "vppcom_epoll_wait() returned %d\n", getpid (), rv);
-
-             goto out;
-           }
-         rv = libc_epoll_pwait (__epfd, __events, __maxevents, 1, __ss);
-         if (rv > 0)
-           {
-             if (VCOM_DEBUG > 2)
-               fprintf (stderr, "[%d] vcom_socket_epoll_pwait: "
-                        "libc_epoll_pwait() returned %d\n", getpid (), rv);
-             goto out;
-           }
-         else if (rv < 0)
-           {
-             int errno_val = errno;
-             perror ("libc_epoll_wait");
-             fprintf (stderr, "[%d]  vcom_socket_epoll_pwait: "
-                      "libc_epoll_wait() failed, errno %d\n",
-                      getpid (), errno_val);
-             goto out;
-           }
-         if (__timeout != -1)
-           now = clib_time_now (&vsm->clib_time);
-       }
-      while (now < timeout);
-    }
-out:
-  return rv;
-}
-
-static inline void
-vcom_pollfds_2_selectfds (
-                          /* src */
-                          struct pollfd *__fds, nfds_t __nfds,
-                          /* dest */
-                          int vcom_nfds,
-                          fd_set * __restrict vcom_readfds,
-                          fd_set * __restrict vcom_writefds,
-                          fd_set * __restrict vcom_exceptfds)
-{
-  nfds_t fds_idx = 0;
-
-  for (fds_idx = 0; fds_idx < __nfds; fds_idx++)
-    {
-      /* ignore negative fds */
-      if (__fds[fds_idx].fd < 0)
-       {
-         continue;
-       }
-
-      /* for POLLRDHUP, POLLERR, POLLHUP and  POLLNVAL */
-      FD_SET (__fds[fds_idx].fd, vcom_exceptfds);
-
-      /* requested events */
-      if (__fds[fds_idx].events)
-       {
-         if (__fds[fds_idx].events & POLLIN)
-           {
-             FD_SET (__fds[fds_idx].fd, vcom_readfds);
-           }
-         if (__fds[fds_idx].events & POLLPRI)
-           {
-             FD_SET (__fds[fds_idx].fd, vcom_readfds);
-           }
-         if (__fds[fds_idx].events & POLLOUT)
-           {
-             FD_SET (__fds[fds_idx].fd, vcom_writefds);
-           }
-#if defined __USE_XOPEN || defined __USE_XOPEN2K8
-         if (__fds[fds_idx].events & POLLRDNORM)
-           {
-             FD_SET (__fds[fds_idx].fd, vcom_readfds);
-           }
-         if (__fds[fds_idx].events & POLLRDBAND)
-           {
-             FD_SET (__fds[fds_idx].fd, vcom_readfds);
-           }
-         if (__fds[fds_idx].events & POLLWRNORM)
-           {
-             FD_SET (__fds[fds_idx].fd, vcom_writefds);
-           }
-         if (__fds[fds_idx].events & POLLWRBAND)
-           {
-             FD_SET (__fds[fds_idx].fd, vcom_writefds);
-           }
-#endif
-       }
-    }                          /* for (fds_idx = 0; fds_idx < __nfds; fds_idx++) */
-}
-
-static inline void
-vcom_selectfds_2_pollfds (
-                          /* dest */
-                          struct pollfd *__fds, nfds_t __nfds, int *nfd,
-                          /* src */
-                          int vcom_nfds,
-                          fd_set * __restrict vcom_readfds,
-                          fd_set * __restrict vcom_writefds,
-                          fd_set * __restrict vcom_exceptfds)
-{
-  nfds_t fds_idx = 0;
-
-
-  for (fds_idx = 0; fds_idx < __nfds; fds_idx++)
-    {
-      /* ignore negative fds */
-      if (__fds[fds_idx].fd < 0)
-       {
-         __fds[fds_idx].revents = 0;
-       }
-
-      /* for POLLRDHUP, POLLERR, POLLHUP and  POLLNVAL */
-      if (FD_ISSET (__fds[fds_idx].fd, vcom_exceptfds))
-       {
-         /*
-          * TBD: for now any select exception
-          *      is flagged as POLLERR
-          * */
-         __fds[fds_idx].revents |= POLLERR;
-       }
-
-      /* requested events */
-      if (__fds[fds_idx].events & POLLIN)
-       {
-         if (FD_ISSET (__fds[fds_idx].fd, vcom_readfds))
-           {
-             __fds[fds_idx].revents |= POLLIN;
-           }
-       }
-      if (__fds[fds_idx].events & POLLPRI)
-       {
-         if (FD_ISSET (__fds[fds_idx].fd, vcom_readfds))
-           {
-             __fds[fds_idx].revents |= POLLIN;
-           }
-       }
-      if (__fds[fds_idx].events & POLLOUT)
-       {
-         if (FD_ISSET (__fds[fds_idx].fd, vcom_writefds))
-           {
-             __fds[fds_idx].revents |= POLLOUT;
-           }
-       }
-#if defined __USE_XOPEN || defined __USE_XOPEN2K8
-      if (__fds[fds_idx].events & POLLRDNORM)
-       {
-         if (FD_ISSET (__fds[fds_idx].fd, vcom_readfds))
-           {
-             __fds[fds_idx].revents |= POLLRDNORM;
-           }
-       }
-      if (__fds[fds_idx].events & POLLRDBAND)
-       {
-         if (FD_ISSET (__fds[fds_idx].fd, vcom_readfds))
-           {
-             __fds[fds_idx].revents |= POLLRDBAND;
-           }
-       }
-      if (__fds[fds_idx].events & POLLWRNORM)
-       {
-         if (FD_ISSET (__fds[fds_idx].fd, vcom_writefds))
-           {
-             __fds[fds_idx].revents |= POLLWRNORM;
-           }
-       }
-      if (__fds[fds_idx].events & POLLWRBAND)
-       {
-         if (FD_ISSET (__fds[fds_idx].fd, vcom_writefds))
-           {
-             __fds[fds_idx].revents |= POLLWRBAND;
-           }
-       }
-#endif
-    }                          /* for (fds_idx = 0; fds_idx < __nfds; fds_idx++) */
-
-  /*
-   * nfd:
-   * the number of structures which have nonzero revents  fields
-   * (in  other  words,  those  descriptors  with events or
-   * errors reported)
-   * */
-  *nfd = 0;
-  for (fds_idx = 0; fds_idx < __nfds; fds_idx++)
-    {
-      /* ignore negative fds */
-      if (__fds[fds_idx].fd < 0)
-       {
-         continue;
-       }
-
-      if (__fds[fds_idx].revents)
-       {
-         (*nfd)++;
-       }
-    }
-}
-
-/*
- * PRE: parameters are validated,
- *      vcom_socket_poll is always called with __timeout set to zero
- *      hence returns immediately
- *
- * ACTION: handle non negative validated vcom fds and ignore rest
- */
-
-/*
- * implements vcom_socket_poll () interface
- *
- * internally uses vcom_socket_select ()
- * to realize the behavior
- * */
-int
-vcom_socket_poll_select_impl (struct pollfd *__fds, nfds_t __nfds,
-                             int __timeout)
-{
-  int rv;
-
-  nfds_t fds_idx = 0;
-  int nfd = 0;
-
-  /* vcom */
-  int vcom_nfds = 0;
-  fd_set vcom_readfds;
-  fd_set vcom_writefds;
-  fd_set vcom_exceptfds;
-  int vcom_nfd = -1;
-  /* invalid max_vcom_fd is -1 */
-  int max_vcom_fd = -1;
-
-  /* __timeout is zero to get ready events and return immediately */
-  struct timeval tv = {.tv_sec = 0,.tv_usec = 0 };
-
-  /* validate __nfds from select perspective */
-  if (__nfds > FD_SETSIZE)
-    {
-      rv = -EINVAL;
-      goto poll_done;
-    }
-
-  /* zero vcom fd sets */
-  /*
-   * V vcom fd set
-   */
-#define _(V)      \
-    FD_ZERO ((V))
-
-  _(&vcom_readfds);
-  _(&vcom_writefds);
-  _(&vcom_exceptfds);
-#undef _
-
-  vcom_nfds = 0;
-  vcom_nfd = -1;
-
-
-  for (fds_idx = 0; fds_idx < __nfds; fds_idx++)
-    {
-      /* ignore negative fds */
-      if (__fds[fds_idx].fd < 0)
-       {
-         continue;
-       }
-
-      /* non negative validated vcom fds */
-      if (__fds[fds_idx].fd > FD_SETSIZE)
-       {
-         rv = -EINVAL;
-         goto poll_done;
-       }
-
-      /* max_vcom_fd and vcom_nfd */
-      if (__fds[fds_idx].fd > max_vcom_fd)
-       {
-         /* requested events */
-         if (__fds[fds_idx].events)
-           {
-             max_vcom_fd = __fds[fds_idx].fd;
-           }
-       }
-      ++vcom_nfd;
-    }
-
-  vcom_nfds = max_vcom_fd != -1 ? max_vcom_fd + 1 : 0;
-
-  if (!vcom_nfds)
-    {
-      rv = vcom_nfds;
-      goto poll_done;
-    }
-
-  vcom_pollfds_2_selectfds (
-                            /* src */
-                            __fds, __nfds,
-                            /* dest */
-                            vcom_nfds,
-                            &vcom_readfds, &vcom_writefds, &vcom_exceptfds);
-
-  /* select on vcom fds */
-  vcom_nfd = vcom_socket_select (vcom_nfds,
-                                &vcom_readfds,
-                                &vcom_writefds, &vcom_exceptfds, &tv);
-  if (VCOM_DEBUG > 2)
-    fprintf (stderr,
-            "[%d] vcom_socket_select: "
-            "'%04d'='%04d'\n", getpid (), vcom_nfd, vcom_nfds);
-
-  if (vcom_nfd < 0)
-    {
-      rv = vcom_nfd;
-      goto poll_done;
-    }
-
-  vcom_selectfds_2_pollfds (
-                            /* dest */
-                            __fds, __nfds, &nfd,
-                            /* src */
-                            vcom_nfds,
-                            &vcom_readfds, &vcom_writefds, &vcom_exceptfds);
-
-  rv = nfd;
-
-poll_done:
-  return rv;
-}
-
-/*
- * TBD: remove this static function once vppcom
- *      has an implementation in place
- *
- * ACTION:
- */
-static int
-vppcom_poll (struct pollfd *__fds, nfds_t __nfds, double time_to_wait)
-{
-  return -EOPNOTSUPP;
-}
-
-int
-vcom_socket_poll_vppcom_impl (struct pollfd *__fds, nfds_t __nfds,
-                             int __timeout)
-{
-  nfds_t fds_idx = 0;
-
-  /* in seconds eg. 3.123456789 seconds */
-  double time_to_wait = (double) 0;
-
-  i32 sid;
-  i32 vep_idx;
-
-  /* replace vcom fd with session idx */
-  for (fds_idx = 0; fds_idx < __nfds; fds_idx++)
-    {
-      /* ignore negative fds */
-      if (__fds[fds_idx].fd < 0)
-       {
-         continue;
-       }
-
-      /* non negative validated vcom fds */
-      sid = vcom_socket_get_sid (__fds[fds_idx].fd);
-      if (sid != INVALID_SESSION_ID)
-       {
-         __fds[fds_idx].fd = sid;
-       }
-      else
-       {
-         /* get vep_idx */
-         vep_idx = vcom_socket_get_vep_idx (__fds[fds_idx].fd);
-         if (vep_idx != INVALID_VEP_IDX)
-           {
-             __fds[fds_idx].fd = vep_idx;
-           }
-         else
-           {
-             return -EBADF;
-           }
-       }
-    }
-
-  /* validate __timeout */
-  if (__timeout > 0)
-    {
-      time_to_wait = (double) __timeout / (double) 1000;
-    }
-  else if (__timeout == 0)
-    {
-      time_to_wait = (double) 0;
-    }
-  else
-    {
-      time_to_wait = ~0;
-    }
-
-  return vppcom_poll (__fds, __nfds, time_to_wait);
-}
-
-int
-vcom_socket_poll (struct pollfd *__fds, nfds_t __nfds, int __timeout)
-{
-  /* select an implementation */
-
-  /* return vcom_socket_poll_vppcom_impl (__fds, __nfds, __timeout); */
-  return vcom_socket_poll_select_impl (__fds, __nfds, __timeout);
-}
-
-#ifdef __USE_GNU
-int
-vcom_socket_ppoll (struct pollfd *__fds, nfds_t __nfds,
-                  const struct timespec *__timeout, const __sigset_t * __ss)
-{
-  return -EOPNOTSUPP;
-}
-#endif
-
-int
-vcom_socket_main_init (void)
-{
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-
-  if (VCOM_DEBUG > 0)
-    printf ("vcom_socket_main_init\n");
-
-  if (!vsm->init)
-    {
-      /* TBD: define FD_MAXSIZE and use it here */
-      pool_alloc (vsm->vsockets, FD_SETSIZE);
-      vsm->sockidx_by_fd = hash_create (0, sizeof (i32));
-
-      pool_alloc (vsm->vepolls, FD_SETSIZE);
-      vsm->epollidx_by_epfd = hash_create (0, sizeof (i32));
-
-      pool_alloc (vsm->vepitems, FD_SETSIZE);
-      vsm->epitemidx_by_epfdfd = hash_create (0, sizeof (i32));
-
-      vsm->epitemidxs_by_epfd = hash_create (0, sizeof (i32 *));
-      vsm->epitemidxs_by_fd = hash_create (0, sizeof (i32 *));
-
-      clib_time_init (&vsm->clib_time);
-
-      vsm->init = 1;
-    }
-
-  return 0;
-}
-
-
-void
-vcom_socket_main_show (void)
-{
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  vcom_socket_t *vsock;
-
-  vcom_epoll_t *vepoll;
-
-  vcom_epitem_t *vepitem;
-
-  i32 epfd;
-  i32 fd;
-  i32 *vepitemidxs, *vepitemidxs_var;
-
-  if (vsm->init)
-    {
-      /* from active list of vsockets show vsock */
-
-      /* *INDENT-OFF* */
-      pool_foreach (vsock, vsm->vsockets,
-        ({
-          printf(
-                 "fd='%04d', sid='%08x',type='%-30s'\n",
-                 vsock->fd, vsock->sid,
-                 vcom_socket_type_str (vsock->type));
-        }));
-      /* *INDENT-ON* */
-
-      /* from active list of vepolls, show vepoll */
-
-      /* *INDENT-OFF* */
-      pool_foreach (vepoll, vsm->vepolls,
-        ({
-          printf(
-                 "epfd='%04d', vep_idx='%08x', "
-                 "type='%-30s', "
-                 "flags='%d', count='%d', close='%d'\n",
-                 vepoll->epfd, vepoll->vep_idx,
-                 vcom_socket_epoll_type_str (vepoll->type),
-                 vepoll->flags, vepoll->count, vepoll->close);
-        }));
-      /* *INDENT-ON* */
-
-      /* from active list of vepitems, show vepitem */
-
-      /* *INDENT-OFF* */
-      pool_foreach (vepitem, vsm->vepitems,
-        ({
-          printf(
-                 "epfd='%04d', fd='%04d', "
-                 "next_fd='%04d', prev_fd='%04d', "
-                 "type='%-30s', "
-                 "events='%04x', revents='%04x'\n",
-                 vepitem->epfd, vepitem->fd,
-                 vepitem->next_fd, vepitem->prev_fd,
-                 vcom_socket_vcom_fd_type_str (vepitem->type),
-                 vepitem->event.events, vepitem->revent.events);
-        }));
-
-      /* *INDENT-ON* */
-
-      /* show epitemidxs for epfd */
-      /* *INDENT-OFF* */
-      hash_foreach (epfd, vepitemidxs,
-                    vsm->epitemidxs_by_epfd,
-      ({
-        printf("\n[ '%04d': ", epfd);
-        vec_foreach (vepitemidxs_var,vepitemidxs)
-        {
-          printf("'%04d' ", (int)vepitemidxs_var[0]);
-        }
-        printf("]\n");
-      }));
-      /* *INDENT-ON* */
-
-      /* show epitemidxs for fd */
-      /* *INDENT-OFF* */
-      hash_foreach (fd, vepitemidxs,
-                    vsm->epitemidxs_by_fd,
-      ({
-        printf("\n{ '%04d': ", fd);
-        vec_foreach (vepitemidxs_var,vepitemidxs)
-        {
-          printf("'%04d' ", (int)vepitemidxs_var[0]);
-        }
-        printf("}\n");
-      }));
-      /* *INDENT-ON* */
-
-    }
-}
-
-void
-vcom_socket_main_destroy (void)
-{
-  vcom_socket_main_t *vsm = &vcom_socket_main;
-  vcom_socket_t *vsock;
-
-  vcom_epoll_t *vepoll;
-
-  vcom_epitem_t *vepitem;
-
-  i32 epfd;
-  i32 fd;
-  i32 *vepitemidxs;
-
-
-  if (VCOM_DEBUG > 0)
-    printf ("vcom_socket_main_destroy\n");
-
-  if (vsm->init)
-    {
-
-      /*
-       * from active list of vepitems,
-       * remove all "vepitem" elements from the pool in a safe way
-       * */
-
-      /* *INDENT-OFF* */
-      pool_flush (vepitem, vsm->vepitems,
-        ({
-          if ((vepitem->type == FD_TYPE_EPOLL) ||
-              (vepitem->type == FD_TYPE_VCOM_SOCKET))
-          {
-             vcom_socket_epoll_ctl1 (vepitem->epfd, EPOLL_CTL_DEL,
-                                     vepitem->fd, NULL);
-             vepitem_init (vepitem);
-          }
-        }));
-      /* *INDENT-ON* */
-
-      pool_free (vsm->vepitems);
-      hash_free (vsm->epitemidx_by_epfdfd);
-
-      /* free vepitemidxs for each epfd */
-      /* *INDENT-OFF* */
-      hash_foreach (epfd, vepitemidxs,
-                    vsm->epitemidxs_by_epfd,
-      ({
-        vec_free (vepitemidxs);
-      }));
-      /* *INDENT-ON* */
-      hash_free (vsm->epitemidxs_by_epfd);
-
-      /* free vepitemidxs for each fd */
-      /* *INDENT-OFF* */
-      hash_foreach (fd, vepitemidxs,
-                    vsm->epitemidxs_by_fd,
-      ({
-        vec_free (vepitemidxs);
-      }));
-      /* *INDENT-ON* */
-      hash_free (vsm->epitemidxs_by_fd);
-
-
-      /*
-       * from active list of vsockets,
-       * close socket and vppcom session
-       * */
-
-      /* *INDENT-OFF* */
-      pool_foreach (vsock, vsm->vsockets,
-        ({
-          if (vsock->type == SOCKET_TYPE_VPPCOM_BOUND)
-            {
-              vppcom_session_close (vsock->sid);
-              vcom_socket_close_socket (vsock->fd);
-              vsocket_init (vsock);
-            }
-        }));
-      /* *INDENT-ON* */
-
-      /*
-       * return vsocket element to the pool
-       * */
-
-      /* *INDENT-OFF* */
-      pool_flush (vsock, vsm->vsockets,
-        ({
-          // vsocket_init(vsock);
-          ;
-        }));
-      /* *INDENT-ON* */
-
-      pool_free (vsm->vsockets);
-      hash_free (vsm->sockidx_by_fd);
-
-      /*
-       * from active list of vepolls,
-       * close epoll and vppcom_epoll
-       * */
-
-      /* *INDENT-OFF* */
-      pool_foreach (vepoll, vsm->vepolls,
-        ({
-          if (vepoll->type == EPOLL_TYPE_VPPCOM_BOUND)
-            {
-              vppcom_session_close (vepoll->vep_idx);
-              vcom_socket_close_epoll (vepoll->epfd); /* TBD: */
-              vepoll_init (vepoll);
-            }
-        }));
-      /* *INDENT-ON* */
-
-      /*
-       * return vepoll element to the pool
-       * */
-
-      /* *INDENT-OFF* */
-      pool_flush (vepoll, vsm->vepolls,
-        ({
-          // vepoll_init(vepoll);
-          ;
-        }));
-      /* *INDENT-ON* */
-
-      pool_free (vsm->vepolls);
-      hash_free (vsm->epollidx_by_epfd);
-
-      vsm->init = 0;
-    }
-}
-
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */