mirror of
https://github.com/espressif/openthread.git
synced 2026-07-28 06:37:46 +00:00
[border-router] add platform API otPlatInfraIfHasAddress (#6430)
This commit removes the need of getting LLA of infra interface but adds a new platform API otPlatInfraIfHasAddress which matches the infra interface and a given address. Background: The infra interface LLA is used in the Routing Manager for only testing if RA/RS message is initiated from the infra interface.
This commit is contained in:
@@ -57,25 +57,20 @@ extern "C" {
|
||||
*
|
||||
* @note This method MUST be called before any other otBorderRouting* APIs.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aInfraIfIndex The infrastructure interface index.
|
||||
* @param[in] aInfraIfIsRunning A boolean that indicates whether the infrastructure
|
||||
* interface is running.
|
||||
* @param[in] aInfraIfLinkLocalAddress A pointer to the IPv6 link-local address of the infrastructure
|
||||
* interface. NULL if the IPv6 link-local address is missing.
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aInfraIfIndex The infrastructure interface index.
|
||||
* @param[in] aInfraIfIsRunning A boolean that indicates whether the infrastructure
|
||||
* interface is running.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully started the Border Routing Manager on given infrastructure.
|
||||
* @retval OT_ERROR_INVALID_STATE The Border Routing Manager has already been initialized.
|
||||
* @retval OT_ERROR_INVALID_ARGS The index or the IPv6 link-local address of the infra interface is not valid.
|
||||
* @retval OT_ERROR_INVALID_ARGS The index of the infrastructure interface is not valid.
|
||||
* @retval OT_ERROR_FAILED Internal failure. Usually due to failure in generating random prefixes.
|
||||
*
|
||||
* @sa otPlatInfraIfStateChanged.
|
||||
*
|
||||
*/
|
||||
otError otBorderRoutingInit(otInstance * aInstance,
|
||||
uint32_t aInfraIfIndex,
|
||||
bool aInfraIfIsRunning,
|
||||
const otIp6Address *aInfraIfLinkLocalAddress);
|
||||
otError otBorderRoutingInit(otInstance *aInstance, uint32_t aInfraIfIndex, bool aInfraIfIsRunning);
|
||||
|
||||
/**
|
||||
* This method enables/disables the Border Routing Manager.
|
||||
|
||||
@@ -53,7 +53,7 @@ extern "C" {
|
||||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (101)
|
||||
#define OPENTHREAD_API_VERSION (102)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
@@ -46,6 +46,17 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This method tells whether an infra interface has the given IPv6 address assigned.
|
||||
*
|
||||
* @param[in] aInfraIfIndex The index of the infra interface.
|
||||
* @param[in] aAddress The IPv6 address.
|
||||
*
|
||||
* @returns TRUE if the infra interface has given IPv6 address assigned, FALSE otherwise.
|
||||
*
|
||||
*/
|
||||
bool otPlatInfraIfHasAddress(uint32_t aInfraIfIndex, const otIp6Address *aAddress);
|
||||
|
||||
/**
|
||||
* This method sends an ICMPv6 Neighbor Discovery message on given infrastructure interface.
|
||||
*
|
||||
@@ -94,24 +105,22 @@ extern void otPlatInfraIfRecvIcmp6Nd(otInstance * aInstance,
|
||||
* The infra interface driver calls this method to notify OpenThread
|
||||
* of the interface state changes.
|
||||
*
|
||||
* It is fine for the platform to call to method even when the running state
|
||||
* of the interface hasn't changed. In this case, the Routing Manager state is
|
||||
* not affected.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance structure.
|
||||
* @param[in] aInfraIfIndex The index of the infrastructure interface.
|
||||
* @param[in] aIsRunning A boolean that indicates whether the infrastructure
|
||||
* interface is running.
|
||||
* @param[in] aLinkLocalAddress A pointer to the IPv6 link-local address of the infrastructure
|
||||
* interface. NULL if the IPv6 link-local address is lost.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully updated the infra interface status.
|
||||
* @retval OT_ERROR_INVALID_STATE The Routing Manager is not initialized.
|
||||
* @retval OT_ERROR_INVALID_ARGS The @p aInfraIfIndex doesn't match the infra interface the
|
||||
* Routing Manager are initialized with, or the @p aLinkLocalAddress
|
||||
* is not a valid IPv6 link-local address.
|
||||
* Routing Manager are initialized with.
|
||||
*
|
||||
*/
|
||||
extern otError otPlatInfraIfStateChanged(otInstance * aInstance,
|
||||
uint32_t aInfraIfIndex,
|
||||
bool aIsRunning,
|
||||
const otIp6Address *aLinkLocalAddress);
|
||||
extern otError otPlatInfraIfStateChanged(otInstance *aInstance, uint32_t aInfraIfIndex, bool aIsRunning);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
||||
@@ -44,15 +44,11 @@
|
||||
using namespace ot;
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
otError otBorderRoutingInit(otInstance * aInstance,
|
||||
uint32_t aInfraIfIndex,
|
||||
bool aInfraIfIsRunning,
|
||||
const otIp6Address *aInfraIfLinkLocalAddress)
|
||||
otError otBorderRoutingInit(otInstance *aInstance, uint32_t aInfraIfIndex, bool aInfraIfIsRunning)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.Get<BorderRouter::RoutingManager>().Init(
|
||||
aInfraIfIndex, aInfraIfIsRunning, static_cast<const Ip6::Address *>(aInfraIfLinkLocalAddress));
|
||||
return instance.Get<BorderRouter::RoutingManager>().Init(aInfraIfIndex, aInfraIfIsRunning);
|
||||
}
|
||||
|
||||
otError otBorderRoutingSetEnabled(otInstance *aInstance, bool aEnabled)
|
||||
|
||||
@@ -53,15 +53,11 @@ extern "C" void otPlatInfraIfRecvIcmp6Nd(otInstance * aInstance,
|
||||
aInfraIfIndex, static_cast<const Ip6::Address &>(*aSrcAddress), aBuffer, aBufferLength);
|
||||
}
|
||||
|
||||
extern "C" otError otPlatInfraIfStateChanged(otInstance * aInstance,
|
||||
uint32_t aInfraIfIndex,
|
||||
bool aIsRunning,
|
||||
const otIp6Address *aLinkLocalAddress)
|
||||
extern "C" otError otPlatInfraIfStateChanged(otInstance *aInstance, uint32_t aInfraIfIndex, bool aIsRunning)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.Get<BorderRouter::RoutingManager>().HandleInfraIfStateChanged(
|
||||
aInfraIfIndex, aIsRunning, static_cast<const Ip6::Address *>(aLinkLocalAddress));
|
||||
return instance.Get<BorderRouter::RoutingManager>().HandleInfraIfStateChanged(aInfraIfIndex, aIsRunning);
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
|
||||
@@ -72,8 +72,6 @@ RoutingManager::RoutingManager(Instance &aInstance)
|
||||
, mRouterSolicitCount(0)
|
||||
, mRoutingPolicyTimer(aInstance, HandleRoutingPolicyTimer)
|
||||
{
|
||||
mInfraIfLinkLocalAddress.Clear();
|
||||
|
||||
mLocalOmrPrefix.Clear();
|
||||
memset(mAdvertisedOmrPrefixes, 0, sizeof(mAdvertisedOmrPrefixes));
|
||||
|
||||
@@ -82,7 +80,7 @@ RoutingManager::RoutingManager(Instance &aInstance)
|
||||
memset(mDiscoveredPrefixes, 0, sizeof(mDiscoveredPrefixes));
|
||||
}
|
||||
|
||||
Error RoutingManager::Init(uint32_t aInfraIfIndex, bool aInfraIfIsRunning, const Ip6::Address *aInfraIfLinkLocalAddress)
|
||||
Error RoutingManager::Init(uint32_t aInfraIfIndex, bool aInfraIfIsRunning)
|
||||
{
|
||||
Error error;
|
||||
|
||||
@@ -95,7 +93,7 @@ Error RoutingManager::Init(uint32_t aInfraIfIndex, bool aInfraIfIsRunning, const
|
||||
mInfraIfIndex = aInfraIfIndex;
|
||||
|
||||
// Initialize the infra interface status.
|
||||
SuccessOrExit(error = HandleInfraIfStateChanged(mInfraIfIndex, aInfraIfIsRunning, aInfraIfLinkLocalAddress));
|
||||
SuccessOrExit(error = HandleInfraIfStateChanged(mInfraIfIndex, aInfraIfIsRunning));
|
||||
|
||||
exit:
|
||||
if (error != kErrorNone)
|
||||
@@ -175,7 +173,7 @@ exit:
|
||||
|
||||
void RoutingManager::EvaluateState(void)
|
||||
{
|
||||
if (mIsEnabled && Get<Mle::MleRouter>().IsAttached() && mInfraIfIsRunning && mInfraIfLinkLocalAddress.IsLinkLocal())
|
||||
if (mIsEnabled && Get<Mle::MleRouter>().IsAttached() && mInfraIfIsRunning)
|
||||
{
|
||||
Start();
|
||||
}
|
||||
@@ -242,13 +240,9 @@ void RoutingManager::RecvIcmp6Message(uint32_t aInfraIfIndex,
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
const Ip6::Icmp::Header *icmp6Header;
|
||||
const Ip6::Address * infraLinkLocalAddr;
|
||||
|
||||
VerifyOrExit(IsInitialized() && mIsRunning, error = kErrorDrop);
|
||||
|
||||
VerifyOrExit(aInfraIfIndex == mInfraIfIndex, error = kErrorDrop);
|
||||
infraLinkLocalAddr = static_cast<const Ip6::Address *>(&mInfraIfLinkLocalAddress);
|
||||
|
||||
VerifyOrExit(aBuffer != nullptr && aBufferLength >= sizeof(*icmp6Header), error = kErrorParse);
|
||||
|
||||
icmp6Header = reinterpret_cast<const Ip6::Icmp::Header *>(aBuffer);
|
||||
@@ -260,7 +254,7 @@ void RoutingManager::RecvIcmp6Message(uint32_t aInfraIfIndex,
|
||||
break;
|
||||
case Ip6::Icmp::Header::kTypeRouterSolicit:
|
||||
// Drop Router Solicitations initiated from infra interface.
|
||||
VerifyOrExit(aSrcAddress != *infraLinkLocalAddr, error = kErrorDrop);
|
||||
VerifyOrExit(!otPlatInfraIfHasAddress(mInfraIfIndex, &aSrcAddress), error = kErrorDrop);
|
||||
HandleRouterSolicit(aSrcAddress, aBuffer, aBufferLength);
|
||||
break;
|
||||
default:
|
||||
@@ -274,29 +268,18 @@ exit:
|
||||
}
|
||||
}
|
||||
|
||||
Error RoutingManager::HandleInfraIfStateChanged(uint32_t aInfraIfIndex,
|
||||
bool aIsRunning,
|
||||
const Ip6::Address *aLinkLocalAddress)
|
||||
Error RoutingManager::HandleInfraIfStateChanged(uint32_t aInfraIfIndex, bool aIsRunning)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
VerifyOrExit(IsInitialized(), error = kErrorInvalidState);
|
||||
VerifyOrExit(aInfraIfIndex == mInfraIfIndex, error = kErrorInvalidArgs);
|
||||
VerifyOrExit(aLinkLocalAddress == nullptr || aLinkLocalAddress->IsLinkLocal(), error = kErrorInvalidArgs);
|
||||
VerifyOrExit(aIsRunning != mInfraIfIsRunning);
|
||||
|
||||
otLogInfoBr("infra interface state changed: %s, link-local-addr=%s", aIsRunning ? "RUNNING" : "NOT RUNNING",
|
||||
(aLinkLocalAddress != nullptr) ? aLinkLocalAddress->ToString().AsCString() : "(null)");
|
||||
otLogInfoBr("infra interface (%u) state changed: %sRUNNING -> %sRUNNING", aInfraIfIndex,
|
||||
(mInfraIfIsRunning ? "" : "NOT "), (aIsRunning ? "" : "NOT "));
|
||||
|
||||
mInfraIfIsRunning = aIsRunning;
|
||||
if (aLinkLocalAddress == nullptr)
|
||||
{
|
||||
mInfraIfLinkLocalAddress.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
mInfraIfLinkLocalAddress = *aLinkLocalAddress;
|
||||
}
|
||||
|
||||
EvaluateState();
|
||||
|
||||
exit:
|
||||
|
||||
@@ -85,17 +85,15 @@ public:
|
||||
/**
|
||||
* This method initializes the routing manager on given infrastructure interface.
|
||||
*
|
||||
* @param[in] aInfraIfIndex An infrastructure network interface index.
|
||||
* @param[in] aInfraIfIsRunning A boolean that indicates whether the infrastructure
|
||||
* interface is running.
|
||||
* @param[in] aInfraIfLinkLocalAddress A pointer to the IPv6 link-local address of the infrastructure
|
||||
* interface. NULL if the IPv6 link-local address is missing.
|
||||
* @param[in] aInfraIfIndex An infrastructure network interface index.
|
||||
* @param[in] aInfraIfIsRunning A boolean that indicates whether the infrastructure
|
||||
* interface is running.
|
||||
*
|
||||
* @retval kErrorNone Successfully started the routing manager.
|
||||
* @retval kErrorInvalidArgs The index of the infra interface is not valid.
|
||||
* @retval kErrorNone Successfully started the routing manager.
|
||||
* @retval kErrorInvalidArgs The index of the infra interface is not valid.
|
||||
*
|
||||
*/
|
||||
Error Init(uint32_t aInfraIfIndex, bool aInfraIfIsRunning, const Ip6::Address *aInfraIfLinkLocalAddress);
|
||||
Error Init(uint32_t aInfraIfIndex, bool aInfraIfIsRunning);
|
||||
|
||||
/**
|
||||
* This method enables/disables the Border Routing Manager.
|
||||
@@ -129,20 +127,17 @@ public:
|
||||
/**
|
||||
* This method handles infrastructure interface state changes.
|
||||
*
|
||||
* @param[in] aInfraIfIndex The index of the infrastructure interface.
|
||||
* @param[in] aIsRunning A boolean that indicates whether the infrastructure
|
||||
* interface is running.
|
||||
* @param[in] aLinkLocalAddress A pointer to the IPv6 link local address of the infrastructure
|
||||
* interface. NULL if the IPv6 link local address is lost.
|
||||
* @param[in] aInfraIfIndex The index of the infrastructure interface.
|
||||
* @param[in] aIsRunning A boolean that indicates whether the infrastructure
|
||||
* interface is running.
|
||||
*
|
||||
* @retval kErrorNone Successfully updated the infra interface status.
|
||||
* @retval kErrorInvalidState The Routing Manager is not initialized.
|
||||
* @retval kErrorInvalidArgs The @p aInfraIfIndex doesn't match the infra interface the Routing Manager are
|
||||
* initialized with, or the @p aLinkLocalAddress is not a valid IPv6 link-local
|
||||
* address.
|
||||
* @retval kErrorInvalidArgs The @p aInfraIfIndex doesn't match the infra interface
|
||||
* the Routing Manager is initialized with.
|
||||
*
|
||||
*/
|
||||
Error HandleInfraIfStateChanged(uint32_t aInfraIfIndex, bool aIsRunning, const Ip6::Address *aLinkLocalAddress);
|
||||
Error HandleInfraIfStateChanged(uint32_t aInfraIfIndex, bool aIsRunning);
|
||||
|
||||
private:
|
||||
enum : uint16_t
|
||||
@@ -260,12 +255,6 @@ private:
|
||||
// messages will be sent.
|
||||
uint32_t mInfraIfIndex;
|
||||
|
||||
// The IPv6 link-local address of the infra interface. It's
|
||||
// UNSPECIFIED if no valid IPv6 link-local address is associated
|
||||
// with the infra interface and the Routing Manager will be
|
||||
// stopped.
|
||||
Ip6::Address mInfraIfLinkLocalAddress;
|
||||
|
||||
// The OMR prefix loaded from local persistent storage or randomly
|
||||
// generated if non is found in persistent storage.
|
||||
Ip6::Prefix mLocalOmrPrefix;
|
||||
|
||||
@@ -59,17 +59,44 @@
|
||||
#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 otIp6Address sInfraIfLinkLocalAddr;
|
||||
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);
|
||||
|
||||
bool otPlatInfraIfHasAddress(uint32_t aInfraIfIndex, const otIp6Address *aAddress)
|
||||
{
|
||||
bool ret = false;
|
||||
struct ifaddrs *ifAddrs = nullptr;
|
||||
|
||||
VerifyOrDie(getifaddrs(&ifAddrs) != -1, OT_EXIT_ERROR_ERRNO);
|
||||
|
||||
for (struct ifaddrs *addr = ifAddrs; addr != nullptr; addr = addr->ifa_next)
|
||||
{
|
||||
struct sockaddr_in6 *ip6Addr;
|
||||
|
||||
if (if_nametoindex(addr->ifa_name) != aInfraIfIndex || addr->ifa_addr->sa_family != AF_INET6)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ip6Addr = reinterpret_cast<sockaddr_in6 *>(addr->ifa_addr);
|
||||
if (memcmp(&ip6Addr->sin6_addr, aAddress, sizeof(*aAddress)) == 0)
|
||||
{
|
||||
ExitNow(ret = true);
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
freeifaddrs(ifAddrs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
otError otPlatInfraIfSendIcmp6Nd(uint32_t aInfraIfIndex,
|
||||
const otIp6Address *aDestAddress,
|
||||
const uint8_t * aBuffer,
|
||||
@@ -144,37 +171,6 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
const otIp6Address *platformInfraIfGetLinkLocalAddress(void)
|
||||
{
|
||||
const otIp6Address *ret = nullptr;
|
||||
struct ifaddrs * ifAddrs = nullptr;
|
||||
|
||||
VerifyOrDie(getifaddrs(&ifAddrs) != -1, OT_EXIT_ERROR_ERRNO);
|
||||
|
||||
for (struct ifaddrs *addr = ifAddrs; addr != nullptr; addr = addr->ifa_next)
|
||||
{
|
||||
struct sockaddr_in6 *ip6Addr;
|
||||
|
||||
if (strncmp(addr->ifa_name, sInfraIfName, sizeof(sInfraIfName)) != 0 || addr->ifa_addr->sa_family != AF_INET6)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ip6Addr = reinterpret_cast<sockaddr_in6 *>(addr->ifa_addr);
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&ip6Addr->sin6_addr))
|
||||
{
|
||||
memcpy(&sInfraIfLinkLocalAddr, &ip6Addr->sin6_addr, sizeof(sInfraIfLinkLocalAddr));
|
||||
ExitNow(ret = &sInfraIfLinkLocalAddr);
|
||||
}
|
||||
}
|
||||
|
||||
otLogWarnPlat("cannot find IPv6 link-local address for interface %s", sInfraIfName);
|
||||
|
||||
exit:
|
||||
freeifaddrs(ifAddrs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool platformInfraIfIsRunning(void)
|
||||
{
|
||||
int sock;
|
||||
@@ -350,12 +346,14 @@ static void ReceiveNetLinkMessage(otInstance *aInstance)
|
||||
{
|
||||
switch (header->nlmsg_type)
|
||||
{
|
||||
case RTM_NEWLINK:
|
||||
case RTM_DELLINK:
|
||||
// There are no effective netlink message types to get us notified
|
||||
// of interface RUNNING state changes. But addresses events are
|
||||
// usually associated with interface state changes.
|
||||
case RTM_NEWADDR:
|
||||
case RTM_DELADDR:
|
||||
SuccessOrDie(otPlatInfraIfStateChanged(aInstance, sInfraIfIndex, platformInfraIfIsRunning(),
|
||||
platformInfraIfGetLinkLocalAddress()));
|
||||
case RTM_NEWLINK:
|
||||
case RTM_DELLINK:
|
||||
SuccessOrDie(otPlatInfraIfStateChanged(aInstance, sInfraIfIndex, platformInfraIfIsRunning()));
|
||||
break;
|
||||
case NLMSG_ERROR:
|
||||
{
|
||||
|
||||
@@ -525,14 +525,6 @@ void platformInfraIfDeinit(void);
|
||||
*/
|
||||
bool platformInfraIfIsRunning(void);
|
||||
|
||||
/**
|
||||
* this function returns the IPv6 link-local address of the infrastructure interface.
|
||||
*
|
||||
* @returns A pointer to the link-local address; NULL if no link-local address is present.
|
||||
*
|
||||
*/
|
||||
const otIp6Address *platformInfraIfGetLinkLocalAddress(void);
|
||||
|
||||
/**
|
||||
* This function updates the read fd set.
|
||||
*
|
||||
|
||||
@@ -111,8 +111,7 @@ otInstance *otSysInit(otPlatformConfig *aPlatformConfig)
|
||||
|
||||
infraIfIndex = platformInfraIfInit(instance, aPlatformConfig->mBackboneInterfaceName);
|
||||
|
||||
SuccessOrDie(otBorderRoutingInit(instance, infraIfIndex, platformInfraIfIsRunning(),
|
||||
platformInfraIfGetLinkLocalAddress()));
|
||||
SuccessOrDie(otBorderRoutingInit(instance, infraIfIndex, platformInfraIfIsRunning()));
|
||||
SuccessOrDie(otBorderRoutingSetEnabled(instance, /* aEnabled */ true));
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user