+ if (vec_len (wrk->unhandled_evts_vector))
+ {
+ for (i = 0; i < vec_len (wrk->unhandled_evts_vector); i++)
+ {
+ vcl_epoll_wait_handle_mq_event (wrk, &wrk->unhandled_evts_vector[i],
+ events, &n_evts);
+ if (n_evts == maxevents)
+ {
+ i += 1;
+ break;
+ }
+ }
+
+ vec_delete (wrk->unhandled_evts_vector, i, 0);
+ }
+
+ if (vcm->cfg.use_mq_eventfd)
+ return vppcom_epoll_wait_eventfd (wrk, events, maxevents, n_evts,
+ wait_for_time);
+
+ return vppcom_epoll_wait_condvar (wrk, events, maxevents, n_evts,
+ wait_for_time);
+}
+
+int
+vppcom_session_attr (uint32_t session_handle, uint32_t op,
+ void *buffer, uint32_t * buflen)
+{
+ vcl_worker_t *wrk = vcl_worker_get_current ();
+ vcl_session_t *session;
+ int rv = VPPCOM_OK;
+ u32 *flags = buffer;
+ vppcom_endpt_t *ep = buffer;
+
+ session = vcl_session_get_w_handle (wrk, session_handle);
+ if (!session)
+ return VPPCOM_EBADFD;
+
+ switch (op)
+ {
+ case VPPCOM_ATTR_GET_NREAD:
+ rv = vppcom_session_read_ready (session);
+ VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_NREAD: sid %u, nread = %d",
+ getpid (), rv);
+ break;
+
+ case VPPCOM_ATTR_GET_NWRITE:
+ rv = vppcom_session_write_ready (session);
+ VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_NWRITE: sid %u, nwrite = %d",
+ getpid (), session_handle, rv);
+ break;
+
+ case VPPCOM_ATTR_GET_FLAGS:
+ if (PREDICT_TRUE (buffer && buflen && (*buflen >= sizeof (*flags))))
+ {
+ *flags = O_RDWR | (VCL_SESS_ATTR_TEST (session->attr,
+ VCL_SESS_ATTR_NONBLOCK));
+ *buflen = sizeof (*flags);
+ VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_FLAGS: sid %u, flags = 0x%08x, "
+ "is_nonblocking = %u", getpid (),
+ session_handle, *flags,
+ VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK));
+ }
+ else
+ rv = VPPCOM_EINVAL;
+ break;
+
+ case VPPCOM_ATTR_SET_FLAGS:
+ if (PREDICT_TRUE (buffer && buflen && (*buflen == sizeof (*flags))))
+ {
+ if (*flags & O_NONBLOCK)
+ VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_NONBLOCK);
+ else
+ VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_NONBLOCK);
+
+ VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_FLAGS: sid %u, flags = 0x%08x,"
+ " is_nonblocking = %u",
+ getpid (), session_handle, *flags,
+ VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK));
+ }
+ else
+ rv = VPPCOM_EINVAL;
+ break;
+
+ case VPPCOM_ATTR_GET_PEER_ADDR:
+ if (PREDICT_TRUE (buffer && buflen &&
+ (*buflen >= sizeof (*ep)) && ep->ip))
+ {
+ ep->is_ip4 = session->transport.is_ip4;
+ ep->port = session->transport.rmt_port;
+ if (session->transport.is_ip4)
+ clib_memcpy_fast (ep->ip, &session->transport.rmt_ip.ip4,
+ sizeof (ip4_address_t));
+ else
+ clib_memcpy_fast (ep->ip, &session->transport.rmt_ip.ip6,
+ sizeof (ip6_address_t));
+ *buflen = sizeof (*ep);
+ VDBG (1, "VCL<%d>: VPPCOM_ATTR_GET_PEER_ADDR: sid %u, is_ip4 = %u, "
+ "addr = %U, port %u", getpid (),
+ session_handle, ep->is_ip4, format_ip46_address,
+ &session->transport.rmt_ip,
+ ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
+ clib_net_to_host_u16 (ep->port));
+ }
+ else
+ rv = VPPCOM_EINVAL;
+ break;
+
+ case VPPCOM_ATTR_GET_LCL_ADDR:
+ if (PREDICT_TRUE (buffer && buflen &&
+ (*buflen >= sizeof (*ep)) && ep->ip))
+ {
+ ep->is_ip4 = session->transport.is_ip4;
+ ep->port = session->transport.lcl_port;
+ if (session->transport.is_ip4)
+ clib_memcpy_fast (ep->ip, &session->transport.lcl_ip.ip4,
+ sizeof (ip4_address_t));
+ else
+ clib_memcpy_fast (ep->ip, &session->transport.lcl_ip.ip6,
+ sizeof (ip6_address_t));
+ *buflen = sizeof (*ep);
+ VDBG (1, "VCL<%d>: VPPCOM_ATTR_GET_LCL_ADDR: sid %u, is_ip4 = %u,"
+ " addr = %U port %d", getpid (),
+ session_handle, ep->is_ip4, format_ip46_address,
+ &session->transport.lcl_ip,
+ ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
+ clib_net_to_host_u16 (ep->port));
+ }
+ else
+ rv = VPPCOM_EINVAL;
+ break;
+
+ case VPPCOM_ATTR_GET_LIBC_EPFD:
+ rv = session->libc_epfd;
+ VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_LIBC_EPFD: libc_epfd %d",
+ getpid (), rv);
+ break;
+
+ case VPPCOM_ATTR_SET_LIBC_EPFD:
+ if (PREDICT_TRUE (buffer && buflen &&
+ (*buflen == sizeof (session->libc_epfd))))
+ {
+ session->libc_epfd = *(int *) buffer;
+ *buflen = sizeof (session->libc_epfd);
+
+ VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_LIBC_EPFD: libc_epfd %d, "
+ "buflen %d", getpid (), session->libc_epfd, *buflen);
+ }
+ else
+ rv = VPPCOM_EINVAL;
+ break;
+
+ case VPPCOM_ATTR_GET_PROTOCOL:
+ if (buffer && buflen && (*buflen >= sizeof (int)))
+ {
+ *(int *) buffer = session->session_type;
+ *buflen = sizeof (int);
+
+ VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_PROTOCOL: %d (%s), buflen %d",
+ getpid (), *(int *) buffer, *(int *) buffer ? "UDP" : "TCP",
+ *buflen);
+ }
+ else
+ rv = VPPCOM_EINVAL;
+ break;
+
+ case VPPCOM_ATTR_GET_LISTEN:
+ if (buffer && buflen && (*buflen >= sizeof (int)))
+ {
+ *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
+ VCL_SESS_ATTR_LISTEN);
+ *buflen = sizeof (int);
+
+ VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_LISTEN: %d, buflen %d",
+ getpid (), *(int *) buffer, *buflen);
+ }
+ else
+ rv = VPPCOM_EINVAL;
+ break;
+
+ case VPPCOM_ATTR_GET_ERROR:
+ if (buffer && buflen && (*buflen >= sizeof (int)))
+ {
+ *(int *) buffer = 0;
+ *buflen = sizeof (int);
+
+ VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_ERROR: %d, buflen %d, #VPP-TBD#",
+ getpid (), *(int *) buffer, *buflen);
+ }
+ else
+ rv = VPPCOM_EINVAL;
+ break;
+
+ case VPPCOM_ATTR_GET_TX_FIFO_LEN:
+ if (buffer && buflen && (*buflen >= sizeof (u32)))
+ {
+
+ /* VPP-TBD */
+ *(size_t *) buffer = (session->sndbuf_size ? session->sndbuf_size :
+ session->tx_fifo ? session->tx_fifo->nitems :
+ vcm->cfg.tx_fifo_size);
+ *buflen = sizeof (u32);
+
+ VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_TX_FIFO_LEN: %u (0x%x), "
+ "buflen %d, #VPP-TBD#", getpid (),
+ *(size_t *) buffer, *(size_t *) buffer, *buflen);
+ }
+ else
+ rv = VPPCOM_EINVAL;
+ break;
+
+ case VPPCOM_ATTR_SET_TX_FIFO_LEN:
+ if (buffer && buflen && (*buflen == sizeof (u32)))
+ {
+ /* VPP-TBD */
+ session->sndbuf_size = *(u32 *) buffer;
+ VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_TX_FIFO_LEN: %u (0x%x), "
+ "buflen %d, #VPP-TBD#", getpid (),
+ session->sndbuf_size, session->sndbuf_size, *buflen);
+ }
+ else
+ rv = VPPCOM_EINVAL;
+ break;
+
+ case VPPCOM_ATTR_GET_RX_FIFO_LEN:
+ if (buffer && buflen && (*buflen >= sizeof (u32)))
+ {
+
+ /* VPP-TBD */
+ *(size_t *) buffer = (session->rcvbuf_size ? session->rcvbuf_size :
+ session->rx_fifo ? session->rx_fifo->nitems :
+ vcm->cfg.rx_fifo_size);
+ *buflen = sizeof (u32);
+
+ VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_RX_FIFO_LEN: %u (0x%x), "
+ "buflen %d, #VPP-TBD#", getpid (),
+ *(size_t *) buffer, *(size_t *) buffer, *buflen);
+ }
+ else
+ rv = VPPCOM_EINVAL;
+ break;
+
+ case VPPCOM_ATTR_SET_RX_FIFO_LEN:
+ if (buffer && buflen && (*buflen == sizeof (u32)))
+ {
+ /* VPP-TBD */
+ session->rcvbuf_size = *(u32 *) buffer;
+ VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_RX_FIFO_LEN: %u (0x%x), "
+ "buflen %d, #VPP-TBD#", getpid (),
+ session->sndbuf_size, session->sndbuf_size, *buflen);
+ }
+ else
+ rv = VPPCOM_EINVAL;
+ break;