/*
 * 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;

} 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;

  if (__cmd == FIONREAD)
    rv = vppcom_session_attr (__sid, VPPCOM_ATTR_GET_NREAD, 0, 0);
  else
    rv = -EOPNOTSUPP;
  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;
  vcom_socket_main_t *vsm = &vcom_socket_main;
  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", vsm->my_pid);
	  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",
		   vsm->my_pid, 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", vsm->my_pid, 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_session_getsockname (int sid, vppcom_endpt_t * ep)
{
  int rv;
  uint32_t size = sizeof (*ep);

  rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LCL_ADDR, ep, &size);
  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;


  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;

  vppcom_endpt_t ep;
  ep.ip = (u8 *) & ((const struct sockaddr_in *) __addr)->sin_addr;
  rv = vcom_session_getsockname (vsock->sid, &ep);
  if (rv == 0)
    {
      if (ep.vrf == VPPCOM_VRF_DEFAULT)
	{
	  __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;
	      *__len = sizeof (struct sockaddr_in);
	      break;

	    case AF_INET6:
	      ((struct sockaddr_in6 *) __addr)->sin6_port = ep.port;
	      *__len = sizeof (struct sockaddr_in6);
	      break;

	    default:
	      break;
	    }
	}
    }

  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;


  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;

  vppcom_endpt_t ep;
  ep.ip = (u8 *) & ((const struct sockaddr_in *) __addr)->sin_addr;
  rv = vcom_session_getpeername (vsock->sid, &ep);
  if (rv == 0)
    {
      if (ep.vrf == VPPCOM_VRF_DEFAULT)
	{
	  __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;
	      *__len = sizeof (struct sockaddr_in);
	      break;

	    case AF_INET6:
	      ((struct sockaddr_in6 *) __addr)->sin6_port = ep.port;
	      *__len = sizeof (struct sockaddr_in6);
	      break;

	    default:
	      break;
	    }
	}
    }

  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);
}

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)
	{
	  if (ep.vrf == VPPCOM_VRF_DEFAULT)
	    {
	      __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;
		  memcpy (&((struct sockaddr_in *) __addr)->sin_addr,
			  src_addr, sizeof (struct in_addr));

		  *__addr_len = sizeof (struct sockaddr_in);
		  break;

		case AF_INET6:
		  ((struct sockaddr_in6 *) __addr)->sin6_port = ep.port;
		  memcpy (((struct sockaddr_in6 *) __addr)->sin6_addr.
			  __in6_u.__u6_addr8, src_addr,
			  sizeof (struct in6_addr));
		  *__addr_len = sizeof (struct sockaddr_in6);
		  break;

		default:
		  rv = -EAFNOSUPPORT;
		  break;
		}
	    }
	  else
	    rv = -1;
	}
    }
  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 (!(!flags || (flags & (SOCK_NONBLOCK | SOCK_CLOEXEC))))
    {
      /* TBD: return proper error code */
      return -1;
    }

  /* TBD: return proper error code */

  if (!vcom_socket_is_connection_mode_socket (__fd))
    {
      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)
	{
	  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,
				      -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, 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)
	{
	  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)
	{
	  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;
		}
	    }
	}
      else
	{
	  /* when __addr is NULL, nothing is filled in,
	   * in this case, __addr_len is not used,
	   * and should also be null
	   * */
	  if (__addr_len)
	    {
	      /* TBD: return proper error code */
	      return -1;
	    }
	}
    }

  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);
}

#ifdef __USE_GNU
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);
}
#endif

/* 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)
{
  vcom_socket_main_t *vsm = &vcom_socket_main;
  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",
		 vsm->my_pid, 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",
		 vsm->my_pid, 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;
  int rv2;
  double time_to_wait = (double) 0;
  double timeout;
  vcom_epoll_t *vepoll;
  i32 vep_idx;
  static struct epoll_event *libc_ev = 0;

  /* validate __event */
  if (!__events || (__timeout < -1))
    {
      fprintf (stderr, "[%d] ERROR: vcom_socket_epoll_pwait: "
	       "Bad args __events %p, __timeout %d\n", vsm->my_pid,
	       __events, __timeout);
      rv = -EFAULT;
      goto out;
    }

  time_to_wait = ((__timeout > 0) ?
		  (double) __timeout / (double) 1000 : (double) __timeout);

  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", vsm->my_pid, __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",
	       vsm->my_pid, vepoll->count, vepoll->vcl_cnt, vepoll->libc_cnt);
      rv = -EINVAL;
      goto out;
    }

  if (vepoll->libc_cnt == 0)
    {
      rv = vppcom_epoll_wait (vep_idx, __events, __maxevents, time_to_wait);
    }
  else if (vepoll->vcl_cnt == 0)
    {
      rv = libc_epoll_pwait (__epfd, __events, __maxevents, __timeout, __ss);
    }
  else
    {
      vec_validate (libc_ev, __maxevents);
      timeout = clib_time_now (&vsm->clib_time) + time_to_wait;
      do
	{
	  rv = vppcom_epoll_wait (vep_idx, __events, __maxevents, 0);
	  rv2 = libc_epoll_pwait (__epfd, libc_ev, __maxevents, 1, __ss);
	  if ((rv > 0) || (rv2 > 0))
	    {
	      int n = __maxevents - rv;
	      n = rv2 <= n ? rv2 : n;
	      rv = (rv > 0) ? rv : 0;

	      clib_memcpy (&__events[rv], libc_ev, n * sizeof (*libc_ev));
	      rv += rv2;
	      goto out;
	    }
	  else if ((rv < 0) || (rv2 < 0))
	    {
	      if (rv < 0)
		fprintf (stderr,
			 "[%d] ERROR: vppcom_epoll_wait() returned %d\n",
			 vsm->my_pid, rv);
	      if (rv2 < 0)
		{
		  fprintf (stderr,
			   "[%d] ERROR: libc_epoll_wait() failed, errno %d\n",
			   vsm->my_pid, errno);
		  rv = (rv < 0) ? rv : -errno;
		}
	      goto out;
	    }
	}
      while ((__timeout == -1)
	     || (clib_time_now (&vsm->clib_time) < timeout));
    }

out:
  vec_reset_length (libc_ev);
  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;
  vcom_socket_main_t *vsm = &vcom_socket_main;

  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", vsm->my_pid, 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->my_pid = getpid ();

      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:
 */
