From 555afc498fd24e85d337cc7da1a2a7d938a63e17 Mon Sep 17 00:00:00 2001 From: Suvesh Pratapa Date: Sun, 14 Apr 2024 20:57:58 -0400 Subject: [PATCH] [cli] add cli toggle (for test harness) to accept tmf udp messages from unknown origins Reference devices that are part of the Thread test harness construct CoAP packets sent on TMF port 61631 for certain tests, for example in the 5.9.x series where they have to force address errors (a/ae) for duplicate DUA or re-registration tests. These tests started to fail when reference device firmware was updated recently to a newer OpenThread stack that included the change in https://github.com/openthread/openthread/pull/9437. Example: ``` udp send fd00:db9:0:0:0:ff:fe00:5000 61631 -x 4102d63697b16e02646eff0401010010fd007d037d037d0389c3a350cdcf36e0' Ip6-----------: Dropping TMF message from untrusted origin ``` For certification purposes, we are adding a cli toggle (for reference devices) to disable the filter that drops TMF messages from unknown origins. --- include/openthread/instance.h | 2 +- include/openthread/thread_ftd.h | 29 ++++++++++++++++++++++++++ src/cli/README.md | 36 ++++++++++++++++++++++++++++++++- src/cli/cli.cpp | 31 ++++++++++++++++++++++++++++ src/core/api/thread_ftd_api.cpp | 10 +++++++++ src/core/net/ip6.cpp | 9 ++++++++- src/core/net/ip6.hpp | 24 ++++++++++++++++++++++ 7 files changed, 138 insertions(+), 3 deletions(-) diff --git a/include/openthread/instance.h b/include/openthread/instance.h index c3538cdfa7f0..a956397bb24a 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 (404) +#define OPENTHREAD_API_VERSION (405) /** * @addtogroup api-instance diff --git a/include/openthread/thread_ftd.h b/include/openthread/thread_ftd.h index 0928acc88aee..0f1891836286 100644 --- a/include/openthread/thread_ftd.h +++ b/include/openthread/thread_ftd.h @@ -851,6 +851,35 @@ void otThreadSetCcmEnabled(otInstance *aInstance, bool aEnabled); */ void otThreadSetThreadVersionCheckEnabled(otInstance *aInstance, bool aEnabled); +/** + * Sets whether the filter to drop TMF UDP messages from untrusted origin is enabled. + * + * TMF messages are only trusted when they originate from a trusted source, such as the Thread interface. In + * special cases, such as when a device uses platform UDP socket to send TMF messages, they will be dropped due + * to untrusted origin. This filter is enabled by default. + * + * When this filter is disabled, UDP messages sent to the TMF port that originate from untrusted origin (such as + * host, CLI or an external IPv6 node) will be allowed. + * + * @note This API requires `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` and is only used by Thread Test Harness + * to test network behavior by sending special TMF messages from the CLI on a POSIX host. + * + * @param[in] aInstance A pointer to an OpenThread instance. + * @param[in] aEnabled TRUE to enable filter, FALSE otherwise. + * + */ +void otThreadSetTmfOriginFilterEnabled(otInstance *aInstance, bool aEnabled); + +/** + * Indicates whether the filter that drops TMF UDP messages from untrusted origin is enabled or not. + * + * This is intended for testing only and available when `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` config is enabled. + * + * @returns TRUE if the filter is enabled, FALSE otherwise. + * + */ +bool otThreadIsTmfOriginFilterEnabled(otInstance *aInstance); + /** * Gets the range of router IDs that are allowed to assign to nodes within the thread network. * diff --git a/src/cli/README.md b/src/cli/README.md index 2921b19a6414..b8d1b6c6621d 100644 --- a/src/cli/README.md +++ b/src/cli/README.md @@ -123,6 +123,7 @@ Done - [tcp](README_TCP.md) - [thread](#thread-start) - [timeinqueue](#timeinqueue) +- [tmforiginfilter](#tmforiginfilter-enabledisable) - [trel](#trel) - [tvcheck](#tvcheck-enable) - [txpower](#txpower) @@ -3728,6 +3729,39 @@ Reset the TX queue time-in-queue statistics. Done ``` +### tmforiginfilter \[enable|disable\] + +Enable/disable filter that drops UDP messages sent to the TMF port from untrusted origin. Also get the current state +of the filter if no argument is specified. + +Note: This filter is enabled by default. + +This is intended for testing only. `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` is required. + +Get the current state of the filter. + +``` +> tmforiginfilter +Enabled +``` + +Enable or disable the filter. + +``` +> tmforiginfilter enable +Done +> +> tmforiginfilter +Enabled +> +> tmforiginfilter disable +Done +> +> tmforiginfilter +Disabled +> +``` + ### trel Indicate whether TREL radio operation is enabled or not. @@ -3821,7 +3855,7 @@ Done ### tvcheck disable -Enable thread version check when upgrading to router or leader. +Disable thread version check when upgrading to router or leader. Note: Thread version check is enabled by default. diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp index 2a98ee0ecd7b..5b36aee3afbf 100644 --- a/src/cli/cli.cpp +++ b/src/cli/cli.cpp @@ -1251,6 +1251,34 @@ template <> otError Interpreter::Process(Arg aArgs[]) return ProcessEnableDisable(aArgs, otThreadSetCcmEnabled); } +/** + * @cli tmforiginfilter + * @code + * tmforiginfilter + * Enabled + * @endcode + * @par + * @code + * tmforiginfilter enable + * Done + * @endcode + * @code + * tmforiginfilter disable + * Done + * @endcode + * @par + * @cparam tmforiginfilter [@ca{enable|disable}] + * By default the filter that drops TMF UDP messages from untrusted origin + * is enabled. When disabled, UDP messages sent to the TMF port that originate + * from untrusted origin (such as host, CLI or an external IPv6 node) will be + * allowed. + * @note `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` is required. + */ +template <> otError Interpreter::Process(Arg aArgs[]) +{ + return ProcessEnableDisable(aArgs, otThreadIsTmfOriginFilterEnabled, otThreadSetTmfOriginFilterEnabled); +} + /** * @cli tvcheck (enable,disable) * @code @@ -8702,6 +8730,9 @@ otError Interpreter::ProcessCommand(Arg aArgs[]) #if OPENTHREAD_CONFIG_TX_QUEUE_STATISTICS_ENABLE CmdEntry("timeinqueue"), #endif +#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE + CmdEntry("tmforiginfilter"), +#endif #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE CmdEntry("trel"), #endif diff --git a/src/core/api/thread_ftd_api.cpp b/src/core/api/thread_ftd_api.cpp index 1b19693cd25f..ec3b9b4d4c30 100644 --- a/src/core/api/thread_ftd_api.cpp +++ b/src/core/api/thread_ftd_api.cpp @@ -388,6 +388,16 @@ void otThreadSetThreadVersionCheckEnabled(otInstance *aInstance, bool aEnabled) AsCoreType(aInstance).Get().SetThreadVersionCheckEnabled(aEnabled); } +void otThreadSetTmfOriginFilterEnabled(otInstance *aInstance, bool aEnabled) +{ + AsCoreType(aInstance).Get().SetTmfOriginFilterEnabled(aEnabled); +} + +bool otThreadIsTmfOriginFilterEnabled(otInstance *aInstance) +{ + return AsCoreType(aInstance).Get().IsTmfOriginFilterEnabled(); +} + void otThreadGetRouterIdRange(otInstance *aInstance, uint8_t *aMinRouterId, uint8_t *aMaxRouterId) { AssertPointerIsNotNull(aMinRouterId); diff --git a/src/core/net/ip6.cpp b/src/core/net/ip6.cpp index d5b2e27ed639..74d3e4fe60df 100644 --- a/src/core/net/ip6.cpp +++ b/src/core/net/ip6.cpp @@ -68,6 +68,9 @@ RegisterLogModule("Ip6"); Ip6::Ip6(Instance &aInstance) : InstanceLocator(aInstance) , mIsReceiveIp6FilterEnabled(false) +#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE + , mTmfOriginFilterEnabled(true) +#endif , mSendQueueTask(aInstance) , mIcmp(aInstance) , mUdp(aInstance) @@ -1239,7 +1242,11 @@ Error Ip6::HandleDatagram(OwnedPtr aMessagePtr, bool aIsReassembled) error = aMessagePtr->Read(aMessagePtr->GetOffset() + Udp::Header::kDestPortFieldOffset, destPort)); destPort = BigEndian::HostSwap16(destPort); - if (destPort == Tmf::kUdpPort) + if (destPort == Tmf::kUdpPort +#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE + && mTmfOriginFilterEnabled +#endif + ) { LogNote("Dropping TMF message from untrusted origin"); ExitNow(error = kErrorDrop); diff --git a/src/core/net/ip6.hpp b/src/core/net/ip6.hpp index de04eef8dd3d..f0c2cf7d088c 100644 --- a/src/core/net/ip6.hpp +++ b/src/core/net/ip6.hpp @@ -350,6 +350,26 @@ class Ip6 : public InstanceLocator, private NonCopyable void ResetBorderRoutingCounters(void) { ClearAllBytes(mBorderRoutingCounters); } #endif +#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE + + /** + * Enables or disables the filter that drops TMF UDP messages from untrusted origin. + * + * @param[in] aEnabled TRUE to enable filter, FALSE otherwise. + * + */ + void SetTmfOriginFilterEnabled(bool aEnabled) { mTmfOriginFilterEnabled = aEnabled; } + + /** + * Indicates whether the filter that drops TMF UDP messages from untrusted origin is enabled or not. + * + * @returns TRUE if the filter is enabled, FALSE otherwise. + * + */ + bool IsTmfOriginFilterEnabled(void) { return mTmfOriginFilterEnabled; } + +#endif // OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE + private: static constexpr uint8_t kDefaultHopLimit = OPENTHREAD_CONFIG_IP6_HOP_LIMIT_DEFAULT; static constexpr uint8_t kIp6ReassemblyTimeout = OPENTHREAD_CONFIG_IP6_REASSEMBLY_TIMEOUT; @@ -402,6 +422,10 @@ class Ip6 : public InstanceLocator, private NonCopyable bool mIsReceiveIp6FilterEnabled; +#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE + bool mTmfOriginFilterEnabled : 1; +#endif + Callback mReceiveIp6DatagramCallback; #if OPENTHREAD_CONFIG_NAT64_TRANSLATOR_ENABLE