22 #include <sys/types.h> 23 #include <sys/socket.h> 31 #include <stdatomic.h> 55 struct msghdr msg = { 0 };
59 struct iovec io = {.iov_base = iobuf,.iov_len =
sizeof (iobuf) };
62 char buf[CMSG_SPACE (
sizeof (fd))];
67 msg.msg_control = u.buf;
68 msg.msg_controllen =
sizeof (u.buf);
71 if ((size = recvmsg (sock, &msg, 0)) < 0)
73 perror (
"recvmsg failed");
76 cmsg = CMSG_FIRSTHDR (&msg);
77 if (cmsg && cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
79 memmove (&fd, CMSG_DATA (cmsg),
sizeof (fd));
99 if ((sock = socket (AF_UNIX, SOCK_SEQPACKET, 0)) < 0)
101 perror (
"Stat client couldn't open socket");
105 struct sockaddr_un un = { 0 };
106 un.sun_family = AF_UNIX;
107 strncpy ((
char *) un.sun_path, socket_name, sizeof (un.sun_path) - 1);
108 if (connect (sock, (
struct sockaddr *) &un,
sizeof (
struct sockaddr_un)) <
115 if ((mfd =
recv_fd (sock)) < 0)
118 fprintf (stderr,
"Receiving file descriptor failed\n");
125 struct stat st = { 0 };
127 if (fstat (mfd, &st) == -1)
130 perror (
"mmap fstat failed");
134 mmap (
NULL, st.st_size, PROT_READ, MAP_SHARED, mfd, 0)) == MAP_FAILED)
137 perror (
"mmap map failed");
201 uint64_t *offset_vector;
220 for (i = 0; i <
vec_len (simple_c); i++)
235 for (i = 0; i <
vec_len (combined_c); i++)
248 for (i = 0; i <
vec_len (offset_vector); i++)
259 uint8_t **name_vector =
264 for (i = 0; i <
vec_len (name_vector); i++)
266 if (offset_vector[i])
278 fprintf (stderr,
"Unknown type: %d\n", ep->
type);
287 for (i = 0; i <
vec_len (res); i++)
292 for (j = 0; j <
vec_len (res[i].simple_counter_vec); j++)
293 vec_free (res[i].simple_counter_vec[j]);
294 vec_free (res[i].simple_counter_vec);
297 for (j = 0; j <
vec_len (res[i].combined_counter_vec); j++)
298 vec_free (res[i].combined_counter_vec[j]);
299 vec_free (res[i].combined_counter_vec);
315 regex_t regex[
vec_len (patterns)];
318 for (i = 0; i <
vec_len (patterns); i++)
320 int rv = regcomp (®ex[i], (
const char *) patterns[i], 0);
323 fprintf (stderr,
"Could not compile regex %s\n", patterns[i]);
331 for (j = 0; j <
vec_len (counter_vec); j++)
333 for (i = 0; i <
vec_len (patterns); i++)
335 int rv = regexec (®ex[i], counter_vec[j].
name, 0,
NULL, 0);
342 if (vec_len (patterns) == 0)
346 for (i = 0; i <
vec_len (patterns); i++)
382 for (i = 0; i <
vec_len (stats); i++)
392 fprintf (stderr,
"Epoch changed while reading, invalid results\n");
422 size_t len = strlen (
string);
426 return string_vector;
469 return strdup (ep->
name);
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
static void stat_segment_access_start(stat_segment_access_t *sa, stat_client_main_t *sm)
int stat_segment_connect_r(const char *socket_name, stat_client_main_t *sm)
int stat_segment_connect(const char *socket_name)
stat_segment_data_t * stat_segment_dump_entry(uint32_t index)
stat_segment_directory_entry_t * directory_vector
void stat_client_free(stat_client_main_t *sm)
char * stat_segment_index_to_name_r(uint32_t index, stat_client_main_t *sm)
void stat_segment_data_free(stat_segment_data_t *res)
counter_t ** simple_counter_vec
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
stat_client_main_t stat_client_main
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Combined counter to hold both packets and byte differences.
stat_segment_shared_header_t * shared_header
uint32_t * stat_segment_ls_r(uint8_t **patterns, stat_client_main_t *sm)
static void * stat_segment_pointer(void *start, uint64_t offset)
uint64_t counter_t
64bit counters
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
stat_segment_data_t * stat_segment_dump_entry_r(uint32_t index, stat_client_main_t *sm)
double stat_segment_heartbeat_r(stat_client_main_t *sm)
vl_api_fib_path_type_t type
#define vec_dup(V)
Return copy of vector (no header, no alignment)
stat_directory_type_t type
stat_segment_data_t * stat_segment_dump_r(uint32_t *stats, stat_client_main_t *sm)
void stat_segment_disconnect(void)
uint8_t ** stat_segment_string_vector(uint8_t **string_vector, const char *string)
#define vec_free(V)
Free vector's memory (no header).
char * stat_segment_index_to_name(uint32_t index)
#define vec_validate_init_c_string(V, S, L)
Make a vector containing a NULL terminated c-string.
uint32_t * stat_segment_ls(uint8_t **patterns)
static stat_segment_directory_entry_t * get_stat_vector_r(stat_client_main_t *sm)
stat_segment_data_t * stat_segment_dump(uint32_t *stats)
static int recv_fd(int sock)
vlib_counter_t ** combined_counter_vec
static bool stat_segment_access_end(stat_segment_access_t *sa, stat_client_main_t *sm)
uint64_t stat_segment_version(void)
stat_client_main_t * stat_client_get(void)
void stat_segment_vec_free(void *vec)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
int stat_segment_vec_len(void *vec)
static stat_segment_data_t copy_data(stat_segment_directory_entry_t *ep, stat_client_main_t *sm)
uint64_t stat_segment_version_r(stat_client_main_t *sm)
double stat_segment_heartbeat(void)
void stat_segment_disconnect_r(stat_client_main_t *sm)
CLIB vectors are ubiquitous dynamically resized arrays with by user defined "headers".
stat_directory_type_t type