__thread uword __vcl_worker_index = ~0;
-static int
-vcl_segment_is_not_mounted (vcl_worker_t * wrk, u64 segment_handle)
-{
- u32 segment_index;
-
- if (segment_handle == VCL_INVALID_SEGMENT_HANDLE)
- return 0;
-
- segment_index = vcl_segment_table_lookup (segment_handle);
- if (segment_index != VCL_INVALID_SEGMENT_INDEX)
- return 0;
-
- return 1;
-}
-
static inline int
vcl_mq_dequeue_batch (vcl_worker_t * wrk, svm_msg_q_t * mq, u32 n_max_msg)
{
clib_memcpy_fast (&mp->ip, &s->transport.lcl_ip, sizeof (mp->ip));
mp->port = s->transport.lcl_port;
mp->proto = s->session_type;
+ mp->ckpair_index = s->ckpair_index;
+ mp->vrf = s->vrf;
if (s->flags & VCL_SESSION_F_CONNECTED)
mp->flags = TRANSPORT_CFG_F_CONNECTED;
app_send_ctrl_evt_to_vpp (mq, app_evt);
mp->port = s->transport.rmt_port;
mp->lcl_port = s->transport.lcl_port;
mp->proto = s->session_type;
+ mp->ckpair_index = s->ckpair_index;
+ mp->vrf = s->vrf;
if (s->flags & VCL_SESSION_F_CONNECTED)
mp->flags |= TRANSPORT_CFG_F_CONNECTED;
app_send_ctrl_evt_to_vpp (mq, app_evt);
}
static void
-vcl_send_session_disconnected_reply (svm_msg_q_t * mq, u32 context,
- session_handle_t handle, int retval)
+vcl_send_session_disconnected_reply (vcl_worker_t * wrk, vcl_session_t * s,
+ int retval)
{
app_session_evt_t _app_evt, *app_evt = &_app_evt;
session_disconnected_reply_msg_t *rmp;
- app_alloc_ctrl_evt_to_vpp (mq, app_evt,
+ app_alloc_ctrl_evt_to_vpp (s->vpp_evt_q, app_evt,
SESSION_CTRL_EVT_DISCONNECTED_REPLY);
rmp = (session_disconnected_reply_msg_t *) app_evt->evt->data;
- rmp->handle = handle;
- rmp->context = context;
+ rmp->handle = s->vpp_handle;
+ rmp->context = wrk->api_client_handle;
rmp->retval = retval;
- app_send_ctrl_evt_to_vpp (mq, app_evt);
+ app_send_ctrl_evt_to_vpp (s->vpp_evt_q, app_evt);
}
static void
-vcl_send_session_reset_reply (svm_msg_q_t * mq, u32 context,
- session_handle_t handle, int retval)
+vcl_send_session_reset_reply (vcl_worker_t * wrk, vcl_session_t * s,
+ int retval)
{
app_session_evt_t _app_evt, *app_evt = &_app_evt;
session_reset_reply_msg_t *rmp;
- app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_RESET_REPLY);
+ app_alloc_ctrl_evt_to_vpp (s->vpp_evt_q, app_evt,
+ SESSION_CTRL_EVT_RESET_REPLY);
rmp = (session_reset_reply_msg_t *) app_evt->evt->data;
- rmp->handle = handle;
- rmp->context = context;
+ rmp->handle = s->vpp_handle;
+ rmp->context = wrk->api_client_handle;
rmp->retval = retval;
- app_send_ctrl_evt_to_vpp (mq, app_evt);
+ app_send_ctrl_evt_to_vpp (s->vpp_evt_q, app_evt);
}
void
{
app_session_evt_t _app_evt, *app_evt = &_app_evt;
session_worker_update_msg_t *mp;
- svm_msg_q_t *mq;
- mq = vcl_session_vpp_evt_q (wrk, s);
- app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_WORKER_UPDATE);
+ app_alloc_ctrl_evt_to_vpp (s->vpp_evt_q, app_evt,
+ SESSION_CTRL_EVT_WORKER_UPDATE);
mp = (session_worker_update_msg_t *) app_evt->evt->data;
mp->client_index = wrk->api_client_handle;
mp->handle = s->vpp_handle;
mp->req_wrk_index = wrk->vpp_wrk_index;
mp->wrk_index = wrk_index;
- app_send_ctrl_evt_to_vpp (mq, app_evt);
+ app_send_ctrl_evt_to_vpp (s->vpp_evt_q, app_evt);
}
int
u32 ls_index)
{
vcl_session_t *session, *listen_session;
- svm_fifo_t *rx_fifo, *tx_fifo;
- u32 vpp_wrk_index;
svm_msg_q_t *evt_q;
session = vcl_session_alloc (wrk);
goto error;
}
- if (vcl_segment_is_not_mounted (wrk, mp->segment_handle))
+ if (vcl_segment_attach_session (mp->segment_handle, mp->server_rx_fifo,
+ mp->server_tx_fifo,
+ mp->vpp_event_queue_address, 0, session))
{
- VDBG (0, "ERROR: segment for session %u is not mounted!",
- session->session_index);
+ VDBG (0, "failed to attach fifos for %u", session->session_index);
goto error;
}
- rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
- tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
- session->vpp_evt_q = uword_to_pointer (mp->vpp_event_queue_address,
- svm_msg_q_t *);
- rx_fifo->client_session_index = session->session_index;
- tx_fifo->client_session_index = session->session_index;
- rx_fifo->client_thread_index = vcl_get_worker_index ();
- tx_fifo->client_thread_index = vcl_get_worker_index ();
- vpp_wrk_index = tx_fifo->master_thread_index;
- vec_validate (wrk->vpp_event_queues, vpp_wrk_index);
- wrk->vpp_event_queues[vpp_wrk_index] = session->vpp_evt_q;
-
session->vpp_handle = mp->handle;
- session->vpp_thread_index = rx_fifo->master_thread_index;
- session->rx_fifo = rx_fifo;
- session->tx_fifo = tx_fifo;
-
session->session_state = VCL_STATE_READY;
session->transport.rmt_port = mp->rmt.port;
session->transport.is_ip4 = mp->rmt.is_ip4;
return session->session_index;
error:
- evt_q = uword_to_pointer (mp->vpp_event_queue_address, svm_msg_q_t *);
+ vcl_segment_attach_mq (vcl_vpp_worker_segment_handle (0),
+ mp->vpp_event_queue_address, mp->mq_index, &evt_q);
vcl_send_session_accepted_reply (evt_q, mp->context, mp->handle,
VNET_API_ERROR_INVALID_ARGUMENT);
vcl_session_free (wrk, session);
vcl_session_connected_handler (vcl_worker_t * wrk,
session_connected_msg_t * mp)
{
- u32 session_index, vpp_wrk_index;
- svm_fifo_t *rx_fifo, *tx_fifo;
vcl_session_t *session = 0;
+ u32 session_index;
session_index = mp->context;
session = vcl_session_get (wrk, session_index);
}
session->vpp_handle = mp->handle;
- session->vpp_evt_q = uword_to_pointer (mp->vpp_event_queue_address,
- svm_msg_q_t *);
- rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
- tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
- if (vcl_segment_is_not_mounted (wrk, mp->segment_handle))
+
+ if (vcl_segment_attach_session (mp->segment_handle, mp->server_rx_fifo,
+ mp->server_tx_fifo,
+ mp->vpp_event_queue_address, 0, session))
{
- VDBG (0, "segment for session %u is not mounted!",
- session->session_index);
+ VDBG (0, "failed to attach fifos for %u", session->session_index);
session->session_state = VCL_STATE_DETACHED;
vcl_send_session_disconnect (wrk, session);
return session_index;
}
- rx_fifo->client_session_index = session_index;
- tx_fifo->client_session_index = session_index;
- rx_fifo->client_thread_index = vcl_get_worker_index ();
- tx_fifo->client_thread_index = vcl_get_worker_index ();
-
- vpp_wrk_index = tx_fifo->master_thread_index;
- vec_validate (wrk->vpp_event_queues, vpp_wrk_index);
- wrk->vpp_event_queues[vpp_wrk_index] = session->vpp_evt_q;
-
if (mp->ct_rx_fifo)
{
- session->ct_rx_fifo = uword_to_pointer (mp->ct_rx_fifo, svm_fifo_t *);
- session->ct_tx_fifo = uword_to_pointer (mp->ct_tx_fifo, svm_fifo_t *);
- if (vcl_segment_is_not_mounted (wrk, mp->ct_segment_handle))
+ if (vcl_segment_attach_session (mp->ct_segment_handle, mp->ct_rx_fifo,
+ mp->ct_tx_fifo, (uword) ~0, 1, session))
{
- VDBG (0, "ct segment for session %u is not mounted!",
- session->session_index);
+ VDBG (0, "failed to attach ct fifos for %u", session->session_index);
session->session_state = VCL_STATE_DETACHED;
vcl_send_session_disconnect (wrk, session);
return session_index;
}
}
- session->rx_fifo = rx_fifo;
- session->tx_fifo = tx_fifo;
- session->vpp_thread_index = rx_fifo->master_thread_index;
session->transport.is_ip4 = mp->lcl.is_ip4;
clib_memcpy_fast (&session->transport.lcl_ip, &mp->lcl.ip,
sizeof (session->transport.lcl_ip));
vcl_session_table_add_listener (wrk, mp->handle, sid);
session->session_state = VCL_STATE_LISTEN;
- session->vpp_evt_q = uword_to_pointer (mp->vpp_evt_q, svm_msg_q_t *);
- vec_validate (wrk->vpp_event_queues, 0);
- wrk->vpp_event_queues[0] = session->vpp_evt_q;
-
if (vcl_session_is_cl (session))
{
- svm_fifo_t *rx_fifo, *tx_fifo;
- session->vpp_evt_q = uword_to_pointer (mp->vpp_evt_q, svm_msg_q_t *);
- rx_fifo = uword_to_pointer (mp->rx_fifo, svm_fifo_t *);
- rx_fifo->client_session_index = sid;
- tx_fifo = uword_to_pointer (mp->tx_fifo, svm_fifo_t *);
- tx_fifo->client_session_index = sid;
- session->rx_fifo = rx_fifo;
- session->tx_fifo = tx_fifo;
+ if (vcl_segment_attach_session (mp->segment_handle, mp->rx_fifo,
+ mp->tx_fifo, mp->vpp_evt_q, 0, session))
+ {
+ VDBG (0, "failed to attach fifos for %u", session->session_index);
+ session->session_state = VCL_STATE_DETACHED;
+ return VCL_INVALID_SESSION_INDEX;
+ }
}
VDBG (0, "session %u [0x%llx]: listen succeeded!", sid, mp->handle);
{
session_migrated_msg_t *mp = (session_migrated_msg_t *) data;
vcl_session_t *s;
+ u32 fs_index;
s = vcl_session_get_w_vpp_handle (wrk, mp->handle);
if (!s)
return;
}
- s->vpp_thread_index = mp->vpp_thread_index;
+ fs_index = vcl_segment_table_lookup (mp->segment_handle);
+ if (fs_index == VCL_INVALID_SEGMENT_INDEX)
+ {
+ VDBG (0, "segment for session %u is not mounted!", s->session_index);
+ s->session_state = VCL_STATE_DETACHED;
+ return;
+ }
+
s->vpp_handle = mp->new_handle;
- s->vpp_evt_q = uword_to_pointer (mp->vpp_evt_q, svm_msg_q_t *);
- vec_validate (wrk->vpp_event_queues, s->vpp_thread_index);
- wrk->vpp_event_queues[s->vpp_thread_index] = s->vpp_evt_q;
+ vcl_segment_attach_mq (vcl_vpp_worker_segment_handle (0), mp->vpp_evt_q,
+ mp->vpp_thread_index, &s->vpp_evt_q);
vcl_session_table_del_vpp_handle (wrk, mp->handle);
vcl_session_table_add_vpp_handle (wrk, mp->new_handle, s->session_index);
/* Generate new tx event if we have outstanding data */
if (svm_fifo_has_event (s->tx_fifo))
- app_send_io_evt_to_vpp (s->vpp_evt_q, s->tx_fifo->master_session_index,
+ app_send_io_evt_to_vpp (s->vpp_evt_q,
+ s->tx_fifo->shr->master_session_index,
SESSION_IO_EVT_TX, SVM_Q_WAIT);
VDBG (0, "Migrated 0x%lx to thread %u 0x%lx", mp->handle,
- s->vpp_thread_index, mp->new_handle);
+ mp->vpp_thread_index, mp->new_handle);
}
static vcl_session_t *
vppcom_session_disconnect (u32 session_handle)
{
vcl_worker_t *wrk = vcl_worker_get_current ();
- svm_msg_q_t *vpp_evt_q;
vcl_session_t *session, *listen_session;
vcl_session_state_t state;
u64 vpp_handle;
if (state == VCL_STATE_VPP_CLOSING)
{
- vpp_evt_q = vcl_session_vpp_evt_q (wrk, session);
- vcl_send_session_disconnected_reply (vpp_evt_q, wrk->api_client_handle,
- vpp_handle, 0);
+ vcl_send_session_disconnected_reply (wrk, session, 0);
VDBG (1, "session %u [0x%llx]: sending disconnect REPLY...",
session->session_index, vpp_handle);
}
}
else if (session->session_state == VCL_STATE_DISCONNECT)
{
- vcl_send_session_reset_reply (vcl_session_vpp_evt_q (wrk, session),
- wrk->api_client_handle,
- session->vpp_handle, 0);
+ vcl_send_session_reset_reply (wrk, session, 0);
session->session_state = VCL_STATE_UPDATED;
}
return;
VDBG (0, "unknown handle 0x%llx", msg->handle);
return;
}
- if (vcl_segment_is_not_mounted (wrk, msg->segment_handle))
- {
- clib_warning ("segment for session %u is not mounted!",
- s->session_index);
- return;
- }
if (s->rx_fifo)
{
- s->rx_fifo = uword_to_pointer (msg->rx_fifo, svm_fifo_t *);
- s->tx_fifo = uword_to_pointer (msg->tx_fifo, svm_fifo_t *);
- s->rx_fifo->client_session_index = s->session_index;
- s->tx_fifo->client_session_index = s->session_index;
- s->rx_fifo->client_thread_index = wrk->wrk_index;
- s->tx_fifo->client_thread_index = wrk->wrk_index;
+ if (vcl_segment_attach_session (msg->segment_handle, msg->rx_fifo,
+ msg->tx_fifo, (uword) ~0, 0, s))
+ {
+ VDBG (0, "failed to attach fifos for %u", s->session_index);
+ return;
+ }
}
s->session_state = VCL_STATE_UPDATED;
vcl_session_table_del_vpp_handle (wrk, accepted_msg->handle);
vcl_send_session_accepted_reply (session->vpp_evt_q,
accepted_msg->context,
- session->vpp_handle, -1);
+ accepted_msg->handle, -1);
}
clib_fifo_free (session->accept_evts_fifo);
current_wrk = vcl_worker_get_current ();
/* *INDENT-OFF* */
- pool_foreach (wrk, vcm->workers, ({
+ pool_foreach (wrk, vcm->workers) {
if (current_wrk != wrk)
vcl_worker_cleanup (wrk, 0 /* notify vpp */ );
- }));
+ }
/* *INDENT-ON* */
vcl_api_detach (current_wrk);
session->session_type = proto;
session->session_state = VCL_STATE_CLOSED;
session->vpp_handle = ~0;
+ session->ckpair_index = ~0;
session->is_dgram = vcl_proto_is_dgram (proto);
if (is_nonblocking)
}
else if (s->session_state == VCL_STATE_DISCONNECT)
{
- svm_msg_q_t *mq = vcl_session_vpp_evt_q (wrk, s);
- vcl_send_session_reset_reply (mq, wrk->api_client_handle,
- s->vpp_handle, 0);
+ vcl_send_session_reset_reply (wrk, s, 0);
}
else if (s->session_state == VCL_STATE_DETACHED)
{
e->session_index = s->session_index;
}
}
- else if (PREDICT_FALSE (rv < n))
+ else if (PREDICT_FALSE (rv < n && !s->is_dgram))
{
/* More data enqueued while reading. Try to drain it
- * or fill the buffer */
+ * or fill the buffer. Avoid doing that for dgrams */
buf += rv;
n -= rv;
goto read_again;
if (PREDICT_FALSE (svm_fifo_needs_deq_ntf (rx_fifo, n_read)))
{
svm_fifo_clear_deq_ntf (rx_fifo);
- app_send_io_evt_to_vpp (s->vpp_evt_q, s->rx_fifo->master_session_index,
+ app_send_io_evt_to_vpp (s->vpp_evt_q,
+ s->rx_fifo->shr->master_session_index,
SESSION_IO_EVT_RX, SVM_Q_WAIT);
}
0 /* do_evt */ , SVM_Q_WAIT);
if (svm_fifo_set_event (s->tx_fifo))
- app_send_io_evt_to_vpp (s->vpp_evt_q, s->tx_fifo->master_session_index,
- et, SVM_Q_WAIT);
+ app_send_io_evt_to_vpp (
+ s->vpp_evt_q, s->tx_fifo->shr->master_session_index, et, SVM_Q_WAIT);
/* The underlying fifo segment can run out of memory */
if (PREDICT_FALSE (n_write < 0))
{
u32 sid, minbits = clib_max (n_bits, BITS (uword)), bits_set = 0;
vcl_worker_t *wrk = vcl_worker_get_current ();
- vcl_session_t *session = 0;
+ vcl_session_t *s = 0;
int i;
if (n_bits && read_map)
if (!write_map)
goto check_rd;
- /* *INDENT-OFF* */
- clib_bitmap_foreach (sid, wrk->wr_bitmap, ({
- if (!(session = vcl_session_get (wrk, sid)))
- {
- clib_bitmap_set_no_check ((uword*)write_map, sid, 1);
- bits_set++;
- continue;
- }
+ clib_bitmap_foreach (sid, wrk->wr_bitmap)
+ {
+ if (!(s = vcl_session_get (wrk, sid)))
+ {
+ clib_bitmap_set_no_check ((uword *) write_map, sid, 1);
+ bits_set++;
+ continue;
+ }
- if (vcl_session_write_ready (session))
- {
- clib_bitmap_set_no_check ((uword*)write_map, sid, 1);
- bits_set++;
- }
- else
- svm_fifo_add_want_deq_ntf (session->tx_fifo, SVM_FIFO_WANT_DEQ_NOTIF);
- }));
+ if (vcl_session_write_ready (s))
+ {
+ clib_bitmap_set_no_check ((uword *) write_map, sid, 1);
+ bits_set++;
+ }
+ else
+ {
+ svm_fifo_t *txf = vcl_session_is_ct (s) ? s->ct_tx_fifo : s->tx_fifo;
+ svm_fifo_add_want_deq_ntf (txf, SVM_FIFO_WANT_DEQ_NOTIF);
+ }
+ }
check_rd:
if (!read_map)
goto check_mq;
- clib_bitmap_foreach (sid, wrk->rd_bitmap, ({
- if (!(session = vcl_session_get (wrk, sid)))
- {
- clib_bitmap_set_no_check ((uword*)read_map, sid, 1);
- bits_set++;
- continue;
- }
-
- if (vcl_session_read_ready (session))
- {
- clib_bitmap_set_no_check ((uword*)read_map, sid, 1);
- bits_set++;
- }
- }));
- /* *INDENT-ON* */
+ clib_bitmap_foreach (sid, wrk->rd_bitmap)
+ {
+ if (!(s = vcl_session_get (wrk, sid)))
+ {
+ clib_bitmap_set_no_check ((uword *) read_map, sid, 1);
+ bits_set++;
+ continue;
+ }
+
+ if (vcl_session_read_ready (s))
+ {
+ clib_bitmap_set_no_check ((uword *) read_map, sid, 1);
+ bits_set++;
+ }
+ }
check_mq:
vppcom_epoll_wait_eventfd (vcl_worker_t * wrk, struct epoll_event *events,
int maxevents, u32 n_evts, double wait_for_time)
{
- vcl_mq_evt_conn_t *mqc;
+ double wait = 0, start = 0, now;
int __clib_unused n_read;
+ vcl_mq_evt_conn_t *mqc;
int n_mq_evts, i;
u64 buf;
vec_validate (wrk->mq_events, pool_elts (wrk->mq_evt_conns));
-again:
- n_mq_evts = epoll_wait (wrk->mqs_epfd, wrk->mq_events,
- vec_len (wrk->mq_events), wait_for_time);
- for (i = 0; i < n_mq_evts; i++)
+ if (!n_evts)
{
- mqc = vcl_mq_evt_conn_get (wrk, wrk->mq_events[i].data.u32);
- n_read = read (mqc->mq_fd, &buf, sizeof (buf));
- vcl_epoll_wait_handle_mq (wrk, mqc->mq, events, maxevents, 0, &n_evts);
+ wait = wait_for_time;
+ start = clib_time_now (&wrk->clib_time);
}
- if (!n_evts && n_mq_evts > 0)
- goto again;
- return (int) n_evts;
+ do
+ {
+ n_mq_evts = epoll_wait (wrk->mqs_epfd, wrk->mq_events,
+ vec_len (wrk->mq_events), wait);
+ if (n_mq_evts < 0)
+ {
+ VDBG (0, "epoll_wait error %u", errno);
+ return n_evts;
+ }
+
+ for (i = 0; i < n_mq_evts; i++)
+ {
+ mqc = vcl_mq_evt_conn_get (wrk, wrk->mq_events[i].data.u32);
+ n_read = read (mqc->mq_fd, &buf, sizeof (buf));
+ vcl_epoll_wait_handle_mq (wrk, mqc->mq, events, maxevents, 0,
+ &n_evts);
+ }
+
+ if (n_evts)
+ return n_evts;
+ if (wait == -1)
+ continue;
+
+ now = clib_time_now (&wrk->clib_time);
+ wait -= (now - start) * 1e3;
+ start = now;
+ }
+ while (wait > 0);
+
+ return 0;
}
int
void *buffer, uint32_t * buflen)
{
vcl_worker_t *wrk = vcl_worker_get_current ();
- vcl_session_t *session;
- int rv = VPPCOM_OK;
u32 *flags = buffer, tmp_flags = 0;
vppcom_endpt_t *ep = buffer;
+ vcl_session_t *session;
+ int rv = VPPCOM_OK;
session = vcl_session_get_w_handle (wrk, session_handle);
if (!session)
session->flags |= VCL_SESSION_F_CONNECTED;
break;
+ case VPPCOM_ATTR_SET_CKPAIR:
+ if (!(buffer && buflen && (*buflen == sizeof (int))) ||
+ !vcl_session_has_crypto (session))
+ {
+ rv = VPPCOM_EINVAL;
+ break;
+ }
+ session->ckpair_index = *(uint32_t *) buffer;
+ break;
+
+ case VPPCOM_ATTR_SET_VRF:
+ if (!(buffer && buflen && (*buflen == sizeof (u32))))
+ {
+ rv = VPPCOM_EINVAL;
+ break;
+ }
+ session->vrf = *(u32 *) buffer;
+ break;
+
+ case VPPCOM_ATTR_GET_VRF:
+ if (!(buffer && buflen && (*buflen >= sizeof (u32))))
+ {
+ rv = VPPCOM_EINVAL;
+ break;
+ }
+ *(u32 *) buffer = session->vrf;
+ *buflen = sizeof (u32);
+ break;
+
default:
rv = VPPCOM_EINVAL;
break;
return st;
}
+int
+vppcom_add_cert_key_pair (vppcom_cert_key_pair_t *ckpair)
+{
+ if (vcm->cfg.vpp_app_socket_api)
+ {
+ clib_warning ("not supported");
+ return VPPCOM_EINVAL;
+ }
+ return vcl_bapi_add_cert_key_pair (ckpair);
+}
+
+int
+vppcom_del_cert_key_pair (uint32_t ckpair_index)
+{
+ if (vcm->cfg.vpp_app_socket_api)
+ {
+ clib_warning ("not supported");
+ return VPPCOM_EINVAL;
+ }
+ return vcl_bapi_del_cert_key_pair (ckpair_index);
+}
+
/*
* fd.io coding-style-patch-verification: ON
*