1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #16175 from miri64/gnrc_sixlowpan_frag_sfr/enh/mark-ecn

gnrc_sixlowpan_frag_sfr: add support for queue-based ECN
This commit is contained in:
Martine Lenders 2022-10-15 14:01:44 +02:00 committed by GitHub
commit 53ed211fc9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 212 additions and 3 deletions

View File

@ -225,6 +225,10 @@ PSEUDOMODULES += gnrc_sixloenc
PSEUDOMODULES += gnrc_sixlowpan_border_router_default
PSEUDOMODULES += gnrc_sixlowpan_default
PSEUDOMODULES += gnrc_sixlowpan_frag_hint
PSEUDOMODULES += gnrc_sixlowpan_frag_sfr_ecn
PSEUDOMODULES += gnrc_sixlowpan_frag_sfr_ecn_if_in
PSEUDOMODULES += gnrc_sixlowpan_frag_sfr_ecn_if_out
PSEUDOMODULES += gnrc_sixlowpan_frag_sfr_ecn_fqueue
PSEUDOMODULES += gnrc_sixlowpan_frag_sfr_stats
PSEUDOMODULES += gnrc_sixlowpan_iphc_nhc
PSEUDOMODULES += gnrc_sixlowpan_nd_border_router

View File

@ -203,7 +203,7 @@ extern "C" {
#endif
/**
* @brief Indicates whether the sender should react to ECN (UseECN)
* @brief Indicates whether the sender should react to Explicit Congestion Notification (UseECN)
*
* When the sender reacts to Explicit Congestion Notification (ECN) its window
* size will vary between @ref CONFIG_GNRC_SIXLOWPAN_SFR_MIN_WIN_SIZE and @ref
@ -301,6 +301,82 @@ extern "C" {
#ifndef CONFIG_GNRC_SIXLOWPAN_SFR_DG_RETRIES
#define CONFIG_GNRC_SIXLOWPAN_SFR_DG_RETRIES 0U
#endif
/**
* @brief The numerator for the factor for when to mark ECN on incoming `netif`
* queue state
*
* When `gnrc_sixlowpan_frag_sfr_ecn_if_in` is compiled in, nodes will set
* the ECN bit of an RFRAG header when the message queue of the incoming `netif`
* is filled by
* @ref CONFIG_GNRC_SIXLOWPAN_SFR_ECN_IF_IN_NUM / @ref CONFIG_GNRC_SIXLOWPAN_SFR_ECN_IF_IN_DEN
*/
#ifndef CONFIG_GNRC_SIXLOWPAN_SFR_ECN_IF_IN_NUM
#define CONFIG_GNRC_SIXLOWPAN_SFR_ECN_IF_IN_NUM 1U
#endif
/**
* @brief The denominator for the factor for when to mark ECN on incoming `netif`
* queue state
*
* When `gnrc_sixlowpan_frag_sfr_ecn_if_in` is compiled in, nodes will set the
* ECN bit of an RFRAG header when the message queue of the incoming `netif` is
* filled by
* @ref CONFIG_GNRC_SIXLOWPAN_SFR_ECN_IF_IN_NUM / @ref CONFIG_GNRC_SIXLOWPAN_SFR_ECN_IF_IN_DEN
*/
#ifndef CONFIG_GNRC_SIXLOWPAN_SFR_ECN_IF_IN_DEN
#define CONFIG_GNRC_SIXLOWPAN_SFR_ECN_IF_IN_DEN 2U
#endif
/**
* @brief The numerator for the factor for when to mark ECN on the outgoing `netif`'s
* output queue state
*
* When `gnrc_sixlowpan_frag_sfr_ecn_if_out` is compiled in, nodes will set
* the ECN bit of an RFRAG header when the output queue of the outgoing `netif`
* is filled by
* @ref CONFIG_GNRC_SIXLOWPAN_SFR_ECN_IF_OUT_NUM / @ref CONFIG_GNRC_SIXLOWPAN_SFR_ECN_IF_OUT_DEN
*/
#ifndef CONFIG_GNRC_SIXLOWPAN_SFR_ECN_IF_OUT_NUM
#define CONFIG_GNRC_SIXLOWPAN_SFR_ECN_IF_OUT_NUM 1U
#endif
/**
* @brief The denominator for the factor for when to mark ECN on the outgoing `netif`
* output queue state
*
* When `gnrc_sixlowpan_frag_sfr_ecn_if_out` is compiled in, nodes will set the
* ECN bit of an RFRAG header when the output queue of the outgoing `netif` is
* filled by
* @ref CONFIG_GNRC_SIXLOWPAN_SFR_ECN_IF_OUT_NUM / @ref CONFIG_GNRC_SIXLOWPAN_SFR_ECN_IF_OUT_DEN
*/
#ifndef CONFIG_GNRC_SIXLOWPAN_SFR_ECN_IF_OUT_DEN
#define CONFIG_GNRC_SIXLOWPAN_SFR_ECN_IF_OUT_DEN 2U
#endif
/**
* @brief The numerator for the factor for when to mark ECN on frame queue
* state
*
* When `gnrc_sixlowpan_frag_sfr_ecn_fqueue` is compiled in, nodes will set the
* ECN bit of an RFRAG header when the frame queue for SFR is filled by
* @ref CONFIG_GNRC_SIXLOWPAN_SFR_ECN_FQUEUE_NUM / @ref CONFIG_GNRC_SIXLOWPAN_SFR_ECN_FQUEUE_DEN
*/
#ifndef CONFIG_GNRC_SIXLOWPAN_SFR_ECN_FQUEUE_NUM
#define CONFIG_GNRC_SIXLOWPAN_SFR_ECN_FQUEUE_NUM 1U
#endif
/**
* @brief The denominator for the factor for when to mark ECN on frame queue
* state
*
* When `gnrc_sixlowpan_frag_sfr_ecn_fqueue` is compiled in, nodes will set the
* ECN bit of an RFRAG header when the frame queue for SFR is filled by
* @ref CONFIG_GNRC_SIXLOWPAN_SFR_ECN_FQUEUE_NUM / @ref CONFIG_GNRC_SIXLOWPAN_SFR_ECN_FQUEUE_DEN
*/
#ifndef CONFIG_GNRC_SIXLOWPAN_SFR_ECN_FQUEUE_DEN
#define CONFIG_GNRC_SIXLOWPAN_SFR_ECN_FQUEUE_DEN 2U
#endif
/** @} */
/**

View File

@ -240,6 +240,18 @@ ifneq (,$(filter gnrc_sixlowpan_frag_sfr,$(USEMODULE)))
USEMODULE += xtimer
endif
ifneq (,$(filter gnrc_sixlowpan_frag_sfr_ecn_%,$(USEMODULE)))
USEMODULE += gnrc_sixlowpan_frag_sfr_ecn
endif
ifneq (,$(filter gnrc_sixlowpan_frag_sfr_ecn_if_out,$(USEMODULE)))
USEMODULE += gnrc_netif_pktq
endif
ifneq (,$(filter gnrc_sixlowpan_frag_sfr_ecn,$(USEMODULE)))
USEMODULE += gnrc_sixlowpan_frag_sfr
endif
ifneq (,$(filter gnrc_sixlowpan_frag_sfr_stats,$(USEMODULE)))
USEMODULE += gnrc_sixlowpan_frag_sfr
endif

View File

@ -33,7 +33,7 @@ config GNRC_SIXLOWPAN_SFR_OPT_FRAG_SIZE
@ref GNRC_SIXLOWPAN_SFR_MAX_FRAG_SIZE
config GNRC_SIXLOWPAN_SFR_USE_ECN
bool "Indicates whether the sender should react to ECN (UseECN)"
bool "Indicates whether the sender should react to Explicit Content Notification (UseECN)"
default false
help
When the sender reacts to Explicit Congestion Notification (ECN) its
@ -98,4 +98,74 @@ config GNRC_SIXLOWPAN_SFR_DG_RETRIES
int "The maximum number of retries from scratch for a particular datagram (MaxDatagramRetries)"
default 0
menuconfig KCONFIG_USEMODULE_GNRC_SIXLOWPAN_FRAG_SFR_ECN_IF_IN
bool "Configure SFR ECN based on the message queue of the incoming netif"
depends on USEMODULE_GNRC_SIXLOWPAN_FRAG_SFR_ECN_IF_IN
if KCONFIG_USEMODULE_GNRC_SIXLOWPAN_FRAG_SFR_ECN_IF_IN
config GNRC_SIXLOWPAN_SFR_ECN_IF_IN_NUM
int "The numerator for the factor for when to mark ECN on incoming netif queue state"
default 1
help
When `gnrc_sixlowpan_frag_sfr_ecn_if_in` is compiled in, nodes will set
the ECN bit of an RFRAG header when the message queue of the incoming `netif`
is filled by
@ref CONFIG_GNRC_SIXLOWPAN_SFR_ECN_IF_IN_NUM / @ref CONFIG_GNRC_SIXLOWPAN_SFR_ECN_IF_IN_DEN
config GNRC_SIXLOWPAN_SFR_ECN_IF_IN_DEN
int "The denominator for the factor for when to mark ECN on incoming netif queue state"
default 2
help
When `gnrc_sixlowpan_frag_sfr_ecn_if_in` is compiled in, nodes will set the
ECN bit of an RFRAG header when the message queue of the incoming `netif` is
filled by
@ref CONFIG_GNRC_SIXLOWPAN_SFR_ECN_IF_IN_NUM / @ref CONFIG_GNRC_SIXLOWPAN_SFR_ECN_IF_IN_DEN
endif
menuconfig KCONFIG_USEMODULE_GNRC_SIXLOWPAN_FRAG_SFR_ECN_IF_OUT
bool "Configure SFR ECN based on the output queue of the outgoing netif"
depends on USEMODULE_GNRC_SIXLOWPAN_FRAG_SFR_ECN_IF_OUT
if KCONFIG_USEMODULE_GNRC_SIXLOWPAN_FRAG_SFR_ECN_IF_OUT
config GNRC_SIXLOWPAN_SFR_ECN_IF_OUT_NUM
int "The numerator for the factor for when to mark ECN on the outgoing netif's output queue state"
default 1
help
When `gnrc_sixlowpan_frag_sfr_ecn_if_out` is compiled in, nodes will set
the ECN bit of an RFRAG header when the output queue of the outgoing `netif`
is filled by
@ref CONFIG_GNRC_SIXLOWPAN_SFR_ECN_IF_OUT_NUM / @ref CONFIG_GNRC_SIXLOWPAN_SFR_ECN_IF_OUT_DEN
config GNRC_SIXLOWPAN_SFR_ECN_IF_OUT_DEN
int "The denominator for the factor for when to mark ECN on the outgoing netif output queue state"
default 2
help
When `gnrc_sixlowpan_frag_sfr_ecn_if_out` is compiled in, nodes will set the
ECN bit of an RFRAG header when the output queue of the outgoing `netif` is
filled by
@ref CONFIG_GNRC_SIXLOWPAN_SFR_ECN_IF_OUT_NUM / @ref CONFIG_GNRC_SIXLOWPAN_SFR_ECN_IF_OUT_DEN
endif
menuconfig KCONFIG_USEMODULE_GNRC_SIXLOWPAN_FRAG_SFR_ECN_FQUEUE
bool "Configure SFR ECN based on SFR's frame queue"
depends on USEMODULE_GNRC_SIXLOWPAN_FRAG_SFR_ECN_FQUEUE
if KCONFIG_USEMODULE_GNRC_SIXLOWPAN_FRAG_SFR_ECN_FQUEUE
config GNRC_SIXLOWPAN_SFR_ECN_FQUEUE_NUM
int "The numerator for the factor for when to mark ECN on frame queue state"
default 1
help
When `gnrc_sixlowpan_frag_sfr_ecn_fqueue` is compiled in, nodes will set the
ECN bit of an RFRAG header when the frame queue for SFR is filled by
@ref CONFIG_GNRC_SIXLOWPAN_SFR_ECN_FQUEUE_NUM / @ref CONFIG_GNRC_SIXLOWPAN_SFR_ECN_FQUEUE_DEN
config GNRC_SIXLOWPAN_SFR_ECN_FQUEUE_DEN
int "The denominator for the factor for when to mark ECN on frame queue state"
default 2
help
When `gnrc_sixlowpan_frag_sfr_ecn_fqueue` is compiled in, nodes will set the
ECN bit of an RFRAG header when the frame queue for SFR is filled by
@ref CONFIG_GNRC_SIXLOWPAN_SFR_ECN_FQUEUE_NUM / @ref CONFIG_GNRC_SIXLOWPAN_SFR_ECN_FQUEUE_DEN
endif
endif

View File

@ -25,6 +25,7 @@
#endif
#include "net/gnrc/neterr.h"
#include "net/gnrc/netif/internal.h"
#include "net/gnrc/netif/pktq.h"
#include "net/gnrc/pkt.h"
#include "net/gnrc/sixlowpan.h"
#include "net/gnrc/sixlowpan/config.h"
@ -762,10 +763,56 @@ static uint16_t _find_offset_and_copy_rest(uint8_t *data, gnrc_pktsnip_t **pkt,
return cur_frag_size;
}
static void _check_for_ecn(gnrc_pktsnip_t *frame)
{
if (IS_USED(MODULE_GNRC_SIXLOWPAN_FRAG_SFR_ECN) &&
(sixlowpan_sfr_rfrag_is(frame->next->data))) {
int queue_state = 0;
int queue_size = 0;
if (IS_USED(MODULE_GNRC_SIXLOWPAN_FRAG_SFR_ECN_IF_IN)) {
gnrc_netif_t *netif = gnrc_netif_hdr_get_netif(frame->data);
assert(frame->type == GNRC_NETTYPE_NETIF);
assert(frame->next->type == GNRC_NETTYPE_SIXLOWPAN);
queue_state = msg_avail_thread(netif->pid);
queue_size = msg_queue_capacity(netif->pid);
assert(queue_size > 0);
if ((queue_state * CONFIG_GNRC_SIXLOWPAN_SFR_ECN_IF_IN_DEN) >
(queue_size * CONFIG_GNRC_SIXLOWPAN_SFR_ECN_IF_IN_NUM)) {
sixlowpan_sfr_set_ecn(frame->next->data);
}
}
if (IS_USED(MODULE_GNRC_SIXLOWPAN_FRAG_SFR_ECN_IF_OUT)) {
queue_state = gnrc_netif_pktq_usage();
queue_size = CONFIG_GNRC_NETIF_PKTQ_POOL_SIZE;
if ((queue_state * CONFIG_GNRC_SIXLOWPAN_SFR_ECN_IF_OUT_DEN) >
(queue_size * CONFIG_GNRC_SIXLOWPAN_SFR_ECN_IF_OUT_NUM)) {
sixlowpan_sfr_set_ecn(frame->next->data);
}
}
if (IS_USED(MODULE_GNRC_SIXLOWPAN_FRAG_SFR_ECN_FQUEUE)) {
queue_state = clist_count(&_frame_queue);
queue_size = FRAME_QUEUE_POOL_SIZE;
if ((queue_state * CONFIG_GNRC_SIXLOWPAN_SFR_ECN_FQUEUE_DEN) >
(queue_size * CONFIG_GNRC_SIXLOWPAN_SFR_ECN_FQUEUE_NUM)) {
sixlowpan_sfr_set_ecn(frame->next->data);
}
}
}
}
static bool _send_frame(gnrc_pktsnip_t *frame, void *ctx, unsigned page)
{
uint32_t now = xtimer_now_usec();
uint32_t now;
_check_for_ecn(frame);
now = xtimer_now_usec();
if ((CONFIG_GNRC_SIXLOWPAN_SFR_INTER_FRAME_GAP_US == 0) ||
((now - _last_frame_sent) > CONFIG_GNRC_SIXLOWPAN_SFR_INTER_FRAME_GAP_US)) {
DEBUG("6lo sfr: dispatch frame to network interface\n");