X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvcl%2Fvppcom.c;h=5e37dcfef396335d0ed08a8eae6802d680c6ab6c;hb=87d48ad8f6e8008bfd7ffaf56c91cb0c8b362330;hp=a439d2550a1df158092de6dae7dcedf010aa4cd6;hpb=0674f85c803b59ada3643bfaeba1b321abeb5d6a;p=vpp.git diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c index a439d2550a1..5e37dcfef39 100644 --- a/src/vcl/vppcom.c +++ b/src/vcl/vppcom.c @@ -163,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) { @@ -181,11 +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->ckpair_index = s->ckpair_index; 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 @@ -209,11 +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->ckpair_index = s->ckpair_index; 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 @@ -360,6 +385,42 @@ 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) @@ -936,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) { @@ -1031,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); } @@ -1293,7 +1372,6 @@ vppcom_session_create (u8 proto, u8 is_nonblocking) 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) @@ -2923,56 +3001,50 @@ handle_dequeued: } static int -vppcom_epoll_wait_condvar (vcl_worker_t * wrk, struct epoll_event *events, - int maxevents, u32 n_evts, double wait_for_time) +vppcom_epoll_wait_condvar (vcl_worker_t *wrk, struct epoll_event *events, + int maxevents, u32 n_evts, double timeout_ms) { - double wait = 0, start = 0, now; + double end = -1; if (!n_evts) { - wait = wait_for_time; - start = clib_time_now (&wrk->clib_time); + if (timeout_ms > 0) + end = clib_time_now (&wrk->clib_time) + (timeout_ms / 1e3); } do { vcl_epoll_wait_handle_mq (wrk, wrk->app_event_queue, events, maxevents, - wait, &n_evts); - if (n_evts) + timeout_ms, &n_evts); + if (n_evts || !timeout_ms) return n_evts; - if (wait == -1) - continue; - - now = clib_time_now (&wrk->clib_time); - wait -= (now - start) * 1e3; - start = now; } - while (wait > 0); + while (end == -1 || clib_time_now (&wrk->clib_time) < end); return 0; } static int -vppcom_epoll_wait_eventfd (vcl_worker_t * wrk, struct epoll_event *events, - int maxevents, u32 n_evts, double wait_for_time) +vppcom_epoll_wait_eventfd (vcl_worker_t *wrk, struct epoll_event *events, + int maxevents, u32 n_evts, double timeout_ms) { - double wait = 0, start = 0, now; int __clib_unused n_read; vcl_mq_evt_conn_t *mqc; int n_mq_evts, i; + double end = -1; u64 buf; vec_validate (wrk->mq_events, pool_elts (wrk->mq_evt_conns)); if (!n_evts) { - wait = wait_for_time; - start = clib_time_now (&wrk->clib_time); + if (timeout_ms > 0) + end = clib_time_now (&wrk->clib_time) + (timeout_ms / 1e3); } do { n_mq_evts = epoll_wait (wrk->mqs_epfd, wrk->mq_events, - vec_len (wrk->mq_events), wait); + vec_len (wrk->mq_events), timeout_ms); if (n_mq_evts < 0) { VDBG (0, "epoll_wait error %u", errno); @@ -2987,16 +3059,10 @@ vppcom_epoll_wait_eventfd (vcl_worker_t * wrk, struct epoll_event *events, &n_evts); } - if (n_evts) + if (n_evts || !timeout_ms) return n_evts; - if (wait == -1) - continue; - - now = clib_time_now (&wrk->clib_time); - wait -= (now - start) * 1e3; - start = now; } - while (wait > 0); + while (end == -1 || clib_time_now (&wrk->clib_time) < end); return 0; } @@ -3042,6 +3108,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, @@ -3058,6 +3127,7 @@ vppcom_session_attr (uint32_t session_handle, uint32_t op, vcl_worker_t *wrk = vcl_worker_get_current (); u32 *flags = buffer, tmp_flags = 0; vppcom_endpt_t *ep = buffer; + transport_endpt_attr_t tea; vcl_session_t *session; int rv = VPPCOM_OK; @@ -3556,30 +3626,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: @@ -3614,7 +3695,17 @@ vppcom_session_attr (uint32_t session_handle, uint32_t op, rv = VPPCOM_EINVAL; break; } - session->ckpair_index = *(uint32_t *) buffer; + 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: @@ -3637,16 +3728,18 @@ vppcom_session_attr (uint32_t session_handle, uint32_t op, break; case VPPCOM_ATTR_GET_DOMAIN: - if (buffer && buflen && (*buflen >= sizeof (int))) + if (!(buffer && buflen && (*buflen >= sizeof (int)))) { - if (session->transport.is_ip4) - *(int *) buffer = AF_INET; - else - *(int *) buffer = AF_INET6; - *buflen = sizeof (int); + rv = VPPCOM_EINVAL; + break; } + + if (session->transport.is_ip4) + *(int *) buffer = AF_INET; else - rv = VPPCOM_EINVAL; + *(int *) buffer = AF_INET6; + *buflen = sizeof (int); + VDBG (2, "VPPCOM_ATTR_GET_DOMAIN: %d, buflen %u", *(int *) buffer, *buflen); break;