Skip to content

Commit

Permalink
[nd6] add RaFlagsExtOption and track flags in received RAs (openthr…
Browse files Browse the repository at this point in the history
…ead#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.
  • Loading branch information
abtink authored Sep 28, 2023
1 parent 9f76d45 commit 50c70d8
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 11 deletions.
28 changes: 24 additions & 4 deletions src/core/border_router/routing_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
{
Expand All @@ -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;
}
Expand All @@ -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));

Expand Down Expand Up @@ -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;
Expand Down
8 changes: 6 additions & 2 deletions src/core/border_router/routing_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -725,7 +725,7 @@ class RoutingManager : public InstanceLocator
} 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.
Expand All @@ -750,6 +750,9 @@ class RoutingManager : public InstanceLocator
LinkedList<Entry> mEntries;
TimeMilli mTimeout;
uint8_t mNsProbeCount;
bool mManagedAddressConfigFlag : 1;
bool mOtherConfigFlag : 1;
bool mStubRouterFlag : 1;
};

class Iterator : public PrefixTableIterator
Expand All @@ -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);
Expand Down
10 changes: 10 additions & 0 deletions src/core/net/nd6.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
108 changes: 103 additions & 5 deletions src/core/net/nd6.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -458,6 +459,71 @@ class RouteInfoOption : public Option, private Clearable<RouteInfoOption>

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.
*
Expand Down Expand Up @@ -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.
*
Expand All @@ -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 |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Expand All @@ -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;
Expand Down

0 comments on commit 50c70d8

Please sign in to comment.