mirror of
https://github.com/espressif/openthread.git
synced 2026-08-11 13:17:48 +00:00
[posix] ignore required anycast address (#9717)
Ignore Required Anycast address when it is added to or deleted from wpan0 interface in openthread.
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 (384)
|
||||
#define OPENTHREAD_API_VERSION (385)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
@@ -52,12 +52,13 @@ extern "C" {
|
||||
*
|
||||
*/
|
||||
|
||||
#define OT_IP6_PREFIX_SIZE 8 ///< Size of an IPv6 prefix (bytes)
|
||||
#define OT_IP6_PREFIX_BITSIZE (OT_IP6_PREFIX_SIZE * 8) ///< Size of an IPv6 prefix (bits)
|
||||
#define OT_IP6_IID_SIZE 8 ///< Size of an IPv6 Interface Identifier (bytes)
|
||||
#define OT_IP6_ADDRESS_SIZE 16 ///< Size of an IPv6 address (bytes)
|
||||
#define OT_IP6_HEADER_SIZE 40 ///< Size of an IPv6 header (bytes)
|
||||
#define OT_IP6_HEADER_PROTO_OFFSET 6 ///< Offset of the proto field in the IPv6 header (bytes)
|
||||
#define OT_IP6_PREFIX_SIZE 8 ///< Size of an IPv6 prefix (bytes)
|
||||
#define OT_IP6_PREFIX_BITSIZE (OT_IP6_PREFIX_SIZE * 8) ///< Size of an IPv6 prefix (bits)
|
||||
#define OT_IP6_IID_SIZE 8 ///< Size of an IPv6 Interface Identifier (bytes)
|
||||
#define OT_IP6_ADDRESS_SIZE 16 ///< Size of an IPv6 address (bytes)
|
||||
#define OT_IP6_ADDRESS_BITSIZE (OT_IP6_ADDRESS_SIZE * 8) ///< Size of an IPv6 address (bits)
|
||||
#define OT_IP6_HEADER_SIZE 40 ///< Size of an IPv6 header (bytes)
|
||||
#define OT_IP6_HEADER_PROTO_OFFSET 6 ///< Offset of the proto field in the IPv6 header (bytes)
|
||||
|
||||
/**
|
||||
* @struct otIp6InterfaceIdentifier
|
||||
|
||||
@@ -1080,6 +1080,46 @@ exit:
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE
|
||||
|
||||
#ifdef __linux__
|
||||
/**
|
||||
* Returns whether the address is a required anycast address (RFC2373, 2.6.1).
|
||||
*
|
||||
*/
|
||||
static bool isRequiredAnycast(const uint8_t *aAddress, uint8_t aPrefixLength)
|
||||
{
|
||||
bool isRequiredAnycast = false;
|
||||
uint8_t firstBytePos = aPrefixLength / 8;
|
||||
uint8_t remainingBits = aPrefixLength % 8;
|
||||
|
||||
if (aPrefixLength == OT_IP6_ADDRESS_BITSIZE)
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
if (remainingBits != 0)
|
||||
{
|
||||
if ((aAddress[firstBytePos] & ((1 << remainingBits) - 1)) != 0)
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
firstBytePos++;
|
||||
}
|
||||
|
||||
for (int i = firstBytePos; i < OT_IP6_ADDRESS_SIZE; ++i)
|
||||
{
|
||||
if (aAddress[i] != 0)
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
}
|
||||
|
||||
isRequiredAnycast = true;
|
||||
|
||||
exit:
|
||||
return isRequiredAnycast;
|
||||
}
|
||||
#endif // __linux__
|
||||
|
||||
static void processTransmit(otInstance *aInstance)
|
||||
{
|
||||
otMessage *message = nullptr;
|
||||
@@ -1213,6 +1253,15 @@ static void processNetifAddrEvent(otInstance *aInstance, struct nlmsghdr *aNetli
|
||||
addr6.sin6_family = AF_INET6;
|
||||
memcpy(&addr6.sin6_addr, RTA_DATA(rta), sizeof(addr6.sin6_addr));
|
||||
|
||||
// Linux allows adding an IPv6 required anycast address to an interface,
|
||||
// which blocks openthread deriving an address by SLAAC and will cause routing issues.
|
||||
// Ignore the required anycast addresses here to allow OpenThread stack generate one when necessary,
|
||||
// and Linux will prefer the non-required anycast address on the interface.
|
||||
if (isRequiredAnycast(addr.GetBytes(), ifaddr->ifa_prefixlen))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (aNetlinkMessage->nlmsg_type == RTM_NEWADDR)
|
||||
{
|
||||
if (!addr.IsMulticast())
|
||||
|
||||
Reference in New Issue
Block a user