[mesh-forwarder] add delay-aware queue management (#7568)

This commit implements delay-aware queue management. When enabled the
device will monitor time-in-queue of messages in the direct tx queue
and if it is lager than specified thresholds it updates ECN flag
(if message indicates it is ECN-capable) and/or drop the message. This
mechanism is applied to IPv6 messages on the first device that sends
the message into Thread mesh and also on intermediate routers that are
forwarding the message (e.g., as a "mesh lowpan fragment" frame). On an
intermediate router when forwarding the fragments of a message, if any
fragment is dropped by the queue management policy, all subsequent
fragments will also be dropped.

In particular, this commit contains the following:

- Adds `DecompressEcn()` and `MarkCompressedEcn()` in `Lowpan` class
  to decompress or update the ECN field in a compressed IPHC header
  (unit test `test_lowpan` is also updated to test the new methods).
- Adds `UpdateEcnOrDrop()` which implements the main queue management
 logic. This method is used when preparing next direct tx message. It
 decides whether to keep the message as is, update ECN on it or drop
 it.
- Updates `EvictMessage()` to first apply the queue management rule
  to see if any message can be dropped before using the eviction
  logic based on message priority.
- Updates and reuses the `FragmentPriorityList` to track whether
  queue management dropped any of the fragments of same message so
  to also drop any subsequent ones.
- Updates `LogMessage()` to log when a message is dropped by
  queue-management or when ECN is marked on a message.
This commit is contained in:
Abtin Keshavarzian
2022-07-08 13:02:53 -07:00
committed by GitHub
parent 8aca0655e7
commit 2ce3d3bf02
11 changed files with 438 additions and 11 deletions
+21
View File
@@ -170,6 +170,8 @@ static void Test(TestIphcVector &aVector, bool aCompress, bool aDecompress)
if (aCompress)
{
Lowpan::BufferWriter buffer(result, 127);
Message * compressedMsg;
Ip6::Ecn ecn;
VerifyOrQuit((message = sInstance->Get<MessagePool>().Allocate(Message::kTypeIp6)) != nullptr);
@@ -192,6 +194,25 @@ static void Test(TestIphcVector &aVector, bool aCompress, bool aDecompress)
VerifyOrQuit(compressBytes == aVector.mIphcHeader.mLength, "Lowpan::Compress failed");
VerifyOrQuit(message->GetOffset() == aVector.mPayloadOffset, "Lowpan::Compress failed");
VerifyOrQuit(memcmp(iphc, result, iphcLength) == 0, "Lowpan::Compress failed");
// Validate `DecompressEcn()` and `MarkCompressedEcn()`
VerifyOrQuit((compressedMsg = sInstance->Get<MessagePool>().Allocate(Message::kTypeIp6)) != nullptr);
SuccessOrQuit(compressedMsg->AppendBytes(result, compressBytes));
ecn = sLowpan->DecompressEcn(*compressedMsg, /* aOffset */ 0);
VerifyOrQuit(ecn == aVector.GetIpHeader().GetEcn());
printf("Decompressed ECN is %d\n", ecn);
if (ecn != Ip6::kEcnNotCapable)
{
sLowpan->MarkCompressedEcn(*compressedMsg, /*a aOffset */ 0);
ecn = sLowpan->DecompressEcn(*compressedMsg, /* aOffset */ 0);
VerifyOrQuit(ecn == Ip6::kEcnMarked);
printf("ECN is updated to %d\n", ecn);
}
compressedMsg->Free();
}
message->Free();