X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fsession%2Fsession.c;h=be62d929363b56190f7a1f2328b84a344909c453;hb=b5a2f7056967630c2834b0b4bf03520d96806c3e;hp=a102825c6f5247444a7bb467861796f8a04cc755;hpb=5d8a806144fbf46c0575ef24ae081724dfbdbe75;p=vpp.git diff --git a/src/vnet/session/session.c b/src/vnet/session/session.c index a102825c6f5..be62d929363 100644 --- a/src/vnet/session/session.c +++ b/src/vnet/session/session.c @@ -41,17 +41,11 @@ session_send_evt_to_thread (void *data, void *args, u32 thread_index, svm_msg_q_unlock (mq); return -2; } - msg = svm_msg_q_alloc_msg_w_ring (mq, SESSION_MQ_IO_EVT_RING); - if (PREDICT_FALSE (svm_msg_q_msg_is_invalid (&msg))) - { - svm_msg_q_unlock (mq); - return -2; - } - evt = (session_event_t *) svm_msg_q_msg_data (mq, &msg); - evt->event_type = evt_type; switch (evt_type) { case SESSION_CTRL_EVT_RPC: + msg = svm_msg_q_alloc_msg_w_ring (mq, SESSION_MQ_IO_EVT_RING); + evt = (session_event_t *) svm_msg_q_msg_data (mq, &msg); evt->rpc_args.fp = data; evt->rpc_args.arg = args; break; @@ -59,10 +53,15 @@ session_send_evt_to_thread (void *data, void *args, u32 thread_index, case SESSION_IO_EVT_TX: case SESSION_IO_EVT_TX_FLUSH: case SESSION_IO_EVT_BUILTIN_RX: + msg = svm_msg_q_alloc_msg_w_ring (mq, SESSION_MQ_IO_EVT_RING); + evt = (session_event_t *) svm_msg_q_msg_data (mq, &msg); evt->session_index = *(u32 *) data; break; case SESSION_IO_EVT_BUILTIN_TX: case SESSION_CTRL_EVT_CLOSE: + case SESSION_CTRL_EVT_RESET: + msg = svm_msg_q_alloc_msg_w_ring (mq, SESSION_MQ_IO_EVT_RING); + evt = (session_event_t *) svm_msg_q_msg_data (mq, &msg); evt->session_handle = session_handle ((session_t *) data); break; default: @@ -70,6 +69,7 @@ session_send_evt_to_thread (void *data, void *args, u32 thread_index, svm_msg_q_unlock (mq); return -1; } + evt->event_type = evt_type; svm_msg_q_add_and_unlock (mq, &msg); return 0; @@ -92,10 +92,10 @@ session_send_io_evt_to_thread_custom (void *data, u32 thread_index, int session_send_ctrl_evt_to_thread (session_t * s, session_evt_type_t evt_type) { - /* only event supported for now is disconnect */ - ASSERT (evt_type == SESSION_CTRL_EVT_CLOSE); - return session_send_evt_to_thread (s, 0, s->thread_index, - SESSION_CTRL_EVT_CLOSE); + /* only events supported are disconnect and reset */ + ASSERT (evt_type == SESSION_CTRL_EVT_CLOSE + || evt_type == SESSION_CTRL_EVT_RESET); + return session_send_evt_to_thread (s, 0, s->thread_index, evt_type); } void @@ -125,6 +125,7 @@ session_add_self_custom_tx_evt (transport_connection_t * tc, u8 has_prio) s = session_get (tc->s_index, tc->thread_index); ASSERT (s->thread_index == vlib_get_thread_index ()); + ASSERT (s->session_state < SESSION_STATE_TRANSPORT_DELETED); if (!(s->flags & SESSION_F_CUSTOM_TX)) { s->flags |= SESSION_F_CUSTOM_TX; @@ -144,7 +145,7 @@ session_add_self_custom_tx_evt (transport_connection_t * tc, u8 has_prio) } static void -session_program_transport_close (session_t * s) +session_program_transport_ctrl_evt (session_t * s, session_evt_type_t evt) { u32 thread_index = vlib_get_thread_index (); session_evt_elt_t *elt; @@ -158,10 +159,10 @@ session_program_transport_close (session_t * s) elt = session_evt_alloc_ctrl (wrk); clib_memset (&elt->evt, 0, sizeof (session_event_t)); elt->evt.session_handle = session_handle (s); - elt->evt.event_type = SESSION_CTRL_EVT_CLOSE; + elt->evt.event_type = evt; } else - session_send_ctrl_evt_to_thread (s, SESSION_CTRL_EVT_CLOSE); + session_send_ctrl_evt_to_thread (s, evt); } session_t * @@ -602,6 +603,8 @@ session_dequeue_notify (session_t * s) { app_worker_t *app_wrk; + svm_fifo_clear_deq_ntf (s->tx_fifo); + app_wrk = app_worker_get_if_valid (s->app_wrk_index); if (PREDICT_FALSE (!app_wrk)) return -1; @@ -614,8 +617,6 @@ session_dequeue_notify (session_t * s) return session_notify_subscribers (app_wrk->app_index, s, s->tx_fifo, SESSION_IO_EVT_TX); - svm_fifo_clear_deq_ntf (s->tx_fifo); - return 0; } @@ -888,7 +889,7 @@ session_transport_delete_notify (transport_connection_t * tc) s->session_state = SESSION_STATE_CLOSED; session_cleanup_notify (s, SESSION_CLEANUP_TRANSPORT); svm_fifo_dequeue_drop_all (s->tx_fifo); - session_program_transport_close (s); + session_program_transport_ctrl_evt (s, SESSION_CTRL_EVT_CLOSE); break; case SESSION_STATE_TRANSPORT_DELETED: break; @@ -1194,12 +1195,26 @@ session_close (session_t * s) * acknowledge the close */ if (s->session_state == SESSION_STATE_TRANSPORT_CLOSED || s->session_state == SESSION_STATE_TRANSPORT_DELETED) - session_program_transport_close (s); + session_program_transport_ctrl_evt (s, SESSION_CTRL_EVT_CLOSE); return; } s->session_state = SESSION_STATE_CLOSING; - session_program_transport_close (s); + session_program_transport_ctrl_evt (s, SESSION_CTRL_EVT_CLOSE); +} + +/** + * Force a close without waiting for data to be flushed + */ +void +session_reset (session_t * s) +{ + if (s->session_state >= SESSION_STATE_CLOSING) + return; + /* Drop all outstanding tx data */ + svm_fifo_dequeue_drop_all (s->tx_fifo); + s->session_state = SESSION_STATE_CLOSING; + session_program_transport_ctrl_evt (s, SESSION_CTRL_EVT_RESET); } /** @@ -1234,6 +1249,26 @@ session_transport_close (session_t * s) s->thread_index); } +/** + * Force transport close + */ +void +session_transport_reset (session_t * s) +{ + if (s->session_state >= SESSION_STATE_APP_CLOSED) + { + if (s->session_state == SESSION_STATE_TRANSPORT_CLOSED) + s->session_state = SESSION_STATE_CLOSED; + else if (s->session_state >= SESSION_STATE_TRANSPORT_DELETED) + session_free_w_fifos (s); + return; + } + + s->session_state = SESSION_STATE_APP_CLOSED; + transport_reset (session_get_transport_proto (s), s->connection_index, + s->thread_index); +} + /** * Cleanup transport and session state. * @@ -1244,8 +1279,6 @@ session_transport_close (session_t * s) void session_transport_cleanup (session_t * s) { - s->session_state = SESSION_STATE_CLOSED; - /* Delete from main lookup table before we axe the the transport */ session_lookup_del_session (s); transport_cleanup (session_get_transport_proto (s), s->connection_index, @@ -1657,6 +1690,8 @@ session_config_fn (vlib_main_t * vm, unformat_input_t * input) else if (unformat (input, "evt_qs_seg_size %U", unformat_memory_size, &smm->evt_qs_segment_size)) ; + else if (unformat (input, "enable")) + vnet_session_enable_disable (vm, 1 /* is_en */ ); else return clib_error_return (0, "unknown input `%U'", format_unformat_error, input);