1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018 Intel Corporation
8 #include <sys/socket.h>
13 #include <rte_ethdev.h>
14 #include <rte_metrics.h>
15 #include <rte_option.h>
16 #include <rte_string_fns.h>
18 #include "rte_telemetry.h"
19 #include "rte_telemetry_internal.h"
20 #include "rte_telemetry_parser.h"
21 #include "rte_telemetry_socket_tests.h"
27 #define SELFTEST_VALID_CLIENT "/var/run/dpdk/valid_client"
28 #define SELFTEST_INVALID_CLIENT "/var/run/dpdk/invalid_client"
29 #define SOCKET_TEST_CLIENT_PATH "/var/run/dpdk/client"
31 static telemetry_impl *static_telemetry;
33 struct telemetry_message_test {
34 const char *test_name;
35 int (*test_func_ptr)(struct telemetry_impl *telemetry, int fd);
47 rte_telemetry_get_runtime_dir(char *socket_path, size_t size)
49 snprintf(socket_path, size, "%s/telemetry", rte_eal_get_runtime_dir());
53 rte_telemetry_write_to_socket(struct telemetry_impl *telemetry,
54 const char *json_string)
58 if (telemetry == NULL) {
59 TELEMETRY_LOG_ERR("Could not initialise TELEMETRY_API");
63 if (telemetry->request_client == NULL) {
64 TELEMETRY_LOG_ERR("No client has been chosen to write to");
68 if (json_string == NULL) {
69 TELEMETRY_LOG_ERR("Invalid JSON string!");
73 ret = send(telemetry->request_client->fd,
74 json_string, strlen(json_string), 0);
76 TELEMETRY_LOG_ERR("Failed to write to socket for client: %s",
77 telemetry->request_client->file_path);
85 rte_telemetry_send_error_response(struct telemetry_impl *telemetry,
89 const char *status_code, *json_buffer;
92 if (error_type == -EPERM)
93 status_code = "Status Error: Unknown";
94 else if (error_type == -EINVAL)
95 status_code = "Status Error: Invalid Argument 404";
96 else if (error_type == -ENOMEM)
97 status_code = "Status Error: Memory Allocation Error";
99 TELEMETRY_LOG_ERR("Invalid error type");
103 root = json_object();
106 TELEMETRY_LOG_ERR("Could not create root JSON object");
110 ret = json_object_set_new(root, "status_code", json_string(status_code));
112 TELEMETRY_LOG_ERR("Status code field cannot be set");
117 ret = json_object_set_new(root, "data", json_null());
119 TELEMETRY_LOG_ERR("Data field cannot be set");
124 json_buffer = json_dumps(root, 0);
127 ret = rte_telemetry_write_to_socket(telemetry, json_buffer);
129 TELEMETRY_LOG_ERR("Could not write to socket");
137 rte_telemetry_send_global_stats_values(struct telemetry_encode_param *ep,
138 struct telemetry_impl *telemetry)
141 char *json_buffer = NULL;
143 if (telemetry == NULL) {
144 TELEMETRY_LOG_ERR("Invalid telemetry argument");
148 ret = rte_metrics_tel_encode_json_format(ep, &json_buffer);
150 TELEMETRY_LOG_ERR("JSON encode function failed");
151 ret = rte_telemetry_send_error_response(telemetry, ret);
153 TELEMETRY_LOG_ERR("Could not send error");
157 ret = rte_telemetry_write_to_socket(telemetry, json_buffer);
159 TELEMETRY_LOG_ERR("Could not write to socket");
167 rte_telemetry_send_ports_stats_values(struct telemetry_encode_param *ep,
168 struct telemetry_impl *telemetry)
171 char *json_buffer = NULL;
173 if (telemetry == NULL) {
174 TELEMETRY_LOG_ERR("Invalid telemetry argument");
179 TELEMETRY_LOG_ERR("Invalid encode param argument");
183 if (ep->pp.num_metric_ids < 0) {
184 TELEMETRY_LOG_ERR("Invalid num_metric_ids, must be positive");
188 if (ep->pp.num_port_ids < 0) {
189 TELEMETRY_LOG_ERR("Invalid num_port_ids, must be positive");
193 ret = rte_metrics_tel_get_ports_stats_json(ep, telemetry->reg_index,
196 TELEMETRY_LOG_ERR("Function for get_ports_stats_json"
198 ret = rte_telemetry_send_error_response(telemetry, ret);
200 TELEMETRY_LOG_ERR("Could not send error");
204 ret = rte_telemetry_write_to_socket(telemetry, json_buffer);
206 TELEMETRY_LOG_ERR("Could not write to socket");
213 ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
215 TELEMETRY_LOG_ERR("Could not send error");
220 rte_telemetry_initial_accept(struct telemetry_impl *telemetry)
225 ret = rte_metrics_tel_reg_all_ethdev(
226 &telemetry->metrics_register_done,
227 telemetry->reg_index);
229 TELEMETRY_LOG_ERR("Failed to register ethdev metrics");
230 ret = rte_telemetry_send_error_response(telemetry, ret);
232 TELEMETRY_LOG_ERR("Could not send error");
237 ret = rte_telemetry_socket_messaging_testing(telemetry->reg_index[0],
238 telemetry->server_fd);
242 ret = rte_telemetry_parser_test(telemetry);
244 TELEMETRY_LOG_ERR("Parser Tests Failed");
248 TELEMETRY_LOG_INFO("Success - All Parser Tests Passed");
255 rte_telemetry_read_client(struct telemetry_impl *telemetry)
258 int ret, buffer_read;
260 buffer_read = read(telemetry->accept_fd, buf, BUF_SIZE-1);
262 if (buffer_read == -1) {
263 TELEMETRY_LOG_ERR("Read error");
265 } else if (buffer_read == 0) {
268 buf[buffer_read] = '\0';
269 ret = rte_telemetry_parse_client_message(telemetry, buf);
271 TELEMETRY_LOG_WARN("Parse message failed");
276 if (close(telemetry->accept_fd) < 0) {
277 TELEMETRY_LOG_ERR("Close TELEMETRY socket failed");
281 telemetry->accept_fd = 0;
287 rte_telemetry_accept_new_client(struct telemetry_impl *telemetry)
291 if (telemetry->accept_fd <= 0) {
292 ret = listen(telemetry->server_fd, 1);
294 TELEMETRY_LOG_ERR("Listening error with server fd");
298 telemetry->accept_fd = accept(telemetry->server_fd, NULL, NULL);
299 if (telemetry->accept_fd >= 0 &&
300 telemetry->metrics_register_done == 0) {
301 ret = rte_telemetry_initial_accept(telemetry);
303 TELEMETRY_LOG_ERR("Failed to run initial configurations/tests");
308 ret = rte_telemetry_read_client(telemetry);
310 TELEMETRY_LOG_ERR("Failed to read socket buffer");
319 rte_telemetry_read_client_sockets(struct telemetry_impl *telemetry)
322 telemetry_client *client;
323 char client_buf[BUF_SIZE];
326 TAILQ_FOREACH(client, &telemetry->client_list_head, client_list) {
327 bytes = read(client->fd, client_buf, BUF_SIZE-1);
330 client_buf[bytes] = '\0';
331 telemetry->request_client = client;
332 ret = rte_telemetry_parse(telemetry, client_buf);
334 TELEMETRY_LOG_WARN("Parse socket input failed: %i",
345 rte_telemetry_run(void *userdata)
348 struct telemetry_impl *telemetry = userdata;
350 if (telemetry == NULL) {
351 TELEMETRY_LOG_WARN("TELEMETRY could not be initialised");
355 ret = rte_telemetry_accept_new_client(telemetry);
357 TELEMETRY_LOG_ERR("Accept and read new client failed");
361 ret = rte_telemetry_read_client_sockets(telemetry);
363 TELEMETRY_LOG_ERR("Client socket read failed");
371 *rte_telemetry_run_thread_func(void *userdata)
374 struct telemetry_impl *telemetry = userdata;
376 if (telemetry == NULL) {
377 TELEMETRY_LOG_ERR("%s passed a NULL instance", __func__);
381 while (telemetry->thread_status) {
382 rte_telemetry_run(telemetry);
383 ret = usleep(SLEEP_TIME);
385 TELEMETRY_LOG_ERR("Calling thread could not be put to sleep");
391 rte_telemetry_set_socket_nonblock(int fd)
396 TELEMETRY_LOG_ERR("Invalid fd provided");
400 flags = fcntl(fd, F_GETFL, 0);
404 return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
408 rte_telemetry_create_socket(struct telemetry_impl *telemetry)
411 struct sockaddr_un addr;
412 char socket_path[BUF_SIZE];
414 if (telemetry == NULL)
417 telemetry->server_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
418 if (telemetry->server_fd == -1) {
419 TELEMETRY_LOG_ERR("Failed to open socket");
423 ret = rte_telemetry_set_socket_nonblock(telemetry->server_fd);
425 TELEMETRY_LOG_ERR("Could not set socket to NONBLOCK");
429 addr.sun_family = AF_UNIX;
430 rte_telemetry_get_runtime_dir(socket_path, sizeof(socket_path));
431 strlcpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
434 if (bind(telemetry->server_fd, (struct sockaddr *)&addr,
436 TELEMETRY_LOG_ERR("Socket binding error");
443 if (close(telemetry->server_fd) < 0) {
444 TELEMETRY_LOG_ERR("Close TELEMETRY socket failed");
452 rte_telemetry_init(void)
456 const char *telemetry_ctrl_thread = "telemetry";
458 if (static_telemetry) {
459 TELEMETRY_LOG_WARN("TELEMETRY structure already initialised");
463 static_telemetry = calloc(1, sizeof(struct telemetry_impl));
464 if (static_telemetry == NULL) {
465 TELEMETRY_LOG_ERR("Memory could not be allocated");
469 static_telemetry->socket_id = rte_socket_id();
470 rte_metrics_init(static_telemetry->socket_id);
472 ret = pthread_attr_init(&attr);
474 TELEMETRY_LOG_ERR("Pthread attribute init failed");
478 ret = rte_telemetry_create_socket(static_telemetry);
480 ret = rte_telemetry_cleanup();
482 TELEMETRY_LOG_ERR("TELEMETRY cleanup failed");
485 TAILQ_INIT(&static_telemetry->client_list_head);
487 ret = rte_ctrl_thread_create(&static_telemetry->thread_id,
488 telemetry_ctrl_thread, &attr, rte_telemetry_run_thread_func,
489 (void *)static_telemetry);
490 static_telemetry->thread_status = 1;
493 ret = rte_telemetry_cleanup();
495 TELEMETRY_LOG_ERR("TELEMETRY cleanup failed");
503 rte_telemetry_client_cleanup(struct telemetry_client *client)
507 ret = close(client->fd);
508 free(client->file_path);
512 TELEMETRY_LOG_ERR("Close client socket failed");
520 rte_telemetry_cleanup(void)
523 struct telemetry_impl *telemetry = static_telemetry;
524 telemetry_client *client, *temp_client;
526 TAILQ_FOREACH_SAFE(client, &telemetry->client_list_head, client_list,
528 TAILQ_REMOVE(&telemetry->client_list_head, client, client_list);
529 ret = rte_telemetry_client_cleanup(client);
531 TELEMETRY_LOG_ERR("Client cleanup failed");
536 ret = close(telemetry->server_fd);
538 TELEMETRY_LOG_ERR("Close TELEMETRY socket failed");
543 telemetry->thread_status = 0;
544 pthread_join(telemetry->thread_id, NULL);
546 static_telemetry = NULL;
552 rte_telemetry_unregister_client(struct telemetry_impl *telemetry,
553 const char *client_path)
556 telemetry_client *client, *temp_client;
558 if (telemetry == NULL) {
559 TELEMETRY_LOG_WARN("TELEMETRY is not initialised");
563 if (client_path == NULL) {
564 TELEMETRY_LOG_ERR("Invalid client path");
568 if (TAILQ_EMPTY(&telemetry->client_list_head)) {
569 TELEMETRY_LOG_ERR("There are no clients currently registered");
573 TAILQ_FOREACH_SAFE(client, &telemetry->client_list_head, client_list,
575 if (strcmp(client_path, client->file_path) == 0) {
576 TAILQ_REMOVE(&telemetry->client_list_head, client,
578 ret = rte_telemetry_client_cleanup(client);
581 TELEMETRY_LOG_ERR("Client cleanup failed");
589 TELEMETRY_LOG_WARN("Couldn't find client, possibly not registered yet.");
593 ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
595 TELEMETRY_LOG_ERR("Could not send error");
600 rte_telemetry_register_client(struct telemetry_impl *telemetry,
601 const char *client_path)
604 struct sockaddr_un addrs;
606 if (telemetry == NULL) {
607 TELEMETRY_LOG_ERR("Could not initialize TELEMETRY API");
611 if (client_path == NULL) {
612 TELEMETRY_LOG_ERR("Invalid client path");
616 telemetry_client *client;
617 TAILQ_FOREACH(client, &telemetry->client_list_head, client_list) {
618 if (strcmp(client_path, client->file_path) == 0) {
619 TELEMETRY_LOG_WARN("'%s' already registered",
625 fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
627 TELEMETRY_LOG_ERR("Client socket error");
631 ret = rte_telemetry_set_socket_nonblock(fd);
633 TELEMETRY_LOG_ERR("Could not set socket to NONBLOCK");
637 addrs.sun_family = AF_UNIX;
638 strlcpy(addrs.sun_path, client_path, sizeof(addrs.sun_path));
639 telemetry_client *new_client = malloc(sizeof(telemetry_client));
640 new_client->file_path = strdup(client_path);
643 if (connect(fd, (struct sockaddr *)&addrs, sizeof(addrs)) == -1) {
644 TELEMETRY_LOG_ERR("TELEMETRY client connect to %s didn't work",
646 ret = rte_telemetry_client_cleanup(new_client);
648 TELEMETRY_LOG_ERR("Client cleanup failed");
654 TAILQ_INSERT_HEAD(&telemetry->client_list_head, new_client, client_list);
660 rte_telemetry_parse_client_message(struct telemetry_impl *telemetry, char *buf)
664 json_t *root = json_loads(buf, 0, &error);
667 TELEMETRY_LOG_WARN("Could not load JSON object from data passed in : %s",
670 } else if (!json_is_object(root)) {
671 TELEMETRY_LOG_WARN("JSON Request is not a JSON object");
675 json_t *action = json_object_get(root, "action");
676 if (action == NULL) {
677 TELEMETRY_LOG_WARN("Request does not have action field");
679 } else if (!json_is_integer(action)) {
680 TELEMETRY_LOG_WARN("Action value is not an integer");
684 json_t *command = json_object_get(root, "command");
685 if (command == NULL) {
686 TELEMETRY_LOG_WARN("Request does not have command field");
688 } else if (!json_is_string(command)) {
689 TELEMETRY_LOG_WARN("Command value is not a string");
693 action_int = json_integer_value(action);
694 if (action_int != ACTION_POST) {
695 TELEMETRY_LOG_WARN("Invalid action code");
699 if (strcmp(json_string_value(command), "clients") != 0) {
700 TELEMETRY_LOG_WARN("Invalid command");
704 json_t *data = json_object_get(root, "data");
706 TELEMETRY_LOG_WARN("Request does not have data field");
710 json_t *client_path = json_object_get(data, "client_path");
711 if (client_path == NULL) {
712 TELEMETRY_LOG_WARN("Request does not have client_path field");
716 if (!json_is_string(client_path)) {
717 TELEMETRY_LOG_WARN("Client_path value is not a string");
721 ret = rte_telemetry_register_client(telemetry,
722 json_string_value(client_path));
724 TELEMETRY_LOG_ERR("Could not register client");
725 telemetry->register_fail_count++;
732 TELEMETRY_LOG_WARN("Client attempted to register with invalid message");
738 rte_telemetry_dummy_client_socket(const char *valid_client_path)
740 int sockfd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
741 struct sockaddr_un addr = {0};
744 TELEMETRY_LOG_ERR("Test socket creation failure");
748 addr.sun_family = AF_UNIX;
749 strlcpy(addr.sun_path, valid_client_path, sizeof(addr.sun_path));
750 unlink(valid_client_path);
752 if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
753 TELEMETRY_LOG_ERR("Test socket binding failure");
757 if (listen(sockfd, 1) < 0) {
758 TELEMETRY_LOG_ERR("Listen failure");
766 rte_telemetry_selftest(void)
768 const char *invalid_client_path = SELFTEST_INVALID_CLIENT;
769 const char *valid_client_path = SELFTEST_VALID_CLIENT;
772 TELEMETRY_LOG_INFO("Selftest");
774 ret = rte_telemetry_init();
776 TELEMETRY_LOG_ERR("Valid initialisation test failed");
780 TELEMETRY_LOG_INFO("Success - Valid initialisation test passed");
782 ret = rte_telemetry_init();
783 if (ret != -EALREADY) {
784 TELEMETRY_LOG_ERR("Invalid initialisation test failed");
788 TELEMETRY_LOG_INFO("Success - Invalid initialisation test passed");
790 ret = rte_telemetry_unregister_client(static_telemetry,
791 invalid_client_path);
793 TELEMETRY_LOG_ERR("Invalid unregister test failed");
797 TELEMETRY_LOG_INFO("Success - Invalid unregister test passed");
799 sockfd = rte_telemetry_dummy_client_socket(valid_client_path);
801 TELEMETRY_LOG_ERR("Test socket creation failed");
805 ret = rte_telemetry_register_client(static_telemetry, valid_client_path);
807 TELEMETRY_LOG_ERR("Valid register test failed: %i", ret);
811 accept(sockfd, NULL, NULL);
812 TELEMETRY_LOG_INFO("Success - Valid register test passed");
814 ret = rte_telemetry_register_client(static_telemetry, valid_client_path);
815 if (ret != -EINVAL) {
816 TELEMETRY_LOG_ERR("Invalid register test failed: %i", ret);
820 TELEMETRY_LOG_INFO("Success - Invalid register test passed");
822 ret = rte_telemetry_unregister_client(static_telemetry,
823 invalid_client_path);
825 TELEMETRY_LOG_ERR("Invalid unregister test failed: %i", ret);
829 TELEMETRY_LOG_INFO("Success - Invalid unregister test passed");
831 ret = rte_telemetry_unregister_client(static_telemetry, valid_client_path);
833 TELEMETRY_LOG_ERR("Valid unregister test failed: %i", ret);
837 TELEMETRY_LOG_INFO("Success - Valid unregister test passed");
839 ret = rte_telemetry_cleanup();
841 TELEMETRY_LOG_ERR("Cleanup test failed");
845 TELEMETRY_LOG_INFO("Success - Valid cleanup test passed");
851 rte_telemetry_socket_messaging_testing(int index, int socket)
853 struct telemetry_impl *telemetry = calloc(1, sizeof(telemetry_impl));
854 int fd, bad_send_fd, send_fd, bad_fd, bad_recv_fd, recv_fd, ret;
856 if (telemetry == NULL) {
857 TELEMETRY_LOG_ERR("Could not initialize Telemetry API");
861 telemetry->server_fd = socket;
862 telemetry->reg_index[0] = index;
863 TELEMETRY_LOG_INFO("Beginning Telemetry socket message Selftest");
864 rte_telemetry_socket_test_setup(telemetry, &send_fd, &recv_fd);
865 TELEMETRY_LOG_INFO("Register valid client test");
867 ret = rte_telemetry_socket_register_test(telemetry, &fd, send_fd,
870 TELEMETRY_LOG_ERR("Register valid client test failed!");
875 TELEMETRY_LOG_INFO("Success - Register valid client test passed!");
877 TELEMETRY_LOG_INFO("Register invalid/same client test");
878 ret = rte_telemetry_socket_test_setup(telemetry, &bad_send_fd,
880 ret = rte_telemetry_socket_register_test(telemetry, &bad_fd,
881 bad_send_fd, bad_recv_fd);
883 TELEMETRY_LOG_ERR("Register invalid/same client test failed!");
888 TELEMETRY_LOG_INFO("Success - Register invalid/same client test passed!");
890 ret = rte_telemetry_json_socket_message_test(telemetry, fd);
901 rte_telemetry_socket_register_test(struct telemetry_impl *telemetry, int *fd,
902 int send_fd, int recv_fd)
905 char good_req_string[BUF_SIZE];
907 snprintf(good_req_string, sizeof(good_req_string),
908 "{\"action\":1,\"command\":\"clients\",\"data\":{\"client_path\""
909 ":\"%s\"}}", SOCKET_TEST_CLIENT_PATH);
913 ret = send(send_fd, good_req_string, strlen(good_req_string), 0);
915 TELEMETRY_LOG_ERR("Could not send message over socket");
919 rte_telemetry_run(telemetry);
921 if (telemetry->register_fail_count != 0)
924 *fd = accept(recv_fd, NULL, NULL);
930 rte_telemetry_socket_test_setup(struct telemetry_impl *telemetry, int *send_fd,
934 const char *client_path = SOCKET_TEST_CLIENT_PATH;
935 char socket_path[BUF_SIZE];
936 struct sockaddr_un addr = {0};
937 struct sockaddr_un addrs = {0};
938 *send_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
939 *recv_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
941 listen(telemetry->server_fd, 5);
942 addr.sun_family = AF_UNIX;
943 rte_telemetry_get_runtime_dir(socket_path, sizeof(socket_path));
944 strlcpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
946 ret = connect(*send_fd, (struct sockaddr *) &addr, sizeof(addr));
948 TELEMETRY_LOG_ERR("Could not connect socket");
952 telemetry->accept_fd = accept(telemetry->server_fd, NULL, NULL);
954 addrs.sun_family = AF_UNIX;
955 strlcpy(addrs.sun_path, client_path, sizeof(addrs.sun_path));
958 ret = bind(*recv_fd, (struct sockaddr *)&addrs, sizeof(addrs));
960 TELEMETRY_LOG_ERR("Could not bind socket");
968 rte_telemetry_stat_parse(char *buf, struct json_data *json_data_struct)
971 json_t *root = json_loads(buf, 0, &error);
973 json_t *status, *dataArray, *port, *stats, *name, *value, *dataArrayObj,
981 TELEMETRY_LOG_ERR("JSON message is NULL");
986 TELEMETRY_LOG_ERR("Could not load JSON object from data passed in : %s",
989 } else if (!json_is_object(root)) {
990 TELEMETRY_LOG_ERR("JSON Request is not a JSON object");
995 status = json_object_get(root, "status_code");
997 TELEMETRY_LOG_ERR("Request does not have status field");
999 } else if (!json_is_string(status)) {
1000 TELEMETRY_LOG_ERR("Status value is not a string");
1004 json_data_struct->status_code = strdup(json_string_value(status));
1006 dataArray = json_object_get(root, "data");
1007 if (dataArray == NULL) {
1008 TELEMETRY_LOG_ERR("Request does not have data field");
1012 arraylen = json_array_size(dataArray);
1013 if (arraylen == 0) {
1014 json_data_struct->data = "null";
1018 for (i = 0; i < arraylen; i++) {
1019 dataArrayObj = json_array_get(dataArray, i);
1020 port = json_object_get(dataArrayObj, "port");
1021 stats = json_object_get(dataArrayObj, "stats");
1025 TELEMETRY_LOG_ERR("Request does not have port field");
1029 if (!json_is_integer(port)) {
1030 TELEMETRY_LOG_ERR("Port value is not an integer");
1034 json_data_struct->port = json_integer_value(port);
1036 if (stats == NULL) {
1037 TELEMETRY_LOG_ERR("Request does not have stats field");
1041 arraylen = json_array_size(stats);
1042 for (i = 0; i < arraylen; i++) {
1043 statsArrayObj = json_array_get(stats, i);
1044 name = json_object_get(statsArrayObj, "name");
1045 value = json_object_get(statsArrayObj, "value");
1049 TELEMETRY_LOG_ERR("Request does not have name field");
1053 if (!json_is_string(name)) {
1054 TELEMETRY_LOG_ERR("Stat name value is not a string");
1058 json_data_struct->stat_name = strdup(json_string_value(name));
1060 if (value == NULL) {
1061 TELEMETRY_LOG_ERR("Request does not have value field");
1065 if (!json_is_integer(value)) {
1066 TELEMETRY_LOG_ERR("Stat value is not an integer");
1070 json_data_struct->stat_value = json_integer_value(value);
1076 rte_telemetry_free_test_data(struct json_data *data)
1078 free(data->status_code);
1079 free(data->stat_name);
1084 rte_telemetry_valid_json_test(struct telemetry_impl *telemetry, int fd)
1090 int buffer_read = 0;
1092 struct json_data *data_struct;
1094 const char *status = "Status OK: 200";
1095 const char *name = "rx_good_packets";
1096 const char *valid_json_message = "{\"action\":0,\"command\":"
1097 "\"ports_stats_values_by_name\",\"data\":{\"ports\""
1098 ":[0],\"stats\":[\"rx_good_packets\"]}}";
1100 ret = send(fd, valid_json_message, strlen(valid_json_message), 0);
1102 TELEMETRY_LOG_ERR("Could not send message over socket");
1106 rte_telemetry_run(telemetry);
1107 buffer_read = recv(fd, buf, BUF_SIZE-1, 0);
1109 if (buffer_read == -1) {
1110 TELEMETRY_LOG_ERR("Read error");
1114 buf[buffer_read] = '\0';
1115 data_struct = calloc(1, sizeof(struct json_data));
1116 ret = rte_telemetry_stat_parse(buf, data_struct);
1119 TELEMETRY_LOG_ERR("Could not parse stats");
1123 if (strcmp(data_struct->status_code, status) != 0) {
1124 TELEMETRY_LOG_ERR("Status code is invalid");
1128 if (data_struct->port != port) {
1129 TELEMETRY_LOG_ERR("Port is invalid");
1133 if (strcmp(data_struct->stat_name, name) != 0) {
1134 TELEMETRY_LOG_ERR("Stat name is invalid");
1138 if (data_struct->stat_value != value) {
1139 TELEMETRY_LOG_ERR("Stat value is invalid");
1143 rte_telemetry_free_test_data(data_struct);
1147 TELEMETRY_LOG_INFO("Success - Passed valid JSON message test passed");
1153 rte_telemetry_invalid_json_test(struct telemetry_impl *telemetry, int fd)
1158 const char *invalid_json = "{]";
1159 const char *status = "Status Error: Unknown";
1160 const char *data = "null";
1161 struct json_data *data_struct;
1162 int buffer_read = 0;
1165 ret = send(fd, invalid_json, strlen(invalid_json), 0);
1167 TELEMETRY_LOG_ERR("Could not send message over socket");
1171 rte_telemetry_run(telemetry);
1172 buffer_read = recv(fd, buf, BUF_SIZE-1, 0);
1174 if (buffer_read == -1) {
1175 TELEMETRY_LOG_ERR("Read error");
1179 buf[buffer_read] = '\0';
1181 data_struct = calloc(1, sizeof(struct json_data));
1182 ret = rte_telemetry_stat_parse(buf, data_struct);
1185 TELEMETRY_LOG_ERR("Could not parse stats");
1187 if (strcmp(data_struct->status_code, status) != 0) {
1188 TELEMETRY_LOG_ERR("Status code is invalid");
1192 if (strcmp(data_struct->data, data) != 0) {
1193 TELEMETRY_LOG_ERR("Data status is invalid");
1197 rte_telemetry_free_test_data(data_struct);
1201 TELEMETRY_LOG_INFO("Success - Passed invalid JSON message test");
1207 rte_telemetry_json_contents_test(struct telemetry_impl *telemetry, int fd)
1212 const char *status = "Status Error: Invalid Argument 404";
1213 const char *data = "null";
1214 struct json_data *data_struct;
1215 const char *invalid_contents = "{\"action\":0,\"command\":"
1216 "\"ports_stats_values_by_name\",\"data\":{\"ports\""
1217 ":[0],\"stats\":[\"some_invalid_param\","
1218 "\"another_invalid_param\"]}}";
1219 int buffer_read = 0;
1222 ret = send(fd, invalid_contents, strlen(invalid_contents), 0);
1224 TELEMETRY_LOG_ERR("Could not send message over socket");
1228 rte_telemetry_run(telemetry);
1229 buffer_read = recv(fd, buf, BUF_SIZE-1, 0);
1231 if (buffer_read == -1) {
1232 TELEMETRY_LOG_ERR("Read error");
1236 buf[buffer_read] = '\0';
1237 data_struct = calloc(1, sizeof(struct json_data));
1238 ret = rte_telemetry_stat_parse(buf, data_struct);
1241 TELEMETRY_LOG_ERR("Could not parse stats");
1243 if (strcmp(data_struct->status_code, status) != 0) {
1244 TELEMETRY_LOG_ERR("Status code is invalid");
1248 if (strcmp(data_struct->data, data) != 0) {
1249 TELEMETRY_LOG_ERR("Data status is invalid");
1253 rte_telemetry_free_test_data(data_struct);
1257 TELEMETRY_LOG_INFO("Success - Passed invalid JSON content test");
1263 rte_telemetry_json_empty_test(struct telemetry_impl *telemetry, int fd)
1268 const char *status = "Status Error: Invalid Argument 404";
1269 const char *data = "null";
1270 struct json_data *data_struct;
1271 const char *empty_json = "{}";
1272 int buffer_read = 0;
1275 ret = (send(fd, empty_json, strlen(empty_json), 0));
1277 TELEMETRY_LOG_ERR("Could not send message over socket");
1281 rte_telemetry_run(telemetry);
1282 buffer_read = recv(fd, buf, BUF_SIZE-1, 0);
1284 if (buffer_read == -1) {
1285 TELEMETRY_LOG_ERR("Read error");
1289 buf[buffer_read] = '\0';
1290 data_struct = calloc(1, sizeof(struct json_data));
1291 ret = rte_telemetry_stat_parse(buf, data_struct);
1294 TELEMETRY_LOG_ERR("Could not parse stats");
1296 if (strcmp(data_struct->status_code, status) != 0) {
1297 TELEMETRY_LOG_ERR("Status code is invalid");
1301 if (strcmp(data_struct->data, data) != 0) {
1302 TELEMETRY_LOG_ERR("Data status is invalid");
1306 rte_telemetry_free_test_data(data_struct);
1311 TELEMETRY_LOG_INFO("Success - Passed JSON empty message test");
1317 rte_telemetry_json_socket_message_test(struct telemetry_impl *telemetry, int fd)
1320 int ret, fail_count;
1323 struct telemetry_message_test socket_json_tests[] = {
1324 {.test_name = "Invalid JSON test",
1325 .test_func_ptr = rte_telemetry_invalid_json_test},
1326 {.test_name = "Valid JSON test",
1327 .test_func_ptr = rte_telemetry_valid_json_test},
1328 {.test_name = "JSON contents test",
1329 .test_func_ptr = rte_telemetry_json_contents_test},
1330 {.test_name = "JSON empty tests",
1331 .test_func_ptr = rte_telemetry_json_empty_test}
1334 #define NUM_TESTS RTE_DIM(socket_json_tests)
1336 for (i = 0; i < NUM_TESTS; i++) {
1337 TELEMETRY_LOG_INFO("%s", socket_json_tests[i].test_name);
1338 ret = (socket_json_tests[i].test_func_ptr)
1341 TELEMETRY_LOG_ERR("%s failed",
1342 socket_json_tests[i].test_name);
1347 if (fail_count > 0) {
1348 TELEMETRY_LOG_ERR("Failed %i JSON socket message test(s)",
1353 TELEMETRY_LOG_INFO("Success - All JSON tests passed");
1358 int telemetry_log_level;
1360 static struct rte_option option = {
1361 .name = "telemetry",
1362 .usage = "Enable telemetry backend",
1363 .cb = &rte_telemetry_init,
1367 RTE_INIT(rte_telemetry_register)
1369 telemetry_log_level = rte_log_register("lib.telemetry");
1370 if (telemetry_log_level >= 0)
1371 rte_log_set_level(telemetry_log_level, RTE_LOG_ERR);
1373 rte_option_register(&option);