diff --git a/include/openthread/border_router.h b/include/openthread/border_router.h index aaf6f3cab..3b5aad862 100644 --- a/include/openthread/border_router.h +++ b/include/openthread/border_router.h @@ -86,6 +86,31 @@ 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. + * + * @param[in] aInstance A pointer to an OpenThread instance. + * + * @returns The OMR prefix advertisement preference. + * + */ +otRoutePreference otBorderRoutingGetRouteInfoOptionPreference(otInstance *aInstance); + +/** + * This function 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. + * + * 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. + * + * @param[in] aInstance A pointer to an OpenThread instance. + * @param[in] aPreference The route preference to use. + * + */ +void otBorderRoutingSetRouteInfoOptionPreference(otInstance *aInstance, otRoutePreference aPreference); + /** * Gets the Off-Mesh-Routable (OMR) Prefix, for example `fdfc:1ff5:1512:5622::/64`. * diff --git a/include/openthread/instance.h b/include/openthread/instance.h index 161e83763..0b5585078 100644 --- a/include/openthread/instance.h +++ b/include/openthread/instance.h @@ -53,7 +53,7 @@ extern "C" { * @note This number versions both OpenThread platform and user APIs. * */ -#define OPENTHREAD_API_VERSION (222) +#define OPENTHREAD_API_VERSION (223) /** * @addtogroup api-instance diff --git a/src/cli/README.md b/src/cli/README.md index cbb8ad06f..c088da474 100644 --- a/src/cli/README.md +++ b/src/cli/README.md @@ -394,6 +394,25 @@ fd14:1078:b3d5:b0b0:0:0::/96 Done ``` +### br rioprf + +Get the preference used when advertising Route Info Options (e.g., for discovered OMR prefixes) in emitted Router Advertisement message. + +```bash +> br rioprf +med +Done +``` + +### br rioprf \ + +Set the preference (which may be 'high', 'med', or 'low') to use when advertising Route Info Options (e.g., for discovered OMR prefixes) in emitted Router Advertisement message. + +```bash +> br rioprf low +Done +``` + ### bufferinfo Show the current message buffer information. diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp index 2983e167f..535f9581d 100644 --- a/src/cli/cli.cpp +++ b/src/cli/cli.cpp @@ -536,6 +536,57 @@ template <> otError Interpreter::Process(Arg aArgs[]) OutputIp6PrefixLine(nat64Prefix); } #endif // OPENTHREAD_CONFIG_BORDER_ROUTING_NAT64_ENABLE + /** + * @cli br rioprf [high\med\low] + * + * @code + * br rioprf + * med + * Done + * @endcode + * + * @cparam br rioprf [@ca{high}|@ca{med}|@ca{low}] + * + * @code + * br rioprf low + * Done + * @endcode + * + * @par api_copy + * #otBorderRoutingSetRouteInfoOptionPreference + * + */ + else if ((aArgs[0] == "rioprf")) + { + if (aArgs[1].IsEmpty()) + { + OutputLine("%s", + NetworkData::PreferenceToString(otBorderRoutingGetRouteInfoOptionPreference(GetInstancePtr()))); + } + else + { + otRoutePreference preference; + + if (aArgs[1] == "high") + { + preference = OT_ROUTE_PREFERENCE_HIGH; + } + else if (aArgs[1] == "med") + { + preference = OT_ROUTE_PREFERENCE_MED; + } + else if (aArgs[1] == "low") + { + preference = OT_ROUTE_PREFERENCE_LOW; + } + else + { + ExitNow(error = OT_ERROR_INVALID_ARGS); + } + + otBorderRoutingSetRouteInfoOptionPreference(GetInstancePtr(), preference); + } + } else { error = OT_ERROR_INVALID_COMMAND; diff --git a/src/core/api/border_router_api.cpp b/src/core/api/border_router_api.cpp index d90893192..621551655 100644 --- a/src/core/api/border_router_api.cpp +++ b/src/core/api/border_router_api.cpp @@ -54,6 +54,18 @@ otError otBorderRoutingSetEnabled(otInstance *aInstance, bool aEnabled) return AsCoreType(aInstance).Get().SetEnabled(aEnabled); } +otRoutePreference otBorderRoutingGetRouteInfoOptionPreference(otInstance *aInstance) +{ + return static_cast( + AsCoreType(aInstance).Get().GetRouteInfoOptionPreference()); +} + +void otBorderRoutingSetRouteInfoOptionPreference(otInstance *aInstance, otRoutePreference aPreference) +{ + AsCoreType(aInstance).Get().SetRouteInfoOptionPreference( + static_cast(aPreference)); +} + otError otBorderRoutingGetOmrPrefix(otInstance *aInstance, otIp6Prefix *aPrefix) { return AsCoreType(aInstance).Get().GetOmrPrefix(AsCoreType(aPrefix)); diff --git a/src/core/border_router/routing_manager.cpp b/src/core/border_router/routing_manager.cpp index 51d6b79bf..9d6fba53f 100644 --- a/src/core/border_router/routing_manager.cpp +++ b/src/core/border_router/routing_manager.cpp @@ -64,6 +64,7 @@ RoutingManager::RoutingManager(Instance &aInstance) , mIsRunning(false) , mIsEnabled(false) , mInfraIf(aInstance) + , mRouteInfoOptionPreference(NetworkData::kRoutePreferenceMedium) , mIsAdvertisingLocalOnLinkPrefix(false) , mOnLinkPrefixDeprecateTimer(aInstance, HandleOnLinkPrefixDeprecateTimer) , mIsAdvertisingLocalNat64Prefix(false) @@ -127,6 +128,19 @@ exit: return error; } +void RoutingManager::SetRouteInfoOptionPreference(RoutePreference aPreference) +{ + VerifyOrExit(mRouteInfoOptionPreference != aPreference); + + mRouteInfoOptionPreference = aPreference; + + VerifyOrExit(mIsRunning); + StartRoutingPolicyEvaluationJitter(kRoutingPolicyEvaluationJitter); + +exit: + return; +} + Error RoutingManager::GetOmrPrefix(Ip6::Prefix &aPrefix) { Error error = kErrorNone; @@ -872,18 +886,18 @@ void RoutingManager::SendRouterAdvertisement(const OmrPrefixArray &aNewOmrPrefix if (!aNewOmrPrefixes.ContainsMatching(omrPrefix.GetPrefix())) { SuccessOrAssert( - raMsg.AppendRouteInfoOption(omrPrefix.GetPrefix(), /* aRouteLifetime */ 0, omrPrefix.GetPreference())); + raMsg.AppendRouteInfoOption(omrPrefix.GetPrefix(), /* aRouteLifetime */ 0, mRouteInfoOptionPreference)); - LogInfo("RouterAdvert: Added RIO for %s (lifetime=0)", omrPrefix.ToString().AsCString()); + LogInfo("RouterAdvert: Added RIO for %s (lifetime=0)", omrPrefix.GetPrefix().ToString().AsCString()); } } for (const OmrPrefix &omrPrefix : aNewOmrPrefixes) { SuccessOrAssert( - raMsg.AppendRouteInfoOption(omrPrefix.GetPrefix(), kDefaultOmrPrefixLifetime, omrPrefix.GetPreference())); + raMsg.AppendRouteInfoOption(omrPrefix.GetPrefix(), kDefaultOmrPrefixLifetime, mRouteInfoOptionPreference)); - LogInfo("RouterAdvert: Added RIO for %s (lifetime=%u)", omrPrefix.ToString().AsCString(), + LogInfo("RouterAdvert: Added RIO for %s (lifetime=%u)", omrPrefix.GetPrefix().ToString().AsCString(), kDefaultOmrPrefixLifetime); } diff --git a/src/core/border_router/routing_manager.hpp b/src/core/border_router/routing_manager.hpp index 3b923207d..e6650be31 100644 --- a/src/core/border_router/routing_manager.hpp +++ b/src/core/border_router/routing_manager.hpp @@ -79,6 +79,8 @@ class RoutingManager : public InstanceLocator friend class ot::Instance; public: + typedef NetworkData::RoutePreference RoutePreference; ///< Route preference (high, medium, low). + /** * This constructor initializes the routing manager. * @@ -113,6 +115,29 @@ public: */ Error SetEnabled(bool aEnabled); + /** + * 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. + * + * @returns The Route Info Option preference. + * + */ + RoutePreference GetRouteInfoOptionPreference(void) const { return mRouteInfoOptionPreference; } + + /** + * 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. + * + * 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. + * + * @param[in] aPreference The route preference to use. + * + */ + void SetRouteInfoOptionPreference(RoutePreference aPreference); + /** * This method returns the off-mesh-routable (OMR) prefix. * @@ -195,8 +220,6 @@ public: static bool IsValidOmrPrefix(const Ip6::Prefix &aOmrPrefix); private: - typedef NetworkData::RoutePreference RoutePreference; - static constexpr uint16_t kMaxRouterAdvMessageLength = 256; // The maximum RA message length we can handle. // The maximum number of the OMR prefixes to advertise. @@ -509,6 +532,8 @@ private: // advertised on infra link. OmrPrefixArray mAdvertisedOmrPrefixes; + RoutePreference mRouteInfoOptionPreference; + // The currently favored (smallest) discovered on-link prefix. // Prefix length of zero indicates there is none. Ip6::Prefix mFavoredDiscoveredOnLinkPrefix;