mirror of
https://github.com/espressif/openthread.git
synced 2026-08-12 13:47:47 +00:00
[routing-manager] ignore checksum in RA hash calculation (#10230)
This commit modifies the `CalculateHash()` method to use a zero checksum value for RA (ICMPv6) header for both received and emitted RA message. In prepared RA messages, the checksum is always set to zero, and the platform layer is responsible for calculating and updating it. For a received RA, while platforms typically zero out the checksum after validation, this behavior isn't explicitly required by `otPlatInfraIf` APIs. By ignoring the checksum(setting it to zero) during hash calculation, this change ensures correct calculation regardless of platform behavior. This commit also updates `test_routing_manager` to intentionally modify the checksum field in an emitted RA message before passing it back to the OT stack. This validates the updated hash calculation behavior.
This commit is contained in:
@@ -3503,10 +3503,10 @@ void RoutingManager::RaInfo::IncrementTxCountAndSaveHash(const InfraIf::Icmp6Pac
|
||||
mLastHashIndex = 0;
|
||||
}
|
||||
|
||||
CalculateHash(aRaMessage, mHashes[mLastHashIndex]);
|
||||
CalculateHash(RouterAdvert::RxMessage(aRaMessage), mHashes[mLastHashIndex]);
|
||||
}
|
||||
|
||||
bool RoutingManager::RaInfo::IsRaFromManager(const Ip6::Nd::RouterAdvert::RxMessage &aRaMessage) const
|
||||
bool RoutingManager::RaInfo::IsRaFromManager(const RouterAdvert::RxMessage &aRaMessage) const
|
||||
{
|
||||
// Determines whether or not a received RA message was prepared by
|
||||
// by `RoutingManager` itself (is present in the saved `mHashes`).
|
||||
@@ -3516,7 +3516,7 @@ bool RoutingManager::RaInfo::IsRaFromManager(const Ip6::Nd::RouterAdvert::RxMess
|
||||
uint32_t count = Min<uint32_t>(mTxCount, kNumHashEntries);
|
||||
Hash hash;
|
||||
|
||||
CalculateHash(aRaMessage.GetAsPacket(), hash);
|
||||
CalculateHash(aRaMessage, hash);
|
||||
|
||||
for (; count > 0; count--)
|
||||
{
|
||||
@@ -3541,12 +3541,17 @@ bool RoutingManager::RaInfo::IsRaFromManager(const Ip6::Nd::RouterAdvert::RxMess
|
||||
return isFromManager;
|
||||
}
|
||||
|
||||
void RoutingManager::RaInfo::CalculateHash(const InfraIf::Icmp6Packet &aRaMessage, Hash &aHash)
|
||||
void RoutingManager::RaInfo::CalculateHash(const RouterAdvert::RxMessage &aRaMessage, Hash &aHash)
|
||||
{
|
||||
Crypto::Sha256 sha256;
|
||||
RouterAdvert::Header header;
|
||||
Crypto::Sha256 sha256;
|
||||
|
||||
header = aRaMessage.GetHeader();
|
||||
header.SetChecksum(0);
|
||||
|
||||
sha256.Start();
|
||||
sha256.Update(aRaMessage.GetBytes(), aRaMessage.GetLength());
|
||||
sha256.Update(header);
|
||||
sha256.Update(aRaMessage.GetOptionStart(), aRaMessage.GetOptionLength());
|
||||
sha256.Finish(aHash);
|
||||
}
|
||||
|
||||
|
||||
@@ -1259,8 +1259,8 @@ private:
|
||||
}
|
||||
|
||||
void IncrementTxCountAndSaveHash(const InfraIf::Icmp6Packet &aRaMessage);
|
||||
bool IsRaFromManager(const Ip6::Nd::RouterAdvert::RxMessage &aRaMessage) const;
|
||||
static void CalculateHash(const InfraIf::Icmp6Packet &aRaMessage, Hash &aHash);
|
||||
bool IsRaFromManager(const RouterAdvert::RxMessage &aRaMessage) const;
|
||||
static void CalculateHash(const RouterAdvert::RxMessage &aRaMessage, Hash &aHash);
|
||||
|
||||
RouterAdvert::Header mHeader;
|
||||
TimeMilli mHeaderUpdateTime;
|
||||
|
||||
+16
-1
@@ -729,6 +729,22 @@ public:
|
||||
*/
|
||||
bool ContainsAnyOptions(void) const { return (mData.GetLength() > sizeof(Header)); }
|
||||
|
||||
/**
|
||||
* Returns pointer to the start of option bytes (after header).
|
||||
*
|
||||
* @returns Pointer to start of options.
|
||||
*
|
||||
*/
|
||||
const uint8_t *GetOptionStart(void) const { return (mData.GetBytes() + sizeof(Header)); }
|
||||
|
||||
/**
|
||||
* Gets the length (number of bytes) of options.
|
||||
*
|
||||
* @returns Number of bytes after header specifying RA options.
|
||||
*
|
||||
*/
|
||||
uint16_t GetOptionLength(void) const { return ContainsAnyOptions() ? mData.GetLength() - sizeof(Header) : 0; }
|
||||
|
||||
// The following methods are intended to support range-based `for`
|
||||
// loop iteration over `Option`s in the RA message.
|
||||
|
||||
@@ -736,7 +752,6 @@ public:
|
||||
Option::Iterator end(void) const { return Option::Iterator(); }
|
||||
|
||||
private:
|
||||
const uint8_t *GetOptionStart(void) const { return (mData.GetBytes() + sizeof(Header)); }
|
||||
const uint8_t *GetDataEnd(void) const { return mData.GetBytes() + mData.GetLength(); }
|
||||
|
||||
Data<kWithUint16Length> mData;
|
||||
|
||||
@@ -295,7 +295,8 @@ otError otPlatInfraIfSendIcmp6Nd(uint32_t aInfraIfIndex,
|
||||
const uint8_t *aBuffer,
|
||||
uint16_t aBufferLength)
|
||||
{
|
||||
Icmp6Packet packet;
|
||||
Icmp6Packet packet;
|
||||
Ip6::Icmp::Header *header;
|
||||
|
||||
Log("otPlatInfraIfSendIcmp6Nd(aDestAddr: %s, aBufferLength:%u)", AsCoreType(aDestAddress).ToString().AsCString(),
|
||||
aBufferLength);
|
||||
@@ -306,7 +307,9 @@ otError otPlatInfraIfSendIcmp6Nd(uint32_t aInfraIfIndex,
|
||||
|
||||
VerifyOrQuit(aBufferLength >= sizeof(Ip6::Icmp::Header));
|
||||
|
||||
switch (reinterpret_cast<const Ip6::Icmp::Header *>(aBuffer)->GetType())
|
||||
header = reinterpret_cast<Ip6::Icmp::Header *>(const_cast<uint8_t *>(aBuffer));
|
||||
|
||||
switch (header->GetType())
|
||||
{
|
||||
case Ip6::Icmp::Header::kTypeRouterSolicit:
|
||||
Log(" Router Solicit message");
|
||||
@@ -317,6 +320,9 @@ otError otPlatInfraIfSendIcmp6Nd(uint32_t aInfraIfIndex,
|
||||
Log(" Router Advertisement message");
|
||||
LogRouterAdvert(packet);
|
||||
ValidateRouterAdvert(packet);
|
||||
// Intentionally modify the checksum field in RA Header
|
||||
// before passing it back to the OT stack.
|
||||
header->SetChecksum(0x1234);
|
||||
otPlatInfraIfRecvIcmp6Nd(sInstance, kInfraIfIndex, &sInfraIfAddress, aBuffer, aBufferLength);
|
||||
break;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user