diff --git a/include/openthread/instance.h b/include/openthread/instance.h index 0a7f44190..0101f39e8 100644 --- a/include/openthread/instance.h +++ b/include/openthread/instance.h @@ -52,7 +52,7 @@ extern "C" { * * @note This number versions both OpenThread platform and user APIs. */ -#define OPENTHREAD_API_VERSION (594) +#define OPENTHREAD_API_VERSION (595) /** * @addtogroup api-instance diff --git a/include/openthread/ip6.h b/include/openthread/ip6.h index 0d9be5f3c..3d6acb10a 100644 --- a/include/openthread/ip6.h +++ b/include/openthread/ip6.h @@ -605,6 +605,29 @@ void otIp6RemoveAllUnsecurePorts(otInstance *aInstance); */ const uint16_t *otIp6GetUnsecurePorts(otInstance *aInstance, uint8_t *aNumEntries); +/** + * Sets whether to allow link-local unsecure IPv6 datagrams when the Thread role is disabled. + * + * Available only when `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` is enabled. This is intended for testing. By default, + * this is disabled (i.e., unsecure traffic is always dropped regardless of the device's role). + * + * @param[in] aInstance A pointer to an OpenThread instance. + * @param[in] aAllow TRUE to allow, FALSE otherwise. + */ +void otIp6SetAllowUnsecureWhenDisabled(otInstance *aInstance, bool aAllow); + +/** + * Indicates whether allowing link-local unsecure IPv6 datagrams when the Thread role is disabled is enabled. + * + * Available only when `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` is enabled. + * + * @param[in] aInstance A pointer to an OpenThread instance. + * + * @retval TRUE Does allow unsecure IPv6 datagrams when the Thread role is disabled. + * @retval FALSE Does not allow unsecure IPv6 datagrams when the Thread role is disabled. + */ +bool otIp6IsUnsecureAllowedWhenDisabled(otInstance *aInstance); + /** * Test if two IPv6 addresses are the same. * diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp index 64cc8de97..a7b5a14a0 100644 --- a/src/cli/cli.cpp +++ b/src/cli/cli.cpp @@ -7085,6 +7085,32 @@ template <> otError Interpreter::Process(Arg aArgs[]) OutputNewLine(); } +#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE + /** + * @cli unsecureport allwhendisabled + * @code + * unsecureport allwhendisabled + * Disabled + * Done + * @endcode + * @par api_copy + * #otIp6IsUnsecureAllowedWhenDisabled + */ + else if (aArgs[0] == "allwhendisabled") + { + /** + * @cli unsecureport allwhendisabled (enable, disable) + * @code + * unsecureport allwhendisabled enable + * Done + * @endcode + * @cparam unsecureport allwhendisabled @ca{enable|disable} + * @par api_copy + * #otIp6SetAllowUnsecureWhenDisabled + */ + error = ProcessEnableDisable(aArgs + 1, otIp6IsUnsecureAllowedWhenDisabled, otIp6SetAllowUnsecureWhenDisabled); + } +#endif // OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE else { error = OT_ERROR_INVALID_COMMAND; diff --git a/src/core/api/ip6_api.cpp b/src/core/api/ip6_api.cpp index 6b2932b0a..9becd1c88 100644 --- a/src/core/api/ip6_api.cpp +++ b/src/core/api/ip6_api.cpp @@ -312,3 +312,15 @@ void otIp6ResetBorderRoutingCounters(otInstance *aInstance) AsCoreType(aInstance).Get().ResetBorderRoutingCounters(); } #endif + +#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE +void otIp6SetAllowUnsecureWhenDisabled(otInstance *aInstance, bool aAllow) +{ + AsCoreType(aInstance).Get().SetAllowUnsecureWhenDisabled(aAllow); +} + +bool otIp6IsUnsecureAllowedWhenDisabled(otInstance *aInstance) +{ + return AsCoreType(aInstance).Get().IsUnsecureAllowedWhenDisabled(); +} +#endif diff --git a/src/core/net/ip6_filter.cpp b/src/core/net/ip6_filter.cpp index c4f518b43..5fc5cee7f 100644 --- a/src/core/net/ip6_filter.cpp +++ b/src/core/net/ip6_filter.cpp @@ -56,11 +56,12 @@ Error Filter::Apply(const Message &aMessage) const VerifyOrExit(headers.GetDestinationAddress().IsLinkLocalUnicastOrMulticast()); - // Allow all link-local IPv6 datagrams when Thread is not enabled - if (Get().GetRole() == Mle::kRoleDisabled) +#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE + if (mAllowUnsecureWhenDisabled && Get().IsDisabled()) { ExitNow(error = kErrorNone); } +#endif dstPort = headers.GetDestinationPort(); diff --git a/src/core/net/ip6_filter.hpp b/src/core/net/ip6_filter.hpp index 60fc63d47..a1bc668ec 100644 --- a/src/core/net/ip6_filter.hpp +++ b/src/core/net/ip6_filter.hpp @@ -66,6 +66,9 @@ public: */ explicit Filter(Instance &aInstance) : InstanceLocator(aInstance) +#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE + , mAllowUnsecureWhenDisabled(false) +#endif { } @@ -131,6 +134,23 @@ public: return &mUnsecurePorts[0]; } +#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE + /** + * Sets whether to allow link-local unsecure IPv6 datagrams when the Thread role is disabled. + * + * @param[in] aAllow TRUE to allow, FALSE otherwise. + */ + void SetAllowUnsecureWhenDisabled(bool aAllow) { mAllowUnsecureWhenDisabled = aAllow; } + + /** + * Indicates whether allowing link-local unsecure IPv6 datagrams when the Thread role is disabled is enabled. + * + * @retval TRUE Does allow unsecure IPv6 datagrams when the Thread role is disabled. + * @retval FALSE Does not allow unsecure IPv6 datagrams when the Thread role is disabled. + */ + bool IsUnsecureAllowedWhenDisabled(void) const { return mAllowUnsecureWhenDisabled; } +#endif + private: static constexpr uint16_t kMaxUnsecurePorts = 2; @@ -143,6 +163,9 @@ private: Error UpdateUnsecurePorts(Action aAction, uint16_t aPort); Array mUnsecurePorts; +#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE + bool mAllowUnsecureWhenDisabled; +#endif }; } // namespace Ip6