[nd6] add RaFlagsExtOption and track flags in received RAs (#9448)

This commit adds the `RaFlagsExtOption` class to represent an "RA
Flags Extension" Option. It also adds code to `RoutingManager` class
to process this option in received RA messages and check whether or
not the Stub Router Flag is set. Additionally, it checks and tracks
whether or not the `M` (Managed Address) and `O` (Other Config) flags
are set in the received RA message's header.
This commit is contained in:
Abtin Keshavarzian
2023-09-28 14:14:19 -07:00
committed by GitHub
parent 9f76d45de6
commit 50c70d8abe
4 changed files with 143 additions and 11 deletions
+24 -4
View File
@@ -1191,8 +1191,8 @@ void RoutingManager::DiscoveredPrefixTable::ProcessRouterAdvertMessage(const Ip6
ExitNow();
}
router->Clear();
router->mAddress = aSrcAddress;
router->mEntries.Clear();
}
// RA message can indicate router provides default route in the RA
@@ -1201,7 +1201,7 @@ void RoutingManager::DiscoveredPrefixTable::ProcessRouterAdvertMessage(const Ip6
// in a `::/0` RIO override the preference and lifetime values in
// the RA header (per RFC 4191 section 3.1).
ProcessDefaultRoute(aRaMessage.GetHeader(), *router);
ProcessRaHeader(aRaMessage.GetHeader(), *router);
for (const Ip6::Nd::Option &option : aRaMessage)
{
@@ -1215,6 +1215,10 @@ void RoutingManager::DiscoveredPrefixTable::ProcessRouterAdvertMessage(const Ip6
ProcessRouteInfoOption(static_cast<const Ip6::Nd::RouteInfoOption &>(option), *router);
break;
case Ip6::Nd::Option::kTypeRaFlagsExtension:
ProcessRaFlagsExtOption(static_cast<const Ip6::Nd::RaFlagsExtOption &>(option), *router);
break;
default:
break;
}
@@ -1228,12 +1232,16 @@ exit:
return;
}
void RoutingManager::DiscoveredPrefixTable::ProcessDefaultRoute(const Ip6::Nd::RouterAdvertMessage::Header &aRaHeader,
Router &aRouter)
void RoutingManager::DiscoveredPrefixTable::ProcessRaHeader(const Ip6::Nd::RouterAdvertMessage::Header &aRaHeader,
Router &aRouter)
{
Entry *entry;
Ip6::Prefix prefix;
aRouter.mManagedAddressConfigFlag = aRaHeader.IsManagedAddressConfigFlagSet();
aRouter.mOtherConfigFlag = aRaHeader.IsOtherConfigFlagSet();
LogInfo("- RA Header - flags - M:%u O:%u", aRouter.mManagedAddressConfigFlag, aRouter.mOtherConfigFlag);
prefix.Clear();
entry = aRouter.mEntries.FindMatching(Entry::Matcher(prefix, Entry::kTypeRoute));
@@ -1356,6 +1364,18 @@ exit:
return;
}
void RoutingManager::DiscoveredPrefixTable::ProcessRaFlagsExtOption(const Ip6::Nd::RaFlagsExtOption &aRaFlagsOption,
Router &aRouter)
{
VerifyOrExit(aRaFlagsOption.IsValid());
aRouter.mStubRouterFlag = aRaFlagsOption.IsStubRouterFlagSet();
LogInfo("- FlagsExt - StubRouter:%u", aRouter.mStubRouterFlag);
exit:
return;
}
bool RoutingManager::DiscoveredPrefixTable::Contains(const Entry::Checker &aChecker) const
{
bool contains = false;
+6 -2
View File
@@ -725,7 +725,7 @@ private:
} mShared;
};
struct Router
struct Router : public Clearable<Router>
{
// The timeout (in msec) for router staying in active state
// before starting the Neighbor Solicitation (NS) probes.
@@ -750,6 +750,9 @@ private:
LinkedList<Entry> mEntries;
TimeMilli mTimeout;
uint8_t mNsProbeCount;
bool mManagedAddressConfigFlag : 1;
bool mOtherConfigFlag : 1;
bool mStubRouterFlag : 1;
};
class Iterator : public PrefixTableIterator
@@ -763,9 +766,10 @@ private:
void SetInitTime(void) { mData32 = TimerMilli::GetNow().GetValue(); }
};
void ProcessDefaultRoute(const Ip6::Nd::RouterAdvertMessage::Header &aRaHeader, Router &aRouter);
void ProcessRaHeader(const Ip6::Nd::RouterAdvertMessage::Header &aRaHeader, Router &aRouter);
void ProcessPrefixInfoOption(const Ip6::Nd::PrefixInfoOption &aPio, Router &aRouter);
void ProcessRouteInfoOption(const Ip6::Nd::RouteInfoOption &aRio, Router &aRouter);
void ProcessRaFlagsExtOption(const Ip6::Nd::RaFlagsExtOption &aFlagsOption, Router &aRouter);
bool Contains(const Entry::Checker &aChecker) const;
void RemovePrefix(const Entry::Matcher &aMatcher);
void RemoveOrDeprecateEntriesFromInactiveRouters(void);
+10
View File
@@ -170,6 +170,16 @@ uint8_t RouteInfoOption::OptionLengthForPrefix(uint8_t aPrefixLength)
return length;
}
//----------------------------------------------------------------------------------------------------------------------
// RaFlagsExtOption
void RaFlagsExtOption::Init(void)
{
Clear();
SetType(kTypeRaFlagsExtension);
SetSize(sizeof(RaFlagsExtOption));
}
//----------------------------------------------------------------------------------------------------------------------
// RouterAdverMessage::Header
+103 -5
View File
@@ -75,8 +75,9 @@ class Option
public:
enum Type : uint8_t
{
kTypePrefixInfo = 3, ///< Prefix Information Option.
kTypeRouteInfo = 24, ///< Route Information Option.
kTypePrefixInfo = 3, ///< Prefix Information Option.
kTypeRouteInfo = 24, ///< Route Information Option.
kTypeRaFlagsExtension = 26, ///< RA Flags Extension Option.
};
static constexpr uint16_t kLengthUnit = 8; ///< The unit of length in octets.
@@ -458,6 +459,71 @@ private:
static_assert(sizeof(RouteInfoOption) == 8, "invalid RouteInfoOption structure");
/**
* Represents an RA Flags Extension Option.
*
* See RFC-5175 [https://tools.ietf.org/html/rfc5175]
*
*/
OT_TOOL_PACKED_BEGIN
class RaFlagsExtOption : public Option, private Clearable<RaFlagsExtOption>
{
friend class Clearable<RaFlagsExtOption>;
public:
static constexpr Type kType = kTypeRaFlagsExtension; ///< RA Flags Extension Option type.
/**
* Initializes the RA Flags Extension option with proper type and length and sets all flags to zero.
*
*/
void Init(void);
/**
* Tells whether this option is valid.
*
* @returns A boolean indicates whether this option is valid.
*
*/
bool IsValid(void) const { return GetSize() >= sizeof(*this); }
/**
* Indicates whether or not the Stub Router Flag is set.
*
* @retval TRUE The Stub Router Flag is set.
* @retval FALSE The Stub Router Flag is not set.
*
*/
bool IsStubRouterFlagSet(void) const { return (mFlags[0] & kStubRouterFlag) != 0; }
/**
* Sets the Stub Router Flag.
*
*/
void SetStubRouterFlag(void) { mFlags[0] |= kStubRouterFlag; }
RaFlagsExtOption(void) = delete;
private:
// RA Flags Extension Option
//
// 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 | Length | Bit fields available ..
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// ... for assignment |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ .
// Stub router flags defined in [https://www.ietf.org/archive/id/draft-hui-stub-router-ra-flag-01.txt]
static constexpr uint8_t kStubRouterFlag = 1 << 7;
uint8_t mFlags[6];
} OT_TOOL_PACKED_END;
static_assert(sizeof(RaFlagsExtOption) == 8, "invalid RaFlagsExtOption structure");
/**
* Represents a Router Advertisement message.
*
@@ -532,6 +598,36 @@ public:
*/
RoutePreference GetDefaultRouterPreference(void) const;
/**
* Indicates whether or not the Managed Address Config Flag is set in the RA message header.
*
* @retval TRUE The Managed Address Config Flag is set.
* @retval FALSE The Managed Address Config Flag is not set.
*
*/
bool IsManagedAddressConfigFlagSet(void) const { return (mFlags & kManagedAddressConfigFlag) != 0; }
/**
* Sets the Managed Address Config Flag in the RA message.
*
*/
void SetManagedAddressConfigFlag(void) { mFlags |= kManagedAddressConfigFlag; }
/**
* Indicates whether or not the Other Config Flag is set in the RA message header.
*
* @retval TRUE The Other Config Flag is set.
* @retval FALSE The Other Config Flag is not set.
*
*/
bool IsOtherConfigFlagSet(void) const { return (mFlags & kOtherConfigFlag) != 0; }
/**
* Sets the Other Config Flag in the RA message.
*
*/
void SetOtherConfigFlag(void) { mFlags |= kOtherConfigFlag; }
/**
* This method returns the ICMPv6 message type.
*
@@ -548,7 +644,7 @@ public:
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Type | Code | Checksum |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Cur Hop Limit |M|O|H|Prf|Resvd| Router Lifetime |
// | Cur Hop Limit |M|O| |Prf| | Router Lifetime |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Reachable Time |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -557,8 +653,10 @@ public:
// | Options ...
// +-+-+-+-+-+-+-+-+-+-+-+-
static constexpr uint8_t kPreferenceOffset = 3;
static constexpr uint8_t kPreferenceMask = 3 << kPreferenceOffset;
static constexpr uint8_t kManagedAddressConfigFlag = 1 << 7;
static constexpr uint8_t kOtherConfigFlag = 1 << 6;
static constexpr uint8_t kPreferenceOffset = 3;
static constexpr uint8_t kPreferenceMask = 3 << kPreferenceOffset;
uint8_t mType;
uint8_t mCode;