mirror of
https://github.com/espressif/openthread.git
synced 2026-08-19 17:09:51 +00:00
[border-router] border routing optional at runtime (#6629)
This commit allows launching an OpenThread daemon which was built with backbone-router and border-routing support but disabling them at runtime by not specifying the `-B` option.
This commit is contained in:
@@ -145,6 +145,7 @@ LOCAL_EXPORT_C_INCLUDE_DIRS := \
|
||||
|
||||
LOCAL_CPPFLAGS := \
|
||||
-std=c++11 \
|
||||
-Wno-error=non-virtual-dtor \
|
||||
-pedantic-errors \
|
||||
$(NULL)
|
||||
|
||||
@@ -355,6 +356,7 @@ LOCAL_SRC_FILES := \
|
||||
src/posix/platform/hdlc_interface.cpp \
|
||||
src/posix/platform/infra_if.cpp \
|
||||
src/posix/platform/logging.cpp \
|
||||
src/posix/platform/mainloop.cpp \
|
||||
src/posix/platform/memory.cpp \
|
||||
src/posix/platform/misc.cpp \
|
||||
src/posix/platform/multicast_routing.cpp \
|
||||
|
||||
@@ -76,6 +76,7 @@ add_library(openthread-posix
|
||||
hdlc_interface.cpp
|
||||
infra_if.cpp
|
||||
logging.cpp
|
||||
mainloop.cpp
|
||||
memory.cpp
|
||||
misc.cpp
|
||||
multicast_routing.cpp
|
||||
|
||||
@@ -51,6 +51,7 @@ libopenthread_posix_a_SOURCES = \
|
||||
hdlc_interface.cpp \
|
||||
infra_if.cpp \
|
||||
logging.cpp \
|
||||
mainloop.cpp \
|
||||
memory.cpp \
|
||||
misc.cpp \
|
||||
multicast_routing.cpp \
|
||||
@@ -72,6 +73,7 @@ libopenthread_posix_a_LIBADD
|
||||
|
||||
noinst_HEADERS = \
|
||||
hdlc_interface.hpp \
|
||||
mainloop.hpp \
|
||||
multicast_routing.hpp \
|
||||
openthread-posix-config.h \
|
||||
platform-posix.h \
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "multicast_routing.hpp"
|
||||
#include "platform-posix.h"
|
||||
#include "common/code_utils.hpp"
|
||||
#include "posix/platform/mainloop.hpp"
|
||||
|
||||
char gBackboneNetifName[IFNAMSIZ] = "";
|
||||
unsigned int gBackboneNetifIndex = 0;
|
||||
@@ -49,10 +50,10 @@ void platformBackboneInit(otInstance *aInstance, const char *aInterfaceName)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
|
||||
VerifyOrDie(aInterfaceName != nullptr, OT_EXIT_INVALID_ARGUMENTS);
|
||||
VerifyOrExit(aInterfaceName != nullptr);
|
||||
|
||||
VerifyOrDie(strnlen(aInterfaceName, IFNAMSIZ) <= IFNAMSIZ - 1, OT_EXIT_INVALID_ARGUMENTS);
|
||||
strcpy(gBackboneNetifName, aInterfaceName);
|
||||
strncpy(gBackboneNetifName, aInterfaceName, sizeof(gBackboneNetifName));
|
||||
|
||||
gBackboneNetifIndex = if_nametoindex(gBackboneNetifName);
|
||||
VerifyOrDie(gBackboneNetifIndex > 0, OT_EXIT_FAILURE);
|
||||
@@ -62,25 +63,9 @@ void platformBackboneInit(otInstance *aInstance, const char *aInterfaceName)
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
|
||||
sMulticastRoutingManager.Init(aInstance);
|
||||
#endif
|
||||
}
|
||||
|
||||
void platformBackboneUpdateFdSet(fd_set &aReadFdSet, int &aMaxFd)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aReadFdSet);
|
||||
OT_UNUSED_VARIABLE(aMaxFd);
|
||||
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
|
||||
sMulticastRoutingManager.UpdateFdSet(aReadFdSet, aMaxFd);
|
||||
#endif
|
||||
}
|
||||
|
||||
void platformBackboneProcess(const fd_set &aReadSet)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aReadSet);
|
||||
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
|
||||
sMulticastRoutingManager.Process(aReadSet);
|
||||
#endif
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void platformBackboneStateChange(otInstance *aInstance, otChangedFlags aFlags)
|
||||
|
||||
+200
-176
@@ -58,16 +58,7 @@
|
||||
#include "common/code_utils.hpp"
|
||||
#include "common/debug.hpp"
|
||||
#include "lib/platform/exit_code.h"
|
||||
|
||||
static char sInfraIfName[IFNAMSIZ];
|
||||
static uint32_t sInfraIfIndex = 0;
|
||||
static int sInfraIfIcmp6Socket = -1;
|
||||
static int sNetLinkSocket = -1;
|
||||
|
||||
static int CreateIcmp6Socket(void);
|
||||
static int CreateNetLinkSocket(void);
|
||||
static void ReceiveNetLinkMessage(otInstance *aInstance);
|
||||
static void ReceiveIcmp6Message(otInstance *aInstance);
|
||||
#include "posix/platform/infra_if.hpp"
|
||||
|
||||
bool otPlatInfraIfHasAddress(uint32_t aInfraIfIndex, const otIp6Address *aAddress)
|
||||
{
|
||||
@@ -102,95 +93,19 @@ otError otPlatInfraIfSendIcmp6Nd(uint32_t aInfraIfIndex,
|
||||
const uint8_t * aBuffer,
|
||||
uint16_t aBufferLength)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
struct iovec iov;
|
||||
struct in6_pktinfo *packetInfo;
|
||||
|
||||
int hopLimit = 255;
|
||||
uint8_t cmsgBuffer[CMSG_SPACE(sizeof(*packetInfo)) + CMSG_SPACE(sizeof(hopLimit))];
|
||||
struct msghdr msgHeader;
|
||||
struct cmsghdr * cmsgPointer;
|
||||
ssize_t rval;
|
||||
struct sockaddr_in6 dest;
|
||||
|
||||
VerifyOrExit(sInfraIfIcmp6Socket >= 0, error = OT_ERROR_FAILED);
|
||||
VerifyOrExit(aInfraIfIndex == sInfraIfIndex, error = OT_ERROR_DROP);
|
||||
|
||||
memset(cmsgBuffer, 0, sizeof(cmsgBuffer));
|
||||
|
||||
// Send the message
|
||||
memset(&dest, 0, sizeof(dest));
|
||||
dest.sin6_family = AF_INET6;
|
||||
memcpy(&dest.sin6_addr, aDestAddress, sizeof(*aDestAddress));
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&dest.sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&dest.sin6_addr))
|
||||
{
|
||||
dest.sin6_scope_id = sInfraIfIndex;
|
||||
}
|
||||
|
||||
iov.iov_base = const_cast<uint8_t *>(aBuffer);
|
||||
iov.iov_len = aBufferLength;
|
||||
|
||||
msgHeader.msg_namelen = sizeof(dest);
|
||||
msgHeader.msg_name = &dest;
|
||||
msgHeader.msg_iov = &iov;
|
||||
msgHeader.msg_iovlen = 1;
|
||||
msgHeader.msg_control = cmsgBuffer;
|
||||
msgHeader.msg_controllen = sizeof(cmsgBuffer);
|
||||
|
||||
// Specify the interface.
|
||||
cmsgPointer = CMSG_FIRSTHDR(&msgHeader);
|
||||
cmsgPointer->cmsg_level = IPPROTO_IPV6;
|
||||
cmsgPointer->cmsg_type = IPV6_PKTINFO;
|
||||
cmsgPointer->cmsg_len = CMSG_LEN(sizeof(*packetInfo));
|
||||
packetInfo = (struct in6_pktinfo *)CMSG_DATA(cmsgPointer);
|
||||
memset(packetInfo, 0, sizeof(*packetInfo));
|
||||
packetInfo->ipi6_ifindex = sInfraIfIndex;
|
||||
|
||||
// Per section 6.1.2 of RFC 4861, we need to send the ICMPv6 message with IP Hop Limit 255.
|
||||
cmsgPointer = CMSG_NXTHDR(&msgHeader, cmsgPointer);
|
||||
cmsgPointer->cmsg_level = IPPROTO_IPV6;
|
||||
cmsgPointer->cmsg_type = IPV6_HOPLIMIT;
|
||||
cmsgPointer->cmsg_len = CMSG_LEN(sizeof(hopLimit));
|
||||
memcpy(CMSG_DATA(cmsgPointer), &hopLimit, sizeof(hopLimit));
|
||||
|
||||
rval = sendmsg(sInfraIfIcmp6Socket, &msgHeader, 0);
|
||||
if (rval < 0)
|
||||
{
|
||||
otLogWarnPlat("failed to send ICMPv6 message: %s", strerror(errno));
|
||||
ExitNow(error = OT_ERROR_FAILED);
|
||||
}
|
||||
|
||||
if (static_cast<size_t>(rval) != iov.iov_len)
|
||||
{
|
||||
otLogWarnPlat("failed to send ICMPv6 message: partially sent");
|
||||
ExitNow(error = OT_ERROR_FAILED);
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
return ot::Posix::InfraNetif::Get().SendIcmp6Nd(aInfraIfIndex, *aDestAddress, aBuffer, aBufferLength);
|
||||
}
|
||||
|
||||
bool platformInfraIfIsRunning(void)
|
||||
{
|
||||
int sock;
|
||||
struct ifreq ifReq;
|
||||
|
||||
OT_ASSERT(sInfraIfIndex != 0);
|
||||
|
||||
sock = SocketWithCloseExec(AF_INET6, SOCK_DGRAM, IPPROTO_IP, kSocketBlock);
|
||||
VerifyOrDie(sock != -1, OT_EXIT_ERROR_ERRNO);
|
||||
|
||||
memset(&ifReq, 0, sizeof(ifReq));
|
||||
strncpy(ifReq.ifr_name, sInfraIfName, sizeof(ifReq.ifr_name));
|
||||
VerifyOrDie(ioctl(sock, SIOCGIFFLAGS, &ifReq) != -1, OT_EXIT_ERROR_ERRNO);
|
||||
|
||||
close(sock);
|
||||
|
||||
return (ifReq.ifr_flags & IFF_RUNNING);
|
||||
return ot::Posix::InfraNetif::Get().IsRunning();
|
||||
}
|
||||
|
||||
static int CreateIcmp6Socket(void)
|
||||
namespace ot {
|
||||
namespace Posix {
|
||||
namespace {
|
||||
|
||||
int CreateIcmp6Socket(void)
|
||||
{
|
||||
int sock;
|
||||
int rval;
|
||||
@@ -235,76 +150,8 @@ static int CreateIcmp6Socket(void)
|
||||
return sock;
|
||||
}
|
||||
|
||||
uint32_t platformInfraIfInit(otInstance *aInstance, const char *aIfName)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
|
||||
ssize_t rval;
|
||||
uint32_t ifIndex = 0;
|
||||
|
||||
if (strlen(aIfName) >= sizeof(sInfraIfName))
|
||||
{
|
||||
otLogCritPlat("infra interface name '%s' is too long", aIfName);
|
||||
DieNow(OT_EXIT_INVALID_ARGUMENTS);
|
||||
}
|
||||
strcpy(sInfraIfName, aIfName);
|
||||
|
||||
// Initializes the infra interface.
|
||||
ifIndex = if_nametoindex(aIfName);
|
||||
if (ifIndex == 0)
|
||||
{
|
||||
otLogCritPlat("failed to get the index for infra interface %s", aIfName);
|
||||
DieNow(OT_EXIT_INVALID_ARGUMENTS);
|
||||
}
|
||||
sInfraIfIndex = ifIndex;
|
||||
|
||||
sInfraIfIcmp6Socket = CreateIcmp6Socket();
|
||||
#ifdef __linux__
|
||||
rval = setsockopt(sInfraIfIcmp6Socket, SOL_SOCKET, SO_BINDTODEVICE, sInfraIfName, strlen(sInfraIfName));
|
||||
#else // __NetBSD__ || __FreeBSD__ || __APPLE__
|
||||
rval = setsockopt(sInfraIfIcmp6Socket, IPPROTO_IP, IP_BOUND_IF, &sInfraIfIndex, sizeof(sInfraIfIndex));
|
||||
#endif // __linux__
|
||||
VerifyOrDie(rval == 0, OT_EXIT_ERROR_ERRNO);
|
||||
|
||||
sNetLinkSocket = CreateNetLinkSocket();
|
||||
|
||||
return sInfraIfIndex;
|
||||
}
|
||||
|
||||
void platformInfraIfDeinit(void)
|
||||
{
|
||||
if (sInfraIfIcmp6Socket != -1)
|
||||
{
|
||||
close(sInfraIfIcmp6Socket);
|
||||
sInfraIfIcmp6Socket = -1;
|
||||
}
|
||||
|
||||
if (sNetLinkSocket != -1)
|
||||
{
|
||||
close(sNetLinkSocket);
|
||||
sNetLinkSocket = -1;
|
||||
}
|
||||
|
||||
sInfraIfIndex = 0;
|
||||
}
|
||||
|
||||
void platformInfraIfUpdateFdSet(fd_set &aReadFdSet, int &aMaxFd)
|
||||
{
|
||||
VerifyOrExit(sInfraIfIcmp6Socket != -1);
|
||||
VerifyOrExit(sNetLinkSocket != -1);
|
||||
|
||||
FD_SET(sInfraIfIcmp6Socket, &aReadFdSet);
|
||||
aMaxFd = OT_MAX(aMaxFd, sInfraIfIcmp6Socket);
|
||||
|
||||
FD_SET(sNetLinkSocket, &aReadFdSet);
|
||||
aMaxFd = OT_MAX(aMaxFd, sNetLinkSocket);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a net-link socket that subscribes to link & addresses events.
|
||||
static int CreateNetLinkSocket(void)
|
||||
int CreateNetLinkSocket(void)
|
||||
{
|
||||
int sock;
|
||||
int rval;
|
||||
@@ -324,7 +171,175 @@ static int CreateNetLinkSocket(void)
|
||||
return sock;
|
||||
}
|
||||
|
||||
static void ReceiveNetLinkMessage(otInstance *aInstance)
|
||||
} // namespace
|
||||
|
||||
otError InfraNetif::SendIcmp6Nd(uint32_t aInfraIfIndex,
|
||||
const otIp6Address &aDestAddress,
|
||||
const uint8_t * aBuffer,
|
||||
uint16_t aBufferLength)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
struct iovec iov;
|
||||
struct in6_pktinfo *packetInfo;
|
||||
|
||||
int hopLimit = 255;
|
||||
uint8_t cmsgBuffer[CMSG_SPACE(sizeof(*packetInfo)) + CMSG_SPACE(sizeof(hopLimit))];
|
||||
struct msghdr msgHeader;
|
||||
struct cmsghdr * cmsgPointer;
|
||||
ssize_t rval;
|
||||
struct sockaddr_in6 dest;
|
||||
|
||||
VerifyOrExit(mInfraIfIcmp6Socket >= 0, error = OT_ERROR_FAILED);
|
||||
VerifyOrExit(aInfraIfIndex == mInfraIfIndex, error = OT_ERROR_DROP);
|
||||
|
||||
memset(cmsgBuffer, 0, sizeof(cmsgBuffer));
|
||||
|
||||
// Send the message
|
||||
memset(&dest, 0, sizeof(dest));
|
||||
dest.sin6_family = AF_INET6;
|
||||
memcpy(&dest.sin6_addr, &aDestAddress, sizeof(aDestAddress));
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&dest.sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&dest.sin6_addr))
|
||||
{
|
||||
dest.sin6_scope_id = mInfraIfIndex;
|
||||
}
|
||||
|
||||
iov.iov_base = const_cast<uint8_t *>(aBuffer);
|
||||
iov.iov_len = aBufferLength;
|
||||
|
||||
msgHeader.msg_namelen = sizeof(dest);
|
||||
msgHeader.msg_name = &dest;
|
||||
msgHeader.msg_iov = &iov;
|
||||
msgHeader.msg_iovlen = 1;
|
||||
msgHeader.msg_control = cmsgBuffer;
|
||||
msgHeader.msg_controllen = sizeof(cmsgBuffer);
|
||||
|
||||
// Specify the interface.
|
||||
cmsgPointer = CMSG_FIRSTHDR(&msgHeader);
|
||||
cmsgPointer->cmsg_level = IPPROTO_IPV6;
|
||||
cmsgPointer->cmsg_type = IPV6_PKTINFO;
|
||||
cmsgPointer->cmsg_len = CMSG_LEN(sizeof(*packetInfo));
|
||||
packetInfo = (struct in6_pktinfo *)CMSG_DATA(cmsgPointer);
|
||||
memset(packetInfo, 0, sizeof(*packetInfo));
|
||||
packetInfo->ipi6_ifindex = mInfraIfIndex;
|
||||
|
||||
// Per section 6.1.2 of RFC 4861, we need to send the ICMPv6 message with IP Hop Limit 255.
|
||||
cmsgPointer = CMSG_NXTHDR(&msgHeader, cmsgPointer);
|
||||
cmsgPointer->cmsg_level = IPPROTO_IPV6;
|
||||
cmsgPointer->cmsg_type = IPV6_HOPLIMIT;
|
||||
cmsgPointer->cmsg_len = CMSG_LEN(sizeof(hopLimit));
|
||||
memcpy(CMSG_DATA(cmsgPointer), &hopLimit, sizeof(hopLimit));
|
||||
|
||||
rval = sendmsg(mInfraIfIcmp6Socket, &msgHeader, 0);
|
||||
if (rval < 0)
|
||||
{
|
||||
otLogWarnPlat("failed to send ICMPv6 message: %s", strerror(errno));
|
||||
ExitNow(error = OT_ERROR_FAILED);
|
||||
}
|
||||
|
||||
if (static_cast<size_t>(rval) != iov.iov_len)
|
||||
{
|
||||
otLogWarnPlat("failed to send ICMPv6 message: partially sent");
|
||||
ExitNow(error = OT_ERROR_FAILED);
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
bool InfraNetif::IsRunning(void) const
|
||||
{
|
||||
int sock;
|
||||
struct ifreq ifReq;
|
||||
|
||||
OT_ASSERT(mInfraIfIndex != 0);
|
||||
|
||||
sock = SocketWithCloseExec(AF_INET6, SOCK_DGRAM, IPPROTO_IP, kSocketBlock);
|
||||
VerifyOrDie(sock != -1, OT_EXIT_ERROR_ERRNO);
|
||||
|
||||
memset(&ifReq, 0, sizeof(ifReq));
|
||||
strncpy(ifReq.ifr_name, mInfraIfName, sizeof(ifReq.ifr_name));
|
||||
VerifyOrDie(ioctl(sock, SIOCGIFFLAGS, &ifReq) != -1, OT_EXIT_ERROR_ERRNO);
|
||||
|
||||
close(sock);
|
||||
|
||||
return (ifReq.ifr_flags & IFF_RUNNING);
|
||||
}
|
||||
|
||||
void InfraNetif::Init(otInstance *aInstance, const char *aIfName)
|
||||
{
|
||||
ssize_t rval;
|
||||
uint32_t ifIndex = 0;
|
||||
|
||||
VerifyOrExit(aIfName != nullptr);
|
||||
|
||||
VerifyOrDie(strnlen(aIfName, sizeof(mInfraIfName)) <= sizeof(mInfraIfName) - 1, OT_EXIT_INVALID_ARGUMENTS);
|
||||
strncpy(mInfraIfName, aIfName, sizeof(mInfraIfName));
|
||||
|
||||
// Initializes the infra interface.
|
||||
ifIndex = if_nametoindex(aIfName);
|
||||
if (ifIndex == 0)
|
||||
{
|
||||
otLogCritPlat("failed to get the index for infra interface %s", aIfName);
|
||||
DieNow(OT_EXIT_INVALID_ARGUMENTS);
|
||||
}
|
||||
mInfraIfIndex = ifIndex;
|
||||
|
||||
mInfraIfIcmp6Socket = CreateIcmp6Socket();
|
||||
#ifdef __linux__
|
||||
rval = setsockopt(mInfraIfIcmp6Socket, SOL_SOCKET, SO_BINDTODEVICE, mInfraIfName, strlen(mInfraIfName));
|
||||
#else // __NetBSD__ || __FreeBSD__ || __APPLE__
|
||||
rval = setsockopt(mInfraIfIcmp6Socket, IPPROTO_IP, IP_BOUND_IF, &mInfraIfIndex, sizeof(mInfraIfIndex));
|
||||
#endif // __linux__
|
||||
VerifyOrDie(rval == 0, OT_EXIT_ERROR_ERRNO);
|
||||
|
||||
mNetLinkSocket = CreateNetLinkSocket();
|
||||
|
||||
SuccessOrDie(otBorderRoutingInit(aInstance, ifIndex, platformInfraIfIsRunning()));
|
||||
SuccessOrDie(otBorderRoutingSetEnabled(aInstance, /* aEnabled */ true));
|
||||
|
||||
mInstance = aInstance;
|
||||
Mainloop::Manager::Get().Add(*this);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void InfraNetif::Deinit(void)
|
||||
{
|
||||
Mainloop::Manager::Get().Remove(*this);
|
||||
|
||||
if (mInfraIfIcmp6Socket != -1)
|
||||
{
|
||||
close(mInfraIfIcmp6Socket);
|
||||
mInfraIfIcmp6Socket = -1;
|
||||
}
|
||||
|
||||
if (mNetLinkSocket != -1)
|
||||
{
|
||||
close(mNetLinkSocket);
|
||||
mNetLinkSocket = -1;
|
||||
}
|
||||
|
||||
mInfraIfIndex = 0;
|
||||
}
|
||||
|
||||
void InfraNetif::Update(otSysMainloopContext &aContext)
|
||||
{
|
||||
VerifyOrExit(mInfraIfIcmp6Socket != -1);
|
||||
VerifyOrExit(mNetLinkSocket != -1);
|
||||
|
||||
FD_SET(mInfraIfIcmp6Socket, &aContext.mReadFdSet);
|
||||
aContext.mMaxFd = OT_MAX(aContext.mMaxFd, mInfraIfIcmp6Socket);
|
||||
|
||||
FD_SET(mNetLinkSocket, &aContext.mReadFdSet);
|
||||
aContext.mMaxFd = OT_MAX(aContext.mMaxFd, mNetLinkSocket);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void InfraNetif::ReceiveNetLinkMessage(void)
|
||||
{
|
||||
const size_t kMaxNetLinkBufSize = 8192;
|
||||
ssize_t len;
|
||||
@@ -334,7 +349,7 @@ static void ReceiveNetLinkMessage(otInstance *aInstance)
|
||||
uint8_t mBuffer[kMaxNetLinkBufSize];
|
||||
} msgBuffer;
|
||||
|
||||
len = recv(sNetLinkSocket, msgBuffer.mBuffer, sizeof(msgBuffer.mBuffer), 0);
|
||||
len = recv(mNetLinkSocket, msgBuffer.mBuffer, sizeof(msgBuffer.mBuffer), 0);
|
||||
if (len < 0)
|
||||
{
|
||||
otLogCritPlat("failed to receive netlink message: %s", strerror(errno));
|
||||
@@ -353,7 +368,7 @@ static void ReceiveNetLinkMessage(otInstance *aInstance)
|
||||
case RTM_DELADDR:
|
||||
case RTM_NEWLINK:
|
||||
case RTM_DELLINK:
|
||||
SuccessOrDie(otPlatInfraIfStateChanged(aInstance, sInfraIfIndex, platformInfraIfIsRunning()));
|
||||
SuccessOrDie(otPlatInfraIfStateChanged(mInstance, mInfraIfIndex, platformInfraIfIsRunning()));
|
||||
break;
|
||||
case NLMSG_ERROR:
|
||||
{
|
||||
@@ -371,7 +386,7 @@ exit:
|
||||
return;
|
||||
}
|
||||
|
||||
static void ReceiveIcmp6Message(otInstance *aInstance)
|
||||
void InfraNetif::ReceiveIcmp6Message(void)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
uint8_t buffer[1500];
|
||||
@@ -400,7 +415,7 @@ static void ReceiveIcmp6Message(otInstance *aInstance)
|
||||
msg.msg_control = cmsgbuf;
|
||||
msg.msg_controllen = sizeof(cmsgbuf);
|
||||
|
||||
rval = recvmsg(sInfraIfIcmp6Socket, &msg, 0);
|
||||
rval = recvmsg(mInfraIfIcmp6Socket, &msg, 0);
|
||||
if (rval < 0)
|
||||
{
|
||||
otLogWarnPlat("failed to receive ICMPv6 message: %s", strerror(errno));
|
||||
@@ -427,13 +442,13 @@ static void ReceiveIcmp6Message(otInstance *aInstance)
|
||||
}
|
||||
}
|
||||
|
||||
VerifyOrExit(ifIndex == sInfraIfIndex, error = OT_ERROR_DROP);
|
||||
VerifyOrExit(ifIndex == mInfraIfIndex, error = OT_ERROR_DROP);
|
||||
|
||||
// We currently accept only RA & RS messages for the Border Router and it requires that
|
||||
// the hoplimit must be 255 and the source address must be a link-local address.
|
||||
VerifyOrExit(hopLimit == 255 && IN6_IS_ADDR_LINKLOCAL(&srcAddr.sin6_addr), error = OT_ERROR_DROP);
|
||||
|
||||
otPlatInfraIfRecvIcmp6Nd(aInstance, ifIndex, reinterpret_cast<otIp6Address *>(&srcAddr.sin6_addr), buffer,
|
||||
otPlatInfraIfRecvIcmp6Nd(mInstance, ifIndex, reinterpret_cast<otIp6Address *>(&srcAddr.sin6_addr), buffer,
|
||||
bufferLength);
|
||||
|
||||
exit:
|
||||
@@ -443,23 +458,32 @@ exit:
|
||||
}
|
||||
}
|
||||
|
||||
void platformInfraIfProcess(otInstance *aInstance, const fd_set &aReadFdSet)
|
||||
void InfraNetif::Process(const otSysMainloopContext &aContext)
|
||||
{
|
||||
VerifyOrExit(sInfraIfIcmp6Socket != -1);
|
||||
VerifyOrExit(sNetLinkSocket != -1);
|
||||
VerifyOrExit(mInfraIfIcmp6Socket != -1);
|
||||
VerifyOrExit(mNetLinkSocket != -1);
|
||||
|
||||
if (FD_ISSET(sInfraIfIcmp6Socket, &aReadFdSet))
|
||||
if (FD_ISSET(mInfraIfIcmp6Socket, &aContext.mReadFdSet))
|
||||
{
|
||||
ReceiveIcmp6Message(aInstance);
|
||||
ReceiveIcmp6Message();
|
||||
}
|
||||
|
||||
if (FD_ISSET(sNetLinkSocket, &aReadFdSet))
|
||||
if (FD_ISSET(mNetLinkSocket, &aContext.mReadFdSet))
|
||||
{
|
||||
ReceiveNetLinkMessage(aInstance);
|
||||
ReceiveNetLinkMessage();
|
||||
}
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
InfraNetif &InfraNetif::Get(void)
|
||||
{
|
||||
static InfraNetif sInstance;
|
||||
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
} // namespace Posix
|
||||
} // namespace ot
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 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 infrastructure interface for posix.
|
||||
*/
|
||||
|
||||
#include "openthread-posix-config.h"
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include "core/common/non_copyable.hpp"
|
||||
#include "posix/platform/mainloop.hpp"
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
|
||||
namespace ot {
|
||||
namespace Posix {
|
||||
|
||||
/**
|
||||
* This class manages infrastructure network interface.
|
||||
*
|
||||
*/
|
||||
class InfraNetif : public Mainloop::Source, private NonCopyable
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This method updates the fd_set and timeout for mainloop.
|
||||
*
|
||||
* @param[inout] aContext A reference to the mainloop context.
|
||||
*
|
||||
*/
|
||||
void Update(otSysMainloopContext &aContext) override;
|
||||
|
||||
/**
|
||||
* This method performs infrastructure network interface processing.
|
||||
*
|
||||
* @param[in] aContext A reference to the mainloop context.
|
||||
*
|
||||
*/
|
||||
void Process(const otSysMainloopContext &aContext) override;
|
||||
|
||||
/**
|
||||
* This method initializes the infrastructure network interface.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aIfName A pointer to infrastructure network interface name.
|
||||
*
|
||||
*/
|
||||
void Init(otInstance *aInstance, const char *aIfName);
|
||||
|
||||
/**
|
||||
* This method deinitializes the infrastructure network interface.
|
||||
*
|
||||
*/
|
||||
void Deinit(void);
|
||||
|
||||
/**
|
||||
* This method checks whether the infrastructure network interface is running.
|
||||
*
|
||||
*/
|
||||
bool IsRunning(void) const;
|
||||
|
||||
/**
|
||||
* This method sends an ICMPv6 Neighbor Discovery message on given infrastructure interface.
|
||||
*
|
||||
* See RFC 4861: https://tools.ietf.org/html/rfc4861.
|
||||
*
|
||||
* @param[in] aInfraIfIndex The index of the infrastructure interface this message is sent to.
|
||||
* @param[in] aDestAddress The destination address this message is sent to.
|
||||
* @param[in] aBuffer The ICMPv6 message buffer. The ICMPv6 checksum is left zero and the
|
||||
* platform should do the checksum calculate.
|
||||
* @param[in] aBufferLength The length of the message buffer.
|
||||
*
|
||||
* @note Per RFC 4861, the implementation should send the message with IPv6 link-local source address
|
||||
* of interface @p aInfraIfIndex and IP Hop Limit 255.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully sent the ICMPv6 message.
|
||||
* @retval OT_ERROR_FAILED Failed to send the ICMPv6 message.
|
||||
*
|
||||
*/
|
||||
otError SendIcmp6Nd(uint32_t aInfraIfIndex,
|
||||
const otIp6Address &aDestAddress,
|
||||
const uint8_t * aBuffer,
|
||||
uint16_t aBufferLength);
|
||||
/**
|
||||
* This function gets the infrastructure network interface singleton.
|
||||
*
|
||||
* @returns The singleton object.
|
||||
*/
|
||||
static InfraNetif &Get(void);
|
||||
|
||||
private:
|
||||
otInstance *mInstance;
|
||||
char mInfraIfName[IFNAMSIZ];
|
||||
uint32_t mInfraIfIndex = 0;
|
||||
int mInfraIfIcmp6Socket = -1;
|
||||
int mNetLinkSocket = -1;
|
||||
|
||||
void ReceiveNetLinkMessage(void);
|
||||
void ReceiveIcmp6Message(void);
|
||||
};
|
||||
|
||||
} // namespace Posix
|
||||
} // namespace ot
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 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.
|
||||
*/
|
||||
|
||||
#include "posix/platform/mainloop.hpp"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "core/common/code_utils.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace Posix {
|
||||
namespace Mainloop {
|
||||
|
||||
void Manager::Add(Source &aSource)
|
||||
{
|
||||
assert(aSource.mNext == nullptr);
|
||||
|
||||
aSource.mNext = mSources;
|
||||
mSources = &aSource;
|
||||
}
|
||||
|
||||
void Manager::Remove(Source &aSource)
|
||||
{
|
||||
for (Source **pnext = &mSources; *pnext != nullptr; pnext = &(*pnext)->mNext)
|
||||
{
|
||||
if (*pnext == &aSource)
|
||||
{
|
||||
*pnext = aSource.mNext;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
aSource.mNext = nullptr;
|
||||
}
|
||||
|
||||
void Manager::Update(otSysMainloopContext &aContext)
|
||||
{
|
||||
for (Source *source = mSources; source != nullptr; source = source->mNext)
|
||||
{
|
||||
source->Update(aContext);
|
||||
}
|
||||
}
|
||||
|
||||
void Manager::Process(const otSysMainloopContext &aContext)
|
||||
{
|
||||
for (Source *source = mSources; source != nullptr; source = source->mNext)
|
||||
{
|
||||
source->Process(aContext);
|
||||
}
|
||||
}
|
||||
|
||||
Manager &Manager::Get(void)
|
||||
{
|
||||
static Manager sInstance;
|
||||
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
} // namespace Mainloop
|
||||
} // namespace Posix
|
||||
} // namespace ot
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 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 the SPI interface to radio (RCP).
|
||||
*/
|
||||
|
||||
#ifndef OT_POSIX_PLATFORM_MAINLOOP_HPP_
|
||||
#define OT_POSIX_PLATFORM_MAINLOOP_HPP_
|
||||
|
||||
#include <openthread/openthread-system.h>
|
||||
|
||||
namespace ot {
|
||||
namespace Posix {
|
||||
namespace Mainloop {
|
||||
|
||||
/**
|
||||
* This class is the base for all mainloop event sources.
|
||||
*
|
||||
*/
|
||||
class Source
|
||||
{
|
||||
friend class Manager;
|
||||
|
||||
public:
|
||||
/**
|
||||
* This method registers events in the mainloop.
|
||||
*
|
||||
* @param[inout] aContext A reference to the mainloop context.
|
||||
*
|
||||
*/
|
||||
virtual void Update(otSysMainloopContext &aContext) = 0;
|
||||
|
||||
/**
|
||||
* This method processes the mainloop events.
|
||||
*
|
||||
* @param[in] aContext A reference to the mainloop context.
|
||||
*
|
||||
*/
|
||||
virtual void Process(const otSysMainloopContext &aContext) = 0;
|
||||
|
||||
private:
|
||||
Source *mNext = nullptr;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class manages mainloop.
|
||||
*
|
||||
*/
|
||||
class Manager
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This method updates event polls in the mainloop context.
|
||||
*
|
||||
* @param[inout] aContext A reference to the mainloop context.
|
||||
*
|
||||
*/
|
||||
void Update(otSysMainloopContext &aContext);
|
||||
|
||||
/**
|
||||
* This method processes events in the mainloop context.
|
||||
*
|
||||
* @param[in] aContext A reference to the mainloop context.
|
||||
*
|
||||
*/
|
||||
void Process(const otSysMainloopContext &aContext);
|
||||
|
||||
/**
|
||||
* This method adds a new event source into the mainloop.
|
||||
*
|
||||
* @param[in] aSource A reference to the event source.
|
||||
*
|
||||
*/
|
||||
void Add(Source &aSource);
|
||||
|
||||
/**
|
||||
* This method removes an event source from the mainloop.
|
||||
*
|
||||
* @param[in] aSource A reference to the event source.
|
||||
*
|
||||
*/
|
||||
void Remove(Source &aSource);
|
||||
|
||||
/**
|
||||
* This function returns the Mainloop singleton.
|
||||
*
|
||||
* @returns A refernce to the Mainloop singleton.
|
||||
*
|
||||
*/
|
||||
static Manager &Get(void);
|
||||
|
||||
private:
|
||||
Source *mSources = nullptr;
|
||||
};
|
||||
|
||||
} // namespace Mainloop
|
||||
} // namespace Posix
|
||||
} // namespace ot
|
||||
#endif // OT_POSIX_PLATFORM_MAINLOOP_HPP_
|
||||
@@ -57,6 +57,7 @@ void MulticastRoutingManager::Init(otInstance *aInstance)
|
||||
|
||||
otBackboneRouterSetMulticastListenerCallback(aInstance,
|
||||
&MulticastRoutingManager::HandleBackboneMulticastListenerEvent, this);
|
||||
Mainloop::Manager::Get().Add(*this);
|
||||
}
|
||||
|
||||
void MulticastRoutingManager::HandleBackboneMulticastListenerEvent(void * aContext,
|
||||
@@ -138,24 +139,24 @@ exit:
|
||||
return found;
|
||||
}
|
||||
|
||||
void MulticastRoutingManager::UpdateFdSet(fd_set &aReadFdSet, int &aMaxFd) const
|
||||
void MulticastRoutingManager::Update(otSysMainloopContext &aContext)
|
||||
{
|
||||
VerifyOrExit(IsEnabled());
|
||||
|
||||
FD_SET(mMulticastRouterSock, &aReadFdSet);
|
||||
aMaxFd = OT_MAX(aMaxFd, mMulticastRouterSock);
|
||||
FD_SET(mMulticastRouterSock, &aContext.mReadFdSet);
|
||||
aContext.mMaxFd = OT_MAX(aContext.mMaxFd, mMulticastRouterSock);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void MulticastRoutingManager::Process(const fd_set &aReadFdSet)
|
||||
void MulticastRoutingManager::Process(const otSysMainloopContext &aContext)
|
||||
{
|
||||
VerifyOrExit(IsEnabled());
|
||||
|
||||
ExpireMulticastForwardingCache();
|
||||
|
||||
if (FD_ISSET(mMulticastRouterSock, &aReadFdSet))
|
||||
if (FD_ISSET(mMulticastRouterSock, &aContext.mReadFdSet))
|
||||
{
|
||||
ProcessMulticastRouterMessages();
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "core/common/non_copyable.hpp"
|
||||
#include "core/net/ip6_address.hpp"
|
||||
#include "lib/url/url.hpp"
|
||||
#include "posix/platform/mainloop.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace Posix {
|
||||
@@ -51,7 +52,7 @@ namespace Posix {
|
||||
* This class implements Multicast Routing management.
|
||||
*
|
||||
*/
|
||||
class MulticastRoutingManager : private NonCopyable
|
||||
class MulticastRoutingManager : public Mainloop::Source, private NonCopyable
|
||||
{
|
||||
public:
|
||||
/**
|
||||
@@ -59,9 +60,9 @@ public:
|
||||
*
|
||||
*/
|
||||
explicit MulticastRoutingManager()
|
||||
|
||||
: mLastExpireTime(0)
|
||||
, mMulticastRouterSock(-1)
|
||||
, mInstance(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -76,19 +77,18 @@ public:
|
||||
/**
|
||||
* This method updates the fd_set and timeout for mainloop.
|
||||
*
|
||||
* @param[inout] aReadFdSet A reference to fd_set for polling read.
|
||||
* @param[inout] aMaxFd A reference to the current max fd in fd_sets.
|
||||
* @param[inout] aContext A reference to the mainloop context.
|
||||
*
|
||||
*/
|
||||
void UpdateFdSet(fd_set &aReadFdSet, int &aMaxFd) const;
|
||||
void Update(otSysMainloopContext &aContext) override;
|
||||
|
||||
/**
|
||||
* This method performs Multicast Routing processing.
|
||||
*
|
||||
* @param[in] aReadFdSet A reference to read file descriptors.
|
||||
* @param[in] aContext A reference to the mainloop context.
|
||||
*
|
||||
*/
|
||||
void Process(const fd_set &aReadFdSet);
|
||||
void Process(const otSysMainloopContext &aContext) override;
|
||||
|
||||
/**
|
||||
* This method handles Thread state changes.
|
||||
|
||||
@@ -462,23 +462,6 @@ extern unsigned int gNetifIndex;
|
||||
*/
|
||||
void platformBackboneInit(otInstance *aInstance, const char *aInterfaceName);
|
||||
|
||||
/**
|
||||
* This function updates the file descriptor sets with file descriptors used by the platform Backbone network.
|
||||
*
|
||||
* @param[inout] aReadFdSet A reference to the read file descriptors.
|
||||
* @param[inout] aMaxFd A reference to the max file descriptor.
|
||||
*
|
||||
*/
|
||||
void platformBackboneUpdateFdSet(fd_set &aReadFdSet, int &aMaxFd);
|
||||
|
||||
/**
|
||||
* This function performs platform Backbone network processing.
|
||||
*
|
||||
* @param[in] aReadFdSet A reference to the read file descriptors.
|
||||
*
|
||||
*/
|
||||
void platformBackboneProcess(const fd_set &aReadSet);
|
||||
|
||||
/**
|
||||
* This function performs notifies state changes to platform Backbone network.
|
||||
*
|
||||
@@ -500,23 +483,6 @@ extern char gBackboneNetifName[IFNAMSIZ];
|
||||
*/
|
||||
extern unsigned int gBackboneNetifIndex;
|
||||
|
||||
/**
|
||||
* This function initializes the infrastructure interface.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance.
|
||||
* @param[in] aIfName The name of the infrastructure interface.
|
||||
*
|
||||
* @returns The index of the infrastructure interface.
|
||||
*
|
||||
*/
|
||||
uint32_t platformInfraIfInit(otInstance *aInstance, const char *aIfName);
|
||||
|
||||
/**
|
||||
* This function deinitializes the infrastructure interface.
|
||||
*
|
||||
*/
|
||||
void platformInfraIfDeinit(void);
|
||||
|
||||
/**
|
||||
* This function tells if the infrastructure interface is running.
|
||||
*
|
||||
@@ -525,24 +491,6 @@ void platformInfraIfDeinit(void);
|
||||
*/
|
||||
bool platformInfraIfIsRunning(void);
|
||||
|
||||
/**
|
||||
* This function updates the read fd set.
|
||||
*
|
||||
* @param[out] aReadFdSet The fd set to be updated.
|
||||
* @param[out] aMaxFd The maximum fd to be updated.
|
||||
*
|
||||
*/
|
||||
void platformInfraIfUpdateFdSet(fd_set &aReadFdSet, int &aMaxFd);
|
||||
|
||||
/**
|
||||
* This function processes possible events on the infrastructure interface.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance.
|
||||
* @param[in] aReadFdSet The fd set which may contain read vents.
|
||||
*
|
||||
*/
|
||||
void platformInfraIfProcess(otInstance *aInstance, const fd_set &aReadFdSet);
|
||||
|
||||
/**
|
||||
* This function enables daemon.
|
||||
*
|
||||
|
||||
@@ -47,6 +47,8 @@
|
||||
#include <openthread/platform/radio.h>
|
||||
|
||||
#include "common/code_utils.hpp"
|
||||
#include "posix/platform/infra_if.hpp"
|
||||
#include "posix/platform/mainloop.hpp"
|
||||
#include "posix/platform/radio_url.hpp"
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE || OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
@@ -62,7 +64,10 @@ static void processStateChange(otChangedFlags aFlags, void *aContext)
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
platformBackboneStateChange(instance, aFlags);
|
||||
if (gBackboneNetifIndex != 0)
|
||||
{
|
||||
platformBackboneStateChange(instance, aFlags);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
@@ -127,20 +132,7 @@ otInstance *otSysInit(otPlatformConfig *aPlatformConfig)
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
{
|
||||
uint32_t infraIfIndex;
|
||||
|
||||
// Reuse the backbone interface name.
|
||||
if (aPlatformConfig->mBackboneInterfaceName == nullptr || strlen(aPlatformConfig->mBackboneInterfaceName) == 0)
|
||||
{
|
||||
DieNowWithMessage("no infra interface is specified", OT_EXIT_INVALID_ARGUMENTS);
|
||||
}
|
||||
|
||||
infraIfIndex = platformInfraIfInit(instance, aPlatformConfig->mBackboneInterfaceName);
|
||||
|
||||
SuccessOrDie(otBorderRoutingInit(instance, infraIfIndex, platformInfraIfIsRunning()));
|
||||
SuccessOrDie(otBorderRoutingSetEnabled(instance, /* aEnabled */ true));
|
||||
}
|
||||
ot::Posix::InfraNetif::Get().Init(instance, aPlatformConfig->mBackboneInterfaceName);
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE
|
||||
@@ -178,7 +170,7 @@ void otSysDeinit(void)
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
platformInfraIfDeinit();
|
||||
ot::Posix::InfraNetif::Get().Deinit();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -217,6 +209,8 @@ static int trySelect(fd_set *aReadFdSet, fd_set *aWriteFdSet, fd_set *aErrorFdSe
|
||||
|
||||
void otSysMainloopUpdate(otInstance *aInstance, otSysMainloopContext *aMainloop)
|
||||
{
|
||||
ot::Posix::Mainloop::Manager::Get().Update(*aMainloop);
|
||||
|
||||
platformAlarmUpdateTimeout(&aMainloop->mTimeout);
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
|
||||
platformUdpUpdateFdSet(aInstance, &aMainloop->mReadFdSet, &aMainloop->mMaxFd);
|
||||
@@ -225,12 +219,6 @@ void otSysMainloopUpdate(otInstance *aInstance, otSysMainloopContext *aMainloop)
|
||||
platformNetifUpdateFdSet(&aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet,
|
||||
&aMainloop->mMaxFd);
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
platformBackboneUpdateFdSet(aMainloop->mReadFdSet, aMainloop->mMaxFd);
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
platformInfraIfUpdateFdSet(aMainloop->mReadFdSet, aMainloop->mMaxFd);
|
||||
#endif
|
||||
#if OPENTHREAD_POSIX_VIRTUAL_TIME
|
||||
virtualTimeUpdateFdSet(&aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet, &aMainloop->mMaxFd,
|
||||
&aMainloop->mTimeout);
|
||||
@@ -297,6 +285,8 @@ int otSysMainloopPoll(otSysMainloopContext *aMainloop)
|
||||
|
||||
void otSysMainloopProcess(otInstance *aInstance, const otSysMainloopContext *aMainloop)
|
||||
{
|
||||
ot::Posix::Mainloop::Manager::Get().Process(*aMainloop);
|
||||
|
||||
#if OPENTHREAD_POSIX_VIRTUAL_TIME
|
||||
virtualTimeProcess(aInstance, &aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet);
|
||||
#else
|
||||
@@ -312,12 +302,6 @@ void otSysMainloopProcess(otInstance *aInstance, const otSysMainloopContext *aMa
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
|
||||
platformUdpProcess(aInstance, &aMainloop->mReadFdSet);
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
platformBackboneProcess(aMainloop->mReadFdSet);
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
platformInfraIfProcess(aInstance, aMainloop->mReadFdSet);
|
||||
#endif
|
||||
#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
|
||||
platformDaemonProcess(aMainloop);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user