[tmf] add Backbone TMF agent (#5471)

This commit is contained in:
Simon Lin
2020-09-11 10:11:42 -07:00
committed by GitHub
parent 5e3b169068
commit d783c7abc8
25 changed files with 555 additions and 53 deletions
+2
View File
@@ -176,6 +176,7 @@ LOCAL_SRC_FILES := \
src/core/api/thread_api.cpp \
src/core/api/thread_ftd_api.cpp \
src/core/api/udp_api.cpp \
src/core/backbone_router/backbone_tmf.cpp \
src/core/backbone_router/bbr_leader.cpp \
src/core/backbone_router/bbr_local.cpp \
src/core/backbone_router/bbr_manager.cpp \
@@ -291,6 +292,7 @@ LOCAL_SRC_FILES := \
src/lib/spinel/spinel_encoder.cpp \
src/lib/url/url.cpp \
src/posix/platform/alarm.cpp \
src/posix/platform/backbone.cpp \
src/posix/platform/entropy.cpp \
src/posix/platform/hdlc_interface.cpp \
src/posix/platform/logging.cpp \
+5
View File
@@ -39,10 +39,15 @@
extern "C" {
#endif
/**
* This enumeration defines the OpenThread network interface identifiers.
*
*/
typedef enum otNetifIdentifier
{
OT_NETIF_UNSPECIFIED = 0, ///< Unspecified network interface.
OT_NETIF_THREAD, ///< The Thread interface.
OT_NETIF_BACKBONE, ///< The Backbone interface.
} otNetifIdentifier;
/**
+2
View File
@@ -319,6 +319,8 @@ openthread_core_files = [
"api/thread_api.cpp",
"api/thread_ftd_api.cpp",
"api/udp_api.cpp",
"backbone_router/backbone_tmf.cpp",
"backbone_router/backbone_tmf.hpp",
"backbone_router/bbr_leader.cpp",
"backbone_router/bbr_leader.hpp",
"backbone_router/bbr_local.cpp",
+1
View File
@@ -102,6 +102,7 @@ set(COMMON_SOURCES
api/thread_api.cpp
api/thread_ftd_api.cpp
api/udp_api.cpp
backbone_router/backbone_tmf.cpp
backbone_router/bbr_leader.cpp
backbone_router/bbr_local.cpp
backbone_router/bbr_manager.cpp
+2
View File
@@ -144,6 +144,7 @@ SOURCES_COMMON = \
api/thread_api.cpp \
api/thread_ftd_api.cpp \
api/udp_api.cpp \
backbone_router/backbone_tmf.cpp \
backbone_router/bbr_leader.cpp \
backbone_router/bbr_local.cpp \
backbone_router/bbr_manager.cpp \
@@ -325,6 +326,7 @@ endif # OPENTHREAD_ENABLE_VENDOR_EXTENSION
HEADERS_COMMON = \
openthread-core-config.h \
backbone_router/backbone_tmf.hpp \
backbone_router/bbr_leader.hpp \
backbone_router/bbr_local.hpp \
backbone_router/bbr_manager.hpp \
+77
View File
@@ -0,0 +1,77 @@
/*
* Copyright (c) 2020, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file implements Backbone Thread Management Framework (TMF) functionalities.
*/
#include "backbone_tmf.hpp"
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
#include "common/locator-getters.hpp"
namespace ot {
namespace BackboneRouter {
otError BackboneTmfAgent::Start(void)
{
return Coap::Start(kBackboneUdpPort, OT_NETIF_BACKBONE);
}
otError BackboneTmfAgent::Filter(const ot::Coap::Message &aMessage,
const Ip6::MessageInfo & aMessageInfo,
void * aContext)
{
OT_UNUSED_VARIABLE(aMessage);
return static_cast<BackboneTmfAgent *>(aContext)->IsBackboneTmfMessage(aMessageInfo) ? OT_ERROR_NONE
: OT_ERROR_NOT_TMF;
}
bool BackboneTmfAgent::IsBackboneTmfMessage(const Ip6::MessageInfo &aMessageInfo) const
{
const Ip6::Address &dst = aMessageInfo.GetSockAddr();
const Ip6::Address &src = aMessageInfo.GetPeerAddr();
// A Backbone TMF message must comply with following rules:
// The destination must be one of:
// 1. All Network BBRs (Link-Local scope)
// 2. All Domain BBRs (Link-Local scope)
// 3. A Backbone Link-Local address
// The source must be a Backbone Link-local address.
return (Get<BackboneRouter::Local>().IsEnabled() && src.IsLinkLocal() &&
(dst.IsLinkLocal() || dst == Get<BackboneRouter::Local>().GetAllNetworkBackboneRoutersAddress() ||
dst == Get<BackboneRouter::Local>().GetAllDomainBackboneRoutersAddress()));
}
} // namespace BackboneRouter
} // namespace ot
#endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+91
View File
@@ -0,0 +1,91 @@
/*
* Copyright (c) 2020, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file includes definitions for Backbone TMF functionality.
*/
#ifndef OT_CORE_THREAD_BACKBONE_TMF_HPP_
#define OT_CORE_THREAD_BACKBONE_TMF_HPP_
#include "coap/coap.hpp"
namespace ot {
namespace BackboneRouter {
enum
{
kBackboneUdpPort = 61631, ///< Backbone TMF UDP Port
};
/**
* This class implements functionality of the Backbone TMF agent.
*
*/
class BackboneTmfAgent : public Coap::Coap
{
public:
/**
* This constructor initializes the object.
*
* @param[in] aInstance A reference to the OpenThread instance.
*
*/
explicit BackboneTmfAgent(Instance &aInstance)
: Coap::Coap(aInstance)
{
SetInterceptor(&Filter, this);
}
/**
* This method starts the TMF agent.
*
* @retval OT_ERROR_NONE Successfully started the CoAP service.
* @retval OT_ERROR_ALREADY Already started.
*
*/
otError Start(void);
/**
* This method returns whether @p aMessageInfo meets Backbone Thread Management Framework Addressing Rules.
*
* @retval true Thread Management Framework Addressing Rules are met.
* @retval false Thread Management Framework Addressing Rules are not met.
*
*/
bool IsBackboneTmfMessage(const Ip6::MessageInfo &aMessageInfo) const;
private:
static otError Filter(const ot::Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo, void *aContext);
};
} // namespace BackboneRouter
} // namespace ot
#endif // OT_CORE_THREAD_BACKBONE_TMF_HPP_
+25
View File
@@ -56,6 +56,7 @@ Manager::Manager(Instance &aInstance)
, mNdProxyTable(aInstance)
, mMulticastListenersTable(aInstance)
, mTimer(aInstance, Manager::HandleTimer, this)
, mBackboneTmfAgent(aInstance)
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
, mDuaResponseStatus(ThreadStatusTlv::kDuaSuccess)
, mMlrResponseStatus(ThreadStatusTlv::kMlrSuccess)
@@ -67,6 +68,8 @@ Manager::Manager(Instance &aInstance)
void Manager::HandleNotifierEvents(Events aEvents)
{
otError error;
if (aEvents.Contains(kEventThreadBackboneRouterStateChanged))
{
if (Get<BackboneRouter::Local>().GetState() == OT_BACKBONE_ROUTER_STATE_DISABLED)
@@ -75,6 +78,17 @@ void Manager::HandleNotifierEvents(Events aEvents)
Get<Tmf::TmfAgent>().RemoveResource(mDuaRegistration);
mTimer.Stop();
mMulticastListenersTable.Clear();
error = mBackboneTmfAgent.Stop();
if (error != OT_ERROR_NONE)
{
otLogWarnBbr("Stop Backbone TMF agent: %s", otThreadErrorToString(error));
}
else
{
otLogInfoBbr("Stop Backbone TMF agent: %s", otThreadErrorToString(error));
}
}
else
{
@@ -84,6 +98,17 @@ void Manager::HandleNotifierEvents(Events aEvents)
{
mTimer.Start(kTimerInterval);
}
error = mBackboneTmfAgent.Start();
if (error != OT_ERROR_NONE)
{
otLogCritBbr("Start Backbone TMF agent: %s", otThreadErrorToString(error));
}
else
{
otLogInfoBbr("Start Backbone TMF agent: %s", otThreadErrorToString(error));
}
}
}
}
+11
View File
@@ -40,6 +40,7 @@
#include <openthread/backbone_router.h>
#include <openthread/backbone_router_ftd.h>
#include "backbone_router/backbone_tmf.hpp"
#include "backbone_router/bbr_leader.hpp"
#include "backbone_router/multicast_listeners_table.hpp"
#include "backbone_router/ndproxy_table.hpp"
@@ -123,6 +124,14 @@ public:
*/
bool ShouldForwardDuaToBackbone(const Ip6::Address &aAddress);
/**
* This method returns a reference to the Backbone TMF agent.
*
* @returns A reference to the Backbone TMF agent.
*
*/
BackboneTmfAgent &GetBackboneTmfAgent(void) { return mBackboneTmfAgent; }
private:
enum
{
@@ -166,6 +175,8 @@ private:
MulticastListenersTable mMulticastListenersTable;
TimerMilli mTimer;
BackboneTmfAgent mBackboneTmfAgent;
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
Ip6::InterfaceIdentifier mDuaResponseTargetMlIid;
ThreadStatusTlv::DuaStatus mDuaResponseStatus;
+13 -2
View File
@@ -1018,14 +1018,25 @@ Coap::Coap(Instance &aInstance)
{
}
otError Coap::Start(uint16_t aPort)
otError Coap::Start(uint16_t aPort, otNetifIdentifier aNetifIdentifier)
{
otError error;
bool socketOpened = false;
VerifyOrExit(!mSocket.IsBound(), error = OT_ERROR_ALREADY);
SuccessOrExit(error = mSocket.Open(&Coap::HandleUdpReceive, this));
VerifyOrExit((error = mSocket.Bind(aPort)) == OT_ERROR_NONE, IgnoreError(mSocket.Close()));
socketOpened = true;
SuccessOrExit(error = mSocket.BindToNetif(aNetifIdentifier));
SuccessOrExit(error = mSocket.Bind(aPort));
exit:
if (error != OT_ERROR_NONE && socketOpened)
{
IgnoreError(mSocket.Close());
}
return error;
}
+3 -2
View File
@@ -606,13 +606,14 @@ public:
/**
* This method starts the CoAP service.
*
* @param[in] aPort The local UDP port to bind to.
* @param[in] aPort The local UDP port to bind to.
* @param[in] aNetifIdentifier The network interface identifier to bind.
*
* @retval OT_ERROR_NONE Successfully started the CoAP service.
* @retval OT_ERROR_ALREADY Already started.
*
*/
otError Start(uint16_t aPort);
otError Start(uint16_t aPort, otNetifIdentifier aNetifIdentifier = OT_NETIF_UNSPECIFIED);
/**
* This method stops the CoAP service.
+6
View File
@@ -763,10 +763,16 @@ template <> inline BackboneRouter::MulticastListenersTable &Instance::Get(void)
{
return mThreadNetif.mBackboneRouterManager.GetMulticastListenersTable();
}
template <> inline BackboneRouter::NdProxyTable &Instance::Get(void)
{
return mThreadNetif.mBackboneRouterManager.GetNdProxyTable();
}
template <> inline BackboneRouter::BackboneTmfAgent &Instance::Get(void)
{
return mThreadNetif.mBackboneRouterManager.GetBackboneTmfAgent();
}
#endif
#if OPENTHREAD_CONFIG_MLR_ENABLE || OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
+70 -15
View File
@@ -392,6 +392,73 @@ public:
return const_cast<const LinkedList *>(this)->Find(aEntry, const_cast<const Type *&>(aPrevEntry));
}
/**
* This template method searches within a given range of the linked list to find an entry matching a given
* indicator.
*
* The template type `Indicator` specifies the type of @p aIndicator object which is used to match against entries
* in the list. To check that an entry matches the given indicator, the `Matches()` method is invoked on each
* `Type` entry in the list. The `Matches()` method should be provided by `Type` class accordingly:
*
* bool Type::Matches(const Indicator &aIndicator) const
*
* @param[in] aBegin A pointer to the begin of the range.
* @param[in] aEnd A pointer to the end of the range, or nullptr to search all entries after @p aBegin.
* @param[in] aIndicator An indicator to match with entries in the list.
* @param[out] aPrevEntry A pointer to output the previous entry on success (when a match is found in the list).
* @p aPrevEntry is set to nullptr if the matching entry is the head of the list. Otherwise
* it is updated to point to the previous entry before the matching entry in the list.
*
* @returns A pointer to the matching entry if one is found, or nullptr if no matching entry was found.
*
*/
template <typename Inidcator>
const Type *FindMatching(const Type * aBegin,
const Type * aEnd,
const Inidcator &aIndicator,
const Type *& aPrevEntry) const
{
const Type *entry;
aPrevEntry = nullptr;
for (entry = aBegin; entry != aEnd; aPrevEntry = entry, entry = entry->GetNext())
{
if (entry->Matches(aIndicator))
{
break;
}
}
return entry;
}
/**
* This template method searches within a given range of the linked list to find an entry matching a given
* indicator.
*
* The template type `Indicator` specifies the type of @p aIndicator object which is used to match against entries
* in the list. To check that an entry matches the given indicator, the `Matches()` method is invoked on each
* `Type` entry in the list. The `Matches()` method should be provided by `Type` class accordingly:
*
* bool Type::Matches(const Indicator &aIndicator) const
*
* @param[in] aBegin A pointer to the begin of the range.
* @param[in] aEnd A pointer to the end of the range, or nullptr to search all entries after @p aBegin.
* @param[in] aIndicator An indicator to match with entries in the list.
* @param[out] aPrevEntry A pointer to output the previous entry on success (when a match is found in the list).
* @p aPrevEntry is set to nullptr if the matching entry is the head of the list. Otherwise
* it is updated to point to the previous entry before the matching entry in the list.
*
* @returns A pointer to the matching entry if one is found, or nullptr if no matching entry was found.
*
*/
template <typename Inidcator>
Type *FindMatching(const Type *aBegin, const Type *aEnd, const Inidcator &aIndicator, Type *&aPrevEntry)
{
return const_cast<Type *>(FindMatching(aBegin, aEnd, aIndicator, const_cast<const Type *&>(aPrevEntry)));
}
/**
* This template method searches within the linked list to find an entry matching a given indicator.
*
@@ -401,7 +468,7 @@ public:
*
* bool Type::Matches(const Indicator &aIndicator) const
*
* @param[in] aIndicator An indicator to match with entries in the list..
* @param[in] aIndicator An indicator to match with entries in the list.
* @param[out] aPrevEntry A pointer to output the previous entry on success (when a match is found in the list).
* @p aPrevEntry is set to nullptr if the matching entry is the head of the list. Otherwise
* it is updated to point to the previous entry before the matching entry in the list.
@@ -411,19 +478,7 @@ public:
*/
template <typename Inidcator> const Type *FindMatching(const Inidcator &aIndicator, const Type *&aPrevEntry) const
{
const Type *entry;
aPrevEntry = nullptr;
for (entry = mHead; entry != nullptr; aPrevEntry = entry, entry = entry->GetNext())
{
if (entry->Matches(aIndicator))
{
break;
}
}
return entry;
return FindMatching(mHead, nullptr, aIndicator, aPrevEntry);
}
/**
@@ -436,7 +491,7 @@ public:
*
* bool Type::Matches(const Indicator &aIndicator) const
*
* @param[in] aIndicator An indicator to match with entries in the list..
* @param[in] aIndicator An indicator to match with entries in the list.
* @param[out] aPrevEntry A pointer to output the previous entry on success (when a match is found in the list).
* @p aPrevEntry is set to nullptr if the matching entry is the head of the list. Otherwise
* it is updated to point to the previous entry before the matching entry in the list.
+90 -5
View File
@@ -99,13 +99,26 @@ otError Udp::Socket::Bind(uint16_t aPort)
return Bind(SockAddr(aPort));
}
#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
otError Udp::Socket::BindToNetif(otNetifIdentifier aNetifIdentifier)
{
return otPlatUdpBindToNetif(this, aNetifIdentifier);
}
OT_UNUSED_VARIABLE(aNetifIdentifier);
otError error = OT_ERROR_NONE;
#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
SuccessOrExit(error = otPlatUdpBindToNetif(this, aNetifIdentifier));
#endif
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
Get<Udp>().BindToNetif(*this, aNetifIdentifier);
#endif
#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
exit:
#endif
return error;
}
otError Udp::Socket::Connect(const SockAddr &aSockAddr)
{
return Get<Udp>().Connect(*this, aSockAddr);
@@ -131,6 +144,9 @@ Udp::Udp(Instance &aInstance)
, mEphemeralPort(kDynamicPortMin)
, mReceivers()
, mSockets()
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
, mPrevBackboneSockets(nullptr)
#endif
#if OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE
, mUdpForwarderContext(nullptr)
, mUdpForwarder(nullptr)
@@ -204,6 +220,35 @@ exit:
return error;
}
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
void Udp::BindToNetif(SocketHandle &aSocket, otNetifIdentifier aNetifIdentifier)
{
if (aNetifIdentifier == OT_NETIF_BACKBONE)
{
SetBackboneSocket(aSocket);
}
}
void Udp::SetBackboneSocket(SocketHandle &aSocket)
{
RemoveSocket(aSocket);
if (mPrevBackboneSockets != nullptr)
{
mSockets.PushAfter(aSocket, *mPrevBackboneSockets);
}
else
{
mSockets.Push(aSocket);
}
}
const Udp::SocketHandle *Udp::GetBackboneSockets(void)
{
return mPrevBackboneSockets != nullptr ? mPrevBackboneSockets->GetNext() : mSockets.GetHead();
}
#endif
otError Udp::Connect(SocketHandle &aSocket, const SockAddr &aSockAddr)
{
otError error = OT_ERROR_NONE;
@@ -296,14 +341,34 @@ exit:
void Udp::AddSocket(SocketHandle &aSocket)
{
IgnoreError(mSockets.Add(aSocket));
SuccessOrExit(mSockets.Add(aSocket));
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
if (mPrevBackboneSockets == nullptr)
{
mPrevBackboneSockets = &aSocket;
}
#endif
exit:
return;
}
void Udp::RemoveSocket(SocketHandle &aSocket)
{
SuccessOrExit(mSockets.Remove(aSocket));
SocketHandle *prev;
SuccessOrExit(mSockets.Find(aSocket, prev));
mSockets.PopAfter(prev);
aSocket.SetNext(nullptr);
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
if (&aSocket == mPrevBackboneSockets)
{
mPrevBackboneSockets = prev;
}
#endif
exit:
return;
}
@@ -397,7 +462,27 @@ void Udp::HandlePayload(Message &aMessage, MessageInfo &aMessageInfo)
SocketHandle *socket;
SocketHandle *prev;
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
{
const SocketHandle *socketsBegin, *socketsEnd;
if (!aMessageInfo.IsHostInterface())
{
socketsBegin = mSockets.GetHead();
socketsEnd = GetBackboneSockets();
}
else
{
socketsBegin = GetBackboneSockets();
socketsEnd = nullptr;
}
socket = mSockets.FindMatching(socketsBegin, socketsEnd, aMessageInfo, prev);
}
#else
socket = mSockets.FindMatching(aMessageInfo, prev);
#endif
VerifyOrExit(socket != nullptr, OT_NOOP);
aMessage.RemoveHeader(aMessage.GetOffset());
+17 -2
View File
@@ -177,7 +177,6 @@ public:
*/
otError Bind(const SockAddr &aSockAddr);
#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
/**
* This method binds the UDP socket to a specified network interface.
*
@@ -188,7 +187,6 @@ public:
*
*/
otError BindToNetif(otNetifIdentifier aNetifIdentifier);
#endif // OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
/**
* This method binds the UDP socket.
@@ -438,6 +436,15 @@ public:
*/
otError Bind(SocketHandle &aSocket, const SockAddr &aSockAddr);
/**
* This method binds a UDP socket to the Network interface.
*
* @param[in] aSocket A reference to the socket.
* @param[in] aNetifIdentifier The network interface identifier.
*
*/
void BindToNetif(SocketHandle &aSocket, otNetifIdentifier aNetifIdentifier);
/**
* This method connects a UDP socket.
*
@@ -562,9 +569,17 @@ private:
void RemoveSocket(SocketHandle &aSocket);
bool IsMlePort(uint16_t aPort) const;
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
void SetBackboneSocket(SocketHandle &aSocket);
const SocketHandle *GetBackboneSockets(void);
#endif
uint16_t mEphemeralPort;
LinkedList<Receiver> mReceivers;
LinkedList<SocketHandle> mSockets;
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
SocketHandle *mPrevBackboneSockets;
#endif
#if OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE
void * mUdpForwarderContext;
otUdpForwarder mUdpForwarder;
+1
View File
@@ -51,6 +51,7 @@
#include "backbone_router/bbr_leader.hpp"
#endif
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
#include "backbone_router/backbone_tmf.hpp"
#include "backbone_router/bbr_local.hpp"
#include "backbone_router/bbr_manager.hpp"
#endif
+1 -10
View File
@@ -40,16 +40,7 @@ namespace Tmf {
otError TmfAgent::Start(void)
{
otError error;
SuccessOrExit(error = Coap::Start(kUdpPort));
#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
error = mSocket.BindToNetif(OT_NETIF_THREAD);
VerifyOrExit(OT_ERROR_NONE == error, IgnoreError(mSocket.Close()));
#endif
exit:
return error;
return Coap::Start(kUdpPort, OT_NETIF_THREAD);
}
otError TmfAgent::Filter(const ot::Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo, void *aContext)
+30 -10
View File
@@ -103,6 +103,9 @@ void __gcov_flush();
*/
enum
{
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
OT_POSIX_OPT_BACKBONE_INTERFACE_NAME = 'B',
#endif
OT_POSIX_OPT_DEBUG_LEVEL = 'd',
OT_POSIX_OPT_DRY_RUN = 'n',
OT_POSIX_OPT_HELP = 'h',
@@ -116,15 +119,19 @@ enum
OT_POSIX_OPT_REAL_TIME_SIGNAL,
};
static const struct option kOptions[] = {{"debug-level", required_argument, NULL, OT_POSIX_OPT_DEBUG_LEVEL},
{"dry-run", no_argument, NULL, OT_POSIX_OPT_DRY_RUN},
{"help", no_argument, NULL, OT_POSIX_OPT_HELP},
{"interface-name", required_argument, NULL, OT_POSIX_OPT_INTERFACE_NAME},
{"radio-version", no_argument, NULL, OT_POSIX_OPT_RADIO_VERSION},
{"real-time-signal", required_argument, NULL, OT_POSIX_OPT_REAL_TIME_SIGNAL},
{"time-speed", required_argument, NULL, OT_POSIX_OPT_TIME_SPEED},
{"verbose", no_argument, NULL, OT_POSIX_OPT_VERBOSE},
{0, 0, 0, 0}};
static const struct option kOptions[] = {
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
{"backbone-interface-name", required_argument, NULL, OT_POSIX_OPT_BACKBONE_INTERFACE_NAME},
#endif
{"debug-level", required_argument, NULL, OT_POSIX_OPT_DEBUG_LEVEL},
{"dry-run", no_argument, NULL, OT_POSIX_OPT_DRY_RUN},
{"help", no_argument, NULL, OT_POSIX_OPT_HELP},
{"interface-name", required_argument, NULL, OT_POSIX_OPT_INTERFACE_NAME},
{"radio-version", no_argument, NULL, OT_POSIX_OPT_RADIO_VERSION},
{"real-time-signal", required_argument, NULL, OT_POSIX_OPT_REAL_TIME_SIGNAL},
{"time-speed", required_argument, NULL, OT_POSIX_OPT_TIME_SPEED},
{"verbose", no_argument, NULL, OT_POSIX_OPT_VERBOSE},
{0, 0, 0, 0}};
static void PrintUsage(const char *aProgramName, FILE *aStream, int aExitCode)
{
@@ -132,6 +139,9 @@ static void PrintUsage(const char *aProgramName, FILE *aStream, int aExitCode)
"Syntax:\n"
" %s [Options] RadioURL\n"
"Options:\n"
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
" -B --backbone-interface-name Backbone network interface name.\n"
#endif
" -d --debug-level Debug level of logging.\n"
" -h --help Display this usage information.\n"
" -I --interface-name name Thread network interface name.\n"
@@ -165,7 +175,12 @@ static void ParseArg(int aArgCount, char *aArgVector[], PosixConfig *aConfig)
while (true)
{
int index = 0;
int option = getopt_long(aArgCount, aArgVector, "d:hI:ns:v", kOptions, &index);
int option = getopt_long(aArgCount, aArgVector,
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
"B:"
#endif
"d:hI:ns:v",
kOptions, &index);
if (option == -1)
{
@@ -183,6 +198,11 @@ static void ParseArg(int aArgCount, char *aArgVector[], PosixConfig *aConfig)
case OT_POSIX_OPT_INTERFACE_NAME:
aConfig->mPlatformConfig.mInterfaceName = optarg;
break;
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
case OT_POSIX_OPT_BACKBONE_INTERFACE_NAME:
aConfig->mPlatformConfig.mBackboneInterfaceName = optarg;
break;
#endif
case OT_POSIX_OPT_DRY_RUN:
aConfig->mIsDryRun = true;
break;
+1
View File
@@ -61,6 +61,7 @@ list(APPEND OT_PLATFORM_DEFINES "OPENTHREAD_PROJECT_CORE_CONFIG_FILE=\"${OT_CONF
add_library(openthread-posix
alarm.cpp
backbone.cpp
entropy.cpp
hdlc_interface.cpp
logging.cpp
+1
View File
@@ -45,6 +45,7 @@ libopenthread_posix_a_CPPFLAGS = \
libopenthread_posix_a_SOURCES = \
alarm.cpp \
backbone.cpp \
entropy.cpp \
hdlc_interface.cpp \
logging.cpp \
+59
View File
@@ -0,0 +1,59 @@
/*
* Copyright (c) 2020, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file implements the platform Backbone interface management on Linux.
*/
#include "openthread-posix-config.h"
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
#include "platform-posix.h"
#include "common/code_utils.hpp"
char gBackboneNetifName[IFNAMSIZ] = "";
unsigned int gBackboneNetifIndex = 0;
void platformBackboneInit(otInstance *aInstance, const char *aInterfaceName)
{
OT_UNUSED_VARIABLE(aInstance);
VerifyOrExit(aInterfaceName != nullptr, OT_NOOP);
VerifyOrDie(strnlen(aInterfaceName, IFNAMSIZ) <= IFNAMSIZ - 1, OT_EXIT_INVALID_ARGUMENTS);
strcpy(gBackboneNetifName, aInterfaceName);
gBackboneNetifIndex = if_nametoindex(gBackboneNetifName);
VerifyOrDie(gBackboneNetifIndex > 0, OT_EXIT_FAILURE);
exit:
return;
}
#endif
@@ -70,10 +70,11 @@ enum
*/
typedef struct otPlatformConfig
{
const char *mInterfaceName; ///< Thread network interface name.
const char *mRadioUrl; ///< Radio url.
int mRealTimeSignal; ///< The real-time signal for microsecond timer.
uint32_t mSpeedUpFactor; ///< Speed up factor.
const char *mBackboneInterfaceName; ///< Backbone network interface name.
const char *mInterfaceName; ///< Thread network interface name.
const char *mRadioUrl; ///< Radio url.
int mRealTimeSignal; ///< The real-time signal for microsecond timer.
uint32_t mSpeedUpFactor; ///< Speed up factor.
} otPlatformConfig;
/**
+23
View File
@@ -407,6 +407,29 @@ extern char gNetifName[IFNAMSIZ];
*/
extern unsigned int gNetifIndex;
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
/**
* This function initializes platform Backbone network.
*
* @param[in] aInstance A pointer to the OpenThread instance.
* @param[in] aInterfaceName A pointer to Thread network interface name.
*
*/
void platformBackboneInit(otInstance *aInstance, const char *aInterfaceName);
/**
* The name of Backbone network interface.
*
*/
extern char gBackboneNetifName[IFNAMSIZ];
/**
* The index of Backbone network interface.
*
*/
extern unsigned int gBackboneNetifIndex;
#endif
#ifdef __cplusplus
}
#endif
+4
View File
@@ -63,6 +63,10 @@ otInstance *otSysInit(otPlatformConfig *aPlatformConfig)
instance = otInstanceInitSingle();
assert(instance != nullptr);
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
platformBackboneInit(instance, aPlatformConfig->mBackboneInterfaceName);
#endif
#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE
platformNetifInit(instance, aPlatformConfig->mInterfaceName);
#elif OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
+15 -3
View File
@@ -276,9 +276,6 @@ otError otPlatUdpBind(otUdpSocket *aUdpSocket)
VerifyOrExit(0 == setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on)), error = OT_ERROR_FAILED);
}
VerifyOrExit(0 == setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &gNetifIndex, sizeof(gNetifIndex)),
error = OT_ERROR_FAILED);
exit:
if (error == OT_ERROR_FAILED)
{
@@ -316,6 +313,21 @@ otError otPlatUdpBindToNetif(otUdpSocket *aUdpSocket, otNetifIdentifier aNetifId
#endif // __linux__
break;
}
case OT_NETIF_BACKBONE:
{
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
#if __linux__
VerifyOrExit(setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, gBackboneNetifName, strlen(gBackboneNetifName)) == 0,
error = OT_ERROR_FAILED);
#else // __NetBSD__ || __FreeBSD__ || __APPLE__
VerifyOrExit(setsockopt(fd, IPPROTO_IP, IP_BOUND_IF, &gBackboneNetifIndex, sizeof(gBackboneNetifIndex)),
error = OT_ERROR_FAILED);
#endif // __linux__
#else
ExitNow(error = OT_ERROR_NOT_IMPLEMENTED);
#endif
break;
}
}
exit: