mirror of
https://github.com/espressif/openthread.git
synced 2026-06-06 05:24:51 +00:00
[posix] add posix support for sending RA messages to routing manager (#9160)
This commit is contained in:
@@ -80,7 +80,8 @@ typedef enum otIcmp6Code
|
||||
OT_ICMP6_CODE_FRAGM_REAS_TIME_EX = 1, ///< Fragment Reassembly Time Exceeded
|
||||
} otIcmp6Code;
|
||||
|
||||
#define OT_ICMP6_HEADER_DATA_SIZE 4 ///< Size of an message specific data of ICMPv6 Header.
|
||||
#define OT_ICMP6_HEADER_DATA_SIZE 4 ///< Size of ICMPv6 Header.
|
||||
#define OT_ICMP6_ROUTER_ADVERT_MIN_SIZE 16 ///< Size of a Router Advertisement message without any options.
|
||||
|
||||
/**
|
||||
* @struct otIcmp6Header
|
||||
|
||||
@@ -53,7 +53,7 @@ extern "C" {
|
||||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (332)
|
||||
#define OPENTHREAD_API_VERSION (333)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
@@ -56,6 +56,8 @@ extern "C" {
|
||||
#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)
|
||||
|
||||
/**
|
||||
* @struct otIp6InterfaceIdentifier
|
||||
|
||||
@@ -146,6 +146,7 @@ extern int
|
||||
#include <openthread/message.h>
|
||||
#include <openthread/nat64.h>
|
||||
#include <openthread/netdata.h>
|
||||
#include <openthread/platform/border_routing.h>
|
||||
#include <openthread/platform/misc.h>
|
||||
|
||||
#include "common/code_utils.hpp"
|
||||
@@ -1021,6 +1022,71 @@ exit:
|
||||
}
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_NAT64_TRANSLATOR_ENABLE || OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE
|
||||
static constexpr uint8_t kIpVersion4 = 4;
|
||||
static constexpr uint8_t kIpVersion6 = 6;
|
||||
|
||||
static uint8_t getIpVersion(const uint8_t *data)
|
||||
{
|
||||
assert(data != nullptr);
|
||||
|
||||
// Mute compiler warnings.
|
||||
OT_UNUSED_VARIABLE(kIpVersion4);
|
||||
OT_UNUSED_VARIABLE(kIpVersion6);
|
||||
|
||||
return (static_cast<uint8_t>(data[0]) >> 4) & 0x0F;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE
|
||||
|
||||
/**
|
||||
* Returns nullptr if data does not point to a valid ICMPv6 RA message.
|
||||
*
|
||||
*/
|
||||
static const uint8_t *getIcmp6RaMessage(const uint8_t *data, ssize_t length)
|
||||
{
|
||||
const uint8_t *ret = nullptr;
|
||||
otIcmp6Header icmpHeader;
|
||||
|
||||
VerifyOrExit(length >= OT_IP6_HEADER_SIZE + OT_ICMP6_ROUTER_ADVERT_MIN_SIZE);
|
||||
VerifyOrExit(getIpVersion(data) == kIpVersion6);
|
||||
VerifyOrExit(data[OT_IP6_HEADER_PROTO_OFFSET] == OT_IP6_PROTO_ICMP6);
|
||||
|
||||
ret = data + OT_IP6_HEADER_SIZE;
|
||||
memcpy(&icmpHeader, ret, sizeof(icmpHeader));
|
||||
VerifyOrExit(icmpHeader.mType == OT_ICMP6_TYPE_ROUTER_ADVERT, ret = nullptr);
|
||||
VerifyOrExit(icmpHeader.mCode == 0, ret = nullptr);
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns false if the message is not an ICMPv6 RA message.
|
||||
*
|
||||
*/
|
||||
static otError tryProcessIcmp6RaMessage(otInstance *aInstance, const uint8_t *data, ssize_t length)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
const uint8_t *ra = getIcmp6RaMessage(data, length);
|
||||
ssize_t raLength;
|
||||
|
||||
VerifyOrExit(ra != nullptr, error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
#if OPENTHREAD_POSIX_LOG_TUN_PACKETS
|
||||
otLogInfoPlat("[netif] RA to BorderRouting (%hu bytes)", static_cast<uint16_t>(length));
|
||||
otDumpInfoPlat("", data, static_cast<size_t>(length));
|
||||
#endif
|
||||
|
||||
raLength = length + (ra - data);
|
||||
otPlatBorderRoutingProcessIcmp6Ra(aInstance, ra, raLength);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE
|
||||
|
||||
static void processTransmit(otInstance *aInstance)
|
||||
{
|
||||
otMessage *message = nullptr;
|
||||
@@ -1046,13 +1112,20 @@ static void processTransmit(otInstance *aInstance)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE
|
||||
if (tryProcessIcmp6RaMessage(aInstance, reinterpret_cast<uint8_t *>(&packet[offset]), rval) == OT_ERROR_NONE)
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
otMessageSettings settings;
|
||||
|
||||
settings.mLinkSecurityEnabled = (otThreadGetDeviceRole(aInstance) != OT_DEVICE_ROLE_DISABLED);
|
||||
settings.mPriority = OT_MESSAGE_PRIORITY_LOW;
|
||||
#if OPENTHREAD_CONFIG_NAT64_TRANSLATOR_ENABLE
|
||||
isIp4 = (packet[offset] & 0xf0) == 0x40;
|
||||
isIp4 = (getIpVersion(reinterpret_cast<uint8_t *>(&packet[offset])) == kIpVersion4);
|
||||
message = isIp4 ? otIp4NewMessage(aInstance, &settings) : otIp6NewMessage(aInstance, &settings);
|
||||
#else
|
||||
message = otIp6NewMessage(aInstance, &settings);
|
||||
|
||||
Reference in New Issue
Block a user