From 914ca26bc748550c4563d265dbdd314b00f621f6 Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Fri, 5 Mar 2021 18:04:11 +0100 Subject: [PATCH] gnrc_sixlowpan_frag_sfr_congure_sfr: initial import --- makefiles/pseudomodules.inc.mk | 6 + .../net/gnrc/sixlowpan/frag/sfr/congure.h | 2 +- sys/net/gnrc/Makefile.dep | 4 + .../sixlowpan/frag/sfr/congure_sfr.c | 115 ++++++++++++++++++ 4 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 sys/net/gnrc/network_layer/sixlowpan/frag/sfr/congure_sfr.c diff --git a/makefiles/pseudomodules.inc.mk b/makefiles/pseudomodules.inc.mk index 2516929079..6cbb347532 100644 --- a/makefiles/pseudomodules.inc.mk +++ b/makefiles/pseudomodules.inc.mk @@ -236,6 +236,12 @@ PSEUDOMODULES += gnrc_sixlowpan_frag_sfr_stats ## @{ ## PSEUDOMODULES += gnrc_sixlowpan_frag_sfr_congure +## @defgroup net_gnrc_sixlowpan_frag_sfr_congure_sfr gnrc_sixlowpan_frag_sfr_congure_sfr: Appendix C +## @brief Basic congestion control for 6LoWPAN SFR as proposed in Appendix C of RFC 8931 +## @see [RFC 8931, Appendix C](https://tools.ietf.org/html/rfc8931#section-appendix.c) +## @{ +PSEUDOMODULES += gnrc_sixlowpan_frag_sfr_congure_sfr +## @} ## @} PSEUDOMODULES += gnrc_sixlowpan_iphc_nhc PSEUDOMODULES += gnrc_sixlowpan_nd_border_router diff --git a/sys/include/net/gnrc/sixlowpan/frag/sfr/congure.h b/sys/include/net/gnrc/sixlowpan/frag/sfr/congure.h index 068eaee12f..6345e3e336 100644 --- a/sys/include/net/gnrc/sixlowpan/frag/sfr/congure.h +++ b/sys/include/net/gnrc/sixlowpan/frag/sfr/congure.h @@ -15,7 +15,7 @@ * When included, this module enables congestion control for 6LoWPAN Selective Fragment Recovery * (SFR). The flavor of congestion control can be selected using the following sub-modules: * - * - TBD + * - @ref net_gnrc_sixlowpan_frag_sfr_congure_sfr (the default) * @{ * * @file diff --git a/sys/net/gnrc/Makefile.dep b/sys/net/gnrc/Makefile.dep index f61bb305cc..fdec26addd 100644 --- a/sys/net/gnrc/Makefile.dep +++ b/sys/net/gnrc/Makefile.dep @@ -246,6 +246,10 @@ endif ifneq (,$(filter gnrc_sixlowpan_frag_sfr_congure,$(USEMODULE))) USEMODULE += gnrc_sixlowpan_frag_sfr + ifeq (,$(filter gnrc_sixlowpan_frag_sfr_congure_% congure_mock,$(USEMODULE))) + # pick Appendix C as default congestion control + USEMODULE += gnrc_sixlowpan_frag_sfr_congure_sfr + endif endif ifneq (,$(filter gnrc_sixlowpan_frag_sfr_ecn_%,$(USEMODULE))) diff --git a/sys/net/gnrc/network_layer/sixlowpan/frag/sfr/congure_sfr.c b/sys/net/gnrc/network_layer/sixlowpan/frag/sfr/congure_sfr.c new file mode 100644 index 0000000000..b6e446b552 --- /dev/null +++ b/sys/net/gnrc/network_layer/sixlowpan/frag/sfr/congure_sfr.c @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2021 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 "kernel_defines.h" +#include "congure.h" +#include "net/gnrc/sixlowpan/config.h" + +#include "net/gnrc/sixlowpan/frag/sfr/congure.h" + +/* This implements a very simple SFR as suggested in + * https://datatracker.ietf.org/doc/html/rfc8931#appendix-C */ + +typedef congure_snd_t congure_sfr_snd_t; + +static void _snd_init(congure_snd_t *cong, void *ctx); +static int32_t _snd_inter_msg_interval(congure_snd_t *cong, unsigned msg_size); +static void _snd_report_msg_sent(congure_snd_t *cong, unsigned sent_size); +static void _snd_report_msg_discarded(congure_snd_t *cong, unsigned msg_size); +static void _snd_report_msgs_lost(congure_snd_t *cong, congure_snd_msg_t *msgs); +static void _snd_report_msgs_timeout(congure_snd_t *cong, congure_snd_msg_t *msgs); +static void _snd_report_msg_acked(congure_snd_t *cong, congure_snd_msg_t *msg, + congure_snd_ack_t *ack); +static void _snd_report_ecn_ce(congure_snd_t *cong, ztimer_now_t time); + +static congure_sfr_snd_t _sfr_congures_sfr[CONFIG_GNRC_SIXLOWPAN_FRAG_FB_SIZE]; +static const congure_snd_driver_t _driver = { + .init = _snd_init, + .inter_msg_interval = _snd_inter_msg_interval, + .report_msg_sent = _snd_report_msg_sent, + .report_msg_discarded = _snd_report_msg_discarded, + .report_msgs_timeout = _snd_report_msgs_timeout, + .report_msgs_lost = _snd_report_msgs_lost, + .report_msg_acked = _snd_report_msg_acked, + .report_ecn_ce = _snd_report_ecn_ce, +}; + +congure_snd_t *gnrc_sixlowpan_frag_sfr_congure_snd_get(void) +{ + for (unsigned i = 0; i < ARRAY_SIZE(_sfr_congures_sfr); i++) { + if (_sfr_congures_sfr[i].driver == NULL) { + _sfr_congures_sfr[i].driver = &_driver; + return &_sfr_congures_sfr[i]; + } + } + return NULL; +} + +static void _snd_init(congure_snd_t *cong, void *ctx) +{ + (void)ctx; + cong->cwnd = CONFIG_GNRC_SIXLOWPAN_SFR_OPT_WIN_SIZE; +} + +static int32_t _snd_inter_msg_interval(congure_snd_t *cong, unsigned msg_size) +{ + (void)cong; + (void)msg_size; + return CONFIG_GNRC_SIXLOWPAN_SFR_INTER_FRAME_GAP_US; +} + +static void _snd_report_msg_sent(congure_snd_t *cong, unsigned sent_size) +{ + (void)cong; + (void)sent_size; +} + +static void _snd_report_msg_discarded(congure_snd_t *cong, unsigned msg_size) +{ + (void)cong; + (void)msg_size; +} + +static void _snd_report_msgs_lost(congure_snd_t *cong, congure_snd_msg_t *msgs) +{ + /* Appendix C defines loss as timeout, so this does nothing */ + (void)cong; + (void)msgs; +} + +static void _snd_report_msgs_timeout(congure_snd_t *cong, + congure_snd_msg_t *msgs) +{ + (void)msgs; + if (cong->cwnd > 1U) { + cong->cwnd /= 2U; + } +} + +static void _snd_report_msg_acked(congure_snd_t *cong, congure_snd_msg_t *msg, + congure_snd_ack_t *ack) +{ + (void)cong; + (void)msg; + (void)ack; +} + +static void _snd_report_ecn_ce(congure_snd_t *cong, ztimer_now_t time) +{ + (void)time; + if (cong->cwnd > 1U) { + cong->cwnd--; + } +}