diff options
author | Abtin Keshavarzian <abtink@google.com> | 2024-03-26 14:04:02 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-26 14:04:02 -0700 |
commit | d237cd2c02091a40a131a280d4bfb82176580d73 (patch) | |
tree | 28b33cbb68883eb084a0387ac1ca4301eeae7bad | |
parent | dcde8826c05889b4781588a10ded59ab562b9882 (diff) | |
download | openthread-d237cd2c02091a40a131a280d4bfb82176580d73.tar.gz |
[routing-manager] set extra options to append to emitted RAs (#9945)
This commit introduces new API for setting vendor-specific extra
options to append to emitted Router Advertisement messages. Support
for this is also added in CLI under `br raoptions` command.
-rw-r--r-- | include/openthread/border_routing.h | 16 | ||||
-rw-r--r-- | include/openthread/instance.h | 2 | ||||
-rw-r--r-- | src/cli/README_BR.md | 23 | ||||
-rw-r--r-- | src/cli/cli_br.cpp | 41 | ||||
-rw-r--r-- | src/core/api/border_routing_api.cpp | 5 | ||||
-rw-r--r-- | src/core/border_router/routing_manager.cpp | 21 | ||||
-rw-r--r-- | src/core/border_router/routing_manager.hpp | 22 | ||||
-rw-r--r-- | src/core/net/nd6.hpp | 13 |
8 files changed, 139 insertions, 4 deletions
diff --git a/include/openthread/border_routing.h b/include/openthread/border_routing.h index afd2d7e5f..1e5ff6144 100644 --- a/include/openthread/border_routing.h +++ b/include/openthread/border_routing.h @@ -240,6 +240,22 @@ void otBorderRoutingSetRouteInfoOptionPreference(otInstance *aInstance, otRouteP void otBorderRoutingClearRouteInfoOptionPreference(otInstance *aInstance); /** + * Sets additional options to append at the end of emitted Router Advertisement (RA) messages. + * + * The content of @p aOptions is copied internally, so it can be a temporary buffer (e.g., a stack allocated array). + * + * Subsequent calls to this function overwrite the previously set value. + * + * @param[in] aOptions A pointer to the encoded options. Can be `NULL` to clear. + * @param[in] aLength Number of bytes in @p aOptions. + * + * @retval OT_ERROR_NONE Successfully set the extra option bytes. + * @retval OT_ERROR_NO_BUFS Could not allocate buffer to save the buffer. + * + */ +otError otBorderRoutingSetExtraRouterAdvertOptions(otInstance *aInstance, const uint8_t *aOptions, uint16_t aLength); + +/** * Gets the current preference used for published routes in Network Data. * * The preference is determined as follows: diff --git a/include/openthread/instance.h b/include/openthread/instance.h index 84641d422..1ce766c02 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 (401) +#define OPENTHREAD_API_VERSION (402) /** * @addtogroup api-instance diff --git a/src/cli/README_BR.md b/src/cli/README_BR.md index 189de8a6f..8376290d6 100644 --- a/src/cli/README_BR.md +++ b/src/cli/README_BR.md @@ -36,6 +36,7 @@ omrprefix onlinkprefix pd prefixtable +raoptions rioprf routeprf routers @@ -235,6 +236,28 @@ prefix:1200:abba:baba:0::/64, on-link:yes, ms-since-rx:29527, lifetime:1800, pre Done ``` +### raoptions + +Usage: `br raoptions <options>` + +Sets additional options to append at the end of emitted Router Advertisement (RA) messages. `<options>` provided as hex bytes. + +```bash +> br raoptions 0400ff00020001 +Done +``` + +### raoptions clear + +Usage: `br raoptions clear` + +Clear any previously set additional options to append at the end of emitted Router Advertisement (RA) messages. + +```bash +> br raoptions clear +Done +``` + ### rioprf Usage: `br rioprf` diff --git a/src/cli/cli_br.cpp b/src/cli/cli_br.cpp index 85590b925..53f2b3274 100644 --- a/src/cli/cli_br.cpp +++ b/src/cli/cli_br.cpp @@ -538,6 +538,46 @@ void Br::OutputRouterInfo(const otBorderRoutingRouterEntry &aEntry) aEntry.mStubRouterFlag); } +template <> otError Br::Process<Cmd("raoptions")>(Arg aArgs[]) +{ + static constexpr uint16_t kMaxExtraOptions = 800; + + otError error = OT_ERROR_NONE; + uint8_t options[kMaxExtraOptions]; + uint16_t length; + + /** + * @cli br raoptions (set,clear) + * @code + * br raoptions 0400ff00020001 + * Done + * @endcode + * @code + * br raoptions clear + * Done + * @endcode + * @cparam br raoptions @ca{options|clear} + * `br raoptions clear` passes a `nullptr` to #otBorderRoutingSetExtraRouterAdvertOptions. + * Otherwise, you can pass the `options` byte as hex data. + * @par api_copy + * #otBorderRoutingSetExtraRouterAdvertOptions + */ + if (aArgs[0] == "clear") + { + length = 0; + } + else + { + length = sizeof(options); + SuccessOrExit(error = aArgs[0].ParseAsHexString(length, options)); + } + + error = otBorderRoutingSetExtraRouterAdvertOptions(GetInstancePtr(), length > 0 ? options : nullptr, length); + +exit: + return error; +} + template <> otError Br::Process<Cmd("rioprf")>(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -702,6 +742,7 @@ otError Br::Process(Arg aArgs[]) CmdEntry("pd"), #endif CmdEntry("prefixtable"), + CmdEntry("raoptions"), CmdEntry("rioprf"), CmdEntry("routeprf"), CmdEntry("routers"), diff --git a/src/core/api/border_routing_api.cpp b/src/core/api/border_routing_api.cpp index b62ee7041..7c8002dea 100644 --- a/src/core/api/border_routing_api.cpp +++ b/src/core/api/border_routing_api.cpp @@ -75,6 +75,11 @@ void otBorderRoutingClearRouteInfoOptionPreference(otInstance *aInstance) AsCoreType(aInstance).Get<BorderRouter::RoutingManager>().ClearRouteInfoOptionPreference(); } +otError otBorderRoutingSetExtraRouterAdvertOptions(otInstance *aInstance, const uint8_t *aOptions, uint16_t aLength) +{ + return AsCoreType(aInstance).Get<BorderRouter::RoutingManager>().SetExtraRouterAdvertOptions(aOptions, aLength); +} + otRoutePreference otBorderRoutingGetRoutePreference(otInstance *aInstance) { return static_cast<otRoutePreference>( diff --git a/src/core/border_router/routing_manager.cpp b/src/core/border_router/routing_manager.cpp index b4c1b0ae5..bebd795c8 100644 --- a/src/core/border_router/routing_manager.cpp +++ b/src/core/border_router/routing_manager.cpp @@ -363,6 +363,22 @@ exit: return; } +Error RoutingManager::SetExtraRouterAdvertOptions(const uint8_t *aOptions, uint16_t aLength) +{ + Error error = kErrorNone; + + if (aOptions == nullptr) + { + mExtraRaOptions.Free(); + } + else + { + error = mExtraRaOptions.SetFrom(aOptions, aLength); + } + + return error; +} + #if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE void RoutingManager::HandleSrpServerAutoEnableMode(void) { @@ -607,6 +623,11 @@ void RoutingManager::SendRouterAdvertisement(RouterAdvTxMode aRaTxMode) SuccessOrExit(error = mRioAdvertiser.AppendRios(raMsg)); } + if (mExtraRaOptions.GetLength() > 0) + { + SuccessOrExit(error = raMsg.AppendBytes(mExtraRaOptions.GetBytes(), mExtraRaOptions.GetLength())); + } + VerifyOrExit(raMsg.ContainsAnyOptions()); destAddress.SetToLinkLocalAllNodesMulticast(); diff --git a/src/core/border_router/routing_manager.hpp b/src/core/border_router/routing_manager.hpp index bb376eedc..37de6eca3 100644 --- a/src/core/border_router/routing_manager.hpp +++ b/src/core/border_router/routing_manager.hpp @@ -55,6 +55,7 @@ #include "common/error.hpp" #include "common/heap_allocatable.hpp" #include "common/heap_array.hpp" +#include "common/heap_data.hpp" #include "common/linked_list.hpp" #include "common/locator.hpp" #include "common/message.hpp" @@ -234,6 +235,22 @@ public: void ClearRouteInfoOptionPreference(void) { mRioAdvertiser.ClearPreference(); } /** + * Sets additional options to append at the end of emitted Router Advertisement (RA) messages. + * + * The content of @p aOptions is copied internally, so can be a temporary stack variable. + * + * Subsequent calls to this method will overwrite the previously set value. + * + * @param[in] aOptions A pointer to the encoded options. Can be `nullptr` to clear. + * @param[in] aLength Number of bytes in @p aOptions. + * + * @retval kErrorNone Successfully set the extra option bytes. + * @retval kErrorNoBufs Could not allocate buffer to save the buffer. + * + */ + Error SetExtraRouterAdvertOptions(const uint8_t *aOptions, uint16_t aLength); + + /** * Gets the current preference used for published routes in Network Data. * * The preference is determined as follows: @@ -1360,8 +1377,9 @@ private: PdPrefixManager mPdPrefixManager; #endif - RaInfo mRaInfo; - RsSender mRsSender; + RaInfo mRaInfo; + RsSender mRsSender; + Heap::Data mExtraRaOptions; DiscoveredPrefixStaleTimer mDiscoveredPrefixStaleTimer; RoutingPolicyTimer mRoutingPolicyTimer; diff --git a/src/core/net/nd6.hpp b/src/core/net/nd6.hpp index 260606b30..4178f181f 100644 --- a/src/core/net/nd6.hpp +++ b/src/core/net/nd6.hpp @@ -809,6 +809,18 @@ public: Error AppendFlagsExtensionOption(bool aStubRouterFlag); /** + * Appends bytes from a given buffer to the RA message. + * + * @param[in] aBytes A pointer to the buffer containing the bytes to append. + * @param[in] aLength The buffer length. + * + * @retval kErrorNone Bytes are appended successfully. + * @retval kErrorNoBufs Insufficient available buffers to grow the message. + * + */ + Error AppendBytes(const uint8_t *aBytes, uint16_t aLength); + + /** * Indicates whether or not the received RA message contains any options. * * @retval TRUE If the RA message contains at least one option. @@ -820,7 +832,6 @@ public: private: static constexpr uint16_t kCapacityIncrement = 256; - Error AppendBytes(const uint8_t *aBytes, uint16_t aLength); Option *AppendOption(uint16_t aOptionSize); Heap::Array<uint8_t, kCapacityIncrement> mArray; |