aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbtin Keshavarzian <abtink@google.com>2024-03-26 14:04:02 -0700
committerGitHub <noreply@github.com>2024-03-26 14:04:02 -0700
commitd237cd2c02091a40a131a280d4bfb82176580d73 (patch)
tree28b33cbb68883eb084a0387ac1ca4301eeae7bad
parentdcde8826c05889b4781588a10ded59ab562b9882 (diff)
downloadopenthread-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.h16
-rw-r--r--include/openthread/instance.h2
-rw-r--r--src/cli/README_BR.md23
-rw-r--r--src/cli/cli_br.cpp41
-rw-r--r--src/core/api/border_routing_api.cpp5
-rw-r--r--src/core/border_router/routing_manager.cpp21
-rw-r--r--src/core/border_router/routing_manager.hpp22
-rw-r--r--src/core/net/nd6.hpp13
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;