24 #define app_interface_check_thread_and_barrier(_fn, _arg) \ 25 if (PREDICT_FALSE (!vlib_thread_is_main_w_barrier ())) \ 27 vlib_rpc_call_main_thread (_fn, (u8 *) _arg, sizeof(*_arg)); \ 36 clib_memset (app_listener, 0,
sizeof (*app_listener));
64 clib_memset (app_listener, 0xfa,
sizeof (*app_listener));
82 u32 * app_listener_index)
84 *app_index = listener_id >> 16;
85 *app_listener_index = listener_id & 0xFFFF;
90 u32 * app_listener_index)
98 u32 app_index, app_listener_index;
132 u32 table_index, fib_proto;
254 *listener = app_listener;
361 app_ns->ip4_fib_index);
364 app_ns->ip6_fib_index);
374 return app_ns->local_table_index;
466 if (cb_fns->session_accept_callback == 0)
468 if (cb_fns->session_connected_callback == 0)
469 clib_warning (
"No session connected callback function provided");
470 if (cb_fns->session_disconnect_callback == 0)
471 clib_warning (
"No session disconnect callback function provided");
472 if (cb_fns->session_reset_callback == 0)
473 clib_warning (
"No session reset callback function provided");
489 clib_warning (
"memfd seg: vpp's event qs IN binary api svm region");
496 clib_warning (
"shm seg: vpp's event qs NOT IN binary api svm region");
513 options = a->options;
521 return VNET_API_ERROR_APP_UNSUPPORTED_CFG;
533 clib_warning (
"mq eventfds can only be used if socket transport is " 534 "used for binary api");
535 return VNET_API_ERROR_APP_UNSUPPORTED_CFG;
539 return VNET_API_ERROR_APP_UNSUPPORTED_CFG;
545 app->
cb_fns = *a->session_cb_vft;
553 app->
flags |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
562 props->add_segment = 1;
571 props->use_mq_eventfd = 1;
574 props->segment_type = seg_type;
584 APP_DBG (
"New app name: %v api index: %u index %u", app->
name,
600 APP_DBG (
"Delete app name %v api index: %d index: %d", app->
name,
612 app_wrk = app_worker_get (wrk_map->wrk_index);
613 app_worker_free (app_wrk);
634 u32 *wrks = 0, *wrk_index;
637 if (api_client_index == ~0)
643 APP_DBG (
"Detaching for app %v index %u api client index %u", app->
name,
648 app_wrk = app_worker_get (wrk_map->wrk_index);
649 if (app_wrk->api_client_index == api_client_index)
650 vec_add1 (wrks, app_wrk->wrk_index);
662 args->api_client_index = api_client_index;
731 sm->first_is_protected = 1;
758 return VNET_API_ERROR_INVALID_VALUE;
771 a->segment = &fs->
ssvm;
781 return VNET_API_ERROR_INVALID_VALUE;
785 return VNET_API_ERROR_INVALID_VALUE;
800 if (
vec_len (namespace_id) == 0)
809 return VNET_API_ERROR_APP_INVALID_NS;
812 return VNET_API_ERROR_APP_INVALID_NS;
813 if (app_ns->ns_secret != secret)
814 return VNET_API_ERROR_APP_WRONG_NS_SECRET;
826 clib_warning (
"api client index %u does not have an api registration!",
828 return format (0,
"unknown");
845 u32 app_ns_index = 0;
855 return VNET_API_ERROR_INVALID_VALUE;
858 return VNET_API_ERROR_APP_ALREADY_ATTACHED;
887 a->segment = &fs->
ssvm;
907 return VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
923 clib_warning (
"sw_if_index %u not configured with ip %U",
928 return (is_lep ||
ip_is_local (sep->fib_index, &sep->ip, sep->is_ip4));
936 u32 ns_index, fib_index;
941 if (app->
flags & APP_OPTIONS_FLAGS_IS_TRANSPORT_APP)
942 ns_index = sep->ns_index;
955 fib_index = sep->fib_index;
957 fib_index = sep->is_ip4 ? app_ns->ip4_fib_index : app_ns->ip6_fib_index;
958 sep->peer.fib_index = fib_index;
959 sep->fib_index = fib_index;
963 sep->sw_if_index = app_ns->sw_if_index;
969 && sep->peer.sw_if_index != app_ns->sw_if_index)
970 clib_warning (
"Local sw_if_index different from app ns sw_if_index");
972 sep->peer.sw_if_index = app_ns->sw_if_index;
986 return VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
990 return VNET_API_ERROR_INVALID_VALUE;
992 a->sep_ext.app_wrk_index = app_wrk->
wrk_index;
996 return VNET_API_ERROR_INVALID_VALUE_2;
1005 return VNET_API_ERROR_ADDRESS_IN_USE;
1035 return VNET_API_ERROR_INVALID_VALUE;
1050 a->sep_ext.original_tp = a->sep_ext.transport_proto;
1060 return VNET_API_ERROR_SESSION_CONNECT;
1072 return VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
1079 clib_warning (
"app doesn't own handle %llu!", a->handle);
1101 return VNET_API_ERROR_INVALID_VALUE;
1104 return VNET_API_ERROR_INVALID_VALUE;
1149 return (app->
flags & APP_OPTIONS_FLAGS_IS_PROXY);
1155 return (app->
flags & APP_OPTIONS_FLAGS_IS_BUILTIN);
1167 return app->
flags & APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
1173 return app->
flags & APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
1178 u8 transport_proto,
u8 is_start)
1196 sep.is_ip4 = is_ip4;
1198 sep.sw_if_index = app_ns->sw_if_index;
1199 sep.transport_proto = transport_proto;
1204 app->
flags &= ~APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
1224 sep.is_ip4 = is_ip4;
1226 sep.transport_proto = transport_proto;
1243 u8 transport_proto,
u8 is_start)
1249 sep.transport_proto = transport_proto;
1278 transport_proto, is_start);
1280 transport_proto, is_start);
1294 if (transports & (1 << tp))
1310 if (transports & (1 << tp))
1336 0,
"app %u doesn't exist", a->app_index);
1348 0,
"app %u doesn't exist", a->app_index);
1371 app_wrk = app_worker_get (wrk_map->wrk_index);
1372 if (hash_elts (app_wrk->listeners_table) == 0)
1374 hash_foreach (handle, sm_index, app_wrk->listeners_table, ({
1375 vlib_cli_output (vm,
"%U", format_app_worker_listener, app_wrk,
1376 handle, sm_index, verbose);
1396 app_wrk = app_worker_get (wrk_map->wrk_index);
1397 app_worker_format_connects (app_wrk, verbose);
1408 const u8 *app_ns_name, *app_name;
1415 s =
format (s,
"%-10s%-20s%-40s",
"Index",
"Name",
"Namespace");
1429 s =
format (s,
"app-name %v app-index %u ns-index %u seg-size %U\n",
1432 s =
format (s,
"rx-fifo-size %U tx-fifo-size %U workers:\n",
1438 app_wrk = app_worker_get (wrk_map->wrk_index);
1439 s = format (s,
"%U", format_app_worker, app_wrk);
1461 application_format_listeners (app, verbose);
1481 application_format_connects (app, verbose);
1490 int do_server = 0, do_client = 0;
1501 else if (
unformat (input,
"client"))
1503 else if (
unformat (input,
"%u", &app_index))
1505 else if (
unformat (input,
"verbose"))
1524 if (app_index != ~0)
1535 if (!do_server && !do_client)
1540 vlib_cli_output (vm,
"%U", format_application, app, 0);
1552 .short_help =
"show app [server|client] [verbose]",
static void application_name_table_del(application_t *app)
u32 al_index
App listener index in app's listener pool if a listener.
struct _vnet_app_worker_add_del_args vnet_app_worker_add_del_args_t
#define ENDPOINT_INVALID_INDEX
#define APP_NAMESPACE_INVALID_INDEX
session_t * app_worker_proxy_listener(app_worker_t *app, u8 fib_proto, u8 transport_proto)
#define hash_set(h, key, value)
void segment_manager_segment_reader_unlock(segment_manager_t *sm)
static void application_detach_process(application_t *app, u32 api_client_index)
#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.
u32 ns_index
Namespace the application belongs to.
u8 application_has_global_scope(application_t *app)
struct _segment_manager_properties segment_manager_properties_t
struct _vnet_connect_args vnet_connect_args_t
struct _vnet_unlisten_args_t vnet_unlisten_args_t
int application_change_listener_owner(session_t *s, app_worker_t *app_wrk)
u32 session_index
Index in thread pool where session was allocated.
int session_stop_listen(session_t *s)
Ask transport to stop listening on local transport endpoint.
#define session_cli_return_if_not_enabled()
u8 ip_is_local(u32 fib_index, ip46_address_t *ip46_address, u8 is_ip4)
Checks that an ip is local to the requested fib.
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)
transport_connection_t * listen_session_get_transport(session_t *s)
static void app_listener_id_parse(u32 listener_id, u32 *app_index, u32 *app_listener_index)
static app_worker_t * app_listener_select_worker(application_t *app, app_listener_t *al)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
transport_connection_t * session_get_transport(session_t *s)
application_t * application_lookup_name(const u8 *name)
svm_fifo_t * rx_fifo
Pointers to rx/tx buffers.
u8 ip_interface_has_address(u32 sw_if_index, ip46_address_t *ip, u8 is_ip4)
app_listener_t * app_listener_get_w_session(session_t *ls)
int app_worker_connect_session(app_worker_t *app, session_endpoint_t *tep, u32 api_context)
u32 session_lookup_get_index_for_fib(u32 fib_proto, u32 fib_index)
static session_t * listen_session_get_from_handle(session_handle_t handle)
application_t * application_lookup(u32 api_client_index)
app_listener_t * app_listener_get(application_t *app, u32 app_listener_index)
app_listener_t * listeners
Pool of listeners for the app.
u32 wrk_map_index
Worker index in app's map pool.
session_handle_t app_listener_handle(app_listener_t *al)
static session_t * listen_session_alloc(u8 thread_index, session_type_t type)
static uword * clib_bitmap_set(uword *ai, uword i, uword value)
Sets the ith bit of a bitmap to new_value Removes trailing zeros from the bitmap. ...
#define hash_set_mem(h, key, value)
static u8 session_endpoint_fib_proto(session_endpoint_t *sep)
static session_t * session_get(u32 si, u32 thread_index)
int vnet_unlisten(vnet_unlisten_args_t *a)
segment_manager_properties_t * segment_manager_properties_init(segment_manager_properties_t *props)
uword * listeners_table
Lookup tables for listeners.
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)
app_worker_t * application_get_worker(application_t *app, u32 wrk_map_index)
#define SESSION_ENDPOINT_NULL
static u8 session_endpoint_in_ns(session_endpoint_t *sep)
int segment_manager_init(segment_manager_t *sm, u32 first_seg_size, u32 prealloc_fifo_pairs)
Initializes segment manager based on options provided.
application_t * application_get_if_valid(u32 app_index)
struct _vnet_bind_args_t vnet_listen_args_t
static session_handle_t session_handle(session_t *s)
static int application_alloc_and_init(app_init_args_t *a)
#define SESSION_INVALID_INDEX
int application_is_proxy(application_t *app)
enum ssvm_segment_type_ ssvm_segment_type_t
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
u32 first_segment_manager
First segment manager has in the the first segment the application's event fifo.
#define SESSION_LISTENER_PREFIX
struct _vnet_disconnect_args_t vnet_disconnect_args_t
void segment_manager_dealloc_fifos(svm_fifo_t *rx_fifo, svm_fifo_t *tx_fifo)
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.
static app_listener_t * app_listener_get_if_valid(application_t *app, u32 app_listener_index)
#define clib_error_return(e, args...)
u32 app_namespace_index_from_id(const u8 *ns_id)
static int app_validate_namespace(u8 *namespace_id, u64 secret, u32 *app_ns_index)
u8 tls_engine
Preferred tls engine.
segment_manager_t * segment_manager_new()
struct _vnet_app_attach_args_t vnet_app_attach_args_t
struct _session_endpoint_cfg session_endpoint_cfg_t
static const u8 * app_get_name(application_t *app)
#define pool_flush(VAR, POOL, BODY)
Remove all elements from a pool in a safe way.
static app_main_t app_main
static void application_verify_cb_fns(session_cb_vft_t *cb_fns)
clib_error_t * vnet_app_add_tls_key(vnet_app_add_tls_key_args_t *a)
int application_is_builtin(application_t *app)
u32 app_namespace_get_fib_index(app_namespace_t *app_ns, u8 fib_proto)
static session_type_t session_type_from_proto_and_ip(transport_proto_t proto, u8 is_ip4)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
#define hash_unset_mem(h, key)
session_t * app_listener_get_local_session(app_listener_t *al)
#define VL_API_INVALID_FI
static uword clib_bitmap_first_set(uword *ai)
Return the lowest numbered set bit in a bitmap.
static void application_api_table_del(u32 api_client_index)
static session_t * session_get_from_handle(session_handle_t handle)
session_t * app_listener_get_session(app_listener_t *al)
u32 app_index
Index of application that owns the listener.
const u8 * application_name_from_index(u32 app_index)
Returns app name for app-index.
static u32 app_worker_map_index(application_t *app, app_worker_map_t *map)
#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)
app_namespace_t * app_namespace_get(u32 index)
u32 wrk_index
Worker index in global worker pool.
u32 application_session_table(application_t *app, u8 fib_proto)
app_worker_t * app_worker_alloc(application_t *app)
static u64 listen_session_get_handle(session_t *s)
u8 * format_app_worker_listener(u8 *s, va_list *args)
app_worker_map_t * worker_maps
Pool of mappings that keep track of workers associated to this app.
int vnet_application_attach(vnet_app_attach_args_t *a)
Attach application to vpp.
static session_t * session_get_from_handle_if_valid(session_handle_t handle)
#define pool_free(p)
Free a pool.
An API client registration, only in vpp/vlib.
u32 application_local_session_table(application_t *app)
uword * app_by_name
Hash table of builtin apps by name.
static void app_listener_free(application_t *app, app_listener_t *app_listener)
session_t * app_worker_first_listener(app_worker_t *app, u8 fib_proto, u8 transport_proto)
#define vec_free(V)
Free vector's memory (no header).
static application_t * application_alloc(void)
int session_lookup_del_session_endpoint(u32 table_index, session_endpoint_t *sep)
void session_free(session_t *s)
#define clib_warning(format, args...)
#define SESSION_INVALID_HANDLE
struct _stream_session_cb_vft session_cb_vft_t
static void session_endpoint_update_for_app(session_endpoint_cfg_t *sep, application_t *app, u8 is_connect)
clib_bitmap_t * workers
workers accepting connections
struct _transport_connection transport_connection_t
segment_manager_properties_t sm_properties
Segment manager properties.
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
const u8 * app_namespace_id_from_index(u32 index)
void application_format_all_clients(vlib_main_t *vm, int verbose)
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 void application_name_table_add(application_t *app)
struct _app_namespace app_namespace_t
application_t * application_get(u32 app_index)
static u32 segment_manager_index(segment_manager_t *sm)
#define VLIB_CLI_COMMAND(x,...)
int session_listen(session_t *ls, session_endpoint_cfg_t *sep)
Ask transport to listen on session endpoint.
static u32 session_index_from_handle(session_handle_t handle)
#define hash_create(elts, value_bytes)
int app_listener_alloc_and_init(application_t *app, session_endpoint_cfg_t *sep, app_listener_t **listener)
app_listener_t * app_listener_get_w_handle(session_handle_t handle)
int application_alloc_worker_and_init(application_t *app, app_worker_t **wrk)
app_worker_t * application_listener_select_worker(session_t *ls)
static u8 * app_name_from_api_index(u32 api_client_index)
int vnet_listen(vnet_listen_args_t *a)
uword * app_by_api_client_index
Hash table of apps by api client index.
int vnet_application_detach(vnet_app_detach_args_t *a)
Detach application from vpp.
void application_remove_proxy(application_t *app)
session_cb_vft_t cb_fns
Callbacks: shoulder-taps for the server/client.
struct _vnet_application_add_tls_key_args_t vnet_app_add_tls_key_args_t
enum _transport_proto transport_proto_t
u8 * tls_key
PEM encoded key.
#define clib_bitmap_free(v)
Free a bitmap.
u32 accept_rotor
last worker to accept a connection
static svm_msg_q_t * segment_manager_event_queue(segment_manager_t *sm)
struct _vnet_app_detach_args_t vnet_app_detach_args_t
void app_listener_handle_parse(session_handle_t handle, u32 *app_index, u32 *app_listener_index)
int vnet_connect(vnet_connect_args_t *a)
static vlib_main_t * vlib_get_main(void)
static void listen_session_free(session_t *s)
u8 ip_is_zero(ip46_address_t *ip46_address, u8 is_ip4)
u32 app_index
App index in app pool.
static u32 app_listener_id(app_listener_t *al)
app_worker_t * app_worker_get(u32 wrk_index)
application_t * app_pool
Pool from which we allocate all applications.
u64 segment_manager_segment_handle(segment_manager_t *sm, svm_fifo_segment_private_t *segment)
static void application_free(application_t *app)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
u8 * format_application(u8 *s, va_list *args)
u8 * name
Name registered by builtin apps.
void session_close(session_t *s)
Initialize session closing procedure.
static u8 session_endpoint_is_zero(session_endpoint_t *sep)
static app_worker_map_t * app_worker_map_alloc(application_t *app)
ssvm_private_t * session_main_get_evt_q_segment(void)
int vnet_disconnect_session(vnet_disconnect_args_t *a)
app_worker_t * application_get_default_worker(application_t *app)
struct _segment_manager segment_manager_t
#define SESSION_ENDPOINT_CFG_NULL
u32 application_n_workers(application_t *app)
void app_listener_cleanup(app_listener_t *al)
int vnet_app_worker_add_del(vnet_app_worker_add_del_args_t *a)
static void application_api_table_add(u32 app_index, u32 api_client_index)
static void application_format_listeners(application_t *app, int verbose)
int app_worker_start_listen(app_worker_t *app_wrk, app_listener_t *lstnr)
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)
#define app_interface_check_thread_and_barrier(_fn, _arg)
u32 app_index
Index of owning app.
int session_lookup_add_connection(transport_connection_t *tc, u64 value)
Add transport connection to a session table.
app_listener_t * app_listener_lookup(application_t *app, session_endpoint_cfg_t *sep_ext)
static void application_start_stop_proxy_local_scope(application_t *app, u8 transport_proto, u8 is_start)
int app_worker_stop_listen(app_worker_t *app_wrk, app_listener_t *al)
void app_worker_free(app_worker_t *app_wrk)
#define clib_error_return_code(e, code, flags, args...)
u8 * tls_cert
Certificate to be used for listen sessions.
#define transport_proto_foreach(VAR, BODY)
static app_worker_map_t * app_worker_map_get(application_t *app, u32 map_index)
#define vec_foreach(var, vec)
Vector iterator.
u32 app_wrk_index
Index of the app worker that owns the session.
void application_setup_proxy(application_t *app)
void app_worker_format_connects(app_worker_t *app_wrk, int verbose)
static u8 session_endpoint_is_local(session_endpoint_t *sep)
static u8 application_verify_cfg(ssvm_segment_type_t st)
Check app config for given segment type.
static void application_format_connects(application_t *app, int verbose)
int application_is_builtin_proxy(application_t *app)
u32 api_client_index
API index for the worker.
struct _session_endpoint session_endpoint_t
static void app_worker_map_free(application_t *app, app_worker_map_t *map)
void application_start_stop_proxy(application_t *app, transport_proto_t transport_proto, u8 is_start)
segment_manager_properties_t * application_segment_manager_properties(application_t *app)
svm_msg_q_t * event_queue
Application listens for events on this svm queue.
static transport_service_type_t session_transport_service_type(session_t *s)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
void application_format_all_listeners(vlib_main_t *vm, int verbose)
#define APP_DBG(_fmt, _args...)
static segment_manager_t * segment_manager_get(u32 index)
static app_listener_t * app_listener_get_w_id(u32 listener_id)
static session_t * listen_session_get(u32 ls_index)
void ct_session_endpoint(session_t *ll, session_endpoint_t *sep)
static app_listener_t * app_listener_alloc(application_t *app)
u8 application_has_local_scope(application_t *app)
static uword pool_elts(void *v)
Number of active elements in a pool.