+/*
+ * 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 int
+vppcom_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 = vppcom_session_ioctl_va (vsock->sid, __cmd, __ap);
+ break;
+
+ default:
+ rv = -EINVAL;
+ break;
+ }
+
+ return rv;
+}
+