[mle] handle received Advertisements from RxOnlyNeighbor on FED (#9484)

This commit updates `Mle` class such that on an FED (FTD child) when
an MLE message is received, we use `FindRxOnlyNeighborRouter()` in
addition to `FindNeighbor()` before performing security check. This
ensures that the key sequence and frame counters are validated for
messages from a rx-only neighbor router.

After security check and before calling `Handle{MleCommand}()` we
clear the `neighbor` if it is a rx-only except for a subset of MLE
messages such as MLE Advertisement. This ensures that, as an FED, we
are selective about which messages to process from rx-only
neighbors.

This commit also adds a new flavor of `FindRxOnlyNeighborRouter()`
that accepts an `Mac::ExtAddress` as its input parameter.
This commit is contained in:
Abtin Keshavarzian
2023-10-04 21:57:07 -07:00
committed by GitHub
parent 4e52d85dff
commit a363396eb5
4 changed files with 61 additions and 8 deletions
+2 -8
View File
@@ -324,15 +324,9 @@ Interface::Peer *Interface::GetNewPeerEntry(void)
}
#if OPENTHREAD_FTD
if (Get<NeighborTable>().FindRxOnlyNeighborRouter(entry.GetExtAddress()) != nullptr)
{
Mac::Address macAddress;
macAddress.SetExtended(entry.GetExtAddress());
if (Get<NeighborTable>().FindRxOnlyNeighborRouter(macAddress) != nullptr)
{
continue;
}
continue;
}
#endif
+39
View File
@@ -2464,6 +2464,9 @@ void Mle::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageIn
Mac::ExtAddress extAddr;
uint8_t command;
Neighbor *neighbor;
#if OPENTHREAD_FTD
bool isNeighborRxOnly = false;
#endif
LogDebg("Receive MLE message");
@@ -2517,6 +2520,18 @@ void Mle::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageIn
neighbor = (command == kCommandChildIdResponse) ? mNeighborTable.FindParent(extAddr)
: mNeighborTable.FindNeighbor(extAddr);
#if OPENTHREAD_FTD
if (neighbor == nullptr)
{
// As an FED, we may have rx-only neighbors. We find and set
// `neighbor` to perform security processing (frame counter
// and key sequence checks) for messages from such neighbors.
neighbor = mNeighborTable.FindRxOnlyNeighborRouter(extAddr);
isNeighborRxOnly = true;
}
#endif
if (neighbor != nullptr && neighbor->IsStateValid())
{
if (keySequence == neighbor->GetKeySequence())
@@ -2564,6 +2579,30 @@ void Mle::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageIn
}
#endif
#if OPENTHREAD_FTD
if (isNeighborRxOnly)
{
// Clear the `neighbor` if it is a rx-only one before calling
// `Handle{Msg}()`, except for a subset of MLE messages such
// as MLE Advertisement. This ensures that, as an FED, we are
// selective about which messages to process from rx-only
// neighbors.
switch (command)
{
case kCommandAdvertisement:
case kCommandLinkRequest:
case kCommandLinkAccept:
case kCommandLinkAcceptAndRequest:
break;
default:
neighbor = nullptr;
break;
}
}
#endif
rxInfo.mKeySequence = keySequence;
rxInfo.mFrameCounter = frameCounter;
rxInfo.mNeighbor = neighbor;
+9
View File
@@ -167,6 +167,15 @@ exit:
return neighbor;
}
Neighbor *NeighborTable::FindRxOnlyNeighborRouter(const Mac::ExtAddress &aExtAddress)
{
Mac::Address macAddress;
macAddress.SetExtended(aExtAddress);
return FindRxOnlyNeighborRouter(macAddress);
}
Neighbor *NeighborTable::FindRxOnlyNeighborRouter(const Mac::Address &aMacAddress)
{
Neighbor *neighbor = nullptr;
+11
View File
@@ -177,6 +177,17 @@ public:
Neighbor *FindNeighbor(const Ip6::Address &aIp6Address,
Neighbor::StateFilter aFilter = Neighbor::kInStateValidOrRestoring);
/**
* Searches in the neighbor table to find a `Neighbor` for which a one-way link is maintained (as in the
* case of an FTD child with neighbor routers).
*
* @param[in] aExtAddress An Extended address.
*
* @returns A pointer to the Neighbor corresponding to @p aExtAddress, `nullptr` otherwise.
*
*/
Neighbor *FindRxOnlyNeighborRouter(const Mac::ExtAddress &aExtAddress);
/**
* Searches in the neighbor table to find a `Neighbor` for which a one-way link is maintained (as in the
* case of an FTD child with neighbor routers).