[mdns] introduce auto-enable mode (#11669)

This commit introduces "auto-enable mode" in mDNS module. When this
mode is enabled, the mDNS module uses the same infrastructure network
interface as the Border Routing manager. The mDNS module is then
automatically enabled or disabled based on the operational state of
that interface. It is recommended to use the auto-enable mode on
Border Routers. New APIs and CLI commands are added to manage this
mode.

This commit also makes the if-index argument optional in `mdns enable`
CLI command. If an index is not provided, the command defaults to
using the Border Router's infrastructure interface. This help
simplify controlling the mDNS state in test scripts.
This commit is contained in:
Abtin Keshavarzian
2025-07-08 17:03:17 -07:00
committed by GitHub
parent 1bd98b7804
commit 6e07db0898
7 changed files with 170 additions and 19 deletions
+1 -1
View File
@@ -52,7 +52,7 @@ extern "C" {
*
* @note This number versions both OpenThread platform and user APIs.
*/
#define OPENTHREAD_API_VERSION (516)
#define OPENTHREAD_API_VERSION (517)
/**
* @addtogroup api-instance
+33
View File
@@ -184,6 +184,39 @@ otError otMdnsSetEnabled(otInstance *aInstance, bool aEnable, uint32_t aInfraIfI
*/
bool otMdnsIsEnabled(otInstance *aInstance);
/**
* Enables or disables the mDNS auto-enable mode.
*
* Requires `OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE`.
*
* When this mode is enabled, the mDNS module uses the same infrastructure network interface as the Border Routing
* manager. The mDNS module is then automatically enabled or disabled based on the operational state of that interface
* (see `otBorderRoutingInit()` and `otPlatInfraIfStateChanged()`).
*
* It is recommended to use the auto-enable mode on Border Routers. The default state of this mode at initialization
* is controlled by the `OPENTHREAD_CONFIG_MULTICAST_DNS_AUTO_ENABLE_ON_INFRA_IF` configuration.
*
* The auto-enable mode can be disabled by a call to `otMdnsSetAutoEnableMode(false)` or by an explicit call to
* `otMdnsSetEnabled()`. Deactivating the auto-enable mode with `otMdnsSetAutoEnableMode(false)` will not change the
* current operational state of the mDNS module (e.g., if it is currently enabled, it remains enabled).
*
* @param[in] aInstance The OpenThread instance.
* @param[in] aEnable A boolean to enable or disable the auto-enable mode.
*/
void otMdnsSetAutoEnableMode(otInstance *aInstance, bool aEnable);
/**
* Indicates whether the auto-enable mode is enabled or disabled.
*
* Requires `OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE`.
*
* @param[in] aInstance The OpenThread instance.
*
* @retval TRUE The auto-enable mode is enabled.
* @retval FALSE The auto-enable mode is disabled.
*/
bool otMdnsGetAutoEnableMode(otInstance *aInstance);
/**
* Sets whether the mDNS module is allowed to send questions requesting unicast responses referred to as "QU" questions.
*
+27 -2
View File
@@ -48,8 +48,23 @@ template <> otError Mdns::Process<Cmd("enable")>(Arg aArgs[])
otError error;
uint32_t infraIfIndex;
SuccessOrExit(error = aArgs[0].ParseAsUint32(infraIfIndex));
VerifyOrExit(aArgs[1].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
if (aArgs[0].IsEmpty())
{
bool isRunning;
// If no if-index is provided, we use the Border Router's
// infrastructure if-index (if any).
SuccessOrExit(error = otBorderRoutingGetInfraIfInfo(GetInstancePtr(), &infraIfIndex, &isRunning));
VerifyOrExit(isRunning, error = OT_ERROR_INVALID_STATE);
}
else
#endif
{
SuccessOrExit(error = aArgs[0].ParseAsUint32(infraIfIndex));
VerifyOrExit(aArgs[1].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
}
SuccessOrExit(error = otMdnsSetEnabled(GetInstancePtr(), true, infraIfIndex));
@@ -81,6 +96,13 @@ exit:
return error;
}
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
template <> otError Mdns::Process<Cmd("auto")>(Arg aArgs[])
{
return ProcessEnableDisable(aArgs, otMdnsGetAutoEnableMode, otMdnsSetAutoEnableMode);
}
#endif
template <> otError Mdns::Process<Cmd("unicastquestion")>(Arg aArgs[])
{
return ProcessEnableDisable(aArgs, otMdnsIsQuestionUnicastAllowed, otMdnsSetQuestionUnicastAllowed);
@@ -1241,6 +1263,9 @@ otError Mdns::Process(Arg aArgs[])
}
static constexpr Command kCommands[] = {
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
CmdEntry("auto"),
#endif
CmdEntry("browser"),
#if OPENTHREAD_CONFIG_MULTICAST_DNS_ENTRY_ITERATION_API_ENABLE
CmdEntry("browsers"),
+12
View File
@@ -46,6 +46,18 @@ otError otMdnsSetEnabled(otInstance *aInstance, bool aEnable, uint32_t aInfraIfI
bool otMdnsIsEnabled(otInstance *aInstance) { return AsCoreType(aInstance).Get<Dns::Multicast::Core>().IsEnabled(); }
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
void otMdnsSetAutoEnableMode(otInstance *aInstance, bool aEnable)
{
AsCoreType(aInstance).Get<Dns::Multicast::Core>().SetAutoEnableMode(aEnable);
}
bool otMdnsGetAutoEnableMode(otInstance *aInstance)
{
return AsCoreType(aInstance).Get<Dns::Multicast::Core>().GetAutoEnableMode();
}
#endif
void otMdnsSetQuestionUnicastAllowed(otInstance *aInstance, bool aAllow)
{
AsCoreType(aInstance).Get<Dns::Multicast::Core>().SetQuestionUnicastAllowed(aAllow);
+1 -1
View File
@@ -164,7 +164,7 @@ Error InfraIf::HandleStateChanged(uint32_t aIfIndex, bool aIsRunning)
Get<Dns::ServiceDiscovery::Server>().HandleInfraIfStateChanged();
#endif
#if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE && OPENTHREAD_CONFIG_MULTICAST_DNS_AUTO_ENABLE_ON_INFRA_IF
#if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
Get<Dns::Multicast::Core>().HandleInfraIfStateChanged();
#endif
+46 -6
View File
@@ -80,6 +80,7 @@ const char Core::kServicesDnssdLabels[] = "_services._dns-sd._udp";
Core::Core(Instance &aInstance)
: InstanceLocator(aInstance)
, mIsEnabled(false)
, mAutoEnable(kDefaultAutoEnable)
, mIsQuestionUnicastAllowed(kDefaultQuAllowed)
, mMaxMessageSize(kMaxMessageSize)
, mInfraIfIndex(0)
@@ -109,10 +110,15 @@ void Core::AfterInstanceInit(void)
mLocalHost.GenerateName();
}
Error Core::SetEnabled(bool aEnable, uint32_t aInfraIfIndex)
Error Core::SetEnabled(bool aEnable, uint32_t aInfraIfIndex, Requester aRequester)
{
Error error = kErrorNone;
if (aRequester == kRequesterUser)
{
mAutoEnable = false;
}
VerifyOrExit(aEnable != mIsEnabled, error = kErrorAlready);
mIsEnabled = aEnable;
@@ -122,11 +128,12 @@ Error Core::SetEnabled(bool aEnable, uint32_t aInfraIfIndex)
if (mIsEnabled)
{
LogInfo("Enabling on infra-if-index %lu", ToUlong(mInfraIfIndex));
LogInfo("%snabling on infra-if-index %lu", (aRequester == kRequesterAuto) ? "Auto-e" : "E",
ToUlong(mInfraIfIndex));
}
else
{
LogInfo("Disabling");
LogInfo("%sisabling", (aRequester == kRequesterAuto) ? "Auto-d" : "D");
mLocalHost.ClearAddresses();
mHostEntries.Clear();
@@ -151,12 +158,45 @@ exit:
return error;
}
#if OPENTHREAD_CONFIG_MULTICAST_DNS_AUTO_ENABLE_ON_INFRA_IF
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
void Core::SetAutoEnableMode(bool aEnable)
{
VerifyOrExit(mAutoEnable != aEnable);
mAutoEnable = aEnable;
if (mAutoEnable)
{
if (!Get<BorderRouter::InfraIf>().IsRunning())
{
IgnoreError(SetEnabled(false, mInfraIfIndex, kRequesterAuto));
ExitNow();
}
if (IsEnabled())
{
VerifyOrExit(Get<BorderRouter::InfraIf>().GetIfIndex() != mInfraIfIndex);
IgnoreError(SetEnabled(false, mInfraIfIndex, kRequesterAuto));
}
IgnoreError(SetEnabled(true, Get<BorderRouter::InfraIf>().GetIfIndex(), kRequesterAuto));
}
exit:
return;
}
void Core::HandleInfraIfStateChanged(void)
{
IgnoreError(SetEnabled(Get<BorderRouter::InfraIf>().IsRunning(), Get<BorderRouter::InfraIf>().GetIfIndex()));
VerifyOrExit(mAutoEnable);
IgnoreError(SetEnabled(Get<BorderRouter::InfraIf>().IsRunning(), Get<BorderRouter::InfraIf>().GetIfIndex(),
kRequesterAuto));
exit:
return;
}
#endif
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
template <typename EntryType, typename ItemInfo>
Error Core::Register(const ItemInfo &aItemInfo, RequestId aRequestId, RegisterCallback aCallback)
+50 -9
View File
@@ -69,6 +69,11 @@ struct otMdnsIterator
};
namespace ot {
namespace BorderRouter {
class InfraIf;
}
namespace Dns {
namespace Multicast {
@@ -90,6 +95,7 @@ extern "C" void otPlatMdnsHandleHostAddressRemoveAll(otInstance *aInstance, uint
class Core : public InstanceLocator, private NonCopyable
{
friend class ot::Instance;
friend class ot::BorderRouter::InfraIf;
friend void otPlatMdnsHandleReceive(otInstance *aInstance,
otMessage *aMessage,
@@ -172,7 +178,10 @@ public:
* @retval kErrorAlready mDNS is already enabled on an enable request, or is already disabled on a disable request.
* @retval kErrorFailed Failed to enable/disable mDNS.
*/
Error SetEnabled(bool aEnable, uint32_t aInfraIfIndex);
Error SetEnabled(bool aEnable, uint32_t aInfraIfIndex)
{
return SetEnabled(aEnable, aInfraIfIndex, kRequesterUser);
}
/**
* Indicates whether or not mDNS module is enabled.
@@ -182,6 +191,35 @@ public:
*/
bool IsEnabled(void) const { return mIsEnabled; }
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
/**
* Enables or disables the mDNS auto-enable mode.
*
* When this mode is enabled, the mDNS module uses the same infrastructure network interface as the Border Routing
* manager. The mDNS module is then automatically enabled or disabled based on the operational state of that
* interface.
*
* It is recommended to use the auto-enable mode on Border Routers. The default state of this mode at
* initialization is controlled by the `OPENTHREAD_CONFIG_MULTICAST_DNS_AUTO_ENABLE_ON_INFRA_IF` configuration.
*
* The auto-enable mode can be disabled by a call to `SetAutoEnableMode(false)` or by an explicit call to
* `SetEnabled()`. Deactivating the auto-enable mode with `SetAutoEnableMode(false)` will not change the current
* operational state of the mDNS module (e.g., if it is currently enabled, it remains enabled).
*
* @param[in] aEnable A boolean to enable or disable the auto-enable mode.
*/
void SetAutoEnableMode(bool aEnable);
/**
* Indicates whether the auto-enable mode is enabled or disabled.
*
* @retval TRUE The auto-enable mode is enabled.
* @retval FALSE The auto-enable mode is disabled.
*/
bool GetAutoEnableMode(void) const { return mAutoEnable; }
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
/**
* Gets the local host name.
*
@@ -202,13 +240,6 @@ public:
*/
Error SetLocalHostName(const char *aName) { return mLocalHost.SetName(aName); }
#if OPENTHREAD_CONFIG_MULTICAST_DNS_AUTO_ENABLE_ON_INFRA_IF
/**
* Notifies `AdvertisingProxy` that `InfraIf` state changed.
*/
void HandleInfraIfStateChanged(void);
#endif
/**
* Sets whether mDNS module is allowed to send questions requesting unicast responses referred to as "QU" questions.
*
@@ -815,7 +846,8 @@ private:
static constexpr uint16_t kUdpPort = 5353;
static constexpr bool kDefaultQuAllowed = OPENTHREAD_CONFIG_MULTICAST_DNS_DEFAULT_QUESTION_UNICAST_ALLOWED;
static constexpr bool kDefaultAutoEnable = OPENTHREAD_CONFIG_MULTICAST_DNS_AUTO_ENABLE_ON_INFRA_IF;
static constexpr bool kDefaultQuAllowed = OPENTHREAD_CONFIG_MULTICAST_DNS_DEFAULT_QUESTION_UNICAST_ALLOWED;
static constexpr uint32_t kMaxMessageSize = 1200;
@@ -855,6 +887,12 @@ private:
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
enum Requester : uint8_t // Used by `SetEnabled()`.
{
kRequesterUser,
kRequesterAuto,
};
enum Section : uint8_t
{
kQuestionSection,
@@ -2229,6 +2267,8 @@ private:
Error Stop(const BrowserResolverType &aBrowserOrResolver);
void AfterInstanceInit(void);
Error SetEnabled(bool aEnable, uint32_t aInfraIfIndex, Requester aRequester);
void HandleInfraIfStateChanged(void);
void HandleHostAddressEvent(const Ip6::Address &aAddress, bool aAdded, uint32_t aInfraIfIndex);
void HandleHostAddressRemoveAll(uint32_t aInfraIfIndex);
void InvokeConflictCallback(const char *aName, const char *aServiceType);
@@ -2266,6 +2306,7 @@ private:
static const char kServicesDnssdLabels[]; // "_services._dns-sd._udp"
bool mIsEnabled;
bool mAutoEnable;
bool mIsQuestionUnicastAllowed;
uint16_t mMaxMessageSize;
uint32_t mInfraIfIndex;