#include <vnet/session/application.h>
#include <vnet/session/application_interface.h>
+#include <vnet/session/session.h>
/**
* Pool of workers associated to apps
app_worker_free (app_worker_t * app_wrk)
{
application_t *app = application_get (app_wrk->app_index);
- vnet_unbind_args_t _a, *a = &_a;
+ vnet_unlisten_args_t _a, *a = &_a;
u64 handle, *handles = 0;
segment_manager_t *sm;
u32 sm_index;
int i;
+ app_listener_t *al;
+ session_t *ls;
/*
* Listener cleanup
*/
/* *INDENT-OFF* */
- hash_foreach (handle, sm_index, app_wrk->listeners_table,
- ({
- vec_add1 (handles, handle);
+ hash_foreach (handle, sm_index, app_wrk->listeners_table, ({
+ ls = listen_session_get_from_handle (handle);
+ al = app_listener_get (app, ls->al_index);
+ vec_add1 (handles, app_listener_handle (al));
sm = segment_manager_get (sm_index);
sm->app_wrk_index = SEGMENT_MANAGER_INVALID_APP_INDEX;
}));
a->wrk_map_index = app_wrk->wrk_map_index;
a->handle = handles[i];
/* seg manager is removed when unbind completes */
- vnet_unbind (a);
+ (void) vnet_unlisten (a);
}
/*
return sm;
}
+static int
+app_worker_alloc_session_fifos (segment_manager_t * sm, session_t * s)
+{
+ svm_fifo_t *rx_fifo = 0, *tx_fifo = 0;
+ u32 fifo_segment_index;
+ int rv;
+
+ if ((rv = segment_manager_alloc_session_fifos (sm, &rx_fifo, &tx_fifo,
+ &fifo_segment_index)))
+ return rv;
+
+ rx_fifo->master_session_index = s->session_index;
+ rx_fifo->master_thread_index = s->thread_index;
+
+ tx_fifo->master_session_index = s->session_index;
+ tx_fifo->master_thread_index = s->thread_index;
+
+ s->rx_fifo = rx_fifo;
+ s->tx_fifo = tx_fifo;
+ s->svm_segment_index = fifo_segment_index;
+ return 0;
+}
+
int
-app_worker_start_listen (app_worker_t * app_wrk, session_t * ls)
+app_worker_start_listen (app_worker_t * app_wrk,
+ app_listener_t * app_listener)
{
segment_manager_t *sm;
+ session_t *ls;
+
+ if (clib_bitmap_get (app_listener->workers, app_wrk->wrk_map_index))
+ return VNET_API_ERROR_ADDRESS_IN_USE;
+
+ app_listener->workers = clib_bitmap_set (app_listener->workers,
+ app_wrk->wrk_map_index, 1);
+
+ if (app_listener->session_index == SESSION_INVALID_INDEX)
+ return 0;
+
+ ls = session_get (app_listener->session_index, 0);
/* Allocate segment manager. All sessions derived out of a listen session
* have fifos allocated by the same segment manager. */
if (!(sm = app_worker_alloc_segment_manager (app_wrk)))
return -1;
- /* Add to app's listener table. Useful to find all child listeners
- * when app goes down, although, just for unbinding this is not needed */
+ /* Keep track of the segment manager for the listener or this worker */
hash_set (app_wrk->listeners_table, listen_session_get_handle (ls),
segment_manager_index (sm));
- if (!ls->rx_fifo
- && session_transport_service_type (ls) == TRANSPORT_SERVICE_CL)
+ if (session_transport_service_type (ls) == TRANSPORT_SERVICE_CL)
{
- if (session_alloc_fifos (sm, ls))
+ if (!ls->rx_fifo && app_worker_alloc_session_fifos (sm, ls))
return -1;
}
return 0;
}
int
-app_worker_stop_listen (app_worker_t * app_wrk, session_handle_t handle)
+app_worker_stop_listen (app_worker_t * app_wrk, app_listener_t * al)
{
+ session_handle_t handle;
segment_manager_t *sm;
uword *sm_indexp;
- sm_indexp = hash_get (app_wrk->listeners_table, handle);
- if (PREDICT_FALSE (!sm_indexp))
+ if (!clib_bitmap_get (al->workers, app_wrk->wrk_map_index))
+ return 0;
+
+ if (al->session_index != SESSION_INVALID_INDEX)
{
- clib_warning ("listener handle was removed %llu!", handle);
- return -1;
+ session_t *ls;
+
+ ls = listen_session_get (al->session_index);
+ handle = listen_session_get_handle (ls);
+
+ sm_indexp = hash_get (app_wrk->listeners_table, handle);
+ if (PREDICT_FALSE (!sm_indexp))
+ {
+ clib_warning ("listener handle was removed %llu!", handle);
+ return -1;
+ }
+
+ sm = segment_manager_get (*sm_indexp);
+ if (app_wrk->first_segment_manager == *sm_indexp)
+ {
+ /* Delete sessions but don't remove segment manager */
+ app_wrk->first_segment_manager_in_use = 0;
+ segment_manager_del_sessions (sm);
+ }
+ else
+ {
+ segment_manager_init_del (sm);
+ }
+ hash_unset (app_wrk->listeners_table, handle);
}
- sm = segment_manager_get (*sm_indexp);
- if (app_wrk->first_segment_manager == *sm_indexp)
+ if (al->local_index != SESSION_INVALID_INDEX)
{
- /* Delete sessions but don't remove segment manager */
- app_wrk->first_segment_manager_in_use = 0;
- segment_manager_del_sessions (sm);
+ local_session_t *ll, *ls;
+ application_t *app;
+
+ app = application_get (app_wrk->app_index);
+ ll = application_get_local_listen_session (app, al->local_index);
+
+ /* *INDENT-OFF* */
+ pool_foreach (ls, app_wrk->local_sessions, ({
+ if (ls->listener_index == ll->session_index)
+ app_worker_local_session_disconnect (app_wrk->app_index, ls);
+ }));
+ /* *INDENT-ON* */
}
- else
+
+ clib_bitmap_set_no_check (al->workers, app_wrk->wrk_map_index, 0);
+ if (clib_bitmap_is_zero (al->workers))
+ app_listener_cleanup (al);
+
+ return 0;
+}
+
+int
+app_worker_init_accepted (session_t * s)
+{
+ app_worker_t *app_wrk;
+ segment_manager_t *sm;
+ session_t *listener;
+
+ listener = listen_session_get (s->listener_index);
+ app_wrk = application_listener_select_worker (listener);
+ s->app_wrk_index = app_wrk->wrk_index;
+ sm = app_worker_get_listen_segment_manager (app_wrk, listener);
+ return app_worker_alloc_session_fifos (sm, s);
+}
+
+int
+app_worker_accept_notify (app_worker_t * app_wrk, session_t * s)
+{
+ application_t *app = application_get (app_wrk->app_index);
+ return app->cb_fns.session_accept_callback (s);
+}
+
+int
+app_worker_init_connected (app_worker_t * app_wrk, session_t * s)
+{
+ application_t *app = application_get (app_wrk->app_index);
+ segment_manager_t *sm;
+
+ /* Allocate fifos for session, unless the app is a builtin proxy */
+ if (!application_is_builtin_proxy (app))
{
- segment_manager_init_del (sm);
+ sm = app_worker_get_connect_segment_manager (app_wrk);
+ if (app_worker_alloc_session_fifos (sm, s))
+ return -1;
}
- hash_unset (app_wrk->listeners_table, handle);
-
return 0;
}
+int
+app_worker_connect_notify (app_worker_t * app_wrk, session_t * s, u32 opaque)
+{
+ application_t *app = application_get (app_wrk->app_index);
+ return app->cb_fns.session_connected_callback (app_wrk->wrk_index, opaque,
+ s, s == 0 /* is_fail */ );
+}
+
int
app_worker_own_session (app_worker_t * app_wrk, session_t * s)
{
s->tx_fifo = 0;
sm = app_worker_get_or_alloc_connect_segment_manager (app_wrk);
- if (session_alloc_fifos (sm, s))
+ if (app_worker_alloc_session_fifos (sm, s))
return -1;
if (!svm_fifo_is_empty (rxf))
}
int
-app_worker_open_session (app_worker_t * app, session_endpoint_t * sep,
- u32 api_context)
+app_worker_connect_session (app_worker_t * app, session_endpoint_t * sep,
+ u32 api_context)
{
int rv;
}
session_t *
-app_worker_first_listener (app_worker_t * app, u8 fib_proto,
+app_worker_first_listener (app_worker_t * app_wrk, u8 fib_proto,
u8 transport_proto)
{
session_t *listener;
fib_proto == FIB_PROTOCOL_IP4);
/* *INDENT-OFF* */
- hash_foreach (handle, sm_index, app->listeners_table, ({
+ hash_foreach (handle, sm_index, app_wrk->listeners_table, ({
listener = listen_session_get_from_handle (handle);
if (listener->session_type == sst
&& listener->enqueue_epoch != SESSION_PROXY_LISTENER_INDEX)
}
session_t *
-app_worker_proxy_listener (app_worker_t * app, u8 fib_proto,
+app_worker_proxy_listener (app_worker_t * app_wrk, u8 fib_proto,
u8 transport_proto)
{
session_t *listener;
fib_proto == FIB_PROTOCOL_IP4);
/* *INDENT-OFF* */
- hash_foreach (handle, sm_index, app->listeners_table, ({
+ hash_foreach (handle, sm_index, app_wrk->listeners_table, ({
listener = listen_session_get_from_handle (handle);
if (listener->session_type == sst
&& listener->enqueue_epoch == SESSION_PROXY_LISTENER_INDEX)
app_worker_format_local_sessions (app_worker_t * app_wrk, int verbose)
{
vlib_main_t *vm = vlib_get_main ();
+ app_worker_t *client_wrk;
local_session_t *ls;
transport_proto_t tp;
u8 *conn = 0;
tp = session_type_transport_proto(ls->listener_session_type);
conn = format (0, "[L][%U] *:%u", format_transport_proto_short, tp,
ls->port);
- vlib_cli_output (vm, "%-40v%-15u%-20u", conn, ls->app_wrk_index,
- ls->client_wrk_index);
+ client_wrk = app_worker_get (ls->client_wrk_index);
+ vlib_cli_output (vm, "%-40v%-15u%-20u", conn, ls->app_index,
+ client_wrk->app_index);
vec_reset_length (conn);
}));
/* *INDENT-ON* */