From 9ace36d0f9b04e2d4db410607ee33a8e72ef00c5 Mon Sep 17 00:00:00 2001 From: Florin Coras Date: Mon, 28 Oct 2019 13:14:17 -0700 Subject: [PATCH] vcl session: propagate cleanup notifications to apps Type: feature Change-Id: I7f8e3763d7f8364563a25d0fcc782976b906b325 Signed-off-by: Florin Coras --- src/plugins/hs_apps/sapi/vpp_echo.c | 9 +++ src/vcl/vcl_private.h | 1 + src/vcl/vppcom.c | 107 +++++++++++++++++++------------ src/vnet/session/application_interface.h | 5 ++ src/vnet/session/session_api.c | 30 +++++++++ src/vnet/session/session_types.h | 3 + 6 files changed, 115 insertions(+), 40 deletions(-) diff --git a/src/plugins/hs_apps/sapi/vpp_echo.c b/src/plugins/hs_apps/sapi/vpp_echo.c index 560c6a85f3d..12be1f99537 100644 --- a/src/plugins/hs_apps/sapi/vpp_echo.c +++ b/src/plugins/hs_apps/sapi/vpp_echo.c @@ -785,6 +785,12 @@ del_segment_handler (session_app_del_segment_msg_t * mp) ECHO_LOG (2, "Unmaped segment 0x%lx", mp->segment_handle); } +static void +cleanup_handler (session_cleanup_msg_t * mp) +{ + ECHO_LOG (1, "Cleanup confirmed for 0x%lx", mp->handle); +} + static void handle_mq_event (session_event_t * e) { @@ -810,6 +816,9 @@ handle_mq_event (session_event_t * e) case SESSION_CTRL_EVT_APP_DEL_SEGMENT: del_segment_handler ((session_app_del_segment_msg_t *) e->data); break; + case SESSION_CTRL_EVT_CLEANUP: + cleanup_handler ((session_cleanup_msg_t *) e->data); + break; case SESSION_IO_EVT_RX: break; default: diff --git a/src/vcl/vcl_private.h b/src/vcl/vcl_private.h index 30d3774fa93..fd9d73c3547 100644 --- a/src/vcl/vcl_private.h +++ b/src/vcl/vcl_private.h @@ -375,6 +375,7 @@ vcl_session_alloc (vcl_worker_t * wrk) static inline void vcl_session_free (vcl_worker_t * wrk, vcl_session_t * s) { + VDBG (0, "session %u [0x%llx] removed", s->session_index, s->vpp_handle); pool_put (wrk->sessions, s); } diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c index 4b12062215e..916ddf94f02 100644 --- a/src/vcl/vppcom.c +++ b/src/vcl/vppcom.c @@ -712,6 +712,24 @@ vcl_session_disconnected_handler (vcl_worker_t * wrk, return session; } +static void +vcl_session_cleanup_handler (vcl_worker_t * wrk, void *data) +{ + session_cleanup_msg_t *msg; + vcl_session_t *session; + + msg = (session_cleanup_msg_t *) data; + session = vcl_session_get_w_vpp_handle (wrk, msg->handle); + if (!session) + { + VDBG (0, "disconnect confirmed for unknown handle 0x%llx", msg->handle); + return; + } + + vcl_session_table_del_vpp_handle (wrk, msg->handle); + vcl_session_free (wrk, session); +} + static void vcl_session_req_worker_update_handler (vcl_worker_t * wrk, void *data) { @@ -845,6 +863,9 @@ vcl_handle_mq_event (vcl_worker_t * wrk, session_event_t * e) case SESSION_CTRL_EVT_MIGRATED: vcl_session_migrated_handler (wrk, e->data); break; + case SESSION_CTRL_EVT_CLEANUP: + vcl_session_cleanup_handler (wrk, e->data); + break; case SESSION_CTRL_EVT_REQ_WORKER_UPDATE: vcl_session_req_worker_update_handler (wrk, e->data); break; @@ -1244,52 +1265,52 @@ vcl_session_cleanup (vcl_worker_t * wrk, vcl_session_t * session, next_sh = session->vep.next_sh; } + goto cleanup; } - else + + if (session->is_vep_session) { - if (session->is_vep_session) - { - rv = vppcom_epoll_ctl (vep_sh, EPOLL_CTL_DEL, sh, 0); - if (rv < 0) - VDBG (0, "session %u [0x%llx]: EPOLL_CTL_DEL vep_idx %u " - "failed! rv %d (%s)", session->session_index, vpp_handle, - vep_sh, rv, vppcom_retval_str (rv)); - } + rv = vppcom_epoll_ctl (vep_sh, EPOLL_CTL_DEL, sh, 0); + if (rv < 0) + VDBG (0, "session %u [0x%llx]: EPOLL_CTL_DEL vep_idx %u " + "failed! rv %d (%s)", session->session_index, vpp_handle, + vep_sh, rv, vppcom_retval_str (rv)); + } - if (!do_disconnect) - { - VDBG (1, "session %u [0x%llx] disconnect skipped", - session->session_index, vpp_handle); - goto cleanup; - } + if (!do_disconnect) + { + VDBG (1, "session %u [0x%llx] disconnect skipped", + session->session_index, vpp_handle); + goto cleanup; + } - if (state & STATE_LISTEN) - { - rv = vppcom_session_unbind (sh); - if (PREDICT_FALSE (rv < 0)) - VDBG (0, "session %u [0x%llx]: listener unbind failed! " - "rv %d (%s)", session->session_index, vpp_handle, rv, - vppcom_retval_str (rv)); - return rv; - } - else if ((state & STATE_OPEN) - || (vcl_session_is_connectable_listener (wrk, session))) - { - rv = vppcom_session_disconnect (sh); - if (PREDICT_FALSE (rv < 0)) - VDBG (0, "ERROR: session %u [0x%llx]: disconnect failed!" - " rv %d (%s)", session->session_index, vpp_handle, - rv, vppcom_retval_str (rv)); - } - else if (state == STATE_DISCONNECT) - { - svm_msg_q_t *mq = vcl_session_vpp_evt_q (wrk, session); - vcl_send_session_reset_reply (mq, wrk->my_client_index, - session->vpp_handle, 0); - } + if (state & STATE_LISTEN) + { + rv = vppcom_session_unbind (sh); + if (PREDICT_FALSE (rv < 0)) + VDBG (0, "session %u [0x%llx]: listener unbind failed! " + "rv %d (%s)", session->session_index, vpp_handle, rv, + vppcom_retval_str (rv)); + return rv; + } + else if ((state & STATE_OPEN) + || (vcl_session_is_connectable_listener (wrk, session))) + { + rv = vppcom_session_disconnect (sh); + if (PREDICT_FALSE (rv < 0)) + VDBG (0, "ERROR: session %u [0x%llx]: disconnect failed!" + " rv %d (%s)", session->session_index, vpp_handle, + rv, vppcom_retval_str (rv)); + } + else if (state == STATE_DISCONNECT) + { + svm_msg_q_t *mq = vcl_session_vpp_evt_q (wrk, session); + vcl_send_session_reset_reply (mq, wrk->my_client_index, + session->vpp_handle, 0); } - VDBG (0, "session %u [0x%llx] removed", session->session_index, vpp_handle); + /* Session is removed only after vpp confirms the disconnect */ + return rv; cleanup: vcl_session_table_del_vpp_handle (wrk, vpp_handle); @@ -2163,6 +2184,9 @@ vcl_select_handle_mq_event (vcl_worker_t * wrk, session_event_t * e, case SESSION_CTRL_EVT_MIGRATED: vcl_session_migrated_handler (wrk, e->data); break; + case SESSION_CTRL_EVT_CLEANUP: + vcl_session_cleanup_handler (wrk, e->data); + break; case SESSION_CTRL_EVT_WORKER_UPDATE_REPLY: vcl_session_worker_update_reply_handler (wrk, e->data); break; @@ -2774,6 +2798,9 @@ vcl_epoll_wait_handle_mq_event (vcl_worker_t * wrk, session_event_t * e, case SESSION_CTRL_EVT_MIGRATED: vcl_session_migrated_handler (wrk, e->data); break; + case SESSION_CTRL_EVT_CLEANUP: + vcl_session_cleanup_handler (wrk, e->data); + break; case SESSION_CTRL_EVT_REQ_WORKER_UPDATE: vcl_session_req_worker_update_handler (wrk, e->data); break; diff --git a/src/vnet/session/application_interface.h b/src/vnet/session/application_interface.h index a6641477f12..552fec1b6ef 100644 --- a/src/vnet/session/application_interface.h +++ b/src/vnet/session/application_interface.h @@ -510,6 +510,11 @@ typedef struct session_migrate_msg_ u32 vpp_thread_index; } __clib_packed session_migrated_msg_t; +typedef struct session_cleanup_msg_ +{ + session_handle_t handle; +} __clib_packed session_cleanup_msg_t; + typedef struct app_session_event_ { svm_msg_q_msg_t msg; diff --git a/src/vnet/session/session_api.c b/src/vnet/session/session_api.c index c6eeacfea18..a95faada9ae 100644 --- a/src/vnet/session/session_api.c +++ b/src/vnet/session/session_api.c @@ -589,6 +589,35 @@ mq_send_del_segment_cb (u32 app_wrk_index, u64 segment_handle) return 0; } +static void +mq_send_session_cleanup_cb (session_t * s, session_cleanup_ntf_t ntf) +{ + svm_msg_q_msg_t _msg, *msg = &_msg; + session_cleanup_msg_t *mp; + svm_msg_q_t *app_mq; + session_event_t *evt; + app_worker_t *app_wrk; + + /* Only propagate session cleanup notification */ + if (ntf == SESSION_CLEANUP_TRANSPORT) + return; + + app_wrk = app_worker_get_if_valid (s->app_wrk_index); + if (!app_wrk) + return; + + app_mq = app_wrk->event_queue; + if (mq_try_lock_and_alloc_msg (app_mq, msg)) + return; + + evt = svm_msg_q_msg_data (app_mq, msg); + clib_memset (evt, 0, sizeof (*evt)); + evt->event_type = SESSION_CTRL_EVT_CLEANUP; + mp = (session_cleanup_msg_t *) evt->data; + mp->handle = session_handle (s); + svm_msg_q_add_and_unlock (app_mq, msg); +} + /* ### WILL BE DEPRECATED POST 20.01 ### */ static session_cb_vft_t session_mq_cb_vft_old = { .session_accept_callback = mq_send_session_accepted_cb, @@ -606,6 +635,7 @@ static session_cb_vft_t session_mq_cb_vft = { .session_connected_callback = mq_send_session_connected_cb, .session_reset_callback = mq_send_session_reset_cb, .session_migrate_callback = mq_send_session_migrate_cb, + .session_cleanup_callback = mq_send_session_cleanup_cb, .add_segment_callback = mq_send_add_segment_cb, .del_segment_callback = mq_send_del_segment_cb, }; diff --git a/src/vnet/session/session_types.h b/src/vnet/session/session_types.h index 60d5e4d823c..be8ad9cdb83 100644 --- a/src/vnet/session/session_types.h +++ b/src/vnet/session/session_types.h @@ -337,6 +337,7 @@ typedef enum SESSION_CTRL_EVT_APP_ADD_SEGMENT, SESSION_CTRL_EVT_APP_DEL_SEGMENT, SESSION_CTRL_EVT_MIGRATED, + SESSION_CTRL_EVT_CLEANUP, } session_evt_type_t; #define foreach_session_ctrl_evt \ @@ -360,6 +361,8 @@ typedef enum _(APP_DETACH, app_detach) \ _(APP_ADD_SEGMENT, app_add_segment) \ _(APP_DEL_SEGMENT, app_del_segment) \ + _(MIGRATED, migrated) \ + _(CLEANUP, cleanup) \ /* Deprecated and will be removed. Use types above */ #define FIFO_EVENT_APP_RX SESSION_IO_EVT_RX -- 2.16.6