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);
120 u16 msg_id = ntohs (*(
u16 *) elem);
160 output_length =
sizeof (*mb) + ntohl (mb->
data_len);
175 clib_warning (
"main pool index %d already free", pool_index);
214 u8 *data_for_process;
226 if (n <= 0 && errno != EAGAIN)
289 _vec_len (socket_main.
input_buffer) = save_input_buffer_length;
293 data_for_process = (
u8 *)
vec_dup (msg_buffer);
294 _vec_len (data_for_process) = (msg_len +
sizeof (
msgbuf_t));
298 a->
data = data_for_process;
303 if (n > (msg_len +
sizeof (*mbp)))
304 vec_delete (msg_buffer, msg_len +
sizeof (*mbp), 0);
306 _vec_len (msg_buffer) = 0;
313 _vec_len (socket_main.
input_buffer) = save_input_buffer_length;
329 size_t bytes_to_send, remaining_bytes = total_bytes;
331 while (remaining_bytes > 0)
333 bytes_to_send = remaining_bytes > 4096 ? 4096 : remaining_bytes;
349 remaining_bytes -= bytes_to_send;
384 memset (rp, 0,
sizeof (*rp));
389 template.file_descriptor = fd;
441 u32 size =
sizeof (*rp) + (nmsg *
sizeof (vl_api_message_table_entry_t));
443 rp->_vl_msg_id = htons (VL_API_SOCKCLNT_CREATE_REPLY);
447 rp->
count = htons (nmsg);
452 rp->message_table[i].index = htons(hp->value[0]);
453 strncpy((char *)rp->message_table[i].name, (char *)hp->key, 64-1);
475 rp->_vl_msg_id = htons (VL_API_SOCKCLNT_DELETE_REPLY);
497 struct msghdr mh = { 0 };
499 char ctl[CMSG_SPACE (
sizeof (
int) * n_fds)];
500 struct cmsghdr *cmsg;
504 iov[0].iov_base = msg;
505 iov[0].iov_len = strlen (msg);
509 memset (&ctl, 0,
sizeof (ctl));
510 mh.msg_control = ctl;
511 mh.msg_controllen =
sizeof (ctl);
512 cmsg = CMSG_FIRSTHDR (&mh);
513 cmsg->cmsg_len = CMSG_LEN (
sizeof (
int) * n_fds);
514 cmsg->cmsg_level = SOL_SOCKET;
515 cmsg->cmsg_type = SCM_RIGHTS;
516 clib_memcpy (CMSG_DATA (cmsg), fds,
sizeof (
int) * n_fds);
518 rv = sendmsg (socket_fd, &mh, 0);
535 config[0].
size = 256;
536 config[0].
count = 32;
539 config[1].
size = 1024;
540 config[1].
count = 16;
543 config[2].
size = 4096;
547 config[3].
size = 256;
548 config[3].
count = 32;
551 config[4].
size = 1024;
552 config[4].
count = 16;
555 config[5].
size = 4096;
559 config[6].
count = 128;
565 for (i = 0; i < mp->
nitems; i++)
612 memset (memfd, 0,
sizeof (*memfd));
627 memset (a, 0,
sizeof (*a));
658 rmp->_vl_msg_id = htons (VL_API_SOCK_INIT_SHM_REPLY);
677 #define foreach_vlib_api_msg \ 678 _(SOCKCLNT_CREATE, sockclnt_create) \ 679 _(SOCKCLNT_DELETE, sockclnt_delete) \ 680 _(SOCK_INIT_SHM, sock_init_shm) 697 vl_msg_api_set_handlers(VL_API_##N, #n, \ 698 vl_api_##n##_t_handler, \ 700 vl_api_##n##_t_endian, \ 701 vl_api_##n##_t_print, \ 702 sizeof(vl_api_##n##_t), 1); 711 if (strncmp (sock->config,
"/run", 4) == 0)
713 u8 *tmp =
format (0,
"%s", sock->config);
715 while (i && tmp[--i] !=
'/')
732 memset (rp, 0,
sizeof (*rp));
738 template.file_descriptor = sock->fd;
757 vl_api_registration_del_file (rp);
758 index = rp->vl_api_registration_pool_index;
759 vl_socket_free_registration_index (index);
778 else if (
unformat (input,
"default"))
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
vl_api_registration_t * regp
u64 api_pvt_heap_size
size of the api private mheap
static void clib_file_del(clib_file_main_t *um, clib_file_t *f)
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
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_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
#define pool_is_free(P, E)
Use free bitmap to query whether given element is free.
clib_error_t * vl_socket_write_ready(clib_file_t *uf)
struct msgbuf_ msgbuf_t
Message header structure.
void vl_socket_process_api_msg(clib_file_t *uf, vl_api_registration_t *rp, i8 *input_v)
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
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.
memset(h->entries, 0, sizeof(h->entries[0])*entries)
clib_error_t * vl_socket_error_ready(clib_file_t *uf)
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
#define VLIB_INIT_FUNCTION(x)
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.
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_shmem_hdr_t * shmem_hdr
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
#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)
#define clib_warning(format, args...)
#define clib_memcpy(a, b, c)
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
clib_error_t * vlibsocket_init(vlib_main_t *vm)
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)
static uword hash_elts(void *v)
#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)
u32 data_len
message length not including header
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.
#define CLIB_SOCKET_F_SEQPACKET
static vlib_main_t * vlib_get_main(void)
void vl_msg_api_free(void *)
clib_error_t * vlib_unix_recursive_mkdir(char *path)
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).
#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 vlib_cli_output(vlib_main_t *vm, char *fmt,...)
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.