From cf69e61289809cd0ad1ad62ec62b9a71e0e6dc5b Mon Sep 17 00:00:00 2001 From: "Martine S. Lenders" Date: Wed, 5 Feb 2020 16:15:22 +0100 Subject: [PATCH] gnrc_ipv6_ext_frag: initial import of statistics module --- makefiles/pseudomodules.inc.mk | 1 + sys/include/net/gnrc/ipv6/ext/frag.h | 20 +++++++++++ .../ipv6/ext/frag/gnrc_ipv6_ext_frag.c | 23 ++++++++++++ sys/shell/commands/Makefile | 3 ++ sys/shell/commands/sc_gnrc_ipv6_frag_stats.c | 35 +++++++++++++++++++ sys/shell/commands/shell_commands.c | 7 ++++ 6 files changed, 89 insertions(+) create mode 100644 sys/shell/commands/sc_gnrc_ipv6_frag_stats.c diff --git a/makefiles/pseudomodules.inc.mk b/makefiles/pseudomodules.inc.mk index 620365e0be..89deb51363 100644 --- a/makefiles/pseudomodules.inc.mk +++ b/makefiles/pseudomodules.inc.mk @@ -18,6 +18,7 @@ PSEUDOMODULES += event_% PSEUDOMODULES += fmt_% PSEUDOMODULES += gnrc_dhcpv6_% PSEUDOMODULES += gnrc_ipv6_default +PSEUDOMODULES += gnrc_ipv6_ext_frag_stats PSEUDOMODULES += gnrc_ipv6_router PSEUDOMODULES += gnrc_ipv6_router_default PSEUDOMODULES += gnrc_ipv6_nib_6lbr diff --git a/sys/include/net/gnrc/ipv6/ext/frag.h b/sys/include/net/gnrc/ipv6/ext/frag.h index c8852857ed..ead4887892 100644 --- a/sys/include/net/gnrc/ipv6/ext/frag.h +++ b/sys/include/net/gnrc/ipv6/ext/frag.h @@ -93,6 +93,18 @@ typedef struct { uint8_t last; /**< received last fragment */ } gnrc_ipv6_ext_frag_rbuf_t; +/** + * @brief Statistics on reassembly and reassembly + */ +typedef struct { + unsigned rbuf_full; /**< counts the number of events where the + * reassembly buffer is full */ + unsigned frag_full; /**< counts the number of events that there where + * no @ref gnrc_sixlowpan_frag_fb_t available */ + unsigned datagrams; /**< reassembled datagrams */ + unsigned fragments; /**< total fragments of reassembled fragments */ +} gnrc_ipv6_ext_frag_stats_t; + /** * @brief Initializes IPv6 fragmentation and reassembly * @internal @@ -187,6 +199,14 @@ static inline void gnrc_ipv6_ext_frag_rbuf_del(gnrc_ipv6_ext_frag_rbuf_t *rbuf) void gnrc_ipv6_ext_frag_rbuf_gc(void); /** @} */ +/** + * @brief Get the current statistics on reassembly and fragmentation + * + * @return The current statistics on reassembly and fragmentation. + * @return NULL, if module `gnrc_ipv6_ext_frag_stats` is not compiled in. + */ +gnrc_ipv6_ext_frag_stats_t *gnrc_ipv6_ext_frag_stats(void); + #ifdef __cplusplus } #endif diff --git a/sys/net/gnrc/network_layer/ipv6/ext/frag/gnrc_ipv6_ext_frag.c b/sys/net/gnrc/network_layer/ipv6/ext/frag/gnrc_ipv6_ext_frag.c index a807831d59..3c3b63b3b4 100644 --- a/sys/net/gnrc/network_layer/ipv6/ext/frag/gnrc_ipv6_ext_frag.c +++ b/sys/net/gnrc/network_layer/ipv6/ext/frag/gnrc_ipv6_ext_frag.c @@ -40,6 +40,7 @@ static gnrc_ipv6_ext_frag_limits_t _limits_pool[CONFIG_GNRC_IPV6_EXT_FRAG_LIMITS static clist_node_t _free_limits; static xtimer_t _gc_xtimer; static msg_t _gc_msg = { .type = GNRC_IPV6_EXT_FRAG_RBUF_GC }; +static gnrc_ipv6_ext_frag_stats_t _stats; /** * @todo Implement better mechanism as described in @@ -278,6 +279,9 @@ static gnrc_ipv6_ext_frag_send_t *_snd_buf_alloc(void) return snd_buf; } } + if (IS_USED(MODULE_GNRC_IPV6_EXT_FRAG_STATS)) { + _stats.frag_full++; + } return NULL; } @@ -495,6 +499,10 @@ gnrc_pktsnip_t *gnrc_ipv6_ext_frag_reass(gnrc_pktsnip_t *pkt) gnrc_ipv6_ext_frag_rbuf_del(rbuf); ipv6->len = byteorder_htons(byteorder_ntohs(ipv6->len) - sizeof(ipv6_ext_frag_t)); + if (IS_USED(MODULE_GNRC_IPV6_EXT_FRAG_STATS)) { + _stats.fragments++; + _stats.datagrams++; + } return pkt; } else { @@ -562,10 +570,16 @@ gnrc_ipv6_ext_frag_rbuf_t *gnrc_ipv6_ext_frag_rbuf_get(ipv6_hdr_t *ipv6, assert(oldest != NULL); /* reassembly buffer is full, so there needs * to be an oldest entry */ DEBUG("ipv6_ext_frag: dropping oldest entry\n"); + if (IS_USED(MODULE_GNRC_IPV6_EXT_FRAG_STATS)) { + _stats.rbuf_full++; + } gnrc_ipv6_ext_frag_rbuf_del(oldest); res = oldest; _init_rbuf(res, ipv6, id); } + else if (IS_USED(MODULE_GNRC_IPV6_EXT_FRAG_STATS) && (res == NULL)) { + _stats.rbuf_full++; + } return res; } @@ -589,6 +603,11 @@ void gnrc_ipv6_ext_frag_rbuf_gc(void) } } +gnrc_ipv6_ext_frag_stats_t *gnrc_ipv6_ext_frag_stats(void) +{ + return (IS_USED(MODULE_GNRC_IPV6_EXT_FRAG_STATS)) ? &_stats : NULL; +} + typedef struct { uint16_t start; uint16_t end; @@ -698,6 +717,10 @@ static gnrc_pktsnip_t *_completed(gnrc_ipv6_ext_frag_rbuf_t *rbuf) /* rewrite length */ rbuf->ipv6->len = byteorder_htons(rbuf->pkt_len); rbuf->pkt = NULL; + if (IS_USED(MODULE_GNRC_IPV6_EXT_FRAG_STATS)) { + _stats.fragments += clist_count(&rbuf->limits); + _stats.datagrams++; + } gnrc_ipv6_ext_frag_rbuf_free(rbuf); return res; } diff --git a/sys/shell/commands/Makefile b/sys/shell/commands/Makefile index 4705c5a94b..38104f7efc 100644 --- a/sys/shell/commands/Makefile +++ b/sys/shell/commands/Makefile @@ -32,6 +32,9 @@ endif ifneq (,$(filter fib,$(USEMODULE))) SRC += sc_fib.c endif +ifneq (,$(filter gnrc_ipv6_ext_frag_stats,$(USEMODULE))) + SRC += sc_gnrc_ipv6_frag_stats.c +endif ifneq (,$(filter gnrc_ipv6_nib,$(USEMODULE))) SRC += sc_gnrc_ipv6_nib.c endif diff --git a/sys/shell/commands/sc_gnrc_ipv6_frag_stats.c b/sys/shell/commands/sc_gnrc_ipv6_frag_stats.c new file mode 100644 index 0000000000..388bc99c19 --- /dev/null +++ b/sys/shell/commands/sc_gnrc_ipv6_frag_stats.c @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2020 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @{ + * + * @file + * @author Martine Lenders + */ + +#include +#include "net/gnrc/ipv6/ext/frag.h" + +int _gnrc_ipv6_frag_stats(int argc, char **argv) +{ + (void)argc; + (void)argv; + if (IS_USED(MODULE_GNRC_IPV6_EXT_FRAG_STATS)) { + gnrc_ipv6_ext_frag_stats_t *stats = gnrc_ipv6_ext_frag_stats(); + + printf("rbuf full: %u\n", stats->rbuf_full); + printf("frag full: %u\n", stats->frag_full); + printf("frags complete: %u\n", stats->fragments); + printf("dgs complete: %u\n", stats->datagrams); + } + return 0; +} + + +/** @} */ diff --git a/sys/shell/commands/shell_commands.c b/sys/shell/commands/shell_commands.c index d30758cdaf..4f2e537c52 100644 --- a/sys/shell/commands/shell_commands.c +++ b/sys/shell/commands/shell_commands.c @@ -90,6 +90,10 @@ extern int _gnrc_netif_send(int argc, char **argv); extern int _fib_route_handler(int argc, char **argv); #endif +#ifdef MODULE_GNRC_IPV6_EXT_FRAG_STATS +extern int _gnrc_ipv6_frag_stats(int argc, char **argv); +#endif + #ifdef MODULE_GNRC_IPV6_WHITELIST extern int _whitelist(int argc, char **argv); #endif @@ -214,6 +218,9 @@ const shell_command_t _shell_command_list[] = { #ifdef MODULE_FIB {"fibroute", "Manipulate the FIB (info: 'fibroute [add|del]')", _fib_route_handler}, #endif +#ifdef MODULE_GNRC_IPV6_EXT_FRAG_STATS + {"ip6_frag", "IPv6 fragmentation statistics", _gnrc_ipv6_frag_stats }, +#endif #ifdef MODULE_GNRC_IPV6_WHITELIST {"whitelist", "whitelists an address for receival ('whitelist [add|del|help]')", _whitelist }, #endif