1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018 Intel Corporation
11 #include <rte_metrics.h>
12 #include <rte_common.h>
13 #include <rte_ethdev.h>
14 #include <rte_metrics_telemetry.h>
16 #include "rte_telemetry_internal.h"
17 #include "rte_telemetry_parser.h"
19 typedef int (*command_func)(struct telemetry_impl *, int, json_t *);
21 struct rte_telemetry_command {
27 rte_telemetry_command_clients(struct telemetry_impl *telemetry, int action,
32 if (telemetry == NULL) {
33 TELEMETRY_LOG_ERR("Invalid telemetry argument");
37 if (action != ACTION_DELETE) {
38 TELEMETRY_LOG_WARN("Invalid action for this command");
42 if (!json_is_object(data)) {
43 TELEMETRY_LOG_WARN("Invalid data provided for this command");
47 json_t *client_path = json_object_get(data, "client_path");
48 if (!json_is_string(client_path)) {
49 TELEMETRY_LOG_WARN("Command value is not a string");
53 ret = rte_telemetry_unregister_client(telemetry,
54 json_string_value(client_path));
56 TELEMETRY_LOG_ERR("Could not unregister client");
63 ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
65 TELEMETRY_LOG_ERR("Could not send error");
70 rte_telemetry_command_ports(struct telemetry_impl *telemetry, int action,
75 if (telemetry == NULL) {
76 TELEMETRY_LOG_ERR("Invalid telemetry argument");
80 if (!json_is_null(data)) {
81 TELEMETRY_LOG_WARN("Data should be NULL JSON object for 'ports' command");
85 if (action != ACTION_GET) {
86 TELEMETRY_LOG_WARN("Invalid action for this command");
93 ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
95 TELEMETRY_LOG_ERR("Could not send error");
100 rte_telemetry_command_ports_details(struct telemetry_impl *telemetry,
101 int action, json_t *data)
103 json_t *value, *port_ids_json = json_object_get(data, "ports");
104 uint64_t num_port_ids = json_array_size(port_ids_json);
105 int ret, port_ids[num_port_ids];
106 RTE_SET_USED(port_ids);
109 if (telemetry == NULL) {
110 TELEMETRY_LOG_ERR("Invalid telemetry argument");
114 if (action != ACTION_GET) {
115 TELEMETRY_LOG_WARN("Invalid action for this command");
119 if (!json_is_object(data)) {
120 TELEMETRY_LOG_WARN("Invalid data provided for this command");
124 if (!json_is_array(port_ids_json)) {
125 TELEMETRY_LOG_WARN("Invalid Port ID array");
129 json_array_foreach(port_ids_json, index, value) {
130 if (!json_is_integer(value)) {
131 TELEMETRY_LOG_WARN("Port ID given is invalid");
134 port_ids[index] = json_integer_value(value);
140 ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
142 TELEMETRY_LOG_ERR("Could not send error");
147 rte_telemetry_command_port_stats(struct telemetry_impl *telemetry, int action,
152 if (telemetry == NULL) {
153 TELEMETRY_LOG_ERR("Invalid telemetry argument");
157 if (!json_is_null(data)) {
158 TELEMETRY_LOG_WARN("Data should be NULL JSON object for 'port_stats' command");
162 if (action != ACTION_GET) {
163 TELEMETRY_LOG_WARN("Invalid action for this command");
170 ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
172 TELEMETRY_LOG_ERR("Could not send error");
177 rte_telemetry_command_ports_all_stat_values(struct telemetry_impl *telemetry,
178 int action, json_t *data)
181 struct telemetry_encode_param ep;
183 memset(&ep, 0, sizeof(ep));
184 if (telemetry == NULL) {
185 TELEMETRY_LOG_ERR("Invalid telemetry argument");
189 if (action != ACTION_GET) {
190 TELEMETRY_LOG_WARN("Invalid action for this command");
191 ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
193 TELEMETRY_LOG_ERR("Could not send error");
197 if (json_is_object(data)) {
198 TELEMETRY_LOG_WARN("Invalid data provided for this command");
199 ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
201 TELEMETRY_LOG_ERR("Could not send error");
205 ret = rte_metrics_tel_get_port_stats_ids(&ep);
207 TELEMETRY_LOG_ERR("Could not get ports stat values");
208 ret = rte_telemetry_send_error_response(telemetry, ret);
210 TELEMETRY_LOG_ERR("Could not send error");
214 ret = rte_telemetry_send_ports_stats_values(&ep, telemetry);
216 TELEMETRY_LOG_ERR("Sending ports stats values failed");
224 rte_telemetry_command_global_stat_values(struct telemetry_impl *telemetry,
225 int action, json_t *data)
228 struct telemetry_encode_param ep;
230 memset(&ep, 0, sizeof(ep));
231 if (telemetry == NULL) {
232 TELEMETRY_LOG_ERR("Invalid telemetry argument");
236 if (action != ACTION_GET) {
237 TELEMETRY_LOG_WARN("Invalid action for this command");
238 ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
240 TELEMETRY_LOG_ERR("Could not send error");
244 if (json_is_object(data)) {
245 TELEMETRY_LOG_WARN("Invalid data provided for this command");
246 ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
248 TELEMETRY_LOG_ERR("Could not send error");
252 ret = rte_metrics_tel_get_global_stats(&ep);
254 TELEMETRY_LOG_ERR("Could not get global stat values");
255 ret = rte_telemetry_send_error_response(telemetry, ret);
257 TELEMETRY_LOG_ERR("Could not send error");
261 ret = rte_telemetry_send_global_stats_values(&ep, telemetry);
263 TELEMETRY_LOG_ERR("Sending global stats values failed");
271 rte_telemetry_command_ports_stats_values_by_name(struct telemetry_impl
272 *telemetry, int action, json_t *data)
275 struct telemetry_encode_param ep;
276 if (telemetry == NULL) {
277 TELEMETRY_LOG_ERR("Invalid telemetry argument");
281 if (action != ACTION_GET) {
282 TELEMETRY_LOG_WARN("Invalid action for this command");
283 ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
285 TELEMETRY_LOG_ERR("Could not send error");
289 ret = rte_metrics_tel_extract_data(&ep, data);
291 TELEMETRY_LOG_ERR("Extracting JSON data failed");
292 ret = rte_telemetry_send_error_response(telemetry, ret);
294 TELEMETRY_LOG_ERR("Could not send error");
298 ret = rte_telemetry_send_ports_stats_values(&ep, telemetry);
300 TELEMETRY_LOG_ERR("Sending ports stats values failed");
308 rte_telemetry_parse_command(struct telemetry_impl *telemetry, int action,
309 const char *command, json_t *data)
314 if (telemetry == NULL) {
315 TELEMETRY_LOG_ERR("Invalid telemetry argument");
319 struct rte_telemetry_command commands[] = {
322 .fn = &rte_telemetry_command_clients
326 .fn = &rte_telemetry_command_ports
329 .text = "ports_details",
330 .fn = &rte_telemetry_command_ports_details
333 .text = "port_stats",
334 .fn = &rte_telemetry_command_port_stats
337 .text = "ports_stats_values_by_name",
338 .fn = &rte_telemetry_command_ports_stats_values_by_name
341 .text = "ports_all_stat_values",
342 .fn = &rte_telemetry_command_ports_all_stat_values
345 .text = "global_stat_values",
346 .fn = &rte_telemetry_command_global_stat_values
350 const uint32_t num_commands = RTE_DIM(commands);
352 for (i = 0; i < num_commands; i++) {
353 if (strcmp(command, commands[i].text) == 0) {
354 ret = commands[i].fn(telemetry, action, data);
356 TELEMETRY_LOG_ERR("Command Function for %s failed",
364 TELEMETRY_LOG_WARN("\"%s\" command not found", command);
366 ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
368 TELEMETRY_LOG_ERR("Could not send error");
374 rte_telemetry_parse(struct telemetry_impl *telemetry, char *socket_rx_data)
378 json_t *root, *action, *command, *data;
380 if (telemetry == NULL) {
381 TELEMETRY_LOG_ERR("Invalid telemetry argument");
385 root = json_loads(socket_rx_data, 0, &error);
387 TELEMETRY_LOG_WARN("Could not load JSON object from data passed in : %s",
389 ret = rte_telemetry_send_error_response(telemetry, -EPERM);
391 TELEMETRY_LOG_ERR("Could not send error");
393 } else if (!json_is_object(root)) {
394 TELEMETRY_LOG_WARN("JSON Request is not a JSON object");
399 action = json_object_get(root, "action");
400 if (action == NULL) {
401 TELEMETRY_LOG_WARN("Request does not have action field");
403 } else if (!json_is_integer(action)) {
404 TELEMETRY_LOG_WARN("Action value is not an integer");
408 command = json_object_get(root, "command");
409 if (command == NULL) {
410 TELEMETRY_LOG_WARN("Request does not have command field");
412 } else if (!json_is_string(command)) {
413 TELEMETRY_LOG_WARN("Command value is not a string");
417 action_int = json_integer_value(action);
418 if (action_int != ACTION_GET && action_int != ACTION_DELETE) {
419 TELEMETRY_LOG_WARN("Invalid action code");
423 const char *command_string = json_string_value(command);
424 data = json_object_get(root, "data");
426 TELEMETRY_LOG_WARN("Request does not have data field");
430 ret = rte_telemetry_parse_command(telemetry, action_int, command_string,
433 TELEMETRY_LOG_WARN("Could not parse command");
440 ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
442 TELEMETRY_LOG_ERR("Could not send error");