[infra-if] add API for querying infra link status (#8619)

This commit introduces 2 APIs to query infra link status:
- `otSysGetInfraNetifFlags` returns the `ifr_flags` of the infra
  network interface.
- `otSysCountInfraNetifAddresses` counts the numbers of LLA, ULA and
  GUA on the infra network interface.
This commit is contained in:
whd
2023-01-11 07:58:38 -08:00
committed by GitHub
parent 7dd9543687
commit 22fa54dfa2
3 changed files with 95 additions and 2 deletions
@@ -219,6 +219,29 @@ const otRadioSpinelMetrics *otSysGetRadioSpinelMetrics(void);
*/
const otRcpInterfaceMetrics *otSysGetRcpInterfaceMetrics(void);
/**
* This function returns the ifr_flags of the infrastructure network interface.
*
* @returns The ifr_flags of infrastructure network interface.
*
*/
uint32_t otSysGetInfraNetifFlags(void);
typedef struct otSysInfraNetIfAddressCounters
{
uint32_t mLinkLocalAddresses;
uint32_t mUniqueLocalAddresses;
uint32_t mGlobalUnicastAddresses;
} otSysInfraNetIfAddressCounters;
/**
* This functions counts the number of addresses on the infrastructure network interface.
*
* @param[out] aAddressCounters The counters of addresses on infrastructure network interface.
*
*/
void otSysCountInfraNetifAddresses(otSysInfraNetIfAddressCounters *aAddressCounters);
#ifdef __cplusplus
} // end of extern "C"
#endif
+55 -2
View File
@@ -113,6 +113,13 @@ bool platformInfraIfIsRunning(void) { return ot::Posix::InfraNetif::Get().IsRunn
const char *otSysGetInfraNetifName(void) { return ot::Posix::InfraNetif::Get().GetNetifName(); }
uint32_t otSysGetInfraNetifFlags(void) { return ot::Posix::InfraNetif::Get().GetFlags(); }
void otSysCountInfraNetifAddresses(otSysInfraNetIfAddressCounters *aAddressCounters)
{
ot::Posix::InfraNetif::Get().CountAddresses(*aAddressCounters);
}
namespace ot {
namespace Posix {
namespace {
@@ -163,6 +170,15 @@ int CreateIcmp6Socket(void)
return sock;
}
bool IsAddressLinkLocal(const in6_addr &aAddress)
{
return ((aAddress.s6_addr[0] & 0xff) == 0xfe) && ((aAddress.s6_addr[1] & 0xc0) == 0x80);
}
bool IsAddressUniqueLocal(const in6_addr &aAddress) { return (aAddress.s6_addr[0] & 0xfe) == 0xfc; }
bool IsAddressGlobalUnicast(const in6_addr &aAddress) { return (aAddress.s6_addr[0] & 0xe0) == 0x20; }
// Create a net-link socket that subscribes to link & addresses events.
int CreateNetLinkSocket(void)
{
@@ -259,7 +275,9 @@ exit:
return error;
}
bool InfraNetif::IsRunning(void) const
bool InfraNetif::IsRunning(void) const { return (GetFlags() & IFF_RUNNING) && HasLinkLocalAddress(); }
uint32_t InfraNetif::GetFlags(void) const
{
int sock;
struct ifreq ifReq;
@@ -277,7 +295,42 @@ bool InfraNetif::IsRunning(void) const
close(sock);
return (ifReq.ifr_flags & IFF_RUNNING) && HasLinkLocalAddress();
return ifReq.ifr_flags;
}
void InfraNetif::CountAddresses(otSysInfraNetIfAddressCounters &aAddressCounters) const
{
struct ifaddrs *ifAddrs = nullptr;
aAddressCounters.mLinkLocalAddresses = 0;
aAddressCounters.mUniqueLocalAddresses = 0;
aAddressCounters.mGlobalUnicastAddresses = 0;
if (getifaddrs(&ifAddrs) < 0)
{
otLogWarnPlat("failed to get netif addresses: %s", strerror(errno));
ExitNow();
}
for (struct ifaddrs *addr = ifAddrs; addr != nullptr; addr = addr->ifa_next)
{
in6_addr *in6Addr;
if (strncmp(addr->ifa_name, mInfraIfName, sizeof(mInfraIfName)) != 0 || addr->ifa_addr->sa_family != AF_INET6)
{
continue;
}
in6Addr = &(reinterpret_cast<sockaddr_in6 *>(addr->ifa_addr)->sin6_addr);
aAddressCounters.mLinkLocalAddresses += IsAddressLinkLocal(*in6Addr);
aAddressCounters.mUniqueLocalAddresses += IsAddressUniqueLocal(*in6Addr);
aAddressCounters.mGlobalUnicastAddresses += IsAddressGlobalUnicast(*in6Addr);
}
freeifaddrs(ifAddrs);
exit:
return;
}
bool InfraNetif::HasLinkLocalAddress(void) const
+17
View File
@@ -35,6 +35,7 @@
#include <net/if.h>
#include <openthread/nat64.h>
#include <openthread/openthread-system.h>
#include "core/common/non_copyable.hpp"
#include "posix/platform/mainloop.hpp"
@@ -107,6 +108,22 @@ public:
*/
bool IsRunning(void) const;
/**
* This method returns the ifr_flags of the infrastructure network interface.
*
* @returns The ifr_flags of the infrastructure network interface.
*
*/
uint32_t GetFlags(void) const;
/**
* This functions counts the number of addresses on the infrastructure network interface.
*
* @param[out] aAddressCounters The counters of addresses on infrastructure network interface.
*
*/
void CountAddresses(otSysInfraNetIfAddressCounters &aAddressCounters) const;
/**
* This method sends an ICMPv6 Neighbor Discovery message on given infrastructure interface.
*