diff options
author | Florin Coras <fcoras@cisco.com> | 2018-07-27 05:45:06 -0700 |
---|---|---|
committer | Dave Barach <openvpp@barachs.net> | 2018-07-31 11:36:54 +0000 |
commit | 460dce6e2d017cc7b2151fd0fa61d464570489d7 (patch) | |
tree | 19e944702f8b7fcb659a8166f50a03ee5eba9a7a /src/vcl | |
parent | e939bf1b508e1fae6929dd8cf0f3effdc2c12549 (diff) |
vcl: add read/write udp support
Change-Id: Ie6171c12055cde6915856de340839f5da1b1b1da
Signed-off-by: Florin Coras <fcoras@cisco.com>
Diffstat (limited to 'src/vcl')
-rw-r--r-- | src/vcl/vcl_bapi.c | 14 | ||||
-rw-r--r-- | src/vcl/vcl_cfg.c | 1 | ||||
-rw-r--r-- | src/vcl/vcl_private.h | 9 | ||||
-rw-r--r-- | src/vcl/vcl_test_server.c | 17 | ||||
-rw-r--r-- | src/vcl/vppcom.c | 142 |
5 files changed, 111 insertions, 72 deletions
diff --git a/src/vcl/vcl_bapi.c b/src/vcl/vcl_bapi.c index 0201cd82966..311df64528c 100644 --- a/src/vcl/vcl_bapi.c +++ b/src/vcl/vcl_bapi.c @@ -132,6 +132,7 @@ vl_api_map_another_segment_t_handler (vl_api_map_another_segment_t * mp) svm_fifo_segment_create_args_t *a = &_a; int rv; + vcm->mounting_segment = 1; memset (a, 0, sizeof (*a)); a->segment_name = (char *) mp->segment_name; a->segment_size = mp->segment_size; @@ -147,6 +148,7 @@ vl_api_map_another_segment_t_handler (vl_api_map_another_segment_t * mp) VDBG (1, "VCL<%d>: mapped new segment '%s' size %d", getpid (), mp->segment_name, mp->segment_size); + vcm->mounting_segment = 0; } static void @@ -356,6 +358,18 @@ done: vppcom_session_table_add_listener (mp->handle, session_index); session->session_state = STATE_LISTEN; + if (session->is_dgram) + { + 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 = session_index; + tx_fifo = uword_to_pointer (mp->tx_fifo, svm_fifo_t *); + tx_fifo->client_session_index = session_index; + session->rx_fifo = rx_fifo; + session->tx_fifo = tx_fifo; + } + VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: bind succeeded!", getpid (), mp->handle, mp->context); done_unlock: diff --git a/src/vcl/vcl_cfg.c b/src/vcl/vcl_cfg.c index 279a975719e..6e6a0ac0da4 100644 --- a/src/vcl/vcl_cfg.c +++ b/src/vcl/vcl_cfg.c @@ -21,6 +21,7 @@ */ static vppcom_main_t _vppcom_main = { .debug = VPPCOM_DEBUG_INIT, + .init = 0, .my_client_index = ~0 }; diff --git a/src/vcl/vcl_private.h b/src/vcl/vcl_private.h index 327a7fc02fe..af58cdc3ac9 100644 --- a/src/vcl/vcl_private.h +++ b/src/vcl/vcl_private.h @@ -237,6 +237,9 @@ typedef struct vppcom_main_t_ /** Pool of cut through registrations */ vcl_cut_through_registration_t *cut_through_registrations; + /** Flag indicating that a new segment is being mounted */ + volatile u32 mounting_segment; + #ifdef VCL_ELOG /* VPP Event-logger */ elog_main_t elog_main; @@ -313,6 +316,12 @@ vcl_session_get_index_from_handle (u64 handle) return VCL_INVALID_SESSION_INDEX; } +static inline u8 +vcl_session_is_ct (vcl_session_t * s) +{ + return (s->our_evt_q != 0); +} + static inline int vppcom_session_at_index (u32 session_index, vcl_session_t * volatile *sess) { diff --git a/src/vcl/vcl_test_server.c b/src/vcl/vcl_test_server.c index 6a2fda0be57..b49383eb73a 100644 --- a/src/vcl/vcl_test_server.c +++ b/src/vcl/vcl_test_server.c @@ -425,14 +425,17 @@ main (int argc, char **argv) return -1; } - rv = vppcom_session_listen (ssm->listen_fd, 10); - if (rv < 0) + if (!ssm->cfg.transport_udp) { - errno_val = errno = -rv; - perror ("ERROR in main()"); - fprintf (stderr, "SERVER: ERROR: listen failed " - "(errno = %d)!\n", errno_val); - return -1; + rv = vppcom_session_listen (ssm->listen_fd, 10); + if (rv < 0) + { + errno_val = errno = -rv; + perror ("ERROR in main()"); + fprintf (stderr, "SERVER: ERROR: listen failed " + "(errno = %d)!\n", errno_val); + return -1; + } } ssm->epfd = vppcom_epoll_create (); diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c index d1c4413b2a8..a74e55af634 100644 --- a/src/vcl/vppcom.c +++ b/src/vcl/vppcom.c @@ -33,9 +33,15 @@ static void vcl_wait_for_memory (void *mem) { u8 __clib_unused test; + if (vcm->mounting_segment) + { + while (vcm->mounting_segment) + ; + return; + } if (1 || vcm->debug) { - sleep (1); + usleep (1e5); return; } if (signal (SIGSEGV, sigsegv_signal)) @@ -359,6 +365,8 @@ vcl_session_accepted_handler (session_accepted_msg_t * mp) hash_set (vcm->session_index_by_vpp_handles, mp->handle, session_index); session->transport.lcl_port = listen_session->transport.lcl_port; session->transport.lcl_ip = listen_session->transport.lcl_ip; + session->session_type = listen_session->session_type; + session->is_dgram = session->session_type == VPPCOM_PROTO_UDP; VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: client accept request from %s" " address %U port %d queue %p!", getpid (), mp->handle, session_index, @@ -405,13 +413,18 @@ done: if (rv) goto done_unlock; + rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *); + tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *); + vcl_wait_for_memory (rx_fifo); + rx_fifo->client_session_index = session_index; + tx_fifo->client_session_index = session_index; + if (mp->client_event_queue_address) { session->vpp_evt_q = uword_to_pointer (mp->server_event_queue_address, svm_msg_q_t *); session->our_evt_q = uword_to_pointer (mp->client_event_queue_address, svm_msg_q_t *); - vcl_wait_for_memory (session->vpp_evt_q); session->ct_registration = vcl_ct_registration_add (session->our_evt_q, session_index); } @@ -419,11 +432,6 @@ done: 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 *); - rx_fifo->client_session_index = session_index; - tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *); - tx_fifo->client_session_index = session_index; - session->rx_fifo = rx_fifo; session->tx_fifo = tx_fifo; session->vpp_handle = mp->handle; @@ -762,11 +770,10 @@ vppcom_session_create (u8 proto, u8 is_nonblocking) session->session_type = proto; session->session_state = STATE_START; session->vpp_handle = ~0; + session->is_dgram = proto == VPPCOM_PROTO_UDP; if (is_nonblocking) VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_NONBLOCK); - else - VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_NONBLOCK); vcl_evt (VCL_EVT_CREATE, session, session_type, session->session_state, is_nonblocking, session_index); @@ -929,6 +936,10 @@ vppcom_session_bind (uint32_t session_index, vppcom_endpt_t * ep) session->session_type ? "UDP" : "TCP"); vcl_evt (VCL_EVT_BIND, session); VCL_SESSION_UNLOCK (); + + if (session->session_type == VPPCOM_PROTO_UDP) + vppcom_session_listen (session_index, 10); + done: return rv; } @@ -1225,12 +1236,20 @@ vcl_is_rx_evt_for_session (session_event_t * e, u32 sid, u8 is_ct) return (e->event_type == SESSION_IO_EVT_CT_TX); } +static inline u8 +vcl_session_is_readable (vcl_session_t * s) +{ + return ((s->session_state & STATE_OPEN) + || (s->session_state == STATE_LISTEN + && s->session_type == VPPCOM_PROTO_UDP)); +} + static inline int vppcom_session_read_internal (uint32_t session_index, void *buf, int n, u8 peek) { int n_read = 0, rv, is_nonblocking; - vcl_session_t *session = 0; + vcl_session_t *s = 0; svm_fifo_t *rx_fifo; svm_msg_q_msg_t msg; session_event_t *e; @@ -1239,9 +1258,9 @@ vppcom_session_read_internal (uint32_t session_index, void *buf, int n, ASSERT (buf); - VCL_SESSION_LOCK_AND_GET (session_index, &session); + VCL_SESSION_LOCK_AND_GET (session_index, &s); - if (PREDICT_FALSE (session->is_vep)) + if (PREDICT_FALSE (s->is_vep)) { VCL_SESSION_UNLOCK (); clib_warning ("VCL<%d>: ERROR: sid %u: cannot " @@ -1250,24 +1269,24 @@ vppcom_session_read_internal (uint32_t session_index, void *buf, int n, goto done; } - is_nonblocking = VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK); - rx_fifo = session->rx_fifo; + is_nonblocking = VCL_SESS_ATTR_TEST (s->attr, VCL_SESS_ATTR_NONBLOCK); + rx_fifo = s->rx_fifo; - if (PREDICT_FALSE (!(session->session_state & STATE_OPEN))) + if (PREDICT_FALSE (!vcl_session_is_readable (s))) { - session_state_t state = session->session_state; + session_state_t state = s->session_state; VCL_SESSION_UNLOCK (); rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN); VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: %s session is not open! " "state 0x%x (%s), returning %d (%s)", - getpid (), session->vpp_handle, session_index, state, + getpid (), s->vpp_handle, session_index, state, vppcom_session_state_str (state), rv, vppcom_retval_str (rv)); goto done; } VCL_SESSION_UNLOCK (); - mq = session->our_evt_q ? session->our_evt_q : vcm->app_event_queue; + mq = vcl_session_is_ct (s) ? s->our_evt_q : vcm->app_event_queue; is_full = svm_fifo_is_full (rx_fifo); if (svm_fifo_is_empty (rx_fifo)) @@ -1286,7 +1305,7 @@ vppcom_session_read_internal (uint32_t session_index, void *buf, int n, svm_msg_q_sub_w_lock (mq, &msg); e = svm_msg_q_msg_data (mq, &msg); if (!vcl_is_rx_evt_for_session (e, session_index, - session->our_evt_q != 0)) + s->our_evt_q != 0)) { vcl_handle_mq_ctrl_event (e); svm_msg_q_free_msg (mq, &msg); @@ -1303,27 +1322,24 @@ vppcom_session_read_internal (uint32_t session_index, void *buf, int n, } } - if (peek) - n_read = svm_fifo_peek (rx_fifo, 0, n, buf); + if (s->is_dgram) + n_read = app_recv_dgram_raw (rx_fifo, buf, n, &s->transport, 1, peek); else - n_read = svm_fifo_dequeue_nowait (rx_fifo, n, buf); - ASSERT (n_read > 0); - svm_fifo_unset_event (rx_fifo); + n_read = app_recv_stream_raw (rx_fifo, buf, n, 1, peek); - if (session->our_evt_q && is_full) - app_send_io_evt_to_vpp (session->vpp_evt_q, rx_fifo, SESSION_IO_EVT_CT_RX, + if (vcl_session_is_ct (s) && is_full) + app_send_io_evt_to_vpp (s->vpp_evt_q, rx_fifo, SESSION_IO_EVT_CT_RX, SVM_Q_WAIT); - if (VPPCOM_DEBUG > 2) { if (n_read > 0) clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: read %d bytes " - "from (%p)", getpid (), session->vpp_handle, + "from (%p)", getpid (), s->vpp_handle, session_index, n_read, rx_fifo); else clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: nothing read! " - "returning %d (%s)", getpid (), session->vpp_handle, + "returning %d (%s)", getpid (), s->vpp_handle, session_index, rv, vppcom_retval_str (rv)); } return n_read; @@ -1389,45 +1405,46 @@ int vppcom_session_write (uint32_t session_index, void *buf, size_t n) { int rv, n_write, is_nonblocking; - vcl_session_t *session = 0; + vcl_session_t *s = 0; svm_fifo_t *tx_fifo = 0; + session_evt_type_t et; svm_msg_q_msg_t msg; session_event_t *e; svm_msg_q_t *mq; ASSERT (buf); - VCL_SESSION_LOCK_AND_GET (session_index, &session); + VCL_SESSION_LOCK_AND_GET (session_index, &s); - tx_fifo = session->tx_fifo; - is_nonblocking = VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK); + tx_fifo = s->tx_fifo; + is_nonblocking = VCL_SESS_ATTR_TEST (s->attr, VCL_SESS_ATTR_NONBLOCK); - if (PREDICT_FALSE (session->is_vep)) + if (PREDICT_FALSE (s->is_vep)) { VCL_SESSION_UNLOCK (); clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: " "cannot write to an epoll session!", - getpid (), session->vpp_handle, session_index); + getpid (), s->vpp_handle, session_index); rv = VPPCOM_EBADFD; goto done; } - if (!(session->session_state & STATE_OPEN)) + if (!(s->session_state & STATE_OPEN)) { - session_state_t state = session->session_state; + session_state_t state = s->session_state; rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN); VCL_SESSION_UNLOCK (); VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: session is not open! " "state 0x%x (%s)", - getpid (), session->vpp_handle, session_index, + getpid (), s->vpp_handle, session_index, state, vppcom_session_state_str (state)); goto done; } VCL_SESSION_UNLOCK (); - mq = session->our_evt_q ? session->our_evt_q : vcm->app_event_queue; + mq = vcl_session_is_ct (s) ? s->our_evt_q : vcm->app_event_queue; if (svm_fifo_is_full (tx_fifo)) { if (is_nonblocking) @@ -1448,7 +1465,7 @@ vppcom_session_write (uint32_t session_index, void *buf, size_t n) svm_msg_q_sub_w_lock (mq, &msg); e = svm_msg_q_msg_data (mq, &msg); if (!vcl_is_tx_evt_for_session (e, session_index, - session->our_evt_q != 0)) + s->our_evt_q != 0)) { vcl_handle_mq_ctrl_event (e); svm_msg_q_free_msg (mq, &msg); @@ -1465,31 +1482,27 @@ vppcom_session_write (uint32_t session_index, void *buf, size_t n) } } - n_write = svm_fifo_enqueue_nowait (tx_fifo, n, (void *) buf); - ASSERT (n_write > 0); + ASSERT (FIFO_EVENT_APP_TX + 1 == SESSION_IO_EVT_CT_TX); + et = FIFO_EVENT_APP_TX + vcl_session_is_ct (s); + if (s->is_dgram) + n_write = app_send_dgram_raw (tx_fifo, &s->transport, + s->vpp_evt_q, buf, n, et, SVM_Q_WAIT); + else + n_write = app_send_stream_raw (tx_fifo, s->vpp_evt_q, buf, n, et, + SVM_Q_WAIT); - if (svm_fifo_set_event (tx_fifo)) - { - session_evt_type_t et; - VCL_SESSION_LOCK_AND_GET (session_index, &session); - et = session->our_evt_q ? SESSION_IO_EVT_CT_TX : FIFO_EVENT_APP_TX; - app_send_io_evt_to_vpp (session->vpp_evt_q, tx_fifo, et, SVM_Q_WAIT); - VCL_SESSION_UNLOCK (); - VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: added FIFO_EVENT_APP_TX " - "to vpp_event_q %p, n_write %d", getpid (), - session->vpp_handle, session_index, session->vpp_evt_q, n_write); - } + ASSERT (n_write > 0); if (VPPCOM_DEBUG > 2) { if (n_write <= 0) clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: " - "FIFO-FULL (%p)", getpid (), session->vpp_handle, + "FIFO-FULL (%p)", getpid (), s->vpp_handle, session_index, tx_fifo); else clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: " "wrote %d bytes tx-fifo: (%p)", getpid (), - session->vpp_handle, session_index, n_write, tx_fifo); + s->vpp_handle, session_index, n_write, tx_fifo); } return n_write; @@ -2885,18 +2898,11 @@ vppcom_session_recvfrom (uint32_t session_index, void *buffer, VCL_SESSION_UNLOCK (); VDBG (0, "VCL<%d>: invalid session, sid (%u) has been closed!", getpid (), session_index); - rv = VPPCOM_EBADFD; VCL_SESSION_UNLOCK (); - goto done; + return VPPCOM_EBADFD; } ep->is_ip4 = session->transport.is_ip4; ep->port = session->transport.rmt_port; - if (session->transport.is_ip4) - clib_memcpy (ep->ip, &session->transport.rmt_ip.ip4, - sizeof (ip4_address_t)); - else - clib_memcpy (ep->ip, &session->transport.rmt_ip.ip6, - sizeof (ip6_address_t)); VCL_SESSION_UNLOCK (); } @@ -2908,10 +2914,16 @@ vppcom_session_recvfrom (uint32_t session_index, void *buffer, { clib_warning ("VCL<%d>: Unsupport flags for recvfrom %d", getpid (), flags); - rv = VPPCOM_EAFNOSUPPORT; + return VPPCOM_EAFNOSUPPORT; } -done: + if (session->transport.is_ip4) + clib_memcpy (ep->ip, &session->transport.rmt_ip.ip4, + sizeof (ip4_address_t)); + else + clib_memcpy (ep->ip, &session->transport.rmt_ip.ip6, + sizeof (ip6_address_t)); + return rv; } |