mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-17 02:23:49 +01:00
netstats: initial import of IPv6 netstats
This commit is contained in:
parent
d5274572e8
commit
6707c20b7d
@ -507,6 +507,10 @@ ifneq (,$(filter gnrc_netdev2,$(USEMODULE)))
|
|||||||
USEMODULE += netopt
|
USEMODULE += netopt
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifneq (,$(filter netstats_%, $(USEMODULE)))
|
||||||
|
USEMODULE += netstats
|
||||||
|
endif
|
||||||
|
|
||||||
ifneq (,$(filter pthread,$(USEMODULE)))
|
ifneq (,$(filter pthread,$(USEMODULE)))
|
||||||
USEMODULE += xtimer
|
USEMODULE += xtimer
|
||||||
USEMODULE += timex
|
USEMODULE += timex
|
||||||
|
|||||||
@ -33,7 +33,9 @@ PSEUDOMODULES += lwip_udp
|
|||||||
PSEUDOMODULES += lwip_udplite
|
PSEUDOMODULES += lwip_udplite
|
||||||
PSEUDOMODULES += netdev_default
|
PSEUDOMODULES += netdev_default
|
||||||
PSEUDOMODULES += netif
|
PSEUDOMODULES += netif
|
||||||
|
PSEUDOMODULES += netstats
|
||||||
PSEUDOMODULES += netstats_l2
|
PSEUDOMODULES += netstats_l2
|
||||||
|
PSEUDOMODULES += netstats_ipv6
|
||||||
PSEUDOMODULES += newlib
|
PSEUDOMODULES += newlib
|
||||||
PSEUDOMODULES += newlib_nano
|
PSEUDOMODULES += newlib_nano
|
||||||
PSEUDOMODULES += pktqueue
|
PSEUDOMODULES += pktqueue
|
||||||
|
|||||||
@ -29,6 +29,8 @@ USEMODULE += gnrc_icmpv6_echo
|
|||||||
USEMODULE += shell
|
USEMODULE += shell
|
||||||
USEMODULE += shell_commands
|
USEMODULE += shell_commands
|
||||||
USEMODULE += ps
|
USEMODULE += ps
|
||||||
|
USEMODULE += netstats_l2
|
||||||
|
USEMODULE += netstats_ipv6
|
||||||
|
|
||||||
# Comment this out to disable code in RIOT that does safety checking
|
# Comment this out to disable code in RIOT that does safety checking
|
||||||
# which is not needed in a production environment but helps in the
|
# which is not needed in a production environment but helps in the
|
||||||
|
|||||||
@ -30,6 +30,7 @@
|
|||||||
#include "mutex.h"
|
#include "mutex.h"
|
||||||
#include "net/ipv6.h"
|
#include "net/ipv6.h"
|
||||||
#include "net/ipv6/addr.h"
|
#include "net/ipv6/addr.h"
|
||||||
|
#include "net/netstats.h"
|
||||||
#include "xtimer.h"
|
#include "xtimer.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -344,6 +345,9 @@ typedef struct {
|
|||||||
xtimer_t rtr_adv_timer; /**< Timer for periodic router advertisements */
|
xtimer_t rtr_adv_timer; /**< Timer for periodic router advertisements */
|
||||||
msg_t rtr_adv_msg; /**< msg_t for gnrc_ipv6_netif_t::rtr_adv_timer */
|
msg_t rtr_adv_msg; /**< msg_t for gnrc_ipv6_netif_t::rtr_adv_timer */
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef MODULE_NETSTATS_IPV6
|
||||||
|
netstats_t stats; /**< transceiver's statistics */
|
||||||
|
#endif
|
||||||
} gnrc_ipv6_netif_t;
|
} gnrc_ipv6_netif_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -587,6 +591,18 @@ static inline bool gnrc_ipv6_netif_addr_is_non_unicast(const ipv6_addr_t *addr)
|
|||||||
*/
|
*/
|
||||||
void gnrc_ipv6_netif_init_by_dev(void);
|
void gnrc_ipv6_netif_init_by_dev(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get sent and received statistics about IPv6 traffic on this interface.
|
||||||
|
*
|
||||||
|
* @note This function is only available if compiled with module `netstats_ipv6`.
|
||||||
|
*
|
||||||
|
* @param[in] pid The PID to the interface.
|
||||||
|
*
|
||||||
|
* @return A @ref netstats_t pointer to the statistics.
|
||||||
|
* @return NULL if no statistics are available.
|
||||||
|
*/
|
||||||
|
netstats_t *gnrc_ipv6_netif_get_stats(kernel_pid_t pid);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -18,6 +18,8 @@
|
|||||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifndef NETSTATS_H
|
#ifndef NETSTATS_H
|
||||||
#define NETSTATS_H
|
#define NETSTATS_H
|
||||||
|
|
||||||
@ -25,6 +27,15 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name @ref net_netstats module names
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define NETSTATS_LAYER2 (0x01)
|
||||||
|
#define NETSTATS_IPV6 (0x02)
|
||||||
|
#define NETSTATS_ALL (0xFF)
|
||||||
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Global statistics struct
|
* @brief Global statistics struct
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -373,6 +373,11 @@ static void _send_to_iface(kernel_pid_t iface, gnrc_pktsnip_t *pkt)
|
|||||||
gnrc_pktbuf_release(pkt);
|
gnrc_pktbuf_release(pkt);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#ifdef MODULE_NETSTATS_IPV6
|
||||||
|
if_entry->stats.tx_success++;
|
||||||
|
if_entry->stats.tx_bytes += gnrc_pkt_len(pkt->next);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef MODULE_GNRC_SIXLOWPAN
|
#ifdef MODULE_GNRC_SIXLOWPAN
|
||||||
if (if_entry->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) {
|
if (if_entry->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) {
|
||||||
DEBUG("ipv6: send to 6LoWPAN instead\n");
|
DEBUG("ipv6: send to 6LoWPAN instead\n");
|
||||||
@ -419,6 +424,9 @@ static void _send_unicast(kernel_pid_t iface, uint8_t *dst_l2addr,
|
|||||||
|
|
||||||
DEBUG("ipv6: send unicast over interface %" PRIkernel_pid "\n", iface);
|
DEBUG("ipv6: send unicast over interface %" PRIkernel_pid "\n", iface);
|
||||||
/* and send to interface */
|
/* and send to interface */
|
||||||
|
#ifdef MODULE_NETSTATS_IPV6
|
||||||
|
gnrc_ipv6_netif_get_stats(iface)->tx_unicast_count++;
|
||||||
|
#endif
|
||||||
_send_to_iface(iface, pkt);
|
_send_to_iface(iface, pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,6 +494,9 @@ static inline void _send_multicast_over_iface(kernel_pid_t iface, gnrc_pktsnip_t
|
|||||||
DEBUG("ipv6: send multicast over interface %" PRIkernel_pid "\n", iface);
|
DEBUG("ipv6: send multicast over interface %" PRIkernel_pid "\n", iface);
|
||||||
/* mark as multicast */
|
/* mark as multicast */
|
||||||
((gnrc_netif_hdr_t *)pkt->data)->flags |= GNRC_NETIF_HDR_FLAGS_MULTICAST;
|
((gnrc_netif_hdr_t *)pkt->data)->flags |= GNRC_NETIF_HDR_FLAGS_MULTICAST;
|
||||||
|
#ifdef MODULE_NETSTATS_IPV6
|
||||||
|
gnrc_ipv6_netif_get_stats(iface)->tx_mcast_count++;
|
||||||
|
#endif
|
||||||
/* and send to interface */
|
/* and send to interface */
|
||||||
_send_to_iface(iface, pkt);
|
_send_to_iface(iface, pkt);
|
||||||
}
|
}
|
||||||
@ -788,6 +799,13 @@ static void _receive(gnrc_pktsnip_t *pkt)
|
|||||||
|
|
||||||
if (netif != NULL) {
|
if (netif != NULL) {
|
||||||
iface = ((gnrc_netif_hdr_t *)netif->data)->if_pid;
|
iface = ((gnrc_netif_hdr_t *)netif->data)->if_pid;
|
||||||
|
|
||||||
|
#ifdef MODULE_NETSTATS_IPV6
|
||||||
|
assert(iface);
|
||||||
|
netstats_t *stats = gnrc_ipv6_netif_get_stats(iface);
|
||||||
|
stats->rx_count++;
|
||||||
|
stats->rx_bytes += (gnrc_pkt_len(pkt) - netif->size);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
first_ext = pkt;
|
first_ext = pkt;
|
||||||
|
|||||||
@ -897,6 +897,14 @@ void gnrc_ipv6_netif_init_by_dev(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MODULE_NETSTATS_IPV6
|
||||||
|
netstats_t *gnrc_ipv6_netif_get_stats(kernel_pid_t pid)
|
||||||
|
{
|
||||||
|
gnrc_ipv6_netif_t *iface = gnrc_ipv6_netif_get(pid);
|
||||||
|
return &(iface->stats);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -73,23 +73,51 @@ static bool _is_iface(kernel_pid_t dev)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MODULE_NETSTATS_L2
|
#if defined(MODULE_NETSTATS)
|
||||||
static int _netif_stats(kernel_pid_t dev, bool reset)
|
const char *_netstats_module_to_str(uint8_t module)
|
||||||
|
{
|
||||||
|
switch (module) {
|
||||||
|
case NETSTATS_LAYER2:
|
||||||
|
return "Layer 2";
|
||||||
|
case NETSTATS_IPV6:
|
||||||
|
return "IPv6";
|
||||||
|
case NETSTATS_ALL:
|
||||||
|
return "all";
|
||||||
|
default:
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _netif_stats(kernel_pid_t dev, unsigned module, bool reset)
|
||||||
{
|
{
|
||||||
netstats_t *stats;
|
netstats_t *stats;
|
||||||
int res = -ENOTSUP;
|
int res = -ENOTSUP;
|
||||||
|
|
||||||
|
if (module == NETSTATS_LAYER2) {
|
||||||
res = gnrc_netapi_get(dev, NETOPT_STATS, 0, &stats, sizeof(&stats));
|
res = gnrc_netapi_get(dev, NETOPT_STATS, 0, &stats, sizeof(&stats));
|
||||||
|
}
|
||||||
|
#ifdef MODULE_NETSTATS_IPV6
|
||||||
|
else if (module == NETSTATS_IPV6) {
|
||||||
|
stats = gnrc_ipv6_netif_get_stats(dev);
|
||||||
|
if (stats != NULL) {
|
||||||
|
res = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
puts(" Protocol or device doesn't provide statistics.");
|
puts(" Protocol or device doesn't provide statistics.");
|
||||||
}
|
}
|
||||||
else if (reset) {
|
else if (reset) {
|
||||||
memset(stats, 0, sizeof(netstats_t));
|
memset(stats, 0, sizeof(netstats_t));
|
||||||
puts("Reset statistics!");
|
printf("Reset statistics for module %s!\n", _netstats_module_to_str(module));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
printf(" RX packets %u bytes %u\n"
|
printf(" Statistics for %s\n"
|
||||||
|
" RX packets %u bytes %u\n"
|
||||||
" TX packets %u (Multicast: %u) bytes %u\n"
|
" TX packets %u (Multicast: %u) bytes %u\n"
|
||||||
" TX succeeded %u errors %u\n",
|
" TX succeeded %u errors %u\n",
|
||||||
|
_netstats_module_to_str(module),
|
||||||
(unsigned) stats->rx_count,
|
(unsigned) stats->rx_count,
|
||||||
(unsigned) stats->rx_bytes,
|
(unsigned) stats->rx_bytes,
|
||||||
(unsigned) (stats->tx_unicast_count + stats->tx_mcast_count),
|
(unsigned) (stats->tx_unicast_count + stats->tx_mcast_count),
|
||||||
@ -97,6 +125,7 @@ static int _netif_stats(kernel_pid_t dev, bool reset)
|
|||||||
(unsigned) stats->tx_bytes,
|
(unsigned) stats->tx_bytes,
|
||||||
(unsigned) stats->tx_success,
|
(unsigned) stats->tx_success,
|
||||||
(unsigned) stats->tx_failed);
|
(unsigned) stats->tx_failed);
|
||||||
|
res = 0;
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -155,7 +184,8 @@ static void _del_usage(char *cmd_name)
|
|||||||
|
|
||||||
static void _stats_usage(char *cmd_name)
|
static void _stats_usage(char *cmd_name)
|
||||||
{
|
{
|
||||||
printf("usage: %s <if_id> stats [reset]\n", cmd_name);
|
printf("usage: %s <if_id> stats [l2|ipv6] [reset]\n", cmd_name);
|
||||||
|
puts(" reset can be only used if the module is specified.");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _print_netopt(netopt_t opt)
|
static void _print_netopt(netopt_t opt)
|
||||||
@ -460,7 +490,10 @@ static void _netif_list(kernel_pid_t dev)
|
|||||||
|
|
||||||
#ifdef MODULE_NETSTATS_L2
|
#ifdef MODULE_NETSTATS_L2
|
||||||
puts("");
|
puts("");
|
||||||
_netif_stats(dev, false);
|
_netif_stats(dev, NETSTATS_LAYER2, false);
|
||||||
|
#endif
|
||||||
|
#ifdef MODULE_NETSTATS_IPV6
|
||||||
|
_netif_stats(dev, NETSTATS_IPV6, false);
|
||||||
#endif
|
#endif
|
||||||
puts("");
|
puts("");
|
||||||
}
|
}
|
||||||
@ -1106,13 +1139,39 @@ int _netif_config(int argc, char **argv)
|
|||||||
|
|
||||||
return _netif_mtu((kernel_pid_t)dev, argv[3]);
|
return _netif_mtu((kernel_pid_t)dev, argv[3]);
|
||||||
}
|
}
|
||||||
#ifdef MODULE_NETSTATS_L2
|
#ifdef MODULE_NETSTATS
|
||||||
else if (strcmp(argv[2], "stats") == 0) {
|
else if (strcmp(argv[2], "stats") == 0) {
|
||||||
|
uint8_t module;
|
||||||
bool reset = false;
|
bool reset = false;
|
||||||
if ((argc > 3) && (strncmp(argv[3], "reset", 5) == 0)) {
|
|
||||||
|
/* check for requested module */
|
||||||
|
if ((argc == 3) || (strcmp(argv[3], "all") == 0)) {
|
||||||
|
module = NETSTATS_ALL;
|
||||||
|
}
|
||||||
|
else if (strcmp(argv[3], "l2") == 0) {
|
||||||
|
module = NETSTATS_LAYER2;
|
||||||
|
}
|
||||||
|
else if (strcmp(argv[3], "ipv6") == 0) {
|
||||||
|
module = NETSTATS_IPV6;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("Module %s doesn't exist or does not provide statistics.\n", argv[3]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if reset flag was given */
|
||||||
|
if ((argc > 4) && (strncmp(argv[4], "reset", 5) == 0)) {
|
||||||
reset = true;
|
reset = true;
|
||||||
}
|
}
|
||||||
return _netif_stats((kernel_pid_t)dev, reset);
|
if (module & NETSTATS_LAYER2) {
|
||||||
|
_netif_stats((kernel_pid_t) dev, NETSTATS_LAYER2, reset);
|
||||||
|
}
|
||||||
|
if (module & NETSTATS_IPV6) {
|
||||||
|
_netif_stats((kernel_pid_t) dev, NETSTATS_IPV6, reset);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef MODULE_GNRC_IPV6_NETIF
|
#ifdef MODULE_GNRC_IPV6_NETIF
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user