43 #define vl_print(handle, ...) clib_warning (__VA_ARGS__) 104 vec_add1 (keys, (u8 *) hp->key);
107 for (i = 0; i <
vec_len (keys); i++)
146 for (i = 0; i < nmsgs; i++)
205 mp->_vl_msg_id = ntohs (VL_API_MEMCLNT_CREATE);
208 strncpy ((
char *) mp->
name, name, sizeof (mp->
name) - 1);
215 struct timespec ts, tsrem;
219 for (i = 0; i < 1000; i++)
226 ts.tv_nsec = 10000 * 1000;
227 while (nanosleep (&ts, &tsrem) < 0)
236 if (ntohs (rp->_vl_msg_id) != VL_API_MEMCLNT_CREATE_REPLY)
238 clib_warning (
"unexpected reply: id %d", ntohs (rp->_vl_msg_id));
241 rv = clib_net_to_host_u32 (rp->
response);
277 mp->_vl_msg_id = ntohs (VL_API_MEMCLNT_DELETE);
307 if (now >= (begin + 2))
321 if (ntohs (rp->_vl_msg_id) != VL_API_MEMCLNT_DELETE_REPLY)
323 clib_warning (
"queue drain: %d", ntohs (rp->_vl_msg_id));
342 vl_api_memclnt_keepalive_reply_t *rmp;
351 rmp->_vl_msg_id = ntohs (VL_API_MEMCLNT_KEEPALIVE_REPLY);
356 #define foreach_api_msg \ 357 _(RX_THREAD_EXIT, rx_thread_exit) \ 358 _(MEMCLNT_CREATE_REPLY, memclnt_create_reply) \ 359 _(MEMCLNT_DELETE_REPLY, memclnt_delete_reply) \ 360 _(MEMCLNT_KEEPALIVE, memclnt_keepalive) 367 vl_msg_api_set_handlers(VL_API_##N, #n, \ 368 vl_api_##n##_t_handler, \ 370 vl_api_##n##_t_endian, \ 371 vl_api_##n##_t_print, \ 372 sizeof(vl_api_##n##_t), 1); 398 return (my_memory_client_main->connected_to_vlib != 0);
403 const char *client_name,
404 int rx_queue_size,
void *(*thread_fn) (
void *),
405 void *thread_fn_arg,
int do_map)
434 thread_fn_arg = (
void *) arg;
438 NULL , thread_fn, thread_fn_arg);
456 const char *client_name,
int rx_queue_size)
465 const char *client_name,
476 const char *client_name,
int rx_queue_size)
485 const char *client_name,
496 const char *client_name,
498 void *(*thread_fn) (
void *),
void *arg)
516 ep->_vl_msg_id = ntohs (VL_API_RX_THREAD_EXIT);
562 if (strlen (plugin_name) + 1 >
sizeof (mp->
name))
569 old_handler = am->
msg_handlers[VL_API_GET_FIRST_MSG_ID_REPLY];
570 am->
msg_handlers[VL_API_GET_FIRST_MSG_ID_REPLY] = (
void *)
581 mp->_vl_msg_id = ntohs (VL_API_GET_FIRST_MSG_ID);
583 strncpy ((
char *) mp->
name, plugin_name, sizeof (mp->
name) - 1);
598 am->
msg_handlers[VL_API_GET_FIRST_MSG_ID_REPLY] = old_handler;
606 mp->_vl_msg_id = ntohs (VL_API_GET_FIRST_MSG_ID);
608 strncpy ((
char *) mp->
name, plugin_name, sizeof (mp->
name) - 1);
623 am->
msg_handlers[VL_API_GET_FIRST_MSG_ID_REPLY] = old_handler;
631 am->
msg_handlers[VL_API_GET_FIRST_MSG_ID_REPLY] = old_handler;
634 clib_warning (
"plugin '%s' not registered", plugin_name);
#define CLIB_MEM_UNPOISON(a, s)
int vl_client_connect_to_vlib(const char *svm_name, const char *client_name, int rx_queue_size)
static u64 unserialize_likely_small_unsigned_integer(serialize_main_t *m)
struct rx_thread_fn_arg rx_thread_fn_arg_t
u8 vl_mem_client_is_connected(void)
int vl_map_shmem(const char *region_name, int is_vlib)
int vl_client_connect_to_vlib_no_map(const char *svm_name, const char *client_name, int rx_queue_size)
int vl_socket_client_read(int wait)
u8 rx_thread_jmpbuf_valid
int vl_client_connect_to_vlib_no_rx_pthread(const char *svm_name, const char *client_name, int rx_queue_size)
int my_client_index
All VLIB-side message handlers use my_client_index to identify the queue / client.
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static f64 clib_time_now(clib_time_t *c)
static void disconnect_from_vlib_internal(u8 do_unmap)
static void vl_api_memclnt_keepalive_t_handler(vl_api_memclnt_keepalive_t *mp)
Stave off the binary API dead client reaper Only sent to inactive clients.
#define hash_set_mem(h, key, value)
int vl_client_connect_to_vlib_thread_fn(const char *svm_name, const char *client_name, int rx_queue_size, void *(*thread_fn)(void *), void *arg)
svm_queue_t * vl_input_queue
Peer input queue pointer.
void * vl_msg_api_alloc(int nbytes)
static void noop_handler(void *notused)
void vl_client_api_unmap(void)
void * vl_socket_client_msg_alloc(int nbytes)
vl_api_registration_t * my_registration
This is the (shared VM) address of the registration, don't use it to id the connection since it can't...
int svm_queue_sub(svm_queue_t *q, u8 *elem, svm_q_conditional_wait_t cond, u32 time)
static void clib_mem_set_thread_index(void)
static void vlibapi_set_main(api_main_t *am)
pthread_t rx_thread_handle
void unserialize_open_data(serialize_main_t *m, u8 *data, uword n_data_bytes)
static void * rx_thread_fn(void *arg)
svm_region_t * vlib_rp
Current binary api segment descriptor.
__thread memory_client_main_t * my_memory_client_main
struct vl_shmem_hdr_ * shmem_hdr
Binary API shared-memory segment header pointer.
static memory_client_main_t * vlibapi_get_memory_client_main(void)
void vl_msg_api_send_shmem(svm_queue_t *q, u8 *elem)
#define hash_create_string(elts, value_bytes)
static void vl_api_memclnt_create_reply_t_handler(vl_api_memclnt_create_reply_t *mp)
int vl_client_connect(const char *name, int ctx_quota, int input_queue_size)
void vl_msg_pop_heap(void *oldheap)
void vl_client_send_disconnect(u8 do_cleanup)
static void vlibapi_set_memory_client_main(memory_client_main_t *mm)
int vl_client_connect_to_vlib_no_rx_pthread_no_map(const char *svm_name, const char *client_name, int rx_queue_size)
void clib_time_init(clib_time_t *c)
void unserialize_cstring(serialize_main_t *m, char **s)
#define CLIB_NOSANITIZE_ADDR
API main structure, used by both vpp and binary API clients.
static void vl_api_memclnt_delete_reply_t_handler(vl_api_memclnt_delete_reply_t *mp)
An API client registration, only in vpp/vlib.
#define vec_free(V)
Free vector's memory (no header).
#define clib_warning(format, args...)
int vl_client_api_map(const char *region_name)
static void unserialize_integer(serialize_main_t *m, void *x, u32 n_bytes)
u16 vl_client_get_first_plugin_msg_id(const char *plugin_name)
svm_queue_t * vl_input_queue
void vl_unmap_shmem_client(void)
static CLIB_NOSANITIZE_ADDR void VL_MSG_API_SVM_QUEUE_UNPOISON(const svm_queue_t *q)
void svm_queue_free(svm_queue_t *q)
#define uword_to_pointer(u, type)
static CLIB_NOSANITIZE_ADDR void VL_API_VEC_UNPOISON(const void *v)
svm_queue_t * svm_queue_alloc_and_init(int nels, int elsize, int consumer_pid)
Allocate and initialize svm queue.
static void clib_mem_free(void *p)
void vl_msg_api_queue_handler(svm_queue_t *q)
pthread_t rx_thread_handle
Bin API thread handle.
static void * clib_mem_alloc(uword size)
static int connect_to_vlib_internal(const char *svm_name, const char *client_name, int rx_queue_size, void *(*thread_fn)(void *), void *thread_fn_arg, int do_map)
void vl_client_install_client_message_handlers(void)
memory_client_main_t * mm
void vl_client_disconnect_from_vlib_no_unmap(void)
static void vl_api_get_first_msg_id_reply_t_handler(vl_api_get_first_msg_id_reply_t *mp)
static void vl_api_name_and_crc_free(void)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define hash_foreach_pair(p, v, body)
Iterate over hash pairs.
int vl_client_disconnect(void)
static void vl_api_rx_thread_exit_t_handler(vl_api_rx_thread_exit_t *mp)
struct _svm_queue svm_queue_t
static api_main_t * vlibapi_get_main(void)
memory_client_main_t memory_client_main
void(** msg_handlers)(void *)
Message handler vector.
void vl_client_disconnect_from_vlib(void)
void * vl_msg_push_heap(void)
int vl_socket_client_write(void)
void * vl_msg_api_alloc_as_if_client(int nbytes)
uword * msg_index_by_name_and_crc
client message index hash table
volatile u8 first_msg_id_reply_ready
static CLIB_NOSANITIZE_ADDR void VL_MSG_API_UNPOISON(const void *a)
non-blocking call - works with both condvar and eventfd signaling
void vl_msg_api_handler(void *the_msg)