[router-advert] RouterAdvMessage to provide default router prf (#7720)

This commit updates and simplifies `RouterAdvMessage`:
- Adds new method to get and set the "default router preference"
- Removes custom overloads of operator `=` and `==` (which
  excluded the checksum field). Instead when we save a received RA
  in `RoutingManager` we directly set the checksum to zero so the
  normal (byte by byte) comparison would properly check all fields.
This commit is contained in:
Abtin Keshavarzian
2022-05-20 11:16:04 -07:00
committed by GitHub
parent 36b2a173f9
commit bffbebc646
3 changed files with 62 additions and 62 deletions
+13 -18
View File
@@ -112,7 +112,7 @@ void RouteInfoOption::SetPreference(RoutePreference aPreference)
mResvdPrf |= (NetworkData::RoutePreferenceToValue(aPreference) << kPreferenceOffset) & kPreferenceMask; mResvdPrf |= (NetworkData::RoutePreferenceToValue(aPreference) << kPreferenceOffset) & kPreferenceMask;
} }
RouteInfoOption::RoutePreference RouteInfoOption::GetPreference(void) const RoutePreference RouteInfoOption::GetPreference(void) const
{ {
return NetworkData::RoutePreferenceFromValue((mResvdPrf & kPreferenceMask) >> kPreferenceOffset); return NetworkData::RoutePreferenceFromValue((mResvdPrf & kPreferenceMask) >> kPreferenceOffset);
} }
@@ -171,29 +171,24 @@ uint8_t RouteInfoOption::OptionLengthForPrefix(uint8_t aPrefixLength)
void RouterAdvMessage::SetToDefault(void) void RouterAdvMessage::SetToDefault(void)
{ {
mHeader.Clear(); OT_UNUSED_VARIABLE(mCode);
mHeader.SetType(Ip6::Icmp::Header::kTypeRouterAdvert); OT_UNUSED_VARIABLE(mCurHopLimit);
mReachableTime = 0; OT_UNUSED_VARIABLE(mReachableTime);
mRetransTimer = 0; OT_UNUSED_VARIABLE(mRetransTimer);
Clear();
mType = Ip6::Icmp::Header::kTypeRouterAdvert;
} }
const RouterAdvMessage &RouterAdvMessage::operator=(const RouterAdvMessage &aOther) RoutePreference RouterAdvMessage::GetDefaultRouterPreference(void) const
{ {
mHeader = aOther.mHeader; return NetworkData::RoutePreferenceFromValue((mFlags & kPreferenceMask) >> kPreferenceOffset);
// Set zero value and let platform do the calculation.
mHeader.SetChecksum(0);
mReachableTime = aOther.mReachableTime;
mRetransTimer = aOther.mRetransTimer;
return *this;
} }
bool RouterAdvMessage::operator==(const RouterAdvMessage &aOther) const void RouterAdvMessage::SetDefaultRouterPreference(RoutePreference aPreference)
{ {
return memcmp(&mHeader.mData, &aOther.mHeader.mData, sizeof(mHeader.mData)) == 0 && mFlags &= ~kPreferenceMask;
mReachableTime == aOther.mReachableTime && mRetransTimer == aOther.mRetransTimer; mFlags |= (NetworkData::RoutePreferenceToValue(aPreference) << kPreferenceOffset) & kPreferenceMask;
} }
//---------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------
+42 -43
View File
@@ -60,6 +60,8 @@ namespace ot {
namespace BorderRouter { namespace BorderRouter {
namespace RouterAdv { namespace RouterAdv {
typedef NetworkData::RoutePreference RoutePreference; ///< Route Preference
/** /**
* This class represents the variable length options in Neighbor Discovery messages. * This class represents the variable length options in Neighbor Discovery messages.
* *
@@ -324,8 +326,6 @@ public:
static constexpr uint16_t kMinSize = kLengthUnit; ///< Minimum size (in bytes) of a Route Info Option static constexpr uint16_t kMinSize = kLengthUnit; ///< Minimum size (in bytes) of a Route Info Option
static constexpr Type kType = Type::kRouteInfo; ///< Route Information Option Type. static constexpr Type kType = Type::kRouteInfo; ///< Route Information Option Type.
typedef NetworkData::RoutePreference RoutePreference; ///< Route Preference
/** /**
* This method initializes the option setting the type and clearing (setting to zero) all other fields. * This method initializes the option setting the type and clearing (setting to zero) all other fields.
* *
@@ -447,14 +447,13 @@ private:
static_assert(sizeof(RouteInfoOption) == 8, "invalid RouteInfoOption structure"); static_assert(sizeof(RouteInfoOption) == 8, "invalid RouteInfoOption structure");
/** /**
* This class implements the Router Advertisement message. * This class implements the Router Advertisement message header.
* *
* See section 4.2 of RFC 4861 for definition of this message. * See section 2.2 of RFC 4191 [https://datatracker.ietf.org/doc/html/rfc4191]
* https://tools.ietf.org/html/rfc4861#section-4.2
* *
*/ */
OT_TOOL_PACKED_BEGIN OT_TOOL_PACKED_BEGIN
class RouterAdvMessage : public Unequatable<RouterAdvMessage> class RouterAdvMessage : public Equatable<RouterAdvMessage>, private Clearable<RouterAdvMessage>
{ {
public: public:
/** /**
@@ -476,70 +475,70 @@ public:
* @param[in] aChecksum The checksum value. * @param[in] aChecksum The checksum value.
* *
*/ */
void SetChecksum(uint16_t aChecksum) { mHeader.SetChecksum(aChecksum); } void SetChecksum(uint16_t aChecksum) { mChecksum = HostSwap16(aChecksum); }
/** /**
* This method sets the Router Lifetime in seconds. * This method sets the Router Lifetime in seconds.
* *
* Zero Router Lifetime means we are not a default router.
*
* @param[in] aRouterLifetime The router lifetime in seconds. * @param[in] aRouterLifetime The router lifetime in seconds.
* *
*/ */
void SetRouterLifetime(uint16_t aRouterLifetime) void SetRouterLifetime(uint16_t aRouterLifetime) { mRouterLifetime = HostSwap16(aRouterLifetime); }
{
mHeader.mData.m16[kRouteLifetimeIdx] = HostSwap16(aRouterLifetime);
}
/** /**
* This method returns the Router Lifetime. * This method gets the Router Lifetime (in seconds).
* *
* Zero Router Lifetime means we are not a default router. * Router Lifetime set to zero indicates that the sender is not a default router.
* *
* @returns The router lifetime in seconds. * @returns The router lifetime in seconds.
* *
*/ */
uint16_t GetRouterLifetime(void) const { return HostSwap16(mHeader.mData.m16[kRouteLifetimeIdx]); } uint16_t GetRouterLifetime(void) const { return HostSwap16(mRouterLifetime); }
/** /**
* This method returns the Managed Address Configuration ('m') flag. * This method sets the default router preference.
* *
* @returns A boolean which indicates whether the 'm' flag is set. * @param[in] aPreference The router preference.
* *
*/ */
bool GetManagedAddrConfig(void) const { return (mHeader.mData.m8[kReservedIdx] & kManagedAddressConfigMask) != 0; } void SetDefaultRouterPreference(RoutePreference aPreference);
/** /**
* This method overloads the assignment operator. * This method gets the default router preference.
*
* @returns The router preference.
* *
*/ */
const RouterAdvMessage &operator=(const RouterAdvMessage &aOther); RoutePreference GetDefaultRouterPreference(void) const;
/**
* This method overloads operator `==` to evaluate whether or not
* two instances of `RouterAdvMessage` are equal.
*
* @param[in] aOther The other `RouterAdvMessage` instance to compare with.
*
* @retval TRUE If the two `RouterAdvMessage` instances are equal.
* @retval FALSE If the two `RouterAdvMessage` instances are not equal.
*
*/
bool operator==(const RouterAdvMessage &aOther) const;
private: private:
// The index of Route Lifetime in ICMPv6 Header Data. In unit of 2 octets. // Router Advertisement Message
static constexpr uint8_t kRouteLifetimeIdx = 1; //
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Type | Code | Checksum |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Cur Hop Limit |M|O|H|Prf|Resvd| Router Lifetime |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Reachable Time |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Retrans Timer |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Options ...
// +-+-+-+-+-+-+-+-+-+-+-+-
// The index of Reserved byte in ICMPv6 Header Data. In unit of 1 octet. static constexpr uint8_t kPreferenceOffset = 3;
static constexpr uint8_t kReservedIdx = 1; static constexpr uint8_t kPreferenceMask = 3 << kPreferenceOffset;
// The bitmask of the Managed Address Configuration ('m') flag. uint8_t mType;
static constexpr uint8_t kManagedAddressConfigMask = 0x80; uint8_t mCode;
uint16_t mChecksum;
Ip6::Icmp::Header mHeader; // The common ICMPv6 header. uint8_t mCurHopLimit;
uint32_t mReachableTime; // The reachable time. In milliseconds. uint8_t mFlags;
uint32_t mRetransTimer; // The retransmission timer. In milliseconds. uint16_t mRouterLifetime;
uint32_t mReachableTime;
uint32_t mRetransTimer;
} OT_TOOL_PACKED_END; } OT_TOOL_PACKED_END;
static_assert(sizeof(RouterAdvMessage) == 16, "invalid RouterAdvMessage structure"); static_assert(sizeof(RouterAdvMessage) == 16, "invalid RouterAdvMessage structure");
+7 -1
View File
@@ -1455,6 +1455,7 @@ bool RoutingManager::UpdateRouterAdvMessage(const RouterAdv::RouterAdvMessage *a
oldRouterAdvMessage = mRouterAdvMessage; oldRouterAdvMessage = mRouterAdvMessage;
mTimeRouterAdvMessageLastUpdate = TimerMilli::GetNow(); mTimeRouterAdvMessageLastUpdate = TimerMilli::GetNow();
if (aRouterAdvMessage == nullptr || aRouterAdvMessage->GetRouterLifetime() == 0) if (aRouterAdvMessage == nullptr || aRouterAdvMessage->GetRouterLifetime() == 0)
{ {
mRouterAdvMessage.SetToDefault(); mRouterAdvMessage.SetToDefault();
@@ -1462,7 +1463,12 @@ bool RoutingManager::UpdateRouterAdvMessage(const RouterAdv::RouterAdvMessage *a
} }
else else
{ {
mRouterAdvMessage = *aRouterAdvMessage; // The checksum is set to zero in `mRouterAdvMessage`
// which indicates to platform that it needs to do the
// calculation and update it.
mRouterAdvMessage = *aRouterAdvMessage;
mRouterAdvMessage.SetChecksum(0);
mLearntRouterAdvMessageFromHost = true; mLearntRouterAdvMessageFromHost = true;
} }