mirror of
https://github.com/espressif/openthread.git
synced 2026-08-09 20:27:47 +00:00
[mesh-forwarder] add RxInfo to encapsulate received frame info (#10451)
This commit introduces a new private struct `RxInfo` in the `MeshForwarder` class, encapsulating information related to a received frame during processing. The `RxInfo` struct contains `FrameData` to track the received frame data bytes, `ThreadLinkInfo`, and `Mac::Addresses`. This simplifies the code by allowing the `RxInfo` to be passed to different methods instead of passing the same information as separate parameters.
This commit is contained in:
@@ -1373,42 +1373,40 @@ exit:
|
||||
|
||||
void MeshForwarder::HandleReceivedFrame(Mac::RxFrame &aFrame)
|
||||
{
|
||||
ThreadLinkInfo linkInfo;
|
||||
Mac::Addresses macAddrs;
|
||||
FrameData frameData;
|
||||
Error error = kErrorNone;
|
||||
Error error = kErrorNone;
|
||||
RxInfo rxInfo;
|
||||
|
||||
VerifyOrExit(mEnabled, error = kErrorInvalidState);
|
||||
|
||||
SuccessOrExit(error = aFrame.GetSrcAddr(macAddrs.mSource));
|
||||
SuccessOrExit(error = aFrame.GetDstAddr(macAddrs.mDestination));
|
||||
rxInfo.mFrameData.Init(aFrame.GetPayload(), aFrame.GetPayloadLength());
|
||||
|
||||
linkInfo.SetFrom(aFrame);
|
||||
SuccessOrExit(error = aFrame.GetSrcAddr(rxInfo.mMacAddrs.mSource));
|
||||
SuccessOrExit(error = aFrame.GetDstAddr(rxInfo.mMacAddrs.mDestination));
|
||||
|
||||
frameData.Init(aFrame.GetPayload(), aFrame.GetPayloadLength());
|
||||
rxInfo.mLinkInfo.SetFrom(aFrame);
|
||||
|
||||
Get<SupervisionListener>().UpdateOnReceive(macAddrs.mSource, linkInfo.IsLinkSecurityEnabled());
|
||||
Get<SupervisionListener>().UpdateOnReceive(rxInfo.mMacAddrs.mSource, rxInfo.IsLinkSecurityEnabled());
|
||||
|
||||
switch (aFrame.GetType())
|
||||
{
|
||||
case Mac::Frame::kTypeData:
|
||||
if (Lowpan::MeshHeader::IsMeshHeader(frameData))
|
||||
if (Lowpan::MeshHeader::IsMeshHeader(rxInfo.mFrameData))
|
||||
{
|
||||
#if OPENTHREAD_FTD
|
||||
HandleMesh(frameData, macAddrs.mSource, linkInfo);
|
||||
HandleMesh(rxInfo);
|
||||
#endif
|
||||
}
|
||||
else if (Lowpan::FragmentHeader::IsFragmentHeader(frameData))
|
||||
else if (Lowpan::FragmentHeader::IsFragmentHeader(rxInfo.mFrameData))
|
||||
{
|
||||
HandleFragment(frameData, macAddrs, linkInfo);
|
||||
HandleFragment(rxInfo);
|
||||
}
|
||||
else if (Lowpan::Lowpan::IsLowpanHc(frameData))
|
||||
else if (Lowpan::Lowpan::IsLowpanHc(rxInfo.mFrameData))
|
||||
{
|
||||
HandleLowpanHC(frameData, macAddrs, linkInfo);
|
||||
HandleLowpanHc(rxInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
VerifyOrExit(frameData.GetLength() == 0, error = kErrorNotLowpanDataFrame);
|
||||
VerifyOrExit(rxInfo.mFrameData.GetLength() == 0, error = kErrorNotLowpanDataFrame);
|
||||
|
||||
LogFrame("Received empty payload frame", aFrame, kErrorNone);
|
||||
}
|
||||
@@ -1431,21 +1429,20 @@ exit:
|
||||
}
|
||||
}
|
||||
|
||||
void MeshForwarder::HandleFragment(FrameData &aFrameData,
|
||||
const Mac::Addresses &aMacAddrs,
|
||||
const ThreadLinkInfo &aLinkInfo)
|
||||
void MeshForwarder::HandleFragment(RxInfo &aRxInfo)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
Lowpan::FragmentHeader fragmentHeader;
|
||||
Message *message = nullptr;
|
||||
|
||||
SuccessOrExit(error = fragmentHeader.ParseFrom(aFrameData));
|
||||
SuccessOrExit(error = fragmentHeader.ParseFrom(aRxInfo.mFrameData));
|
||||
|
||||
#if OPENTHREAD_CONFIG_MULTI_RADIO
|
||||
|
||||
if (aLinkInfo.mLinkSecurity)
|
||||
if (aRxInfo.IsLinkSecurityEnabled())
|
||||
{
|
||||
Neighbor *neighbor = Get<NeighborTable>().FindNeighbor(aMacAddrs.mSource, Neighbor::kInStateAnyExceptInvalid);
|
||||
Neighbor *neighbor =
|
||||
Get<NeighborTable>().FindNeighbor(aRxInfo.GetSrcAddr(), Neighbor::kInStateAnyExceptInvalid);
|
||||
|
||||
if ((neighbor != nullptr) && (fragmentHeader.GetDatagramOffset() == 0))
|
||||
{
|
||||
@@ -1476,22 +1473,22 @@ void MeshForwarder::HandleFragment(FrameData &aFrameData,
|
||||
uint16_t datagramSize = fragmentHeader.GetDatagramSize();
|
||||
|
||||
#if OPENTHREAD_FTD
|
||||
UpdateRoutes(aFrameData, aMacAddrs);
|
||||
UpdateRoutes(aRxInfo);
|
||||
#endif
|
||||
|
||||
SuccessOrExit(error = FrameToMessage(aFrameData, datagramSize, aMacAddrs, message));
|
||||
SuccessOrExit(error = FrameToMessage(aRxInfo, datagramSize, message));
|
||||
|
||||
VerifyOrExit(datagramSize >= message->GetLength(), error = kErrorParse);
|
||||
SuccessOrExit(error = message->SetLength(datagramSize));
|
||||
|
||||
message->SetDatagramTag(fragmentHeader.GetDatagramTag());
|
||||
message->SetTimestampToNow();
|
||||
message->UpdateLinkInfoFrom(aLinkInfo);
|
||||
message->UpdateLinkInfoFrom(aRxInfo.mLinkInfo);
|
||||
|
||||
VerifyOrExit(Get<Ip6::Filter>().Accept(*message), error = kErrorDrop);
|
||||
|
||||
#if OPENTHREAD_FTD
|
||||
SendIcmpErrorIfDstUnreach(*message, aMacAddrs);
|
||||
SendIcmpErrorIfDstUnreach(*message, aRxInfo.mMacAddrs);
|
||||
#endif
|
||||
|
||||
// Allow re-assembly of only one message at a time on a SED by clearing
|
||||
@@ -1515,8 +1512,8 @@ void MeshForwarder::HandleFragment(FrameData &aFrameData,
|
||||
if (msg.GetLength() == fragmentHeader.GetDatagramSize() &&
|
||||
msg.GetDatagramTag() == fragmentHeader.GetDatagramTag() &&
|
||||
msg.GetOffset() == fragmentHeader.GetDatagramOffset() &&
|
||||
msg.GetOffset() + aFrameData.GetLength() <= fragmentHeader.GetDatagramSize() &&
|
||||
msg.IsLinkSecurityEnabled() == aLinkInfo.IsLinkSecurityEnabled())
|
||||
msg.GetOffset() + aRxInfo.mFrameData.GetLength() <= fragmentHeader.GetDatagramSize() &&
|
||||
msg.IsLinkSecurityEnabled() == aRxInfo.IsLinkSecurityEnabled())
|
||||
{
|
||||
message = &msg;
|
||||
break;
|
||||
@@ -1529,17 +1526,17 @@ void MeshForwarder::HandleFragment(FrameData &aFrameData,
|
||||
// message with a new tag. In either case, we can safely clear any
|
||||
// remaining fragments stored in the reassembly list.
|
||||
|
||||
if (!GetRxOnWhenIdle() && (message == nullptr) && aLinkInfo.IsLinkSecurityEnabled())
|
||||
if (!GetRxOnWhenIdle() && (message == nullptr) && aRxInfo.IsLinkSecurityEnabled())
|
||||
{
|
||||
ClearReassemblyList();
|
||||
}
|
||||
|
||||
VerifyOrExit(message != nullptr, error = kErrorDrop);
|
||||
|
||||
message->WriteData(message->GetOffset(), aFrameData);
|
||||
message->MoveOffset(aFrameData.GetLength());
|
||||
message->AddRss(aLinkInfo.GetRss());
|
||||
message->AddLqi(aLinkInfo.GetLqi());
|
||||
message->WriteData(message->GetOffset(), aRxInfo.mFrameData);
|
||||
message->MoveOffset(aRxInfo.mFrameData.GetLength());
|
||||
message->AddRss(aRxInfo.mLinkInfo.GetRss());
|
||||
message->AddLqi(aRxInfo.mLinkInfo.GetLqi());
|
||||
message->SetTimestampToNow();
|
||||
}
|
||||
|
||||
@@ -1550,13 +1547,12 @@ exit:
|
||||
if (message->GetOffset() >= message->GetLength())
|
||||
{
|
||||
mReassemblyList.Dequeue(*message);
|
||||
IgnoreError(HandleDatagram(*message, aMacAddrs.mSource));
|
||||
IgnoreError(HandleDatagram(*message, aRxInfo.GetSrcAddr()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFragmentFrameDrop(error, aFrameData.GetLength(), aMacAddrs, fragmentHeader,
|
||||
aLinkInfo.IsLinkSecurityEnabled());
|
||||
LogFragmentFrameDrop(error, aRxInfo, fragmentHeader);
|
||||
FreeMessage(message);
|
||||
}
|
||||
}
|
||||
@@ -1614,21 +1610,18 @@ bool MeshForwarder::UpdateReassemblyList(void)
|
||||
return mReassemblyList.GetHead() != nullptr;
|
||||
}
|
||||
|
||||
Error MeshForwarder::FrameToMessage(const FrameData &aFrameData,
|
||||
uint16_t aDatagramSize,
|
||||
const Mac::Addresses &aMacAddrs,
|
||||
Message *&aMessage)
|
||||
Error MeshForwarder::FrameToMessage(const RxInfo &aRxInfo, uint16_t aDatagramSize, Message *&aMessage)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
FrameData frameData = aFrameData;
|
||||
FrameData frameData = aRxInfo.mFrameData;
|
||||
Message::Priority priority;
|
||||
|
||||
SuccessOrExit(error = GetFramePriority(frameData, aMacAddrs, priority));
|
||||
SuccessOrExit(error = GetFramePriority(aRxInfo, priority));
|
||||
|
||||
aMessage = Get<MessagePool>().Allocate(Message::kTypeIp6, /* aReserveHeader */ 0, Message::Settings(priority));
|
||||
VerifyOrExit(aMessage, error = kErrorNoBufs);
|
||||
|
||||
SuccessOrExit(error = Get<Lowpan::Lowpan>().Decompress(*aMessage, aMacAddrs, frameData, aDatagramSize));
|
||||
SuccessOrExit(error = Get<Lowpan::Lowpan>().Decompress(*aMessage, aRxInfo.mMacAddrs, frameData, aDatagramSize));
|
||||
|
||||
SuccessOrExit(error = aMessage->AppendData(frameData));
|
||||
aMessage->MoveOffset(frameData.GetLength());
|
||||
@@ -1637,36 +1630,34 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void MeshForwarder::HandleLowpanHC(const FrameData &aFrameData,
|
||||
const Mac::Addresses &aMacAddrs,
|
||||
const ThreadLinkInfo &aLinkInfo)
|
||||
void MeshForwarder::HandleLowpanHc(const RxInfo &aRxInfo)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
Message *message = nullptr;
|
||||
|
||||
#if OPENTHREAD_FTD
|
||||
UpdateRoutes(aFrameData, aMacAddrs);
|
||||
UpdateRoutes(aRxInfo);
|
||||
#endif
|
||||
|
||||
SuccessOrExit(error = FrameToMessage(aFrameData, 0, aMacAddrs, message));
|
||||
SuccessOrExit(error = FrameToMessage(aRxInfo, 0, message));
|
||||
|
||||
message->UpdateLinkInfoFrom(aLinkInfo);
|
||||
message->UpdateLinkInfoFrom(aRxInfo.mLinkInfo);
|
||||
|
||||
VerifyOrExit(Get<Ip6::Filter>().Accept(*message), error = kErrorDrop);
|
||||
|
||||
#if OPENTHREAD_FTD
|
||||
SendIcmpErrorIfDstUnreach(*message, aMacAddrs);
|
||||
SendIcmpErrorIfDstUnreach(*message, aRxInfo.mMacAddrs);
|
||||
#endif
|
||||
|
||||
exit:
|
||||
|
||||
if (error == kErrorNone)
|
||||
{
|
||||
IgnoreError(HandleDatagram(*message, aMacAddrs.mSource));
|
||||
IgnoreError(HandleDatagram(*message, aRxInfo.GetSrcAddr()));
|
||||
}
|
||||
else
|
||||
{
|
||||
LogLowpanHcFrameDrop(error, aFrameData.GetLength(), aMacAddrs, aLinkInfo.IsLinkSecurityEnabled());
|
||||
LogLowpanHcFrameDrop(error, aRxInfo);
|
||||
FreeMessage(message);
|
||||
}
|
||||
}
|
||||
@@ -1690,14 +1681,12 @@ Error MeshForwarder::HandleDatagram(Message &aMessage, const Mac::Address &aMacS
|
||||
return Get<Ip6::Ip6>().HandleDatagram(OwnedPtr<Message>(&aMessage));
|
||||
}
|
||||
|
||||
Error MeshForwarder::GetFramePriority(const FrameData &aFrameData,
|
||||
const Mac::Addresses &aMacAddrs,
|
||||
Message::Priority &aPriority)
|
||||
Error MeshForwarder::GetFramePriority(const RxInfo &aRxInfo, Message::Priority &aPriority)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
Ip6::Headers headers;
|
||||
|
||||
SuccessOrExit(error = headers.DecompressFrom(aFrameData, aMacAddrs, GetInstance()));
|
||||
SuccessOrExit(error = headers.DecompressFrom(aRxInfo.mFrameData, aRxInfo.mMacAddrs, GetInstance()));
|
||||
|
||||
aPriority = Ip6::Ip6::DscpToPriority(headers.GetIp6Header().GetDscp());
|
||||
|
||||
@@ -2025,25 +2014,21 @@ void MeshForwarder::LogFrame(const char *aActionText, const Mac::Frame &aFrame,
|
||||
}
|
||||
|
||||
void MeshForwarder::LogFragmentFrameDrop(Error aError,
|
||||
uint16_t aFrameLength,
|
||||
const Mac::Addresses &aMacAddrs,
|
||||
const Lowpan::FragmentHeader &aFragmentHeader,
|
||||
bool aIsSecure)
|
||||
const RxInfo &aRxInfo,
|
||||
const Lowpan::FragmentHeader &aFragmentHeader)
|
||||
{
|
||||
LogNote("Dropping rx frag frame, error:%s, len:%d, src:%s, dst:%s, tag:%d, offset:%d, dglen:%d, sec:%s",
|
||||
ErrorToString(aError), aFrameLength, aMacAddrs.mSource.ToString().AsCString(),
|
||||
aMacAddrs.mDestination.ToString().AsCString(), aFragmentHeader.GetDatagramTag(),
|
||||
aFragmentHeader.GetDatagramOffset(), aFragmentHeader.GetDatagramSize(), ToYesNo(aIsSecure));
|
||||
ErrorToString(aError), aRxInfo.mFrameData.GetLength(), aRxInfo.GetSrcAddr().ToString().AsCString(),
|
||||
aRxInfo.GetDstAddr().ToString().AsCString(), aFragmentHeader.GetDatagramTag(),
|
||||
aFragmentHeader.GetDatagramOffset(), aFragmentHeader.GetDatagramSize(),
|
||||
ToYesNo(aRxInfo.IsLinkSecurityEnabled()));
|
||||
}
|
||||
|
||||
void MeshForwarder::LogLowpanHcFrameDrop(Error aError,
|
||||
uint16_t aFrameLength,
|
||||
const Mac::Addresses &aMacAddrs,
|
||||
bool aIsSecure)
|
||||
void MeshForwarder::LogLowpanHcFrameDrop(Error aError, const RxInfo &aRxInfo)
|
||||
{
|
||||
LogNote("Dropping rx lowpan HC frame, error:%s, len:%d, src:%s, dst:%s, sec:%s", ErrorToString(aError),
|
||||
aFrameLength, aMacAddrs.mSource.ToString().AsCString(), aMacAddrs.mDestination.ToString().AsCString(),
|
||||
ToYesNo(aIsSecure));
|
||||
aRxInfo.mFrameData.GetLength(), aRxInfo.GetSrcAddr().ToString().AsCString(),
|
||||
aRxInfo.GetDstAddr().ToString().AsCString(), ToYesNo(aRxInfo.IsLinkSecurityEnabled()));
|
||||
}
|
||||
|
||||
#else // #if OT_SHOULD_LOG_AT( OT_LOG_LEVEL_NOTE)
|
||||
@@ -2056,11 +2041,9 @@ void MeshForwarder::LogMessage(MessageAction, const Message &, Error, const Mac:
|
||||
|
||||
void MeshForwarder::LogFrame(const char *, const Mac::Frame &, Error) {}
|
||||
|
||||
void MeshForwarder::LogFragmentFrameDrop(Error, uint16_t, const Mac::Addresses &, const Lowpan::FragmentHeader &, bool)
|
||||
{
|
||||
}
|
||||
void MeshForwarder::LogFragmentFrameDrop(Error, const RxInfo &, const Lowpan::FragmentHeader &) {}
|
||||
|
||||
void MeshForwarder::LogLowpanHcFrameDrop(Error, uint16_t, const Mac::Addresses &, bool) {}
|
||||
void MeshForwarder::LogLowpanHcFrameDrop(Error, const RxInfo &) {}
|
||||
|
||||
#endif // #if OT_SHOULD_LOG_AT( OT_LOG_LEVEL_NOTE)
|
||||
|
||||
|
||||
@@ -411,6 +411,17 @@ private:
|
||||
kAnycastService,
|
||||
};
|
||||
|
||||
struct RxInfo
|
||||
{
|
||||
const Mac::Address &GetSrcAddr(void) const { return mMacAddrs.mSource; }
|
||||
const Mac::Address &GetDstAddr(void) const { return mMacAddrs.mDestination; }
|
||||
bool IsLinkSecurityEnabled(void) const { return mLinkInfo.IsLinkSecurityEnabled(); }
|
||||
|
||||
FrameData mFrameData;
|
||||
ThreadLinkInfo mLinkInfo;
|
||||
Mac::Addresses mMacAddrs;
|
||||
};
|
||||
|
||||
#if OPENTHREAD_FTD
|
||||
class FragmentPriorityList : public Clearable<FragmentPriorityList>
|
||||
{
|
||||
@@ -491,20 +502,17 @@ private:
|
||||
#endif
|
||||
|
||||
void SendIcmpErrorIfDstUnreach(const Message &aMessage, const Mac::Addresses &aMacAddrs);
|
||||
Error CheckReachability(const FrameData &aFrameData, const Mac::Addresses &aMeshAddrs);
|
||||
Error CheckReachability(const RxInfo &aRxInfo);
|
||||
Error CheckReachability(uint16_t aMeshDest, const Ip6::Header &aIp6Header);
|
||||
void UpdateRoutes(const FrameData &aFrameData, const Mac::Addresses &aMeshAddrs);
|
||||
Error FrameToMessage(const FrameData &aFrameData,
|
||||
uint16_t aDatagramSize,
|
||||
const Mac::Addresses &aMacAddrs,
|
||||
Message *&aMessage);
|
||||
void UpdateRoutes(const RxInfo &aRxInfo);
|
||||
Error FrameToMessage(const RxInfo &aRxInfo, uint16_t aDatagramSize, Message *&aMessage);
|
||||
void GetMacDestinationAddress(const Ip6::Address &aIp6Addr, Mac::Address &aMacAddr);
|
||||
void GetMacSourceAddress(const Ip6::Address &aIp6Addr, Mac::Address &aMacAddr);
|
||||
Message *PrepareNextDirectTransmission(void);
|
||||
void HandleMesh(FrameData &aFrameData, const Mac::Address &aMacSource, const ThreadLinkInfo &aLinkInfo);
|
||||
void HandleMesh(RxInfo &aRxInfo);
|
||||
void ResolveRoutingLoops(uint16_t aSourceRloc16, uint16_t aDestRloc16);
|
||||
void HandleFragment(FrameData &aFrameData, const Mac::Addresses &aMacAddrs, const ThreadLinkInfo &aLinkInfo);
|
||||
void HandleLowpanHC(const FrameData &aFrameData, const Mac::Addresses &aMacAddrs, const ThreadLinkInfo &aLinkInfo);
|
||||
void HandleFragment(RxInfo &aRxInfo);
|
||||
void HandleLowpanHc(const RxInfo &aRxInfo);
|
||||
|
||||
void PrepareMacHeaders(Mac::TxFrame &aFrame,
|
||||
Mac::Frame::Type aFrameType,
|
||||
@@ -563,13 +571,11 @@ private:
|
||||
void HandleTimeTick(void);
|
||||
void ScheduleTransmissionTask(void);
|
||||
|
||||
Error GetFramePriority(const FrameData &aFrameData, const Mac::Addresses &aMacAddrs, Message::Priority &aPriority);
|
||||
Error GetFramePriority(const RxInfo &aRxInfo, Message::Priority &aPriority);
|
||||
Error GetFragmentPriority(Lowpan::FragmentHeader &aFragmentHeader,
|
||||
uint16_t aSrcRloc16,
|
||||
Message::Priority &aPriority);
|
||||
void GetForwardFramePriority(const FrameData &aFrameData,
|
||||
const Mac::Addresses &aMeshAddrs,
|
||||
Message::Priority &aPriority);
|
||||
void GetForwardFramePriority(const RxInfo &aRxInfo, Message::Priority &aPriority);
|
||||
|
||||
bool CalcIePresent(const Message *aMessage);
|
||||
Mac::Frame::Version CalcFrameVersion(const Neighbor *aNeighbor, bool aIePresent) const;
|
||||
@@ -588,12 +594,8 @@ private:
|
||||
void LogMessage(MessageAction aAction, const Message &aMessage, Error aError);
|
||||
void LogMessage(MessageAction aAction, const Message &aMessage, Error aError, const Mac::Address *aAddress);
|
||||
void LogFrame(const char *aActionText, const Mac::Frame &aFrame, Error aError);
|
||||
void LogFragmentFrameDrop(Error aError,
|
||||
uint16_t aFrameLength,
|
||||
const Mac::Addresses &aMacAddrs,
|
||||
const Lowpan::FragmentHeader &aFragmentHeader,
|
||||
bool aIsSecure);
|
||||
void LogLowpanHcFrameDrop(Error aError, uint16_t aFrameLength, const Mac::Addresses &aMacAddrs, bool aIsSecure);
|
||||
void LogFragmentFrameDrop(Error aError, const RxInfo &aRxInfo, const Lowpan::FragmentHeader &aFragmentHeader);
|
||||
void LogLowpanHcFrameDrop(Error aError, const RxInfo &aRxInfo);
|
||||
|
||||
#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_NOTE)
|
||||
const char *MessageActionToString(MessageAction aAction, Error aError);
|
||||
|
||||
@@ -641,12 +641,12 @@ exit:
|
||||
return;
|
||||
}
|
||||
|
||||
Error MeshForwarder::CheckReachability(const FrameData &aFrameData, const Mac::Addresses &aMeshAddrs)
|
||||
Error MeshForwarder::CheckReachability(const RxInfo &aRxInfo)
|
||||
{
|
||||
Error error;
|
||||
Ip6::Headers ip6Headers;
|
||||
|
||||
error = ip6Headers.DecompressFrom(aFrameData, aMeshAddrs, GetInstance());
|
||||
error = ip6Headers.DecompressFrom(aRxInfo.mFrameData, aRxInfo.mMacAddrs, GetInstance());
|
||||
|
||||
switch (error)
|
||||
{
|
||||
@@ -660,11 +660,11 @@ Error MeshForwarder::CheckReachability(const FrameData &aFrameData, const Mac::A
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
error = CheckReachability(aMeshAddrs.mDestination.GetShort(), ip6Headers.GetIp6Header());
|
||||
error = CheckReachability(aRxInfo.GetDstAddr().GetShort(), ip6Headers.GetIp6Header());
|
||||
|
||||
if (error == kErrorNoRoute)
|
||||
{
|
||||
SendDestinationUnreachable(aMeshAddrs.mSource.GetShort(), ip6Headers);
|
||||
SendDestinationUnreachable(aRxInfo.GetSrcAddr().GetShort(), ip6Headers);
|
||||
}
|
||||
|
||||
exit:
|
||||
@@ -718,32 +718,36 @@ void MeshForwarder::SendDestinationUnreachable(uint16_t aMeshSource, const Ip6::
|
||||
Ip6::Icmp::Header::kCodeDstUnreachNoRoute, messageInfo, aIp6Headers));
|
||||
}
|
||||
|
||||
void MeshForwarder::HandleMesh(FrameData &aFrameData, const Mac::Address &aMacSource, const ThreadLinkInfo &aLinkInfo)
|
||||
void MeshForwarder::HandleMesh(RxInfo &aRxInfo)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
Mac::Addresses meshAddrs;
|
||||
Lowpan::MeshHeader meshHeader;
|
||||
Mac::Address neighborMacSource;
|
||||
|
||||
// Security Check: only process Mesh Header frames that had security enabled.
|
||||
VerifyOrExit(aLinkInfo.IsLinkSecurityEnabled(), error = kErrorSecurity);
|
||||
VerifyOrExit(aRxInfo.IsLinkSecurityEnabled(), error = kErrorSecurity);
|
||||
|
||||
SuccessOrExit(error = meshHeader.ParseFrom(aFrameData));
|
||||
SuccessOrExit(error = meshHeader.ParseFrom(aRxInfo.mFrameData));
|
||||
|
||||
meshAddrs.mSource.SetShort(meshHeader.GetSource());
|
||||
meshAddrs.mDestination.SetShort(meshHeader.GetDestination());
|
||||
neighborMacSource = aRxInfo.GetSrcAddr();
|
||||
|
||||
UpdateRoutes(aFrameData, meshAddrs);
|
||||
// Switch the `aRxInfo.mMacAddrs` to the mesh header source/destination
|
||||
|
||||
if (Get<Mle::Mle>().HasRloc16(meshAddrs.mDestination.GetShort()) ||
|
||||
Get<ChildTable>().HasMinimalChild(meshAddrs.mDestination.GetShort()))
|
||||
aRxInfo.mMacAddrs.mSource.SetShort(meshHeader.GetSource());
|
||||
aRxInfo.mMacAddrs.mDestination.SetShort(meshHeader.GetDestination());
|
||||
|
||||
UpdateRoutes(aRxInfo);
|
||||
|
||||
if (Get<Mle::Mle>().HasRloc16(aRxInfo.GetDstAddr().GetShort()) ||
|
||||
Get<ChildTable>().HasMinimalChild(aRxInfo.GetDstAddr().GetShort()))
|
||||
{
|
||||
if (Lowpan::FragmentHeader::IsFragmentHeader(aFrameData))
|
||||
if (Lowpan::FragmentHeader::IsFragmentHeader(aRxInfo.mFrameData))
|
||||
{
|
||||
HandleFragment(aFrameData, meshAddrs, aLinkInfo);
|
||||
HandleFragment(aRxInfo);
|
||||
}
|
||||
else if (Lowpan::Lowpan::IsLowpanHc(aFrameData))
|
||||
else if (Lowpan::Lowpan::IsLowpanHc(aRxInfo.mFrameData))
|
||||
{
|
||||
HandleLowpanHC(aFrameData, meshAddrs, aLinkInfo);
|
||||
HandleLowpanHc(aRxInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -755,23 +759,23 @@ void MeshForwarder::HandleMesh(FrameData &aFrameData, const Mac::Address &aMacSo
|
||||
OwnedPtr<Message> messagePtr;
|
||||
Message::Priority priority = Message::kPriorityNormal;
|
||||
|
||||
ResolveRoutingLoops(aMacSource.GetShort(), meshAddrs.mDestination.GetShort());
|
||||
ResolveRoutingLoops(neighborMacSource.GetShort(), aRxInfo.GetDstAddr().GetShort());
|
||||
|
||||
SuccessOrExit(error = CheckReachability(aFrameData, meshAddrs));
|
||||
SuccessOrExit(error = CheckReachability(aRxInfo));
|
||||
|
||||
meshHeader.DecrementHopsLeft();
|
||||
|
||||
GetForwardFramePriority(aFrameData, meshAddrs, priority);
|
||||
GetForwardFramePriority(aRxInfo, priority);
|
||||
messagePtr.Reset(
|
||||
Get<MessagePool>().Allocate(Message::kType6lowpan, /* aReserveHeader */ 0, Message::Settings(priority)));
|
||||
VerifyOrExit(messagePtr != nullptr, error = kErrorNoBufs);
|
||||
|
||||
SuccessOrExit(error = meshHeader.AppendTo(*messagePtr));
|
||||
SuccessOrExit(error = messagePtr->AppendData(aFrameData));
|
||||
SuccessOrExit(error = messagePtr->AppendData(aRxInfo.mFrameData));
|
||||
|
||||
messagePtr->UpdateLinkInfoFrom(aLinkInfo);
|
||||
messagePtr->UpdateLinkInfoFrom(aRxInfo.mLinkInfo);
|
||||
|
||||
LogMessage(kMessageReceive, *messagePtr, kErrorNone, &aMacSource);
|
||||
LogMessage(kMessageReceive, *messagePtr, kErrorNone, &neighborMacSource);
|
||||
|
||||
#if OPENTHREAD_CONFIG_MULTI_RADIO
|
||||
// Since the message will be forwarded, we clear the radio
|
||||
@@ -789,7 +793,8 @@ exit:
|
||||
if (error != kErrorNone)
|
||||
{
|
||||
LogInfo("Dropping rx mesh frame, error:%s, len:%d, src:%s, sec:%s", ErrorToString(error),
|
||||
aFrameData.GetLength(), aMacSource.ToString().AsCString(), ToYesNo(aLinkInfo.IsLinkSecurityEnabled()));
|
||||
aRxInfo.mFrameData.GetLength(), neighborMacSource.ToString().AsCString(),
|
||||
ToYesNo(aRxInfo.IsLinkSecurityEnabled()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -814,14 +819,14 @@ exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void MeshForwarder::UpdateRoutes(const FrameData &aFrameData, const Mac::Addresses &aMeshAddrs)
|
||||
void MeshForwarder::UpdateRoutes(const RxInfo &aRxInfo)
|
||||
{
|
||||
Ip6::Headers ip6Headers;
|
||||
Neighbor *neighbor;
|
||||
|
||||
VerifyOrExit(!aMeshAddrs.mDestination.IsBroadcast() && aMeshAddrs.mSource.IsShort());
|
||||
VerifyOrExit(!aRxInfo.GetDstAddr().IsBroadcast() && aRxInfo.GetSrcAddr().IsShort());
|
||||
|
||||
SuccessOrExit(ip6Headers.DecompressFrom(aFrameData, aMeshAddrs, GetInstance()));
|
||||
SuccessOrExit(ip6Headers.DecompressFrom(aRxInfo.mFrameData, aRxInfo.mMacAddrs, GetInstance()));
|
||||
|
||||
if (!ip6Headers.GetSourceAddress().GetIid().IsLocator() &&
|
||||
Get<NetworkData::Leader>().IsOnMesh(ip6Headers.GetSourceAddress()))
|
||||
@@ -830,14 +835,14 @@ void MeshForwarder::UpdateRoutes(const FrameData &aFrameData, const Mac::Address
|
||||
// inspecting packets being received only for on mesh
|
||||
// addresses.
|
||||
|
||||
Get<AddressResolver>().UpdateSnoopedCacheEntry(ip6Headers.GetSourceAddress(), aMeshAddrs.mSource.GetShort(),
|
||||
aMeshAddrs.mDestination.GetShort());
|
||||
Get<AddressResolver>().UpdateSnoopedCacheEntry(ip6Headers.GetSourceAddress(), aRxInfo.GetSrcAddr().GetShort(),
|
||||
aRxInfo.GetDstAddr().GetShort());
|
||||
}
|
||||
|
||||
neighbor = Get<NeighborTable>().FindNeighbor(ip6Headers.GetSourceAddress());
|
||||
VerifyOrExit(neighbor != nullptr && !neighbor->IsFullThreadDevice());
|
||||
|
||||
if (!Get<Mle::Mle>().HasMatchingRouterIdWith(aMeshAddrs.mSource.GetShort()))
|
||||
if (!Get<Mle::Mle>().HasMatchingRouterIdWith(aRxInfo.GetSrcAddr().GetShort()))
|
||||
{
|
||||
Get<Mle::MleRouter>().RemoveNeighbor(*neighbor);
|
||||
}
|
||||
@@ -960,39 +965,38 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void MeshForwarder::GetForwardFramePriority(const FrameData &aFrameData,
|
||||
const Mac::Addresses &aMeshAddrs,
|
||||
Message::Priority &aPriority)
|
||||
void MeshForwarder::GetForwardFramePriority(const RxInfo &aRxInfo, Message::Priority &aPriority)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
FrameData frameData = aFrameData;
|
||||
RxInfo rxInfo = aRxInfo;
|
||||
bool isFragment = false;
|
||||
Lowpan::FragmentHeader fragmentHeader;
|
||||
|
||||
if (fragmentHeader.ParseFrom(frameData) == kErrorNone)
|
||||
if (fragmentHeader.ParseFrom(rxInfo.mFrameData) == kErrorNone)
|
||||
{
|
||||
isFragment = true;
|
||||
|
||||
if (fragmentHeader.GetDatagramOffset() > 0)
|
||||
{
|
||||
// Get priority from the pre-buffered info
|
||||
ExitNow(error = GetFragmentPriority(fragmentHeader, aMeshAddrs.mSource.GetShort(), aPriority));
|
||||
ExitNow(error = GetFragmentPriority(fragmentHeader, rxInfo.GetSrcAddr().GetShort(), aPriority));
|
||||
}
|
||||
}
|
||||
|
||||
// Get priority from IPv6 header or UDP destination port directly
|
||||
error = GetFramePriority(frameData, aMeshAddrs, aPriority);
|
||||
error = GetFramePriority(rxInfo, aPriority);
|
||||
|
||||
exit:
|
||||
if (error != kErrorNone)
|
||||
{
|
||||
LogNote("Failed to get forwarded frame priority, error:%s, len:%d, src:%s, dst:%s", ErrorToString(error),
|
||||
frameData.GetLength(), aMeshAddrs.mSource.ToString().AsCString(),
|
||||
aMeshAddrs.mDestination.ToString().AsCString());
|
||||
rxInfo.mFrameData.GetLength(), rxInfo.GetSrcAddr().ToString().AsCString(),
|
||||
rxInfo.GetDstAddr().ToString().AsCString());
|
||||
}
|
||||
else if (isFragment)
|
||||
{
|
||||
UpdateFragmentPriority(fragmentHeader, frameData.GetLength(), aMeshAddrs.mSource.GetShort(), aPriority);
|
||||
UpdateFragmentPriority(fragmentHeader, rxInfo.mFrameData.GetLength(), rxInfo.GetSrcAddr().GetShort(),
|
||||
aPriority);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user