mirror of
https://github.com/espressif/openthread.git
synced 2026-08-14 14:47:46 +00:00
[posix] map address with rtnetlink API on Linux (#5629)
* no DAD for anycast address. * add anycast address as non-preferred address. * update address callback to provide more address info.
This commit is contained in:
@@ -53,7 +53,7 @@ extern "C" {
|
||||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (31)
|
||||
#define OPENTHREAD_API_VERSION (32)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
@@ -415,19 +415,29 @@ typedef void (*otIp6ReceiveCallback)(otMessage *aMessage, void *aContext);
|
||||
*/
|
||||
void otIp6SetReceiveCallback(otInstance *aInstance, otIp6ReceiveCallback aCallback, void *aCallbackContext);
|
||||
|
||||
/**
|
||||
* @struct otIp6AddressInfo
|
||||
*
|
||||
* This structure represents IPv6 address information.
|
||||
*
|
||||
*/
|
||||
typedef struct otIp6AddressInfo
|
||||
{
|
||||
const otIp6Address *mAddress; ///< A pointer to the IPv6 address.
|
||||
uint8_t mPrefixLength; ///< The prefix length of mAddress if it is a unicast address.
|
||||
uint8_t mScope : 4; ///< The scope of this address.
|
||||
bool mIsAnycast : 1; ///< Whether this is an anycast address.
|
||||
} otIp6AddressInfo;
|
||||
|
||||
/**
|
||||
* This function pointer is called when an internal IPv6 address is added or removed.
|
||||
*
|
||||
* @param[in] aAddress A pointer to the IPv6 address.
|
||||
* @param[in] aPrefixLength The prefix length if @p aAddress is unicast address, and 128 for multicast address.
|
||||
* @param[in] aAddressInfo A pointer to the IPv6 address information.
|
||||
* @param[in] aIsAdded TRUE if the @p aAddress was added, FALSE if @p aAddress was removed.
|
||||
* @param[in] aContext A pointer to application-specific context.
|
||||
*
|
||||
*/
|
||||
typedef void (*otIp6AddressCallback)(const otIp6Address *aAddress,
|
||||
uint8_t aPrefixLength,
|
||||
bool aIsAdded,
|
||||
void * aContext);
|
||||
typedef void (*otIp6AddressCallback)(const otIp6AddressInfo *aAddressInfo, bool aIsAdded, void *aContext);
|
||||
|
||||
/**
|
||||
* This function registers a callback to notify internal IPv6 address changes.
|
||||
|
||||
+65
-8
@@ -42,6 +42,30 @@
|
||||
namespace ot {
|
||||
namespace Ip6 {
|
||||
|
||||
class AddressInfo : public otIp6AddressInfo
|
||||
{
|
||||
public:
|
||||
AddressInfo(const NetifUnicastAddress &aAddress, Instance &aInstance)
|
||||
{
|
||||
mAddress = &aAddress.mAddress;
|
||||
mPrefixLength = aAddress.mPrefixLength;
|
||||
mScope = aAddress.GetScope();
|
||||
mIsAnycast = aInstance.Get<Mle::MleRouter>().IsAnycastLocator(aAddress.GetAddress());
|
||||
}
|
||||
|
||||
AddressInfo(const NetifMulticastAddress &aAddress)
|
||||
{
|
||||
mAddress = &aAddress.GetAddress();
|
||||
mPrefixLength = kMulticastPrefixLength;
|
||||
mScope = aAddress.GetAddress().GetScope();
|
||||
mIsAnycast = false;
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr uint8_t kMulticastPrefixLength =
|
||||
128; ///< Multicast prefix length used to notify internal address changes.
|
||||
};
|
||||
|
||||
/*
|
||||
* Certain fixed multicast addresses are defined as a set of chained (linked-list) constant `otNetifMulticastAddress`
|
||||
* entries:
|
||||
@@ -128,7 +152,10 @@ void Netif::SubscribeAllNodesMulticast(void)
|
||||
|
||||
for (const NetifMulticastAddress *entry = &linkLocalAllNodesAddress; entry; entry = entry->GetNext())
|
||||
{
|
||||
mAddressCallback(&entry->GetAddress(), kMulticastPrefixLength, /* IsAdded */ true, mAddressCallbackContext);
|
||||
AddressInfo addressInfo(*entry);
|
||||
|
||||
mAddressCallback(&addressInfo,
|
||||
/* IsAdded */ true, mAddressCallbackContext);
|
||||
}
|
||||
|
||||
exit:
|
||||
@@ -175,7 +202,10 @@ void Netif::UnsubscribeAllNodesMulticast(void)
|
||||
|
||||
for (const NetifMulticastAddress *entry = &linkLocalAllNodesAddress; entry; entry = entry->GetNext())
|
||||
{
|
||||
mAddressCallback(&entry->GetAddress(), kMulticastPrefixLength, /* IsAdded */ false, mAddressCallbackContext);
|
||||
AddressInfo addressInfo(*entry);
|
||||
|
||||
mAddressCallback(&addressInfo,
|
||||
/* IsAdded */ false, mAddressCallbackContext);
|
||||
}
|
||||
|
||||
exit:
|
||||
@@ -233,7 +263,10 @@ void Netif::SubscribeAllRoutersMulticast(void)
|
||||
for (const NetifMulticastAddress *entry = &linkLocalAllRoutersAddress; entry != &linkLocalAllNodesAddress;
|
||||
entry = entry->GetNext())
|
||||
{
|
||||
mAddressCallback(&entry->GetAddress(), kMulticastPrefixLength, /* IsAdded */ true, mAddressCallbackContext);
|
||||
AddressInfo addressInfo(*entry);
|
||||
|
||||
mAddressCallback(&addressInfo,
|
||||
/* IsAdded */ true, mAddressCallbackContext);
|
||||
}
|
||||
|
||||
exit:
|
||||
@@ -276,7 +309,10 @@ void Netif::UnsubscribeAllRoutersMulticast(void)
|
||||
for (const NetifMulticastAddress *entry = &linkLocalAllRoutersAddress; entry != &linkLocalAllNodesAddress;
|
||||
entry = entry->GetNext())
|
||||
{
|
||||
mAddressCallback(&entry->GetAddress(), kMulticastPrefixLength, /* IsAdded */ false, mAddressCallbackContext);
|
||||
AddressInfo addressInfo(*entry);
|
||||
|
||||
mAddressCallback(&addressInfo,
|
||||
/* IsAdded */ false, mAddressCallbackContext);
|
||||
}
|
||||
|
||||
exit:
|
||||
@@ -295,7 +331,13 @@ void Netif::SubscribeMulticast(NetifMulticastAddress &aAddress)
|
||||
Get<Notifier>().Signal(kEventIp6MulticastSubscribed);
|
||||
|
||||
VerifyOrExit(mAddressCallback != nullptr, OT_NOOP);
|
||||
mAddressCallback(&aAddress.mAddress, kMulticastPrefixLength, /* IsAdded */ true, mAddressCallbackContext);
|
||||
|
||||
{
|
||||
AddressInfo addressInfo(aAddress);
|
||||
|
||||
mAddressCallback(&addressInfo,
|
||||
/* IsAdded */ true, mAddressCallbackContext);
|
||||
}
|
||||
|
||||
exit:
|
||||
return;
|
||||
@@ -308,7 +350,12 @@ void Netif::UnsubscribeMulticast(const NetifMulticastAddress &aAddress)
|
||||
Get<Notifier>().Signal(kEventIp6MulticastUnsubscribed);
|
||||
|
||||
VerifyOrExit(mAddressCallback != nullptr, OT_NOOP);
|
||||
mAddressCallback(&aAddress.mAddress, kMulticastPrefixLength, /* IsAdded */ false, mAddressCallbackContext);
|
||||
{
|
||||
AddressInfo addressInfo(aAddress);
|
||||
|
||||
mAddressCallback(&addressInfo,
|
||||
/* IsAdded */ false, mAddressCallbackContext);
|
||||
}
|
||||
|
||||
exit:
|
||||
return;
|
||||
@@ -396,7 +443,13 @@ void Netif::AddUnicastAddress(NetifUnicastAddress &aAddress)
|
||||
Get<Notifier>().Signal(aAddress.mRloc ? kEventThreadRlocAdded : kEventIp6AddressAdded);
|
||||
|
||||
VerifyOrExit(mAddressCallback != nullptr, OT_NOOP);
|
||||
mAddressCallback(&aAddress.mAddress, aAddress.mPrefixLength, /* IsAdded */ true, mAddressCallbackContext);
|
||||
|
||||
{
|
||||
AddressInfo addressInfo(aAddress, GetInstance());
|
||||
|
||||
mAddressCallback(&addressInfo,
|
||||
/* IsAdded */ true, mAddressCallbackContext);
|
||||
}
|
||||
|
||||
exit:
|
||||
return;
|
||||
@@ -409,7 +462,11 @@ void Netif::RemoveUnicastAddress(const NetifUnicastAddress &aAddress)
|
||||
Get<Notifier>().Signal(aAddress.mRloc ? kEventThreadRlocRemoved : kEventIp6AddressRemoved);
|
||||
|
||||
VerifyOrExit(mAddressCallback != nullptr, OT_NOOP);
|
||||
mAddressCallback(&aAddress.mAddress, aAddress.mPrefixLength, /* IsAdded */ false, mAddressCallbackContext);
|
||||
{
|
||||
AddressInfo addressInfo(aAddress, GetInstance());
|
||||
|
||||
mAddressCallback(&addressInfo, /* IsAdded */ false, mAddressCallbackContext);
|
||||
}
|
||||
|
||||
exit:
|
||||
return;
|
||||
|
||||
@@ -683,11 +683,6 @@ protected:
|
||||
void UnsubscribeAllNodesMulticast(void);
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kMulticastPrefixLength = 128, ///< Multicast prefix length used to notify internal address changes.
|
||||
};
|
||||
|
||||
class ExternalMulticastAddressIteratorBuilder
|
||||
{
|
||||
public:
|
||||
|
||||
+144
-59
@@ -152,6 +152,40 @@ char gNetifName[IFNAMSIZ];
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE
|
||||
|
||||
namespace {
|
||||
|
||||
/**
|
||||
* This utility class converts binary IPv6 address to text format.
|
||||
*
|
||||
*/
|
||||
class Ip6AddressString
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* The constructor of this converter.
|
||||
*
|
||||
* @param[in] aAddress A pointer to a buffer holding an IPv6 address.
|
||||
*
|
||||
*/
|
||||
Ip6AddressString(const void *aAddress)
|
||||
{
|
||||
VerifyOrDie(inet_ntop(AF_INET6, aAddress, mBuffer, sizeof(mBuffer)) != nullptr, OT_EXIT_ERROR_ERRNO);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the string as a null-terminated C string.
|
||||
*
|
||||
* @returns The null-terminated C string.
|
||||
*
|
||||
*/
|
||||
const char *AsCString(void) const { return mBuffer; }
|
||||
|
||||
private:
|
||||
char mBuffer[INET6_ADDRSTRLEN];
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#ifndef OPENTHREAD_POSIX_TUN_DEVICE
|
||||
|
||||
#ifdef __linux__
|
||||
@@ -171,16 +205,9 @@ char gNetifName[IFNAMSIZ];
|
||||
|
||||
#endif // OPENTHREAD_TUN_DEVICE
|
||||
|
||||
// Some platforms will include linux/ipv6.h in netinet/in.h
|
||||
#if defined(__linux__) && !defined(_IPV6_H) && !defined(_UAPI_IPV6_H)
|
||||
// from linux/ipv6.h
|
||||
struct in6_ifreq
|
||||
{
|
||||
struct in6_addr ifr6_addr;
|
||||
__u32 ifr6_prefixlen;
|
||||
int ifr6_ifindex;
|
||||
};
|
||||
#endif // defined(__linux__) && !defined(_IPV6_H) && !defined(_UAPI_IPV6_H)
|
||||
#if defined(__linux__)
|
||||
static uint32_t sNetlinkSequence = 0; ///< Netlink message sequence.
|
||||
#endif
|
||||
|
||||
#if defined(RTM_NEWMADDR) || defined(__NetBSD__)
|
||||
// on some BSDs (mac OS, FreeBSD), we get RTM_NEWMADDR/RTM_DELMADDR messages, so we don't need to monitor using MLD
|
||||
@@ -298,46 +325,91 @@ static uint8_t NetmaskToPrefixLength(const struct sockaddr_in6 *netmask)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void UpdateUnicast(otInstance *aInstance, const otIp6Address &aAddress, uint8_t aPrefixLength, bool aIsAdded)
|
||||
#if defined(__linux__)
|
||||
static void UpdateUnicastLinux(const otIp6AddressInfo &aAddressInfo, bool aIsAdded)
|
||||
{
|
||||
struct rtattr *rta;
|
||||
|
||||
struct
|
||||
{
|
||||
struct nlmsghdr nh;
|
||||
struct ifaddrmsg ifa;
|
||||
char buf[512];
|
||||
} req;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
|
||||
req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
|
||||
req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_CREATE | NLM_F_EXCL;
|
||||
req.nh.nlmsg_type = aIsAdded ? RTM_NEWADDR : RTM_DELADDR;
|
||||
req.nh.nlmsg_pid = 0;
|
||||
req.nh.nlmsg_seq = ++sNetlinkSequence;
|
||||
|
||||
req.ifa.ifa_family = AF_INET6;
|
||||
req.ifa.ifa_prefixlen = aAddressInfo.mPrefixLength;
|
||||
req.ifa.ifa_flags = IFA_F_NODAD;
|
||||
req.ifa.ifa_scope = aAddressInfo.mScope;
|
||||
req.ifa.ifa_index = gNetifIndex;
|
||||
|
||||
rta = reinterpret_cast<struct rtattr *>((reinterpret_cast<char *>(&req)) + NLMSG_ALIGN(req.nh.nlmsg_len));
|
||||
rta->rta_type = IFA_LOCAL;
|
||||
rta->rta_len = RTA_LENGTH(sizeof(*aAddressInfo.mAddress));
|
||||
|
||||
memcpy(RTA_DATA(rta), aAddressInfo.mAddress, sizeof(*aAddressInfo.mAddress));
|
||||
|
||||
req.nh.nlmsg_len = NLMSG_ALIGN(req.nh.nlmsg_len) + rta->rta_len;
|
||||
|
||||
if (aAddressInfo.mIsAnycast)
|
||||
{
|
||||
struct ifa_cacheinfo cacheinfo;
|
||||
|
||||
rta = reinterpret_cast<struct rtattr *>((reinterpret_cast<char *>(rta)) + rta->rta_len);
|
||||
rta->rta_type = IFA_CACHEINFO;
|
||||
rta->rta_len = RTA_LENGTH(sizeof(cacheinfo));
|
||||
|
||||
memset(&cacheinfo, 0, sizeof(cacheinfo));
|
||||
cacheinfo.ifa_valid = UINT32_MAX;
|
||||
|
||||
memcpy(RTA_DATA(rta), &cacheinfo, sizeof(cacheinfo));
|
||||
|
||||
req.nh.nlmsg_len += rta->rta_len;
|
||||
}
|
||||
|
||||
if (send(sNetlinkFd, &req, req.nh.nlmsg_len, 0) != -1)
|
||||
{
|
||||
otLogInfoPlat("Sent request#%u to %s %s/%u", sNetlinkSequence, (aIsAdded ? "add" : "remove"),
|
||||
Ip6AddressString(aAddressInfo.mAddress).AsCString(), aAddressInfo.mPrefixLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
otLogInfoPlat("Failed to send request#%u to %s %s/%u", sNetlinkSequence, (aIsAdded ? "add" : "remove"),
|
||||
Ip6AddressString(aAddressInfo.mAddress).AsCString(), aAddressInfo.mPrefixLength);
|
||||
}
|
||||
}
|
||||
#endif // defined(__linux__)
|
||||
|
||||
static void UpdateUnicast(otInstance *aInstance, const otIp6AddressInfo &aAddressInfo, bool aIsAdded)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
assert(sInstance == aInstance);
|
||||
|
||||
VerifyOrExit(sIpFd >= 0, error = OT_ERROR_INVALID_STATE);
|
||||
assert(sIpFd >= 0);
|
||||
|
||||
#if defined(__linux__)
|
||||
{
|
||||
struct in6_ifreq ifr6;
|
||||
memcpy(&ifr6.ifr6_addr, &aAddress, sizeof(ifr6.ifr6_addr));
|
||||
|
||||
ifr6.ifr6_ifindex = static_cast<int>(gNetifIndex);
|
||||
ifr6.ifr6_prefixlen = aPrefixLength;
|
||||
|
||||
if (aIsAdded)
|
||||
{
|
||||
VerifyOrDie(ioctl(sIpFd, SIOCSIFADDR, &ifr6) == 0, OT_EXIT_ERROR_ERRNO);
|
||||
}
|
||||
else
|
||||
{
|
||||
VerifyOrExit(ioctl(sIpFd, SIOCDIFADDR, &ifr6) == 0, perror("ioctl"); error = OT_ERROR_FAILED);
|
||||
}
|
||||
}
|
||||
UpdateUnicastLinux(aAddressInfo, aIsAdded);
|
||||
#elif defined(__APPLE__) || defined(__NetBSD__) || defined(__FreeBSD__)
|
||||
{
|
||||
int err;
|
||||
int rval;
|
||||
struct in6_aliasreq ifr6;
|
||||
|
||||
memset(&ifr6, 0, sizeof(ifr6));
|
||||
strlcpy(ifr6.ifra_name, gNetifName, sizeof(ifr6.ifra_name));
|
||||
ifr6.ifra_addr.sin6_family = AF_INET6;
|
||||
ifr6.ifra_addr.sin6_len = sizeof(ifr6.ifra_addr);
|
||||
memcpy(&ifr6.ifra_addr.sin6_addr, &aAddress, sizeof(struct in6_addr));
|
||||
memcpy(&ifr6.ifra_addr.sin6_addr, aAddressInfo.mAddress, sizeof(struct in6_addr));
|
||||
ifr6.ifra_prefixmask.sin6_family = AF_INET6;
|
||||
ifr6.ifra_prefixmask.sin6_len = sizeof(ifr6.ifra_prefixmask);
|
||||
InitNetaskWithPrefixLength(&ifr6.ifra_prefixmask.sin6_addr, aPrefixLength);
|
||||
InitNetaskWithPrefixLength(&ifr6.ifra_prefixmask.sin6_addr, aAddressInfo.mPrefixLength);
|
||||
ifr6.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;
|
||||
ifr6.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
|
||||
|
||||
@@ -346,24 +418,20 @@ static void UpdateUnicast(otInstance *aInstance, const otIp6Address &aAddress, u
|
||||
ifr6.ifra_lifetime.ia6t_preferred = ND6_INFINITE_LIFETIME;
|
||||
#endif
|
||||
|
||||
err = ioctl(sIpFd, aIsAdded ? SIOCAIFADDR_IN6 : SIOCDIFADDR_IN6, &ifr6);
|
||||
if ((err == -1) && (errno == EALREADY))
|
||||
rval = ioctl(sIpFd, aIsAdded ? SIOCAIFADDR_IN6 : SIOCDIFADDR_IN6, &ifr6);
|
||||
if (rval == 0)
|
||||
{
|
||||
err = 0;
|
||||
otLogInfoPlat("%s %s/%u", (aIsAdded ? "Added" : "Removed"),
|
||||
Ip6AddressString(aAddressInfo.mAddress).AsCString(), aAddressInfo.mPrefixLength);
|
||||
}
|
||||
else if (errno != EALREADY)
|
||||
{
|
||||
otLogWarnPlat("Failed to %s %s/%u: %s", (aIsAdded ? "add" : "remove"),
|
||||
Ip6AddressString(aAddressInfo.mAddress).AsCString(), aAddressInfo.mPrefixLength,
|
||||
strerror(errno));
|
||||
}
|
||||
VerifyOrExit(err == 0, perror("ioctl"); error = OT_ERROR_FAILED);
|
||||
}
|
||||
#endif
|
||||
|
||||
exit:
|
||||
if (error != OT_ERROR_NONE)
|
||||
{
|
||||
otLogWarnPlat("%s: %s", __func__, otThreadErrorToString(error));
|
||||
}
|
||||
else
|
||||
{
|
||||
otLogInfoPlat("%s: %s", __func__, otThreadErrorToString(error));
|
||||
}
|
||||
}
|
||||
|
||||
static void UpdateMulticast(otInstance *aInstance, const otIp6Address &aAddress, bool aIsAdded)
|
||||
@@ -385,9 +453,9 @@ static void UpdateMulticast(otInstance *aInstance, const otIp6Address &aAddress,
|
||||
if ((err != 0) && (errno == EINVAL) && (IN6_IS_ADDR_MC_LINKLOCAL(&mreq.ipv6mr_multiaddr)))
|
||||
{
|
||||
// FIX ME
|
||||
// on mac OS (and FreeBSD), the first time we run (but not subsequently), we get a failure on this particular
|
||||
// join. do we need to bring up the interface at least once prior to joining?
|
||||
// we need to figure out why so we can get rid of this workaround
|
||||
// on mac OS (and FreeBSD), the first time we run (but not subsequently), we get a failure on this
|
||||
// particular join. do we need to bring up the interface at least once prior to joining? we need to figure
|
||||
// out why so we can get rid of this workaround
|
||||
char addressString[INET6_ADDRSTRLEN + 1];
|
||||
|
||||
inet_ntop(AF_INET6, mreq.ipv6mr_multiaddr.s6_addr, addressString, sizeof(addressString));
|
||||
@@ -445,15 +513,15 @@ exit:
|
||||
}
|
||||
}
|
||||
|
||||
static void processAddressChange(const otIp6Address *aAddress, uint8_t aPrefixLength, bool aIsAdded, void *aContext)
|
||||
static void processAddressChange(const otIp6AddressInfo *aAddressInfo, bool aIsAdded, void *aContext)
|
||||
{
|
||||
if (aAddress->mFields.m8[0] == 0xff)
|
||||
if (aAddressInfo->mAddress->mFields.m8[0] == 0xff)
|
||||
{
|
||||
UpdateMulticast(static_cast<otInstance *>(aContext), *aAddress, aIsAdded);
|
||||
UpdateMulticast(static_cast<otInstance *>(aContext), *aAddressInfo->mAddress, aIsAdded);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateUnicast(static_cast<otInstance *>(aContext), *aAddress, aPrefixLength, aIsAdded);
|
||||
UpdateUnicast(static_cast<otInstance *>(aContext), *aAddressInfo, aIsAdded);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -959,7 +1027,7 @@ exit:
|
||||
|
||||
#endif
|
||||
|
||||
static void processNetifEvent(otInstance *aInstance)
|
||||
static void processNetlinkEvent(otInstance *aInstance)
|
||||
{
|
||||
const size_t kMaxNetifEvent = 8192;
|
||||
ssize_t length;
|
||||
@@ -1008,6 +1076,23 @@ static void processNetifEvent(otInstance *aInstance)
|
||||
case RTM_IFINFO:
|
||||
processNetifInfoEvent(aInstance, msg);
|
||||
break;
|
||||
|
||||
#else
|
||||
case NLMSG_ERROR:
|
||||
{
|
||||
const struct nlmsgerr *err = reinterpret_cast<const nlmsgerr *>(NLMSG_DATA(msg));
|
||||
|
||||
if (err->error == 0)
|
||||
{
|
||||
otLogInfoPlat("Succeeded to process request#%u", err->msg.nlmsg_seq);
|
||||
}
|
||||
else
|
||||
{
|
||||
otLogWarnPlat("Failed to process request#%u: %s", err->msg.nlmsg_seq, strerror(err->error));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ROUTE_FILTER) || defined(RO_MSGFILTER) || defined(__linux__)
|
||||
@@ -1015,7 +1100,7 @@ static void processNetifEvent(otInstance *aInstance)
|
||||
otLogWarnPlat("unhandled/unexpected netlink/route message (%d).", (int)msg->nlmsg_type);
|
||||
break;
|
||||
#else
|
||||
// this platform doesn't support filtering, so we expect messages of other types...we just ignore them
|
||||
// this platform doesn't support filtering, so we expect messages of other types...we just ignore them
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1190,7 +1275,7 @@ static void platformConfigureTunDevice(otInstance *aInstance,
|
||||
VerifyOrDie(sTunFd >= 0, OT_EXIT_ERROR_ERRNO);
|
||||
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
|
||||
ifr.ifr_flags = IFF_TUN | IFF_NO_PI | static_cast<short>(IFF_TUN_EXCL);
|
||||
|
||||
if (aInterfaceName)
|
||||
{
|
||||
@@ -1451,7 +1536,7 @@ void platformNetifProcess(const fd_set *aReadFdSet, const fd_set *aWriteFdSet, c
|
||||
|
||||
if (FD_ISSET(sNetlinkFd, aReadFdSet))
|
||||
{
|
||||
processNetifEvent(sInstance);
|
||||
processNetlinkEvent(sInstance);
|
||||
}
|
||||
|
||||
#if OPENTHREAD_POSIX_USE_MLD_MONITOR
|
||||
|
||||
Reference in New Issue
Block a user