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));
56 clib_memset (app_listener, 0xfa,
sizeof (*app_listener));
100 u32 table_index, fib_proto;
225 *listener = app_listener;
332 app_ns->ip4_fib_index);
335 app_ns->ip6_fib_index);
345 return app_ns->local_table_index;
437 if (cb_fns->session_accept_callback == 0)
439 if (cb_fns->session_connected_callback == 0)
440 clib_warning (
"No session connected callback function provided");
441 if (cb_fns->session_disconnect_callback == 0)
442 clib_warning (
"No session disconnect callback function provided");
443 if (cb_fns->session_reset_callback == 0)
444 clib_warning (
"No session reset callback function provided");
460 clib_warning (
"memfd seg: vpp's event qs IN binary api svm region");
467 clib_warning (
"shm seg: vpp's event qs NOT IN binary api svm region");
484 options = a->options;
492 return VNET_API_ERROR_APP_UNSUPPORTED_CFG;
504 clib_warning (
"mq eventfds can only be used if socket transport is " 505 "used for binary api");
506 return VNET_API_ERROR_APP_UNSUPPORTED_CFG;
510 return VNET_API_ERROR_APP_UNSUPPORTED_CFG;
516 app->
cb_fns = *a->session_cb_vft;
524 app->
flags |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
533 props->add_segment = 1;
542 props->use_mq_eventfd = 1;
545 props->segment_type = seg_type;
555 APP_DBG (
"New app name: %v api index: %u index %u", app->
name,
582 app_wrk = app_worker_get (wrk_map->wrk_index);
583 app_worker_free (app_wrk);
604 u32 *wrks = 0, *wrk_index;
607 if (api_client_index == ~0)
613 APP_DBG (
"Detaching for app %v index %u api client index %u", app->
name,
618 app_wrk = app_worker_get (wrk_map->wrk_index);
619 if (app_wrk->api_client_index == api_client_index)
620 vec_add1 (wrks, app_wrk->wrk_index);
632 args->api_client_index = api_client_index;
701 sm->first_is_protected = 1;
728 return VNET_API_ERROR_INVALID_VALUE;
741 a->segment = &fs->
ssvm;
751 return VNET_API_ERROR_INVALID_VALUE;
755 return VNET_API_ERROR_INVALID_VALUE;
770 if (
vec_len (namespace_id) == 0)
779 return VNET_API_ERROR_APP_INVALID_NS;
782 return VNET_API_ERROR_APP_INVALID_NS;
783 if (app_ns->ns_secret != secret)
784 return VNET_API_ERROR_APP_WRONG_NS_SECRET;
796 clib_warning (
"api client index %u does not have an api registration!",
798 return format (0,
"unknown");
815 u32 app_ns_index = 0;
825 return VNET_API_ERROR_INVALID_VALUE;
828 return VNET_API_ERROR_APP_ALREADY_ATTACHED;
857 a->segment = &fs->
ssvm;
877 return VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
893 clib_warning (
"sw_if_index %u not configured with ip %U",
898 return (is_lep ||
ip_is_local (sep->fib_index, &sep->ip, sep->is_ip4));
906 u32 ns_index, fib_index;
911 if (app->
flags & APP_OPTIONS_FLAGS_IS_TRANSPORT_APP)
912 ns_index = sep->ns_index;
925 fib_index = sep->fib_index;
927 fib_index = sep->is_ip4 ? app_ns->ip4_fib_index : app_ns->ip6_fib_index;
928 sep->peer.fib_index = fib_index;
929 sep->fib_index = fib_index;
933 sep->sw_if_index = app_ns->sw_if_index;
939 && sep->peer.sw_if_index != app_ns->sw_if_index)
940 clib_warning (
"Local sw_if_index different from app ns sw_if_index");
942 sep->peer.sw_if_index = app_ns->sw_if_index;
958 return VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
962 return VNET_API_ERROR_INVALID_VALUE;
964 a->sep_ext.app_wrk_index = app_wrk->
wrk_index;
968 return VNET_API_ERROR_INVALID_VALUE_2;
977 return VNET_API_ERROR_ADDRESS_IN_USE;
1009 return VNET_API_ERROR_INVALID_VALUE;
1024 a->sep_ext.original_tp = a->sep_ext.transport_proto;
1025 a->sep_ext.transport_proto = TRANSPORT_PROTO_NONE;
1034 return VNET_API_ERROR_SESSION_CONNECT;
1048 return VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
1055 clib_warning (
"app doesn't own handle %llu!", a->handle);
1077 return VNET_API_ERROR_INVALID_VALUE;
1080 return VNET_API_ERROR_INVALID_VALUE;
1125 return (app->
flags & APP_OPTIONS_FLAGS_IS_PROXY);
1131 return (app->
flags & APP_OPTIONS_FLAGS_IS_BUILTIN);
1143 return app->
flags & APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
1149 return app->
flags & APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
1154 u8 transport_proto,
u8 is_start)
1172 sep.is_ip4 = is_ip4;
1174 sep.sw_if_index = app_ns->sw_if_index;
1175 sep.transport_proto = transport_proto;
1180 app->
flags &= ~APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
1200 sep.is_ip4 = is_ip4;
1202 sep.transport_proto = transport_proto;
1219 u8 transport_proto,
u8 is_start)
1225 sep.transport_proto = transport_proto;
1254 transport_proto, is_start);
1256 transport_proto, is_start);
1270 if (transports & (1 << tp))
1286 if (transports & (1 << tp))
1312 0,
"app %u doesn't exist", a->app_index);
1324 0,
"app %u doesn't exist", a->app_index);
1347 app_wrk = app_worker_get (wrk_map->wrk_index);
1348 if (hash_elts (app_wrk->listeners_table) == 0)
1350 hash_foreach (handle, sm_index, app_wrk->listeners_table, ({
1351 vlib_cli_output (vm,
"%U", format_app_worker_listener, app_wrk,
1352 handle, sm_index, verbose);
1372 app_wrk = app_worker_get (wrk_map->wrk_index);
1373 app_worker_format_connects (app_wrk, verbose);
1384 const u8 *app_ns_name, *app_name;
1391 s =
format (s,
"%-10s%-20s%-40s",
"Index",
"Name",
"Namespace");
1405 s =
format (s,
"app-name %v app-index %u ns-index %u seg-size %U\n",
1408 s =
format (s,
"rx-fifo-size %U tx-fifo-size %U workers:\n",
1414 app_wrk = app_worker_get (wrk_map->wrk_index);
1415 s = format (s,
"%U", format_app_worker, app_wrk);
1437 application_format_listeners (app, verbose);
1457 application_format_connects (app, verbose);
1466 int do_server = 0, do_client = 0;
1477 else if (
unformat (input,
"client"))
1479 else if (
unformat (input,
"%u", &app_index))
1481 else if (
unformat (input,
"verbose"))
1500 if (app_index != ~0)
1511 if (!do_server && !do_client)
1516 vlib_cli_output (vm,
"%U", format_application, app, 0);
1528 .short_help =
"show app [server|client] [verbose]",
u32 segment_manager_index(segment_manager_t *sm)
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)
u64 segment_manager_segment_handle(segment_manager_t *sm, fifo_segment_t *segment)
static void application_detach_process(application_t *app, u32 api_client_index)
u32 al_index
app listener index in app pool
#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 _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.
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 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)
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
segment_manager_props_t * application_segment_manager_properties(application_t *app)
static session_handle_t session_handle(session_t *s)
static int application_alloc_and_init(app_init_args_t *a)
u32 app_index
owning app 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.
struct _vnet_disconnect_args_t vnet_disconnect_args_t
void segment_manager_dealloc_fifos(svm_fifo_t *rx_fifo, svm_fifo_t *tx_fifo)
u32 local_index
local listening session index
u32 session_index
global listening session 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)
#define SESSION_INVALID_HANDLE
u8 tls_engine
Preferred tls engine.
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)
struct _segment_manager_props segment_manager_props_t
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)
#define SESSION_INVALID_INDEX
app_worker_t * app_worker_alloc(application_t *app)
session_handle_t app_listen_session_handle(session_t *ls)
Get app listener handle for listening session.
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.
svm_msg_q_t * segment_manager_event_queue(segment_manager_t *sm)
u32 application_local_session_table(application_t *app)
ssvm_private_t ssvm
ssvm segment data
uword * app_by_name
Hash table of builtin apps by name.
segment_manager_t * segment_manager_alloc(void)
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).
segment_manager_props_t sm_properties
Segment manager properties.
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...)
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)
Don't register connection in lookup Does not apply to local apps and transports using the network lay...
clib_bitmap_t * workers
workers accepting connections
struct _transport_connection transport_connection_t
#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 u8 vlib_thread_is_main_w_barrier(void)
static void application_name_table_add(application_t *app)
struct _app_namespace app_namespace_t
application_t * application_get(u32 app_index)
#define VLIB_CLI_COMMAND(x,...)
segment_manager_props_t * application_get_segment_manager_properties(u32 app_index)
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)
Get app listener for listener session handle.
int application_alloc_worker_and_init(application_t *app, app_worker_t **wrk)
segment_manager_props_t * segment_manager_props_init(segment_manager_props_t *props)
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.
fifo_segment_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.
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
struct _vnet_app_detach_args_t vnet_app_detach_args_t
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.
app_worker_t * app_worker_get(u32 wrk_index)
application_t * app_pool
Pool from which we allocate all applications.
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.
session_handle_t ls_handle
session handle of the local or global listening session that also identifies the app listener ...
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
segment_manager_t * segment_manager_get(u32 index)
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 struct option options[]
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)
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 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.