mirror of
https://github.com/espressif/openthread.git
synced 2026-07-31 08:07:47 +00:00
[routing-manager] determine RIO preference based on current role (#8574)
This commit updates how BR determines the preference to use when advertising Route Info Options (RIO) in emitted Router Advertisement (RA) messages. User can explicitly set the preference by calling OpenThread API `otBorderRoutingSetRouteInfoOptionPreference()`. But if not set or the previously set value is cleared by user, RIO preference is determined based on device's current role: - Medium preference when device is in router/leader role, - Low preference when in child role. If a role change causes RIO preference to change, BR schedules to send a new RA using the updated RIO preference.
This commit is contained in:
@@ -141,23 +141,27 @@ otError otBorderRoutingInit(otInstance *aInstance, uint32_t aInfraIfIndex, bool
|
||||
otError otBorderRoutingSetEnabled(otInstance *aInstance, bool aEnabled);
|
||||
|
||||
/**
|
||||
* This function gets the preference used when advertising Route Info Options (e.g., for discovered OMR prefixes) in
|
||||
* Router Advertisement messages sent over the infrastructure link.
|
||||
* This function gets the current preference used when advertising Route Info Options (RIO) in Router Advertisement
|
||||
* messages sent over the infrastructure link.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* The RIO preference is determined as follows:
|
||||
*
|
||||
* @returns The OMR prefix advertisement preference.
|
||||
* - If explicitly set by user by calling `otBorderRoutingSetRouteInfoOptionPreference()`, the given preference is
|
||||
* used.
|
||||
* - Otherwise, it is determined based on device's current role: Medium preference when in router/leader role and
|
||||
* low preference when in child role.
|
||||
*
|
||||
* @returns The current Route Info Option preference.
|
||||
*
|
||||
*/
|
||||
otRoutePreference otBorderRoutingGetRouteInfoOptionPreference(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* This function sets the preference to use when advertising Route Info Options in Router Advertisement messages sent
|
||||
* over the infrastructure link, for example for discovered OMR prefixes.
|
||||
* This function explicitly sets the preference to use when advertising Route Info Options (RIO) in Router
|
||||
* Advertisement messages sent over the infrastructure link.
|
||||
*
|
||||
* By default BR will use `medium` preference level, but this function allows the default value to be changed. As an
|
||||
* example, it can be set to `low` preference in the case where device is a temporary BR (a mobile BR or a
|
||||
* battery-powered BR) to indicate that other BRs (if any) should be preferred over this BR on the infrastructure link.
|
||||
* After a call to this function, BR will use the given preference for all its advertised RIOs. The preference can be
|
||||
* cleared by calling `otBorderRoutingClearRouteInfoOptionPreference()`.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aPreference The route preference to use.
|
||||
@@ -165,6 +169,17 @@ otRoutePreference otBorderRoutingGetRouteInfoOptionPreference(otInstance *aInsta
|
||||
*/
|
||||
void otBorderRoutingSetRouteInfoOptionPreference(otInstance *aInstance, otRoutePreference aPreference);
|
||||
|
||||
/**
|
||||
* This function clears a previously set preference value for advertised Route Info Options.
|
||||
*
|
||||
* After a call to this function, BR will use device's role to determine the RIO preference: Medium preference when
|
||||
* in router/leader role and low preference when in child role.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
*
|
||||
*/
|
||||
void otBorderRoutingClearRouteInfoOptionPreference(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* Gets the local Off-Mesh-Routable (OMR) Prefix, for example `fdfc:1ff5:1512:5622::/64`.
|
||||
*
|
||||
|
||||
@@ -53,7 +53,7 @@ extern "C" {
|
||||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (272)
|
||||
#define OPENTHREAD_API_VERSION (273)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
+36
-16
@@ -652,28 +652,48 @@ template <> otError Interpreter::Process<Cmd("br")>(Arg aArgs[])
|
||||
OutputLine(" prf:%s", PreferenceToString(preference));
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE
|
||||
/**
|
||||
* @cli br rioprf (high,med,low)
|
||||
* @code
|
||||
* br rioprf
|
||||
* med
|
||||
* Done
|
||||
* @endcode
|
||||
* @code
|
||||
* br rioprf low
|
||||
* Done
|
||||
* @endcode
|
||||
* @cparam br rioprf [@ca{high}|@ca{med}|@ca{low}]
|
||||
* @par api_copy
|
||||
* #otBorderRoutingSetRouteInfoOptionPreference
|
||||
*
|
||||
*/
|
||||
else if (aArgs[0] == "rioprf")
|
||||
{
|
||||
/**
|
||||
* @cli br rioprf
|
||||
* @code
|
||||
* br rioprf
|
||||
* med
|
||||
* Done
|
||||
* @endcode
|
||||
* @par api_copy
|
||||
* #otBorderRoutingGetRouteInfoOptionPreference
|
||||
*
|
||||
*/
|
||||
if (aArgs[1].IsEmpty())
|
||||
{
|
||||
OutputLine("%s", PreferenceToString(otBorderRoutingGetRouteInfoOptionPreference(GetInstancePtr())));
|
||||
}
|
||||
/**
|
||||
* @cli br rioprf clear
|
||||
* @code
|
||||
* br rioprf clear
|
||||
* Done
|
||||
* @endcode
|
||||
* @par api_copy
|
||||
* #otBorderRoutingClearRouteInfoOptionPreference
|
||||
*
|
||||
*/
|
||||
else if (aArgs[1] == "clear")
|
||||
{
|
||||
otBorderRoutingClearRouteInfoOptionPreference(GetInstancePtr());
|
||||
}
|
||||
/**
|
||||
* @cli br rioprf (high,med,low)
|
||||
* @code
|
||||
* br rioprf low
|
||||
* Done
|
||||
* @endcode
|
||||
* @cparam br rioprf [@ca{high}|@ca{med}|@ca{low}]
|
||||
* @par api_copy
|
||||
* #otBorderRoutingSetRouteInfoOptionPreference
|
||||
*
|
||||
*/
|
||||
else
|
||||
{
|
||||
otRoutePreference preference;
|
||||
|
||||
@@ -64,6 +64,11 @@ void otBorderRoutingSetRouteInfoOptionPreference(otInstance *aInstance, otRouteP
|
||||
static_cast<NetworkData::RoutePreference>(aPreference));
|
||||
}
|
||||
|
||||
void otBorderRoutingClearRouteInfoOptionPreference(otInstance *aInstance)
|
||||
{
|
||||
AsCoreType(aInstance).Get<BorderRouter::RoutingManager>().ClearRouteInfoOptionPreference();
|
||||
}
|
||||
|
||||
otError otBorderRoutingGetOmrPrefix(otInstance *aInstance, otIp6Prefix *aPrefix)
|
||||
{
|
||||
return AsCoreType(aInstance).Get<BorderRouter::RoutingManager>().GetOmrPrefix(AsCoreType(aPrefix));
|
||||
|
||||
@@ -68,7 +68,8 @@ RoutingManager::RoutingManager(Instance &aInstance)
|
||||
, mIsEnabled(false)
|
||||
, mInfraIf(aInstance)
|
||||
, mLocalOmrPrefix(aInstance)
|
||||
, mRouteInfoOptionPreference(NetworkData::kRoutePreferenceMedium)
|
||||
, mRioPreference(NetworkData::kRoutePreferenceLow)
|
||||
, mUserSetRioPreference(false)
|
||||
, mOnLinkPrefixManager(aInstance)
|
||||
, mDiscoveredPrefixTable(aInstance)
|
||||
#if OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE
|
||||
@@ -122,9 +123,36 @@ exit:
|
||||
|
||||
void RoutingManager::SetRouteInfoOptionPreference(RoutePreference aPreference)
|
||||
{
|
||||
VerifyOrExit(mRouteInfoOptionPreference != aPreference);
|
||||
LogInfo("User explicitly set RIO Preference to %s", RoutePreferenceToString(aPreference));
|
||||
mUserSetRioPreference = true;
|
||||
UpdateRioPreference(aPreference);
|
||||
}
|
||||
|
||||
mRouteInfoOptionPreference = aPreference;
|
||||
void RoutingManager::ClearRouteInfoOptionPreference(void)
|
||||
{
|
||||
VerifyOrExit(mUserSetRioPreference);
|
||||
|
||||
LogInfo("User cleared explicitly set RIO Preference");
|
||||
mUserSetRioPreference = false;
|
||||
SetRioPreferenceBasedOnRole();
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void RoutingManager::SetRioPreferenceBasedOnRole(void)
|
||||
{
|
||||
UpdateRioPreference(Get<Mle::Mle>().IsRouterOrLeader() ? NetworkData::kRoutePreferenceMedium
|
||||
: NetworkData::kRoutePreferenceLow);
|
||||
}
|
||||
|
||||
void RoutingManager::UpdateRioPreference(RoutePreference aPreference)
|
||||
{
|
||||
VerifyOrExit(mRioPreference != aPreference);
|
||||
|
||||
LogInfo("RIO Preference changed: %s -> %s", RoutePreferenceToString(mRioPreference),
|
||||
RoutePreferenceToString(aPreference));
|
||||
mRioPreference = aPreference;
|
||||
|
||||
VerifyOrExit(mIsRunning);
|
||||
ScheduleRoutingPolicyEvaluation(kAfterRandomDelay);
|
||||
@@ -347,6 +375,11 @@ exit:
|
||||
|
||||
void RoutingManager::HandleNotifierEvents(Events aEvents)
|
||||
{
|
||||
if (aEvents.Contains(kEventThreadRoleChanged) && !mUserSetRioPreference)
|
||||
{
|
||||
SetRioPreferenceBasedOnRole();
|
||||
}
|
||||
|
||||
VerifyOrExit(IsInitialized() && IsEnabled());
|
||||
|
||||
if (aEvents.Contains(kEventThreadRoleChanged))
|
||||
@@ -664,7 +697,7 @@ void RoutingManager::SendRouterAdvertisement(RouterAdvTxMode aRaTxMode)
|
||||
{
|
||||
if (prefix.GetLength() != 0)
|
||||
{
|
||||
SuccessOrAssert(raMsg.AppendRouteInfoOption(prefix, /* aRouteLifetime */ 0, mRouteInfoOptionPreference));
|
||||
SuccessOrAssert(raMsg.AppendRouteInfoOption(prefix, /* aRouteLifetime */ 0, mRioPreference));
|
||||
LogInfo("RouterAdvert: Added RIO for %s (lifetime=0)", prefix.ToString().AsCString());
|
||||
}
|
||||
}
|
||||
@@ -738,7 +771,7 @@ void RoutingManager::SendRouterAdvertisement(RouterAdvTxMode aRaTxMode)
|
||||
|
||||
for (const OnMeshPrefix &prefix : mAdvertisedPrefixes)
|
||||
{
|
||||
SuccessOrAssert(raMsg.AppendRouteInfoOption(prefix, kDefaultOmrPrefixLifetime, mRouteInfoOptionPreference));
|
||||
SuccessOrAssert(raMsg.AppendRouteInfoOption(prefix, kDefaultOmrPrefixLifetime, mRioPreference));
|
||||
LogInfo("RouterAdvert: Added RIO for %s (lifetime=%lu)", prefix.ToString().AsCString(),
|
||||
ToUlong(kDefaultOmrPrefixLifetime));
|
||||
}
|
||||
|
||||
@@ -150,28 +150,41 @@ public:
|
||||
void RequestStop(void) { Stop(); }
|
||||
|
||||
/**
|
||||
* This method gets the preference used when advertising Route Info Options (e.g., for discovered OMR prefixes) in
|
||||
* Router Advertisement messages sent over the infrastructure link.
|
||||
* This method gets the current preference used when advertising Route Info Options (RIO) in Router Advertisement
|
||||
* messages sent over the infrastructure link.
|
||||
*
|
||||
* @returns The Route Info Option preference.
|
||||
* The RIO preference is determined as follows:
|
||||
*
|
||||
* - If explicitly set by user by calling `SetRouteInfoOptionPreference()`, the given preference is used.
|
||||
* - Otherwise, it is determined based on device's role: Medium preference when in router/leader role and low
|
||||
* preference when in child role.
|
||||
*
|
||||
* @returns The current Route Info Option preference.
|
||||
*
|
||||
*/
|
||||
RoutePreference GetRouteInfoOptionPreference(void) const { return mRouteInfoOptionPreference; }
|
||||
RoutePreference GetRouteInfoOptionPreference(void) const { return mRioPreference; }
|
||||
|
||||
/**
|
||||
* This method sets the preference to use when advertising Route Info Options (e.g., for discovered OMR prefixes)
|
||||
* in Router Advertisement messages sent over the infrastructure link.
|
||||
* This method explicitly sets the preference to use when advertising Route Info Options (RIO) in Router
|
||||
* Advertisement messages sent over the infrastructure link.
|
||||
*
|
||||
* By default BR will use 'medium' preference level but this method allows the default value to be changed. As an
|
||||
* example, it can be set to 'low' preference in the case where device is a temporary BR (a mobile BR or a
|
||||
* battery-powered BR) to indicate that other BRs (if any) should be preferred over this BR on the infrastructure
|
||||
* link.
|
||||
* After a call to this method, BR will use the given preference for all its advertised RIOs. The preference can be
|
||||
* cleared by calling `ClearRouteInfoOptionPreference`()`.
|
||||
*
|
||||
* @param[in] aPreference The route preference to use.
|
||||
*
|
||||
*/
|
||||
void SetRouteInfoOptionPreference(RoutePreference aPreference);
|
||||
|
||||
/**
|
||||
* This method clears a previously set preference value for advertised Route Info Options.
|
||||
*
|
||||
* After a call to this method, BR will use device role to determine the RIO preference: Medium preference when
|
||||
* in router/leader role and low preference when in child role.
|
||||
*
|
||||
*/
|
||||
void ClearRouteInfoOptionPreference(void);
|
||||
|
||||
/**
|
||||
* This method returns the local off-mesh-routable (OMR) prefix.
|
||||
*
|
||||
@@ -838,6 +851,8 @@ private:
|
||||
void HandleNotifierEvents(Events aEvents);
|
||||
bool IsInitialized(void) const { return mInfraIf.IsInitialized(); }
|
||||
bool IsEnabled(void) const { return mIsEnabled; }
|
||||
void SetRioPreferenceBasedOnRole(void);
|
||||
void UpdateRioPreference(RoutePreference aPreference);
|
||||
Error LoadOrGenerateRandomBrUlaPrefix(void);
|
||||
|
||||
void EvaluateRoutingPolicy(void);
|
||||
@@ -890,7 +905,8 @@ private:
|
||||
// were advertised as RIO in the last sent RA message.
|
||||
OnMeshPrefixArray mAdvertisedPrefixes;
|
||||
|
||||
RoutePreference mRouteInfoOptionPreference;
|
||||
RoutePreference mRioPreference;
|
||||
bool mUserSetRioPreference;
|
||||
|
||||
OnLinkPrefixManager mOnLinkPrefixManager;
|
||||
|
||||
|
||||
@@ -39,6 +39,25 @@
|
||||
namespace ot {
|
||||
namespace NetworkData {
|
||||
|
||||
const char *RoutePreferenceToString(RoutePreference aPreference)
|
||||
{
|
||||
const char *str = "low";
|
||||
|
||||
switch (aPreference)
|
||||
{
|
||||
case kRoutePreferenceHigh:
|
||||
str = "high";
|
||||
break;
|
||||
case kRoutePreferenceMedium:
|
||||
str = "med";
|
||||
break;
|
||||
case kRoutePreferenceLow:
|
||||
break;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
|
||||
|
||||
static bool IsPrefixValid(Instance &aInstance, const Ip6::Prefix &aPrefix)
|
||||
|
||||
@@ -160,6 +160,16 @@ inline RoutePreference RoutePreferenceFromValue(uint8_t aValue)
|
||||
return kRoutePreferences[aValue & kMask];
|
||||
}
|
||||
|
||||
/**
|
||||
* This function converts a router preference to a human-readable string.
|
||||
*
|
||||
* @param[in] aPreference The preference to convert
|
||||
*
|
||||
* @returns The string representation of @p aPreference.
|
||||
*
|
||||
*/
|
||||
const char *RoutePreferenceToString(RoutePreference aPreference);
|
||||
|
||||
/**
|
||||
* This class represents an On-mesh Prefix (Border Router) configuration.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user