From a8924f65f78db30a9825653966051a07412aed9e Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Thu, 30 Jun 2022 12:49:49 -0700 Subject: [PATCH] [routing-manager] get/set preference for RIOs in emitted RA messages (#7849) This commit adds new mechanism in `RoutingManager` to allow user to get or set the preference level to use when advertising Rout Info Options (e.g., for discovered OMR prefixes) in RA messages sent on infra netif. By default 'medium' preference is used. As an example, user can choose to set the preference to 'low' when the device is acting as a temporary BR (a mobile or battery-powered BR) to indicate that other BRs should be preferred over this BR on the infra link. This commit also adds CLI sub-commands for newly added APIs and updates the documentation. --- include/openthread/border_router.h | 25 +++++++++++ include/openthread/instance.h | 2 +- src/cli/README.md | 19 ++++++++ src/cli/cli.cpp | 51 ++++++++++++++++++++++ src/core/api/border_router_api.cpp | 12 +++++ src/core/border_router/routing_manager.cpp | 22 ++++++++-- src/core/border_router/routing_manager.hpp | 29 +++++++++++- 7 files changed, 153 insertions(+), 7 deletions(-) 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;