[mesh-forwarder] limit the Mesh Header frame MTU (#4440)

This commit allows us to use different MTU on different radio links.
Mesh Header frames are forwarded by routers over multiple hops to
reach a final destination. The forwarding path can have routers
supporting different radio links with varying MTU sizes. Since the
originator of the frame does not know the path and the MTU sizes of
supported radio links by the routers in the path, we limit the max
payload length of a Mesh Header frame to a fixed minimum value
(derived from 15.4 radio) ensuring it can be handled by any radio
link.
This commit is contained in:
Abtin Keshavarzian
2020-12-10 11:46:07 -08:00
committed by Jonathan Hui
parent 0829514edc
commit 925f75cf06
3 changed files with 31 additions and 9 deletions
+2 -2
View File
@@ -75,8 +75,8 @@ class Link : public InstanceLocator
public:
enum
{
kMtuSize = OT_RADIO_FRAME_MAX_SIZE, ///< MTU size for TREL frame.
kFcsSize = 2, ///< FCS size for TREL frame.
kMtuSize = 1280 - 48 - sizeof(Header), ///< MTU size for TREL frame.
kFcsSize = 0, ///< FCS size for TREL frame.
};
/**
+26 -6
View File
@@ -579,6 +579,7 @@ uint16_t MeshForwarder::PrepareDataFrame(Mac::TxFrame & aFrame,
uint16_t fcf;
uint8_t *payload;
uint8_t headerLength;
uint16_t maxPayloadLength;
uint16_t payloadLength;
uint16_t fragmentLength;
uint16_t dstpan;
@@ -665,7 +666,8 @@ start:
IgnoreError(Get<Mac::Mac>().AppendHeaderIe(aMessage.IsTimeSync(), aFrame));
#endif
payload = aFrame.GetPayload();
payload = aFrame.GetPayload();
maxPayloadLength = aFrame.GetMaxPayloadLength();
headerLength = 0;
@@ -679,6 +681,24 @@ start:
uint16_t meshHeaderLength;
uint8_t hopsLeft;
// Mesh Header frames are forwarded by routers over multiple
// hops to reach a final destination. The forwarding path can
// have routers supporting different radio links with varying
// MTU sizes. Since the originator of the frame does not know the
// path and the MTU sizes of supported radio links by the routers
// in the path, we limit the max payload length of a Mesh Header
// frame to a fixed minimum value (derived from 15.4 radio)
// ensuring it can be handled by any radio link.
//
// Maximum payload length is calculated by subtracting the frame
// header and footer lengths from the MTU size. The footer
// length is derived by removing the `aFrame.GetFcsSize()` and
// then adding the fixed `kMeshHeaderFrameFcsSize` instead
// (updating the FCS size in the calculation of footer length).
maxPayloadLength = kMeshHeaderFrameMtu - aFrame.GetHeaderLength() -
(aFrame.GetFooterLength() - aFrame.GetFcsSize() + kMeshHeaderFrameFcsSize);
if (mle.IsChild())
{
// REED sets hopsLeft to max (16) + 1. It does not know the route cost.
@@ -718,8 +738,8 @@ start:
// Compress IPv6 Header
if (aMessage.GetOffset() == 0)
{
Lowpan::BufferWriter buffer(payload, aFrame.GetMaxPayloadLength() - headerLength -
Lowpan::FragmentHeader::kFirstFragmentHeaderSize);
Lowpan::BufferWriter buffer(payload,
maxPayloadLength - headerLength - Lowpan::FragmentHeader::kFirstFragmentHeaderSize);
uint8_t hcLength;
Mac::Address meshSource, meshDest;
otError error;
@@ -743,7 +763,7 @@ start:
hcLength = static_cast<uint8_t>(buffer.GetWritePointer() - payload);
headerLength += hcLength;
payloadLength = aMessage.GetLength() - aMessage.GetOffset();
fragmentLength = aFrame.GetMaxPayloadLength() - headerLength;
fragmentLength = maxPayloadLength - headerLength;
if ((payloadLength > fragmentLength) || aAddFragHeader)
{
@@ -777,7 +797,7 @@ start:
payload += Lowpan::FragmentHeader::kFirstFragmentHeaderSize;
headerLength += Lowpan::FragmentHeader::kFirstFragmentHeaderSize;
fragmentLength = aFrame.GetMaxPayloadLength() - headerLength;
fragmentLength = maxPayloadLength - headerLength;
if (payloadLength > fragmentLength)
{
@@ -809,7 +829,7 @@ start:
payload += fragmentHeaderLength;
headerLength += fragmentHeaderLength;
fragmentLength = aFrame.GetMaxPayloadLength() - headerLength;
fragmentLength = maxPayloadLength - headerLength;
if (payloadLength > fragmentLength)
{
+3 -1
View File
@@ -327,7 +327,9 @@ public:
private:
enum : uint8_t
{
kReassemblyTimeout = OPENTHREAD_CONFIG_6LOWPAN_REASSEMBLY_TIMEOUT, // Reassembly timeout (in seconds).
kReassemblyTimeout = OPENTHREAD_CONFIG_6LOWPAN_REASSEMBLY_TIMEOUT, // Reassembly timeout (in seconds).
kMeshHeaderFrameMtu = OT_RADIO_FRAME_MAX_SIZE, // Max. MTU allowed when generating a Mesh Header frame.
kMeshHeaderFrameFcsSize = sizeof(uint16_t), // Frame FCS size for Mesh Header frame.
};
enum MessageAction ///< Defines the action parameter in `LogMessageInfo()` method.