20 #include <sys/types.h> 21 #include <sys/socket.h> 22 #include <netinet/in.h> 23 #include <sys/ioctl.h> 38 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__) 50 #define SOCK_API_REG_HANDLE_BIT (1<<31) 90 if (reg->registration_type == REGISTRATION_TYPE_SOCKET_SERVER) {
91 f = vl_api_registration_file (reg);
92 vlib_cli_output (vm,
"%20s %8d", reg->name, f->file_descriptor);
160 output_length =
sizeof (*mb) + ntohl (mb->data_len);
177 clib_warning (
"main pool index %d already free", pool_index);
234 u8 *data_for_process;
293 if (msgbuf_len >
vec_len (msg_buffer))
308 _vec_len (socket_main.
input_buffer) = save_input_buffer_length;
317 data_for_process = (
u8 *)
vec_dup (msg_buffer);
318 _vec_len (data_for_process) = msgbuf_len;
322 a->
data = data_for_process;
327 if (
vec_len (msg_buffer) > msgbuf_len)
332 _vec_len (msg_buffer) = 0;
334 while (
vec_len (msg_buffer) > 0);
337 _vec_len (socket_main.
input_buffer) = save_input_buffer_length;
352 size_t bytes_to_send, remaining_bytes = total_bytes;
354 while (remaining_bytes > 0)
356 bytes_to_send = remaining_bytes > 4096 ? 4096 : remaining_bytes;
372 remaining_bytes -= bytes_to_send;
412 template.file_descriptor = fd;
464 u32 size =
sizeof (*rp) + (nmsg *
sizeof (vl_api_message_table_entry_t));
466 rp->_vl_msg_id = htons (VL_API_SOCKCLNT_CREATE_REPLY);
470 rp->
count = htons (nmsg);
475 rp->message_table[i].index = htons(hp->value[0]);
476 (void) strncpy_s((char *)rp->message_table[i].name,
501 rp->_vl_msg_id = htons (VL_API_SOCKCLNT_DELETE_REPLY);
523 struct msghdr mh = { 0 };
525 char ctl[CMSG_SPACE (
sizeof (
int) * n_fds)];
526 struct cmsghdr *cmsg;
530 iov[0].iov_base = msg;
531 iov[0].iov_len = strlen (msg);
536 mh.msg_control = ctl;
537 mh.msg_controllen =
sizeof (ctl);
538 cmsg = CMSG_FIRSTHDR (&mh);
539 cmsg->cmsg_len = CMSG_LEN (
sizeof (
int) * n_fds);
540 cmsg->cmsg_level = SOL_SOCKET;
541 cmsg->cmsg_type = SCM_RIGHTS;
544 while ((rv = sendmsg (socket_fd, &mh, 0)) < 0 && errno == EAGAIN)
562 config[0].
size = 256;
563 config[0].
count = 32;
566 config[1].
size = 1024;
567 config[1].
count = 16;
570 config[2].
size = 4096;
574 config[3].
size = 256;
575 config[3].
count = 32;
578 config[4].
size = 1024;
579 config[4].
count = 16;
582 config[5].
size = 4096;
586 config[6].
count = 128;
592 for (i = 0; i < mp->
nitems; i++)
621 int rv, tries = 1000;
690 rmp->_vl_msg_id = htons (VL_API_SOCK_INIT_SHM_REPLY);
725 #define foreach_vlib_api_msg \ 726 _(SOCKCLNT_CREATE, sockclnt_create, 1) \ 727 _(SOCKCLNT_DELETE, sockclnt_delete, 1) \ 728 _(SOCK_INIT_SHM, sock_init_shm, 1) 745 vl_msg_api_set_handlers(VL_API_##N, #n, \ 746 vl_api_##n##_t_handler, \ 748 vl_api_##n##_t_endian, \ 749 vl_api_##n##_t_print, \ 750 sizeof(vl_api_##n##_t), t); 769 template.file_descriptor = sock->fd;
788 vl_api_registration_del_file (rp);
789 index = rp->vl_api_registration_pool_index;
790 vl_socket_free_registration_index (index);
810 else if (
unformat (input,
"default"))
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
void vlibsocket_reference()
u64 api_pvt_heap_size
size of the api private mheap
#define API_SOCKET_FILENAME
static void clib_file_del(clib_file_main_t *um, clib_file_t *f)
#define CLIB_MEM_UNPOISON(a, s)
clib_error_t * vl_sock_api_init(vlib_main_t *vm)
void vl_msg_api_socket_handler(void *the_msg)
static void vl_api_registration_del_file(vl_api_registration_t *reg)
void vl_socket_api_send(vl_api_registration_t *rp, u8 *elem)
volatile int ** vl_api_queue_cursizes
static u32 sock_api_registration_handle(vl_api_registration_t *regp)
void socksvr_file_add(clib_file_main_t *fm, int fd)
static clib_file_t * vl_api_registration_file(vl_api_registration_t *reg)
vl_api_registration_t * registration_pool
#define clib_memcpy_fast(a, b, c)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
void vl_api_sockclnt_delete_t_handler(vl_api_sockclnt_delete_t *mp)
static void vl_api_send_msg(vl_api_registration_t *rp, u8 *elem)
vl_api_registration_t * current_rp
vl_socket_args_for_process_t * process_args
socket_main_t socket_main
#define vec_terminate_c_string(V)
(If necessary) NULL terminate a vector containing a c-string.
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
void vl_sock_api_dump_clients(vlib_main_t *vm, api_main_t *am)
clib_error_t * clib_socket_init(clib_socket_t *s)
u8 data[0]
actual message begins here
static clib_error_t * clib_file_write(clib_file_t *f)
ssvm_shared_header_t * sh
clib_error_t * vl_socket_write_ready(clib_file_t *uf)
struct msgbuf_ msgbuf_t
Message header structure.
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
void * vl_msg_api_alloc_zero(int nbytes)
void * vl_msg_api_alloc(int nbytes)
void vl_api_sockclnt_create_t_handler(vl_api_sockclnt_create_t *mp)
trace_cfg_t * api_trace_cfg
Current trace configuration.
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
#define vec_add(V, E, N)
Add N elements to end of vector V (no header, unspecified alignment)
#define CLIB_SOCKET_F_IS_SERVER
u32 clib_file_index
Socket only: file index.
static vl_api_registration_t * vl_socket_get_registration(u32 reg_index)
clib_error_t * vl_socket_error_ready(clib_file_t *uf)
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
void vl_api_sock_init_shm_t_handler(vl_api_sock_init_shm_t *mp)
int ssvm_master_init_memfd(ssvm_private_t *memfd)
Initialize memfd segment master.
static char * vlib_unix_get_runtime_dir(void)
vlib_node_registration_t vl_api_clnt_node
(constructor) VLIB_REGISTER_NODE (vl_api_clnt_node)
#define clib_error_return(e, args...)
clib_file_main_t file_main
#define vec_resize(V, N)
Resize a vector (no header, unspecified alignment) Add N elements to end of given vector V...
static u32 socket_api_registration_handle_to_index(u32 reg_index)
static clib_error_t * socksvr_accept_ready(clib_file_t *uf)
vl_registration_type_t registration_type
type
static clib_error_t * socksvr_config(vlib_main_t *vm, unformat_input_t *input)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
void vl_init_shmem(svm_region_t *vlib_rp, vl_api_shm_elem_config_t *config, int is_vlib, int is_private_region)
static void vlib_process_signal_event(vlib_main_t *vm, uword node_index, uword type_opaque, uword data)
clib_error_t * clib_socket_accept(clib_socket_t *server, clib_socket_t *client)
#define clib_error_return_unix(e, args...)
#define pool_put(P, E)
Free an object E in pool P.
#define vec_dup(V)
Return copy of vector (no header, no alignment)
svm_region_t ** vlib_private_rps
Vector of all mapped shared-VM segments.
#define VLIB_CONFIG_FUNCTION(x, n,...)
clib_error_t * vl_socket_read_ready(clib_file_t *uf)
void(* file_update)(clib_file_t *file, clib_file_update_type_t update_type)
void svm_region_init_mapped_region(svm_map_region_args_t *a, svm_region_t *rp)
API main structure, used by both vpp and binary API clients.
An API client registration, only in vpp/vlib.
Shared memory connection.
clib_socket_t socksvr_listen_socket
sll srl srl sll sra u16x4 i
#define vec_free(V)
Free vector's memory (no header).
#define VLIB_MAIN_LOOP_EXIT_FUNCTION(x)
vl_api_registration_t * vl_socket_api_client_handle_to_registration(u32 handle)
void vl_api_call_reaper_functions(u32 client_index)
#define clib_warning(format, args...)
u8 * output_vector
Socket only: output vector.
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
int * additional_fds_to_close
static vl_api_registration_t * vl_api_client_index_to_registration(u32 index)
static u32 vl_api_registration_file_index(vl_api_registration_t *reg)
void clib_mem_destroy_mspace(void *mspace)
static uword hash_elts(void *v)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
#define vec_delete(V, N, M)
Delete N elements starting at element M.
static uword clib_file_add(clib_file_main_t *um, clib_file_t *template)
Message header structure.
u8 vl_socket_api_registration_handle_is_valid(u32 reg_handle)
#define vec_append(v1, v2)
Append v2 after v1.
struct _socket_t clib_socket_t
#define UNIX_FILE_DATA_AVAILABLE_TO_WRITE
i8 * unprocessed_input
Socket only: pending input.
static vlib_main_t * vlib_get_main(void)
void vl_msg_api_free(void *)
void vl_socket_free_registration_index(u32 pool_index)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define hash_foreach_pair(p, v, body)
Iterate over hash pairs.
vl_api_shm_elem_config_t * vl_api_make_shm_config(vl_api_sock_init_shm_t *mp)
clib_error_t * vl_sock_api_send_fd_msg(int socket_fd, int fds[], int n_fds)
#define foreach_vlib_api_msg
#define clib_unix_warning(format, args...)
u32 vl_api_registration_pool_index
Index in VLIB's brain (not shared memory).
static api_main_t * vlibapi_get_main(void)
#define SOCK_API_REG_HANDLE_BIT
static void unix_save_error(unix_main_t *um, clib_error_t *error)
uword * msg_index_by_name_and_crc
client message index hash table
#define CLIB_SOCKET_F_ALLOW_GROUP_WRITE
void vl_socket_process_api_msg(vl_api_registration_t *rp, i8 *input_v)
static clib_error_t * socksvr_bogus_write(clib_file_t *uf)
static clib_error_t * socket_exit(vlib_main_t *vm)
static uword pool_elts(void *v)
Number of active elements in a pool.