Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[posix] add posix support for sending RA messages to routing manager #9160

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion include/openthread/icmp6.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion include/openthread/instance.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions include/openthread/ip6.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
75 changes: 74 additions & 1 deletion src/posix/platform/netif.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -1021,6 +1022,71 @@ static void processReceive(otMessage *aMessage, void *aContext)
}
}

#if OPENTHREAD_CONFIG_NAT64_TRANSLATOR_ENABLE || OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE
abtink marked this conversation as resolved.
Show resolved Hide resolved
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)
{
abtink marked this conversation as resolved.
Show resolved Hide resolved
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
abtink marked this conversation as resolved.
Show resolved Hide resolved

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;
Expand All @@ -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);
Expand Down
Loading