44 app_name =
format (0,
"builtin-%d%c", app->index, 0);
68 app_ns->ip4_fib_index);
71 app_ns->ip6_fib_index);
81 return app_ns->local_table_index;
90 if (app->api_client_index == ~0)
97 if (q->cursize == q->maxsize)
162 memset (app, 0,
sizeof (*app));
168 clib_warning (
"[%d] New app (%d)", getpid (), app->index);
176 u64 handle, *handles = 0;
186 clib_warning (
"[%d] Delete app (%d)", getpid (), app->index);
198 vec_add1 (handles, handle);
199 sm = segment_manager_get (index);
200 sm->app_index = SEGMENT_MANAGER_INVALID_APP_INDEX;
204 for (i = 0; i <
vec_len (handles); i++)
206 a->app_index = app->index;
207 a->handle = handles[
i];
225 && app->first_segment_manager != app->connects_seg_manager)
253 if (cb_fns->session_accept_callback == 0)
255 if (cb_fns->session_connected_callback == 0)
256 clib_warning (
"No session connected callback function provided");
257 if (cb_fns->session_disconnect_callback == 0)
258 clib_warning (
"No session disconnect callback function provided");
259 if (cb_fns->session_reset_callback == 0)
260 clib_warning (
"No session reset callback function provided");
276 clib_warning (
"memfd seg: vpp's event qs IN binary api svm region");
283 clib_warning (
"shm seg: vpp's event qs NOT IN binary api svm region");
295 u32 first_seg_size, prealloc_fifo_pairs;
309 return VNET_API_ERROR_APP_UNSUPPORTED_CFG;
319 return VNET_API_ERROR_APP_UNSUPPORTED_CFG;
325 sm->app_index = app->index;
331 props->add_segment = 1;
341 props->segment_type = seg_type;
348 sm->first_is_protected = 1;
354 app->api_client_index = api_client_index;
356 app->cb_fns = *cb_fns;
362 app->name =
vec_dup (app_name);
367 app->flags |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
379 sm->app_index = app->index;
415 && app->first_segment_manager_in_use == 0)
418 app->first_segment_manager_in_use = 1;
423 sm->app_index = app->index;
446 s->app_index = srv->index;
483 if (srv &&
hash_get (srv->listeners_table, handle) == 0)
492 indexp =
hash_get (srv->listeners_table, handle);
496 if (srv->first_segment_manager == *indexp)
499 srv->first_segment_manager_in_use = 0;
545 ASSERT (app->connects_seg_manager != (
u32) ~ 0);
581 return (app->flags & APP_OPTIONS_FLAGS_IS_PROXY);
587 return (app->flags & APP_OPTIONS_FLAGS_IS_BUILTIN);
603 return app->cb_fns.add_segment_callback (app->api_client_index, fs);
609 return app->flags & APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
615 return app->flags & APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
637 hash_foreach (handle, sm_index, app->listeners_table, ({
638 listener = listen_session_get_from_handle (handle);
639 if (listener->session_type == sst
640 && listener->listener_index != SESSION_PROXY_LISTENER_INDEX)
661 hash_foreach (handle, sm_index, app->listeners_table, ({
662 listener = listen_session_get_from_handle (handle);
663 if (listener->session_type == sst
664 && listener->listener_index == SESSION_PROXY_LISTENER_INDEX)
674 u8 transport_proto,
u8 is_start)
690 sep.sw_if_index = app_ns->sw_if_index;
691 sep.transport_proto = transport_proto;
710 sep.transport_proto = transport_proto;
724 u8 transport_proto,
u8 is_start)
730 sep.transport_proto = transport_proto;
759 transport_proto, is_start);
761 transport_proto, is_start);
768 u16 transports = app->proxied_transports;
775 if (transports & (1 << tp))
784 u16 transports = app->proxied_transports;
791 if (transports & (1 << tp))
800 return &app->sm_properties;
807 return &app->sm_properties;
815 memset (s, 0,
sizeof (*s));
827 memset (s, 0xfc,
sizeof (*s));
840 u32 session_index, server_index;
850 sep->transport_proto =
852 sep->port = ll->
port;
870 return VNET_API_ERROR_ADDRESS_IN_USE;
872 pool_get (server->local_listen_sessions, ll);
873 memset (ll, 0,
sizeof (*ll));
877 ll->
port = sep->port;
898 u32 table_index, ll_index, server_index;
921 ASSERT (server->index == server_index);
932 if (ls->listener_index == ll->session_index)
933 application_local_session_disconnect (server->index, ls);
946 u32 seg_size, evt_q_sz, evt_q_elts, margin = 16 << 10;
948 int rv, has_transport, seg_index;
958 evt_q_elts = props->evt_q_size + cprops->evt_q_size;
959 evt_q_sz = evt_q_elts *
sizeof (session_fifo_event_t);
960 seg_size = props->rx_fifo_size + props->tx_fifo_size + evt_q_sz + margin;
974 ls->
port = tc->lcl_port;
995 clib_warning (
"failed to add fifos in cut-through segment");
1009 if ((rv = server->cb_fns.add_segment_callback (server->api_client_index,
1012 clib_warning (
"failed to notify server of new segment");
1017 if ((rv = server->cb_fns.session_accept_callback ((
stream_session_t *) ls)))
1019 clib_warning (
"failed to send accept cut-through notify to server");
1022 if (server->flags & APP_OPTIONS_FLAGS_IS_BUILTIN)
1041 u32 * session_index)
1043 *app_index = key >> 32;
1044 *session_index = key & 0xFFFFFFFF;
1053 int rv, is_fail = 0;
1060 if ((rv = client->cb_fns.add_segment_callback (client->api_client_index,
1063 clib_warning (
"failed to notify client %u of new segment",
1074 client->cb_fns.session_connected_callback (client->index, ls->
client_opaque,
1079 hash_set (client->local_connects, client_key, client_key);
1103 hash_unset (client->local_connects, client_key);
1107 server->cb_fns.del_segment_callback (server->api_client_index,
1110 client->cb_fns.del_segment_callback (client->api_client_index,
1143 client->cb_fns.session_connected_callback (client->index,
1174 u32 index, server_index, session_index, table_index;
1176 u64 handle, *handles = 0;
1188 application_local_listener_session_endpoint (ll, &sep);
1189 session_lookup_del_session_endpoint (table_index, &sep);
1196 if (app->local_sessions)
1200 application_local_session_disconnect (app->index, ls);
1211 vec_add1 (handles, handle);
1215 for (i = 0; i <
vec_len (handles); i++)
1239 0,
"app %u doesn't exist", a->app_index);
1240 app->tls_cert =
vec_dup (a->cert);
1251 0,
"app %u doesn't exist", a->app_index);
1252 app->tls_key =
vec_dup (a->key);
1260 u64 handle = va_arg (*args,
u64);
1261 u32 sm_index = va_arg (*args,
u32);
1262 int verbose = va_arg (*args,
int);
1269 s =
format (s,
"%-40s%-20s%-15s%-15s%-10s",
"Connection",
"App",
1270 "API Client",
"ListenerID",
"SegManager");
1272 s =
format (s,
"%-40s%-20s",
"Connection",
"App");
1283 s =
format (s,
"%-40s%-20s%-15u%-15u%-10u", str, app_name,
1284 app->api_client_index, handle, sm_index);
1287 s =
format (s,
"%-40s%-20s", str, app_name);
1299 u8 *app_name, *s = 0;
1306 "API Client",
"SegManager");
1313 if (app->connects_seg_manager == (
u32) ~ 0)
1329 u32 session_index, thread_index;
1332 session_index = fifo->master_session_index;
1333 thread_index = fifo->master_thread_index;
1335 session =
session_get (session_index, thread_index);
1339 s =
format (s,
"%-40s%-20s%-15u%-10u", str, app_name,
1340 app->api_client_index, app->connects_seg_manager);
1342 s =
format (s,
"%-40s%-20s", str, app_name);
1375 tp = session_type_transport_proto(ls->listener_session_type);
1376 conn = format (0,
"[L][%U] *:%u", format_transport_proto_short, tp,
1378 vlib_cli_output (vm,
"%-40v%-15u%-20s", conn, ls->app_index,
"*");
1379 vec_reset_length (conn);
1382 tp = session_type_transport_proto(ls->listener_session_type);
1383 conn = format (0,
"[L][%U] *:%u", format_transport_proto_short, tp,
1385 vlib_cli_output (vm,
"%-40v%-15u%-20u", conn, ls->app_index,
1387 vec_reset_length (conn);
1398 u32 app_index, session_index;
1409 "Peer App",
"SegManager");
1417 hash_foreach (client_key, value, app->local_connects, ({
1418 application_client_local_connect_key_parse (client_key, &app_index,
1420 server = application_get (app_index);
1421 ls = application_get_local_session (server, session_index);
1422 vlib_cli_output (vm,
"%-40s%-15s%-20s",
"TODO", ls->app_index, ls->client_index);
1433 const u8 *app_ns_name;
1439 s =
format (s,
"%-10s%-20s%-15s%-15s%-15s%-15s%-15s",
"Index",
"Name",
1440 "API Client",
"Namespace",
"Add seg size",
"Rx-f size",
1443 s =
format (s,
"%-10s%-20s%-15s%-40s",
"Index",
"Name",
"API Client",
1452 s =
format (s,
"%-10u%-20s%-15d%-15u%-15U%-15U%-15U", app->index,
1453 app_name, app->api_client_index, app->ns_index,
1456 props->tx_fifo_size);
1458 s =
format (s,
"%-10u%-20s%-15d%-40s", app->index, app_name,
1459 app->api_client_index, app_ns_name);
1496 if (
hash_elts (app->listeners_table) == 0)
1498 hash_foreach (handle, sm_index, app->listeners_table, ({
1499 vlib_cli_output (vm,
"%U", format_application_listener, app,
1500 handle, sm_index, verbose);
1524 if (app->local_connects)
1535 if (app->connects_seg_manager == (
u32)~0)
1547 int do_server = 0, do_client = 0, do_local = 0;
1557 else if (
unformat (input,
"client"))
1559 else if (
unformat (input,
"local"))
1561 else if (
unformat (input,
"verbose"))
1574 if (!do_server && !do_client)
1591 .short_help =
"show app [server|client] [verbose]",
int application_open_session(application_t *app, session_endpoint_t *sep, u32 api_context)
static void application_table_add(application_t *app)
segment_manager_t * application_get_local_segment_manager_w_session(application_t *app, local_session_t *ls)
svm_queue_t * segment_manager_alloc_queue(svm_fifo_segment_private_t *segment, u32 queue_size)
Allocates shm queue in the first segment.
session_type_t listener_session_type
Has transport embedded when listener not purely local.
void application_free_local_session(application_t *app, local_session_t *s)
#define hash_set(h, key, value)
void segment_manager_segment_reader_unlock(segment_manager_t *sm)
void application_format_local_connects(application_t *app, int verbose)
u32 application_n_listeners(application_t *app)
static session_handle_t application_local_session_handle(local_session_t *ls)
#define hash_unset(h, key)
u64 session_lookup_endpoint_listener(u32 table_index, session_endpoint_t *sep, u8 use_rules)
Lookup listener for session endpoint in table.
u8 application_has_global_scope(application_t *app)
struct _transport_connection transport_connection_t
struct _segment_manager_properties segment_manager_properties_t
#define session_cli_return_if_not_enabled()
segment_manager_properties_t * application_get_segment_manager_properties(u32 app_index)
static clib_error_t * show_app_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
int application_stop_listen(application_t *srv, session_handle_t handle)
Stop listening on session associated to handle.
clib_error_t * vnet_unbind(vnet_unbind_args_t *a)
int application_start_local_listen(application_t *server, session_endpoint_t *sep, session_handle_t *handle)
#define SESSION_PROXY_LISTENER_INDEX
application_t * application_lookup_name(const u8 *name)
application_t * application_new()
u32 session_lookup_get_index_for_fib(u32 fib_proto, u32 fib_index)
u32 client_index
Client data.
local_session_t * application_get_local_session_from_handle(session_handle_t handle)
application_t * application_lookup(u32 api_client_index)
void application_local_sessions_del(application_t *app)
#define hash_set_mem(h, key, value)
svm_fifo_t * server_tx_fifo
segment_manager_properties_t * segment_manager_properties_init(segment_manager_properties_t *props)
#define segment_manager_foreach_segment_w_lock(VAR, SM, BODY)
struct _vnet_application_add_tls_cert_args_t vnet_app_add_tls_cert_args_t
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
clib_error_t * vnet_app_add_tls_cert(vnet_app_add_tls_cert_args_t *a)
static stream_session_t * listen_session_get_from_handle(session_handle_t handle)
int segment_manager_init(segment_manager_t *sm, u32 first_seg_size, u32 prealloc_fifo_pairs)
Initializes segment manager based on options provided.
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
#define SESSION_ENDPOINT_NULL
struct _svm_fifo svm_fifo_t
segment_manager_t * application_get_listen_segment_manager(application_t *app, stream_session_t *s)
int application_is_proxy(application_t *app)
enum ssvm_segment_type_ ssvm_segment_type_t
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
static void application_table_del(application_t *app)
void application_format_local_sessions(application_t *app, int verbose)
int application_local_session_connect_notify(local_session_t *ls)
u32 transport_listener_index
struct _stream_session_cb_vft session_cb_vft_t
struct _vnet_unbind_args_t vnet_unbind_args_t
svm_fifo_segment_private_t * segment_manager_get_segment_w_lock(segment_manager_t *sm, u32 segment_index)
Reads a segment from the segment manager's pool and acquires reader lock.
#define hash_foreach(key_var, value_var, h, body)
session_type_t session_type
Type.
static stream_session_t * listen_session_get(u32 index)
#define transport_proto_foreach(VAR, BODY)
static u8 * app_get_name_from_reg_index(application_t *app)
static local_session_t * application_get_local_listen_session(application_t *app, u32 session_index)
struct _stream_session_t stream_session_t
segment_manager_t * segment_manager_new()
local_session_t * application_alloc_local_session(application_t *app)
int application_add_segment_notify(u32 app_index, ssvm_private_t *fs)
Send an API message to the external app, to map new segment.
static void application_verify_cb_fns(session_cb_vft_t *cb_fns)
int session_open(u32 app_index, session_endpoint_t *rmt, u32 opaque)
Ask transport to open connection to remote transport endpoint.
clib_error_t * vnet_app_add_tls_key(vnet_app_add_tls_key_args_t *a)
static void listen_session_del(stream_session_t *s)
int application_is_builtin(application_t *app)
u32 app_namespace_get_fib_index(app_namespace_t *app_ns, u8 fib_proto)
static svm_fifo_t * svm_fifo_segment_get_fifo_list(svm_fifo_segment_private_t *fifo_segment)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
#define hash_unset_mem(h, key)
#define VL_API_INVALID_FI
struct _session_endpoint session_endpoint_t
static void local_session_parse_handle(session_handle_t handle, u32 *server_index, u32 *session_index)
static u8 * app_get_name(application_t *app)
svm_fifo_t * server_rx_fifo
fifo pointers.
stream_session_t * application_proxy_listener(application_t *app, u8 fib_proto, u8 transport_proto)
static u8 session_handle_is_local(session_handle_t handle)
static application_t * app_pool
Pool from which we allocate all applications.
#define pool_put(P, E)
Free an object E in pool P.
#define APP_INVALID_INDEX
#define vec_dup(V)
Return copy of vector (no header, no alignment)
svm_fifo_segment_private_t * segment_manager_get_segment(segment_manager_t *sm, u32 segment_index)
Reads a segment from the segment manager's pool without lock.
u8 segment_manager_has_fifos(segment_manager_t *sm)
stream_session_t * application_first_listener(application_t *app, u8 fib_proto, u8 transport_proto)
u32 svm_segment_index
Segment index where fifos were allocated.
static u8 application_local_session_listener_has_transport(local_session_t *ls)
app_namespace_t * app_namespace_get(u32 index)
u32 application_session_table(application_t *app, u8 fib_proto)
void segment_manager_del_segment(segment_manager_t *sm, svm_fifo_segment_private_t *fs)
Remove segment without lock.
u8 * application_name_from_index(u32 app_index)
Returns app name.
int segment_manager_add_segment(segment_manager_t *sm, u32 segment_size)
Adds segment to segment manager's pool.
volatile u8 session_state
State.
static stream_session_t * session_get(u32 si, u32 thread_index)
local_session_t * application_get_local_session(application_t *app, u32 session_index)
#define SEGMENT_MANAGER_INVALID_APP_INDEX
An API client registration, only in vpp/vlib.
u32 application_local_session_table(application_t *app)
static session_type_t session_type_from_proto_and_ip(transport_proto_t proto, u8 is_ip4)
static transport_proto_t session_type_transport_proto(session_type_t st)
svm_queue_t * vl_api_client_index_to_input_queue(u32 index)
u8 * format_stream_session(u8 *s, va_list *args)
Format stream session as per the following format.
#define vec_free(V)
Free vector's memory (no header).
segment_manager_t * application_get_connect_segment_manager(application_t *app)
int session_lookup_del_session_endpoint(u32 table_index, session_endpoint_t *sep)
#define clib_warning(format, args...)
#define SESSION_INVALID_HANDLE
u16 port
Port for connection.
int application_start_listen(application_t *srv, session_endpoint_t *sep, session_handle_t *res)
Start listening local transport endpoint for requested transport.
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
struct _application application_t
const u8 * app_namespace_id_from_index(u32 index)
static uword * app_by_api_client_index
Hash table of apps by api client index.
static vl_api_registration_t * vl_api_client_index_to_registration(u32 index)
int session_lookup_add_session_endpoint(u32 table_index, session_endpoint_t *sep, u64 value)
static u32 vl_api_registration_file_index(vl_api_registration_t *reg)
static u8 session_has_transport(stream_session_t *s)
int application_local_session_disconnect_w_index(u32 app_index, u32 ls_index)
int segment_manager_try_alloc_fifos(svm_fifo_segment_private_t *fifo_segment, u32 rx_fifo_size, u32 tx_fifo_size, svm_fifo_t **rx_fifo, svm_fifo_t **tx_fifo)
struct _app_namespace app_namespace_t
static u32 segment_manager_index(segment_manager_t *sm)
static segment_manager_t * application_alloc_segment_manager(application_t *app)
#define VLIB_CLI_COMMAND(x,...)
#define hash_create(elts, value_bytes)
ssvm_private_t * session_manager_get_evt_q_segment(void)
void segment_manager_init_del(segment_manager_t *sm)
#define pool_put_index(p, i)
Free pool element with given index.
static uword hash_elts(void *v)
static void application_client_local_connect_key_parse(uword key, u32 *app_index, u32 *session_index)
static uword * app_by_name
Hash table of builtin apps by name.
int application_stop_local_listen(application_t *server, session_handle_t lh)
Clean up local session table.
void application_remove_proxy(application_t *app)
struct _vnet_application_add_tls_key_args_t vnet_app_add_tls_key_args_t
int listen_session_get_local_session_endpoint(stream_session_t *listener, session_endpoint_t *sep)
void application_del(application_t *app)
u32 application_get_index(application_t *app)
int application_local_session_disconnect(u32 app_index, local_session_t *ls)
void application_format_all_listeners(vlib_main_t *vm, int do_local, int verbose)
int stream_session_stop_listen(stream_session_t *s)
Ask transport to stop listening on local transport endpoint.
static uword pointer_to_uword(const void *p)
static vlib_main_t * vlib_get_main(void)
u8 ip_is_zero(ip46_address_t *ip46_address, u8 is_ip4)
void segment_manager_del(segment_manager_t *sm)
Removes segment manager.
void send_local_session_disconnect_callback(u32 app_index, local_session_t *ls)
u8 * format_application_listener(u8 *s, va_list *args)
enum _transport_proto transport_proto_t
transport_connection_t * listen_session_get_transport(stream_session_t *s)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
u8 * format_application(u8 *s, va_list *args)
static stream_session_t * listen_session_new(u8 thread_index, session_type_t type)
application_t * application_get(u32 index)
u32 session_index
Session index.
void segment_manager_del_sessions(segment_manager_t *sm)
Initiate disconnects for all sessions 'owned' by a segment manager.
struct _segment_manager segment_manager_t
struct _svm_queue svm_queue_t
static clib_error_t * application_start_stop_proxy_fib_proto(application_t *app, u8 fib_proto, u8 transport_proto, u8 is_start)
#define hash_get_mem(h, key)
int application_init(application_t *app, u32 api_client_index, u8 *app_name, u64 *options, session_cb_vft_t *cb_fns)
static uword application_client_local_connect_key(local_session_t *ls)
static void application_start_stop_proxy_local_scope(application_t *app, u8 transport_proto, u8 is_start)
#define clib_error_return_code(e, code, flags, args...)
int application_alloc_connects_segment_manager(application_t *app)
void application_setup_proxy(application_t *app)
static u8 application_verify_cfg(ssvm_segment_type_t st)
Check app config for given segment type.
int application_is_builtin_proxy(application_t *app)
int application_local_session_cleanup(application_t *client, application_t *server, local_session_t *ls)
void application_start_stop_proxy(application_t *app, transport_proto_t transport_proto, u8 is_start)
int application_api_queue_is_full(application_t *app)
segment_manager_properties_t * application_segment_manager_properties(application_t *app)
static void application_local_listener_session_endpoint(local_session_t *ll, session_endpoint_t *sep)
#define APP_INVALID_SEGMENT_MANAGER_INDEX
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
static svm_queue_t * segment_manager_event_queue(segment_manager_t *sm)
segment_manager_t * application_get_local_segment_manager(application_t *app)
static segment_manager_t * segment_manager_get(u32 index)
static u64 listen_session_get_handle(stream_session_t *s)
application_t * application_get_if_valid(u32 index)
void application_format_connects(application_t *app, int verbose)
void application_format_all_clients(vlib_main_t *vm, int do_local, int verbose)
int application_local_session_connect(u32 table_index, application_t *client, application_t *server, local_session_t *ll, u32 opaque)
int stream_session_listen(stream_session_t *s, session_endpoint_t *sep)
Ask transport to listen on local transport endpoint.
u8 application_has_local_scope(application_t *app)
u32 app_index
Server index.
static uword pool_elts(void *v)
Number of active elements in a pool.