+svm_msg_q_t *
+vcl_worker_ctrl_mq (vcl_worker_t * wrk)
+{
+ return wrk->ctrl_mq;
+}
+
+void
+vcl_cleanup_bapi (void)
+{
+ socket_client_main_t *scm = &socket_client_main;
+ api_main_t *am = vlibapi_get_main ();
+
+ am->my_client_index = ~0;
+ am->my_registration = 0;
+ am->vl_input_queue = 0;
+ am->msg_index_by_name_and_crc = 0;
+ scm->socket_fd = 0;
+
+ vl_client_api_unmap ();
+}
+
+int
+vcl_session_read_ready (vcl_session_t * session)
+{
+ u32 max_deq;
+
+ /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
+ if (PREDICT_FALSE (session->is_vep))
+ {
+ VDBG (0, "ERROR: session %u: cannot read from an epoll session!",
+ session->session_index);
+ return VPPCOM_EBADFD;
+ }
+
+ if (PREDICT_FALSE (!(session->session_state & (STATE_OPEN | STATE_LISTEN))))
+ {
+ vcl_session_state_t state = session->session_state;
+ int rv;
+
+ rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
+
+ VDBG (1, "session %u [0x%llx]: not open! state 0x%x (%s), ret %d (%s)",
+ session->session_index, session->vpp_handle, state,
+ vppcom_session_state_str (state), rv, vppcom_retval_str (rv));
+ return rv;
+ }
+
+ if (session->session_state & STATE_LISTEN)
+ return clib_fifo_elts (session->accept_evts_fifo);
+
+ if (vcl_session_is_ct (session))
+ return svm_fifo_max_dequeue_cons (session->ct_rx_fifo);
+
+ max_deq = svm_fifo_max_dequeue_cons (session->rx_fifo);
+
+ if (session->is_dgram)
+ {
+ session_dgram_pre_hdr_t ph;
+
+ if (max_deq <= SESSION_CONN_HDR_LEN)
+ return 0;
+ if (svm_fifo_peek (session->rx_fifo, 0, sizeof (ph), (u8 *) & ph) < 0)
+ return 0;
+ if (ph.data_length + SESSION_CONN_HDR_LEN > max_deq)
+ return 0;
+
+ return ph.data_length;
+ }
+
+ return max_deq;
+}
+
+int
+vcl_session_write_ready (vcl_session_t * session)
+{
+ /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
+ if (PREDICT_FALSE (session->is_vep))
+ {
+ VDBG (0, "session %u [0x%llx]: cannot write to an epoll session!",
+ session->session_index, session->vpp_handle);
+ return VPPCOM_EBADFD;
+ }
+
+ if (PREDICT_FALSE (session->session_state & STATE_LISTEN))
+ {
+ if (session->tx_fifo)
+ return svm_fifo_max_enqueue_prod (session->tx_fifo);
+ else
+ return VPPCOM_EBADFD;
+ }
+
+ if (PREDICT_FALSE (!(session->session_state & STATE_OPEN)))
+ {
+ vcl_session_state_t state = session->session_state;
+ int rv;
+
+ rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
+ VDBG (0, "session %u [0x%llx]: not open! state 0x%x (%s), ret %d (%s)",
+ session->session_index, session->vpp_handle, state,
+ vppcom_session_state_str (state), rv, vppcom_retval_str (rv));
+ return rv;
+ }
+
+ if (vcl_session_is_ct (session))
+ return svm_fifo_max_enqueue_prod (session->ct_tx_fifo);
+
+ if (session->is_dgram)
+ {
+ u32 max_enq = svm_fifo_max_enqueue_prod (session->tx_fifo);
+
+ if (max_enq <= sizeof (session_dgram_hdr_t))
+ return 0;
+ return max_enq - sizeof (session_dgram_hdr_t);
+ }
+
+ return svm_fifo_max_enqueue_prod (session->tx_fifo);
+}
+
+int
+vcl_segment_attach (u64 segment_handle, char *name, ssvm_segment_type_t type,
+ int fd)
+{
+ fifo_segment_create_args_t _a, *a = &_a;
+ int rv;
+
+ memset (a, 0, sizeof (*a));
+ a->segment_name = name;
+ a->segment_type = type;
+
+ if (type == SSVM_SEGMENT_MEMFD)
+ a->memfd_fd = fd;
+
+ clib_rwlock_writer_lock (&vcm->segment_table_lock);
+
+ if ((rv = fifo_segment_attach (&vcm->segment_main, a)))
+ {
+ clib_warning ("svm_fifo_segment_attach ('%s') failed", name);
+ return rv;
+ }
+ hash_set (vcm->segment_table, segment_handle, a->new_segment_indices[0]);
+
+ clib_rwlock_writer_unlock (&vcm->segment_table_lock);
+
+ vec_reset_length (a->new_segment_indices);
+ return 0;
+}
+
+u32
+vcl_segment_table_lookup (u64 segment_handle)
+{
+ uword *seg_indexp;
+
+ clib_rwlock_reader_lock (&vcm->segment_table_lock);
+ seg_indexp = hash_get (vcm->segment_table, segment_handle);
+ clib_rwlock_reader_unlock (&vcm->segment_table_lock);
+
+ if (!seg_indexp)
+ return VCL_INVALID_SEGMENT_INDEX;
+ return ((u32) * seg_indexp);
+}
+
+void
+vcl_segment_detach (u64 segment_handle)
+{
+ fifo_segment_main_t *sm = &vcm->segment_main;
+ fifo_segment_t *segment;
+ u32 segment_index;
+
+ segment_index = vcl_segment_table_lookup (segment_handle);
+ if (segment_index == (u32) ~ 0)
+ return;
+
+ clib_rwlock_writer_lock (&vcm->segment_table_lock);
+
+ segment = fifo_segment_get_segment (sm, segment_index);
+ fifo_segment_delete (sm, segment);
+ hash_unset (vcm->segment_table, segment_handle);
+
+ clib_rwlock_writer_unlock (&vcm->segment_table_lock);
+
+ VDBG (0, "detached segment %u handle %u", segment_index, segment_handle);
+}
+
+