X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvcl%2Fvppcom.c;h=a0f4338f902d1dba9e50b4108a0fb7f637ec4fce;hb=83b2f5e34bba21f9ce8f04719715d3b85b16a2e8;hp=9c99f66cf28ed77edbe9d63f49a474a7b2df3a08;hpb=785b6ea80ce2e6458069257955fa27b3ff8c52ab;p=vpp.git diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c index 9c99f66cf28..a0f4338f902 100644 --- a/src/vcl/vppcom.c +++ b/src/vcl/vppcom.c @@ -22,33 +22,17 @@ __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) { - svm_msg_q_msg_t *msg; - u32 n_msgs; - int i; + u32 n_msgs = 0, sz, len; - n_msgs = clib_min (svm_msg_q_size (mq), n_max_msg); - for (i = 0; i < n_msgs; i++) + while ((sz = svm_msg_q_size (mq))) { - vec_add2 (wrk->mq_msg_vector, msg, 1); - svm_msg_q_sub_w_lock (mq, msg); + len = vec_len (wrk->mq_msg_vector); + vec_validate (wrk->mq_msg_vector, len + sz - 1); + svm_msg_q_sub_raw_batch (mq, wrk->mq_msg_vector + len, sz); + n_msgs += sz; } return n_msgs; } @@ -179,6 +163,18 @@ format_ip46_address (u8 * s, va_list * args) * VPPCOM Utility Functions */ +static void +vcl_msg_add_ext_config (vcl_session_t *s, uword *offset) +{ + svm_fifo_chunk_t *c; + + c = vcl_segment_alloc_chunk (vcl_vpp_worker_segment_handle (0), + 0 /* one slice only */, s->ext_config->len, + offset); + if (c) + clib_memcpy_fast (c->data, s->ext_config, s->ext_config->len); +} + static void vcl_send_session_listen (vcl_worker_t * wrk, vcl_session_t * s) { @@ -197,9 +193,17 @@ vcl_send_session_listen (vcl_worker_t * wrk, vcl_session_t * s) clib_memcpy_fast (&mp->ip, &s->transport.lcl_ip, sizeof (mp->ip)); mp->port = s->transport.lcl_port; mp->proto = s->session_type; + mp->vrf = s->vrf; if (s->flags & VCL_SESSION_F_CONNECTED) mp->flags = TRANSPORT_CFG_F_CONNECTED; + if (s->ext_config) + vcl_msg_add_ext_config (s, &mp->ext_config); app_send_ctrl_evt_to_vpp (mq, app_evt); + if (s->ext_config) + { + clib_mem_free (s->ext_config); + s->ext_config = 0; + } } static void @@ -223,9 +227,18 @@ vcl_send_session_connect (vcl_worker_t * wrk, vcl_session_t * s) mp->port = s->transport.rmt_port; mp->lcl_port = s->transport.lcl_port; mp->proto = s->session_type; + mp->vrf = s->vrf; if (s->flags & VCL_SESSION_F_CONNECTED) mp->flags |= TRANSPORT_CFG_F_CONNECTED; + if (s->ext_config) + vcl_msg_add_ext_config (s, &mp->ext_config); app_send_ctrl_evt_to_vpp (mq, app_evt); + + if (s->ext_config) + { + clib_mem_free (s->ext_config); + s->ext_config = 0; + } } void @@ -372,12 +385,47 @@ done: return ret; } +int +vcl_session_transport_attr (vcl_worker_t *wrk, vcl_session_t *s, u8 is_get, + transport_endpt_attr_t *attr) +{ + app_session_evt_t _app_evt, *app_evt = &_app_evt; + session_transport_attr_msg_t *mp; + svm_msg_q_t *mq; + f64 timeout; + + ASSERT (!wrk->session_attr_op); + wrk->session_attr_op = 1; + wrk->session_attr_op_rv = -1; + + mq = s->vpp_evt_q; + app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_TRANSPORT_ATTR); + mp = (session_transport_attr_msg_t *) app_evt->evt->data; + memset (mp, 0, sizeof (*mp)); + mp->client_index = wrk->api_client_handle; + mp->handle = s->vpp_handle; + mp->is_get = is_get; + mp->attr = *attr; + app_send_ctrl_evt_to_vpp (mq, app_evt); + + timeout = clib_time_now (&wrk->clib_time) + 1; + + while (wrk->session_attr_op && clib_time_now (&wrk->clib_time) < timeout) + vcl_flush_mq_events (); + + if (!wrk->session_attr_op_rv && is_get) + *attr = wrk->session_attr_rv; + + wrk->session_attr_op = 0; + + return wrk->session_attr_op_rv; +} + static u32 vcl_session_accepted_handler (vcl_worker_t * wrk, session_accepted_msg_t * mp, u32 ls_index) { vcl_session_t *session, *listen_session; - svm_fifo_t *rx_fifo, *tx_fifo; svm_msg_q_t *evt_q; session = vcl_session_alloc (wrk); @@ -390,26 +438,15 @@ vcl_session_accepted_handler (vcl_worker_t * wrk, session_accepted_msg_t * mp, 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 (); - session->vpp_handle = mp->handle; - 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; @@ -437,7 +474,8 @@ vcl_session_accepted_handler (vcl_worker_t * wrk, session_accepted_msg_t * mp, 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); @@ -448,7 +486,6 @@ static u32 vcl_session_connected_handler (vcl_worker_t * wrk, session_connected_msg_t * mp) { - svm_fifo_t *rx_fifo, *tx_fifo; vcl_session_t *session = 0; u32 session_index; @@ -470,40 +507,29 @@ vcl_session_connected_handler (vcl_worker_t * wrk, } 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 (); - 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->transport.is_ip4 = mp->lcl.is_ip4; clib_memcpy_fast (&session->transport.lcl_ip, &mp->lcl.ip, sizeof (session->transport.lcl_ip)); @@ -607,18 +633,16 @@ vcl_session_bound_handler (vcl_worker_t * wrk, session_bound_msg_t * mp) session->transport.lcl_port = mp->lcl_port; 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 *); 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); @@ -664,6 +688,7 @@ vcl_session_migrated_handler (vcl_worker_t * wrk, void *data) { 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) @@ -672,15 +697,31 @@ vcl_session_migrated_handler (vcl_worker_t * wrk, void *data) return; } + /* Only validate if a value is provided */ + if (mp->segment_handle != SESSION_INVALID_HANDLE) + { + fs_index = vcl_segment_table_lookup (mp->segment_handle); + if (fs_index == VCL_INVALID_SEGMENT_INDEX) + { + VDBG (0, "segment %lx for session %u is not mounted!", + mp->segment_handle, 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 *); + + 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, @@ -879,21 +920,15 @@ vcl_session_worker_update_reply_handler (vcl_worker_t * wrk, void *data) 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; @@ -962,6 +997,21 @@ vcl_worker_rpc_handler (vcl_worker_t * wrk, void *data) (vcm->wrk_rpc_fn) (((session_app_wrk_rpc_msg_t *) data)->data); } +static void +vcl_session_transport_attr_reply_handler (vcl_worker_t *wrk, void *data) +{ + session_transport_attr_reply_msg_t *mp; + + if (!wrk->session_attr_op) + return; + + mp = (session_transport_attr_reply_msg_t *) data; + + wrk->session_attr_op_rv = mp->retval; + wrk->session_attr_op = 0; + wrk->session_attr_rv = mp->attr; +} + static int vcl_handle_mq_event (vcl_worker_t * wrk, session_event_t * e) { @@ -1057,6 +1107,9 @@ vcl_handle_mq_event (vcl_worker_t * wrk, session_event_t * e) case SESSION_CTRL_EVT_APP_WRK_RPC: vcl_worker_rpc_handler (wrk, e->data); break; + case SESSION_CTRL_EVT_TRANSPORT_ATTR_REPLY: + vcl_session_transport_attr_reply_handler (wrk, e->data); + break; default: clib_warning ("unhandled %u", e->event_type); } @@ -1131,18 +1184,15 @@ vcl_handle_pending_wrk_updates (vcl_worker_t * wrk) } void -vcl_flush_mq_events (void) +vcl_worker_flush_mq_events (vcl_worker_t *wrk) { - vcl_worker_t *wrk = vcl_worker_get_current (); svm_msg_q_msg_t *msg; session_event_t *e; svm_msg_q_t *mq; int i; mq = wrk->app_event_queue; - svm_msg_q_lock (mq); vcl_mq_dequeue_batch (wrk, mq, ~0); - svm_msg_q_unlock (mq); for (i = 0; i < vec_len (wrk->mq_msg_vector); i++) { @@ -1155,6 +1205,12 @@ vcl_flush_mq_events (void) vcl_handle_pending_wrk_updates (wrk); } +void +vcl_flush_mq_events (void) +{ + vcl_worker_flush_mq_events (vcl_worker_get_current ()); +} + static int vppcom_session_unbind (u32 session_handle) { @@ -1284,10 +1340,10 @@ vppcom_app_destroy (void) 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); @@ -1553,6 +1609,10 @@ vppcom_unformat_proto (uint8_t * proto, char *proto_str) *proto = VPPCOM_PROTO_QUIC; else if (!strcmp (proto_str, "quic")) *proto = VPPCOM_PROTO_QUIC; + else if (!strcmp (proto_str, "DTLS")) + *proto = VPPCOM_PROTO_DTLS; + else if (!strcmp (proto_str, "dtls")) + *proto = VPPCOM_PROTO_DTLS; else return 1; return 0; @@ -1568,11 +1628,11 @@ vppcom_session_accept (uint32_t listen_session_handle, vppcom_endpt_t * ep, vcl_session_t *listen_session = 0; vcl_session_t *client_session = 0; vcl_session_msg_t *evt; - svm_msg_q_msg_t msg; - session_event_t *e; u8 is_nonblocking; int rv; +again: + listen_session = vcl_session_get_w_handle (wrk, listen_session_handle); if (!listen_session) return VPPCOM_EBADFD; @@ -1596,19 +1656,9 @@ vppcom_session_accept (uint32_t listen_session_handle, vppcom_endpt_t * ep, if (svm_msg_q_is_empty (wrk->app_event_queue) && is_nonblocking) return VPPCOM_EAGAIN; - if (svm_msg_q_sub (wrk->app_event_queue, &msg, SVM_Q_WAIT, 0)) - return VPPCOM_EAGAIN; - - e = svm_msg_q_msg_data (wrk->app_event_queue, &msg); - if (e->event_type != SESSION_CTRL_EVT_ACCEPTED) - { - vcl_handle_mq_event (wrk, e); - svm_msg_q_free_msg (wrk->app_event_queue, &msg); - continue; - } - clib_memcpy_fast (&accepted_msg, e->data, sizeof (accepted_msg)); - svm_msg_q_free_msg (wrk->app_event_queue, &msg); - break; + svm_msg_q_wait (wrk->app_event_queue, SVM_MQ_WAIT_EMPTY); + vcl_worker_flush_mq_events (wrk); + goto again; } handle: @@ -1814,12 +1864,6 @@ vppcom_session_stream_connect (uint32_t session_handle, return rv; } -static u8 -vcl_is_rx_evt_for_session (session_event_t * e, u32 sid, u8 is_ct) -{ - return (e->event_type == SESSION_IO_EVT_RX && e->session_index == sid); -} - static inline int vppcom_session_read_internal (uint32_t session_handle, void *buf, int n, u8 peek) @@ -1828,7 +1872,6 @@ vppcom_session_read_internal (uint32_t session_handle, void *buf, int n, int rv, n_read = 0, is_nonblocking; vcl_session_t *s = 0; svm_fifo_t *rx_fifo; - svm_msg_q_msg_t msg; session_event_t *e; svm_msg_q_t *mq; u8 is_ct; @@ -1873,16 +1916,9 @@ vppcom_session_read_internal (uint32_t session_handle, void *buf, int n, if (is_ct) svm_fifo_unset_event (s->rx_fifo); svm_fifo_unset_event (rx_fifo); - svm_msg_q_lock (mq); - if (svm_msg_q_is_empty (mq)) - svm_msg_q_wait (mq); - svm_msg_q_sub_w_lock (mq, &msg); - e = svm_msg_q_msg_data (mq, &msg); - svm_msg_q_unlock (mq); - if (!vcl_is_rx_evt_for_session (e, s->session_index, is_ct)) - vcl_handle_mq_event (wrk, e); - svm_msg_q_free_msg (mq, &msg); + svm_msg_q_wait (mq, SVM_MQ_WAIT_EMPTY); + vcl_worker_flush_mq_events (wrk); } } @@ -1921,7 +1957,8 @@ 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); } @@ -1952,8 +1989,6 @@ vppcom_session_read_segments (uint32_t session_handle, int n_read = 0, is_nonblocking; vcl_session_t *s = 0; svm_fifo_t *rx_fifo; - svm_msg_q_msg_t msg; - session_event_t *e; svm_msg_q_t *mq; u8 is_ct; @@ -1987,16 +2022,9 @@ vppcom_session_read_segments (uint32_t session_handle, if (is_ct) svm_fifo_unset_event (s->rx_fifo); svm_fifo_unset_event (rx_fifo); - svm_msg_q_lock (mq); - if (svm_msg_q_is_empty (mq)) - svm_msg_q_wait (mq); - svm_msg_q_sub_w_lock (mq, &msg); - e = svm_msg_q_msg_data (mq, &msg); - svm_msg_q_unlock (mq); - if (!vcl_is_rx_evt_for_session (e, s->session_index, is_ct)) - vcl_handle_mq_event (wrk, e); - svm_msg_q_free_msg (mq, &msg); + svm_msg_q_wait (mq, SVM_MQ_WAIT_EMPTY); + vcl_worker_flush_mq_events (wrk); } } @@ -2043,12 +2071,6 @@ vppcom_session_free_segments (uint32_t session_handle, uint32_t n_bytes) s->rx_bytes_pending -= n_bytes; } -static u8 -vcl_is_tx_evt_for_session (session_event_t * e, u32 sid, u8 is_ct) -{ - return (e->event_type == SESSION_IO_EVT_TX && e->session_index == sid); -} - always_inline u8 vcl_fifo_is_writeable (svm_fifo_t * f, u32 len, u8 is_dgram) { @@ -2065,9 +2087,7 @@ vppcom_session_write_inline (vcl_worker_t * wrk, vcl_session_t * s, void *buf, { int n_write, is_nonblocking; session_evt_type_t et; - svm_msg_q_msg_t msg; svm_fifo_t *tx_fifo; - session_event_t *e; svm_msg_q_t *mq; u8 is_ct; @@ -2105,17 +2125,9 @@ vppcom_session_write_inline (vcl_worker_t * wrk, vcl_session_t * s, void *buf, svm_fifo_add_want_deq_ntf (tx_fifo, SVM_FIFO_WANT_DEQ_NOTIF); if (vcl_session_is_closing (s)) return vcl_session_closing_error (s); - svm_msg_q_lock (mq); - if (svm_msg_q_is_empty (mq)) - svm_msg_q_wait (mq); - svm_msg_q_sub_w_lock (mq, &msg); - e = svm_msg_q_msg_data (mq, &msg); - svm_msg_q_unlock (mq); - - if (!vcl_is_tx_evt_for_session (e, s->session_index, is_ct)) - vcl_handle_mq_event (wrk, e); - svm_msg_q_free_msg (mq, &msg); + svm_msg_q_wait (mq, SVM_MQ_WAIT_EMPTY); + vcl_worker_flush_mq_events (wrk); } } @@ -2132,8 +2144,8 @@ vppcom_session_write_inline (vcl_worker_t * wrk, vcl_session_t * s, void *buf, 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)) @@ -2318,35 +2330,22 @@ vcl_select_handle_mq (vcl_worker_t * wrk, svm_msg_q_t * mq, session_event_t *e; u32 i; - svm_msg_q_lock (mq); if (svm_msg_q_is_empty (mq)) { if (*bits_set) - { - svm_msg_q_unlock (mq); - return 0; - } + return 0; if (!time_to_wait) - { - svm_msg_q_unlock (mq); - return 0; - } + return 0; else if (time_to_wait < 0) - { - svm_msg_q_wait (mq); - } + svm_msg_q_wait (mq, SVM_MQ_WAIT_EMPTY); else { if (svm_msg_q_timedwait (mq, time_to_wait)) - { - svm_msg_q_unlock (mq); - return 0; - } + return 0; } } vcl_mq_dequeue_batch (wrk, mq, ~0); - svm_msg_q_unlock (mq); for (i = 0; i < vec_len (wrk->mq_msg_vector); i++) { @@ -2422,7 +2421,7 @@ vppcom_select (int n_bits, vcl_si_set * read_map, vcl_si_set * write_map, { 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) @@ -2453,43 +2452,46 @@ vppcom_select (int n_bits, vcl_si_set * read_map, vcl_si_set * write_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: @@ -2734,10 +2736,13 @@ vppcom_epoll_ctl (uint32_t vep_handle, int op, uint32_t session_handle, s->vep.et_mask = VEP_DEFAULT_ET_MASK; s->vep.ev = *event; txf = vcl_session_is_ct (s) ? s->ct_tx_fifo : s->tx_fifo; - if (event->events & EPOLLOUT) - svm_fifo_add_want_deq_ntf (txf, SVM_FIFO_WANT_DEQ_NOTIF_IF_FULL); - else - svm_fifo_del_want_deq_ntf (txf, SVM_FIFO_WANT_DEQ_NOTIF_IF_FULL); + if (txf) + { + if (event->events & EPOLLOUT) + svm_fifo_add_want_deq_ntf (txf, SVM_FIFO_WANT_DEQ_NOTIF_IF_FULL); + else + svm_fifo_del_want_deq_ntf (txf, SVM_FIFO_WANT_DEQ_NOTIF_IF_FULL); + } VDBG (1, "EPOLL_CTL_MOD: vep_sh %u, sh %u, events 0x%x, data 0x%llx!", vep_handle, session_handle, event->events, event->data.u64); break; @@ -2964,30 +2969,20 @@ vcl_epoll_wait_handle_mq (vcl_worker_t * wrk, svm_msg_q_t * mq, if (vec_len (wrk->mq_msg_vector) && svm_msg_q_is_empty (mq)) goto handle_dequeued; - svm_msg_q_lock (mq); if (svm_msg_q_is_empty (mq)) { if (!wait_for_time) - { - svm_msg_q_unlock (mq); - return 0; - } + return 0; else if (wait_for_time < 0) - { - svm_msg_q_wait (mq); - } + svm_msg_q_wait (mq, SVM_MQ_WAIT_EMPTY); else { if (svm_msg_q_timedwait (mq, wait_for_time / 1e3)) - { - svm_msg_q_unlock (mq); - return 0; - } + return 0; } } ASSERT (maxevents > *num_ev); vcl_mq_dequeue_batch (wrk, mq, ~0); - svm_msg_q_unlock (mq); handle_dequeued: for (i = 0; i < vec_len (wrk->mq_msg_vector); i++) @@ -3039,25 +3034,49 @@ static int 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 @@ -3101,6 +3120,9 @@ vppcom_epoll_wait (uint32_t vep_handle, struct epoll_event *events, } vec_reset_length (wrk->unhandled_evts_vector); } + /* Request to only drain unhandled */ + if ((int) wait_for_time == -2) + return n_evts; if (vcm->cfg.use_mq_eventfd) return vppcom_epoll_wait_eventfd (wrk, events, maxevents, n_evts, @@ -3115,10 +3137,11 @@ 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, tmp_flags = 0; vppcom_endpt_t *ep = buffer; + transport_endpt_attr_t tea; + vcl_session_t *session; + int rv = VPPCOM_OK; session = vcl_session_get_w_handle (wrk, session_handle); if (!session) @@ -3615,30 +3638,41 @@ vppcom_session_attr (uint32_t session_handle, uint32_t op, break; case VPPCOM_ATTR_GET_TCP_USER_MSS: - if (buffer && buflen && (*buflen >= sizeof (u32))) + if (!(buffer && buflen && (*buflen >= sizeof (u32)))) { - /* VPP-TBD */ - *(u32 *) buffer = session->user_mss; - *buflen = sizeof (int); + rv = VPPCOM_EINVAL; + break; + } - VDBG (2, "VPPCOM_ATTR_GET_TCP_USER_MSS: %d, buflen %d, #VPP-TBD#", - *(int *) buffer, *buflen); + tea.type = TRANSPORT_ENDPT_ATTR_MSS; + tea.mss = *(u32 *) buffer; + if (vcl_session_transport_attr (wrk, session, 1 /* is_get */, &tea)) + rv = VPPCOM_ENOPROTOOPT; + + if (!rv) + { + *(u32 *) buffer = tea.mss; + *buflen = sizeof (int); } - else - rv = VPPCOM_EINVAL; + + VDBG (2, "VPPCOM_ATTR_GET_TCP_USER_MSS: %d, buflen %d", *(int *) buffer, + *buflen); break; case VPPCOM_ATTR_SET_TCP_USER_MSS: - if (buffer && buflen && (*buflen == sizeof (u32))) + if (!(buffer && buflen && (*buflen == sizeof (u32)))) { - /* VPP-TBD */ - session->user_mss = *(u32 *) buffer; - - VDBG (2, "VPPCOM_ATTR_SET_TCP_USER_MSS: %u, buflen %d, #VPP-TBD#", - session->user_mss, *buflen); + rv = VPPCOM_EINVAL; + break; } - else - rv = VPPCOM_EINVAL; + + tea.type = TRANSPORT_ENDPT_ATTR_MSS; + tea.mss = *(u32 *) buffer; + if (vcl_session_transport_attr (wrk, session, 0 /* is_get */, &tea)) + rv = VPPCOM_ENOPROTOOPT; + + VDBG (2, "VPPCOM_ATTR_SET_TCP_USER_MSS: %u, buflen %d", tea.mss, + *buflen); break; case VPPCOM_ATTR_SET_SHUT: @@ -3666,6 +3700,62 @@ vppcom_session_attr (uint32_t session_handle, uint32_t op, 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; + } + if (!session->ext_config) + { + vcl_session_alloc_ext_cfg (session, TRANSPORT_ENDPT_EXT_CFG_CRYPTO); + } + else if (session->ext_config->type != TRANSPORT_ENDPT_EXT_CFG_CRYPTO) + { + rv = VPPCOM_EINVAL; + break; + } + + session->ext_config->crypto.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; + + case VPPCOM_ATTR_GET_DOMAIN: + if (!(buffer && buflen && (*buflen >= sizeof (int)))) + { + rv = VPPCOM_EINVAL; + break; + } + + if (session->transport.is_ip4) + *(int *) buffer = AF_INET; + else + *(int *) buffer = AF_INET6; + *buflen = sizeof (int); + + VDBG (2, "VPPCOM_ATTR_GET_DOMAIN: %d, buflen %u", *(int *) buffer, + *buflen); + break; + default: rv = VPPCOM_EINVAL; break; @@ -3975,6 +4065,9 @@ vppcom_proto_str (vppcom_proto_t proto) case VPPCOM_PROTO_QUIC: proto_str = "QUIC"; break; + case VPPCOM_PROTO_DTLS: + proto_str = "DTLS"; + break; default: proto_str = "UNKNOWN"; break; @@ -4045,6 +4138,28 @@ vppcom_retval_str (int retval) 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 *