20 #include <sys/types.h> 21 #include <sys/socket.h> 22 #include <netinet/in.h> 23 #include <sys/ioctl.h> 39 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__) 71 if (reg->registration_type == REGISTRATION_TYPE_SOCKET_SERVER) {
72 f = pool_elt_at_index (fm->file_pool, reg->clib_file_index);
73 vlib_cli_output (vm,
"%16s %8d",
74 reg->name, f->file_descriptor);
84 u16 msg_id = ntohs (*(
u16 *) elem);
100 tmp = clib_host_to_net_u32 (nbytes);
106 (
u8 *) & tmp, sizeof (tmp));
117 u8 * elem,
u8 * data_vector)
120 u16 msg_id = ntohs (*(
u16 *) elem);
136 nbytes += msg_length;
137 nbytes +=
vec_len (data_vector);
140 tmp = clib_host_to_net_u32 (nbytes);
146 (
u8 *) & tmp, sizeof (tmp));
156 data_vector,
vec_len (data_vector));
162 u8 * elem,
u32 msg_length,
int free)
165 u16 msg_id = ntohs (*(
u16 *) elem);
179 nbytes += msg_length;
182 tmp = clib_host_to_net_u32 (nbytes);
188 (
u8 *) & tmp, sizeof (tmp));
200 u8 * elem,
u32 msg_length)
208 u8 * elem,
u32 msg_length)
220 clib_warning (
"main pool index %d already free", pool_index);
237 u8 *the_msg = (
u8 *) (input_v +
sizeof (
u32));
260 if (n <= 0 && errno != EAGAIN)
306 msg_len = clib_net_to_host_u32 (*((
u32 *) msg_buffer));
317 if (msg_len >
vec_len (msg_buffer))
332 _vec_len (socket_main.
input_buffer) = save_input_buffer_length;
341 _vec_len (msg_buffer) = 0;
349 _vec_len (socket_main.
input_buffer) = save_input_buffer_length;
357 u8 * buffer,
uword buffer_bytes)
437 memset (rp, 0,
sizeof (*rp));
442 template.file_descriptor = fd;
454 struct sockaddr_in client_addr;
458 client_len =
sizeof (client_addr);
465 (
struct sockaddr *) &client_addr,
466 (socklen_t *) & client_len);
499 rp->_vl_msg_id = htons (VL_API_SOCKCLNT_CREATE_REPLY);
522 rp->_vl_msg_id = htons (VL_API_SOCKCLNT_DELETE_REPLY);
538 #define foreach_vlib_api_msg \ 539 _(SOCKCLNT_CREATE, sockclnt_create) \ 540 _(SOCKCLNT_DELETE, sockclnt_delete) 550 struct sockaddr_in serv_addr;
556 vl_msg_api_set_handlers(VL_API_##N, #n, \ 557 vl_api_##n##_t_handler, \ 559 vl_api_##n##_t_endian, \ 560 vl_api_##n##_t_print, \ 561 sizeof(vl_api_##n##_t), 1); 568 sockfd = socket (AF_INET, SOCK_STREAM, 0);
575 rv = ioctl (sockfd, FIONBIO, &one);
582 rv = setsockopt (sockfd, SOL_SOCKET, SO_REUSEADDR, &one,
sizeof (one));
589 bzero ((
char *) &serv_addr,
sizeof (serv_addr));
590 serv_addr.sin_family = AF_INET;
595 bind_address = INADDR_LOOPBACK;
598 portno = socket_main.
portno;
602 serv_addr.sin_port = clib_host_to_net_u16 (portno);
603 serv_addr.sin_addr.s_addr = clib_host_to_net_u32 (bind_address);
605 if (bind (sockfd, (
struct sockaddr *) &serv_addr,
sizeof (serv_addr)) < 0)
611 rv = listen (sockfd, 5);
619 memset (rp, 0,
sizeof (*rp));
625 template.file_descriptor = sockfd;
644 clib_file_del (fm, fm->file_pool + rp->clib_file_index);
645 index = rp->vl_api_registration_pool_index;
646 vl_free_socket_registration_index (index);
663 if (
unformat (input,
"port %d", &portno))
665 socket_main.
portno = portno;
682 socket_main.
portno = port;
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
void dump_socket_clients(vlib_main_t *vm, api_main_t *am)
static void clib_file_del(clib_file_main_t *um, clib_file_t *f)
static clib_error_t * socksvr_config(vlib_main_t *vm, unformat_input_t *input)
vl_api_registration_t * registration_pool
void vl_socket_api_send_with_data(vl_api_registration_t *rp, u8 *elem, u8 *data_vector)
static clib_error_t * socket_exit(vlib_main_t *vm)
int size
for sanity checking
void vl_socket_add_pending_output(clib_file_t *uf, vl_api_registration_t *rp, u8 *buffer, uword buffer_bytes)
vl_api_registration_t * current_rp
void socksvr_set_port(u16 port)
#define SOCKSVR_DEFAULT_PORT
#define pool_is_free(P, E)
Use free bitmap to query whether given element is free.
socket_main_t socket_main
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
trace_cfg_t * api_trace_cfg
Current trace configuration.
#define vec_add(V, E, N)
Add N elements to end of vector V (no header, unspecified alignment)
u32 clib_file_index
Socket only: file index.
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
static clib_error_t * socksvr_bogus_write(clib_file_t *uf)
static void socket_process_msg(clib_file_t *uf, vl_api_registration_t *rp, i8 *input_v)
#define VLIB_INIT_FUNCTION(x)
void vl_free_socket_registration_index(u32 pool_index)
#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...
void vl_socket_api_send(vl_api_registration_t *rp, u8 *elem)
void * vl_msg_api_alloc(int nbytes)
vl_registration_type_t registration_type
type
static clib_error_t * socksvr_accept_ready(clib_file_t *uf)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
#define clib_error_return_unix(e, args...)
void vl_msg_api_free(void *)
#define pool_put(P, E)
Free an object E in pool P.
#define VLIB_CONFIG_FUNCTION(x, n,...)
void socksvr_file_add(clib_file_main_t *fm, int fd)
u32 unprocessed_msg_length
Socket only: unprocssed length.
void vl_socket_api_send_with_length_no_free(vl_api_registration_t *rp, u8 *elem, u32 msg_length)
static clib_error_t * socksvr_api_init(vlib_main_t *vm)
void(* file_update)(clib_file_t *file, unix_file_update_type_t update_type)
void vl_msg_api_socket_handler(void *the_msg)
API main structure, used by both vpp and binary API clients.
An API client registration, only in vpp/vlib.
void socksvr_set_bind_address(u32 bind_address)
void vl_api_sockclnt_create_t_handler(vl_api_sockclnt_create_t *mp)
#define vec_free(V)
Free vector's memory (no header).
#define foreach_vlib_api_msg
#define VLIB_MAIN_LOOP_EXIT_FUNCTION(x)
#define clib_warning(format, args...)
clib_error_t * vlibsocket_init(vlib_main_t *vm)
#define clib_memcpy(a, b, c)
u8 * output_vector
Socket only: output vecto.
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
clib_error_t * vl_socket_write_ready(clib_file_t *uf)
#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)
#define vec_append(v1, v2)
Append v2 after v1.
#define UNIX_FILE_DATA_AVAILABLE_TO_WRITE
i8 * unprocessed_input
Socket only: pending input.
clib_error_t * vl_socket_read_ready(clib_file_t *uf)
static void socket_del_pending_output(clib_file_t *uf, vl_api_registration_t *rp, uword n_bytes)
void vl_socket_api_send_with_length(vl_api_registration_t *rp, u8 *elem, u32 msg_length)
clib_error_t * vl_socket_error_ready(clib_file_t *uf)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
u32 vl_api_registration_pool_index
Index in VLIB's brain (not shared memory).
Shared memory connection.
static void vl_socket_api_send_with_length_internal(vl_api_registration_t *rp, u8 *elem, u32 msg_length, int free)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
void vl_msg_api_send(vl_api_registration_t *rp, u8 *elem)
void vl_api_sockclnt_delete_t_handler(vl_api_sockclnt_delete_t *mp)
static uword pool_elts(void *v)
Number of active elements in a pool.