diff --git a/src/core/border_router/routing_manager.cpp b/src/core/border_router/routing_manager.cpp index fd69a0c6511..bdfaa14fae9 100644 --- a/src/core/border_router/routing_manager.cpp +++ b/src/core/border_router/routing_manager.cpp @@ -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(option), *router); break; + case Ip6::Nd::Option::kTypeRaFlagsExtension: + ProcessRaFlagsExtOption(static_cast(option), *router); + break; + default: break; } @@ -1228,12 +1232,16 @@ void RoutingManager::DiscoveredPrefixTable::ProcessRouterAdvertMessage(const Ip6 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 @@ void RoutingManager::DiscoveredPrefixTable::ProcessRouteInfoOption(const Ip6::Nd 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; diff --git a/src/core/border_router/routing_manager.hpp b/src/core/border_router/routing_manager.hpp index b779461a416..a00dd34781a 100644 --- a/src/core/border_router/routing_manager.hpp +++ b/src/core/border_router/routing_manager.hpp @@ -725,7 +725,7 @@ class RoutingManager : public InstanceLocator } mShared; }; - struct Router + struct Router : public Clearable { // The timeout (in msec) for router staying in active state // before starting the Neighbor Solicitation (NS) probes. @@ -750,6 +750,9 @@ class RoutingManager : public InstanceLocator LinkedList mEntries; TimeMilli mTimeout; uint8_t mNsProbeCount; + bool mManagedAddressConfigFlag : 1; + bool mOtherConfigFlag : 1; + bool mStubRouterFlag : 1; }; class Iterator : public PrefixTableIterator @@ -763,9 +766,10 @@ class RoutingManager : public InstanceLocator 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); diff --git a/src/core/net/nd6.cpp b/src/core/net/nd6.cpp index cc5e6bfb0cc..3d24b6ad70d 100644 --- a/src/core/net/nd6.cpp +++ b/src/core/net/nd6.cpp @@ -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 diff --git a/src/core/net/nd6.hpp b/src/core/net/nd6.hpp index 9cf5c08039e..bc116a450af 100644 --- a/src/core/net/nd6.hpp +++ b/src/core/net/nd6.hpp @@ -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 @@ class RouteInfoOption : public Option, private Clearable 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 +{ + friend class Clearable; + +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 @@ class RouterAdvertMessage */ 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 @@ class RouterAdvertMessage // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | 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 @@ class RouterAdvertMessage // | 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;