Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions subsys/net/lib/shell/net_shell_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,17 @@
#include "net_private.h"
#include "../ip/ipv6.h"

enum net_shell_stats_format {
NET_SHELL_STATS_FORMAT_DEFAULT,
NET_SHELL_STATS_FORMAT_KEY_VALUE,
NET_SHELL_STATS_FORMAT_HEX_BLOB,
NET_SHELL_STATS_FORMAT_BOTH
};

struct net_shell_user_data {
const struct shell *sh;
void *user_data;
enum net_shell_stats_format vendor_stats_format;
};

#if !defined(NET_VLAN_MAX_COUNT)
Expand Down
83 changes: 69 additions & 14 deletions subsys/net/lib/shell/stats.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ static const char *priority2str(enum net_priority priority)
#if defined(CONFIG_NET_STATISTICS_ETHERNET) && \
defined(CONFIG_NET_STATISTICS_USER_API)
static void print_eth_stats(struct net_if *iface, struct net_stats_eth *data,
const struct shell *sh)
const struct shell *sh, struct net_shell_user_data *user_data)
{
PR("Statistics for Ethernet interface %p [%d]\n", iface,
net_if_get_by_iface(iface));
Expand All @@ -69,16 +69,42 @@ static void print_eth_stats(struct net_if *iface, struct net_stats_eth *data,

#if defined(CONFIG_NET_STATISTICS_ETHERNET_VENDOR)
if (data->vendor) {
PR("Vendor specific statistics for Ethernet "
"interface %p [%d]:\n",
iface, net_if_get_by_iface(iface));
size_t i = 0;
enum net_shell_stats_format format = NET_SHELL_STATS_FORMAT_DEFAULT;

if (user_data) {
format = user_data->vendor_stats_format;
}

PR("Vendor specific statistics for Ethernet interface %p [%d]:\n",
iface, net_if_get_by_iface(iface));

/* Print key-value pairs if requested */
if (format == NET_SHELL_STATS_FORMAT_DEFAULT ||
format == NET_SHELL_STATS_FORMAT_KEY_VALUE ||
format == NET_SHELL_STATS_FORMAT_BOTH) {
do {
PR("%s : %u\n", data->vendor[i].key, data->vendor[i].value);
i++;
} while (data->vendor[i].key);
}

do {
PR("%s : %u\n", data->vendor[i].key,
data->vendor[i].value);
i++;
} while (data->vendor[i].key);
/* Print hex blob if requested */
if (format == NET_SHELL_STATS_FORMAT_HEX_BLOB ||
format == NET_SHELL_STATS_FORMAT_BOTH) {
/* Suitable for parsing */
PR("Vendor stats hex blob: ");
for (i = 0; data->vendor[i].key; i++) {
uint32_t v = data->vendor[i].value;

PR("%02x%02x%02x%02x",
(uint8_t)(v & 0xFF),
(uint8_t)((v >> 8) & 0xFF),
(uint8_t)((v >> 16) & 0xFF),
(uint8_t)((v >> 24) & 0xFF));
}
PR("\n");
}
}
#endif /* CONFIG_NET_STATISTICS_ETHERNET_VENDOR */
}
Expand Down Expand Up @@ -513,7 +539,7 @@ static void net_shell_print_statistics(struct net_if *iface, void *user_data)
ret = net_mgmt(NET_REQUEST_STATS_GET_ETHERNET, iface,
&eth_data, sizeof(eth_data));
if (!ret) {
print_eth_stats(iface, &eth_data, sh);
print_eth_stats(iface, &eth_data, sh, data);
}
}
#endif /* CONFIG_NET_STATISTICS_ETHERNET && CONFIG_NET_STATISTICS_USER_API */
Expand Down Expand Up @@ -551,6 +577,18 @@ int cmd_net_stats_all(const struct shell *sh, size_t argc, char *argv[])

#if defined(CONFIG_NET_STATISTICS)
user_data.sh = sh;
user_data.vendor_stats_format = NET_SHELL_STATS_FORMAT_DEFAULT;

/* Parse format argument if provided */
if (argc > 1) {
if (strcmp(argv[1], "key-value") == 0) {
user_data.vendor_stats_format = NET_SHELL_STATS_FORMAT_KEY_VALUE;
} else if (strcmp(argv[1], "hex-blob") == 0) {
user_data.vendor_stats_format = NET_SHELL_STATS_FORMAT_HEX_BLOB;
} else if (strcmp(argv[1], "both") == 0) {
user_data.vendor_stats_format = NET_SHELL_STATS_FORMAT_BOTH;
}
}

/* Print global network statistics */
net_shell_print_statistics_all(&user_data);
Expand Down Expand Up @@ -596,6 +634,18 @@ int cmd_net_stats_iface(const struct shell *sh, size_t argc, char *argv[])
}

data.sh = sh;
data.vendor_stats_format = NET_SHELL_STATS_FORMAT_DEFAULT;

/* Parse format argument if provided */
if (argc > 2) {
if (strcmp(argv[2], "key-value") == 0) {
data.vendor_stats_format = NET_SHELL_STATS_FORMAT_KEY_VALUE;
} else if (strcmp(argv[2], "hex-blob") == 0) {
data.vendor_stats_format = NET_SHELL_STATS_FORMAT_HEX_BLOB;
} else if (strcmp(argv[2], "both") == 0) {
data.vendor_stats_format = NET_SHELL_STATS_FORMAT_BOTH;
}
}

net_shell_print_statistics(iface, &data);
#else
Expand Down Expand Up @@ -645,15 +695,20 @@ static int cmd_net_stats(const struct shell *sh, size_t argc, char *argv[])

SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_stats,
SHELL_CMD(all, NULL,
"Show network statistics for all network interfaces.",
"Show network statistics for all network interfaces.\n"
"Usage: net stats all [key-value|hex-blob|both]",
cmd_net_stats_all),
SHELL_CMD(iface, IFACE_DYN_CMD,
"'net stats <index>' shows network statistics for "
"one specific network interface.",
"'net stats <index> [key-value|hex-blob|both]' shows network statistics for "
"one specific network interface.\n"
"Format options:\n"
" key-value: Show vendor stats as key-value pairs (default)\n"
" hex-blob: Show vendor stats as hex blob for parsing\n"
" both: Show both key-value and hex blob formats",
cmd_net_stats_iface),
SHELL_SUBCMD_SET_END
);

SHELL_SUBCMD_ADD((net), stats, &net_cmd_stats,
"Show network statistics.",
cmd_net_stats, 1, 1);
cmd_net_stats, 1, 3);
Loading