Skip to content

Commit

Permalink
[posix] Add posix support for sending RA messages to routing manager
Browse files Browse the repository at this point in the history
  • Loading branch information
erjiaqing committed Jun 9, 2023
1 parent e7b591e commit 202332c
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 3 deletions.
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 an message specific data of ICMPv6 Header.
#define OT_ICMP6_ROUTER_ADVERT_MIN_SIZE 16 ///< Size of an 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 (329)
#define OPENTHREAD_API_VERSION (330)

/**
* @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
65 changes: 64 additions & 1 deletion src/posix/platform/netif.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1021,6 +1021,65 @@ static void processReceive(otMessage *aMessage, void *aContext)
}
}

enum IpVersion {
IP_VERSION_IP4 = 4,
IP_VERSION_IP6 = 6,
};

#if OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE
static IpVersion getIpVersion(const uint8_t *data) {
assert(data != nullptr);

return static_cast<IpVersion>((data[0] >> 4) & 0x0F);
}

/**
* Returns nullptr if data is not pointed 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) == IP_VERSION_IP6);
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);
VerifyOrExit(icmpHeader.mCode == 0);

exit:
return ret;
}

/**
* Returns false if the message is not an ICMPv6 RA message.
*
*/
static bool tryProcessIcmp6RaMessage(otInstance *aInstance, const uint8_t *data, ssize_t length)
{
const uint8_t *ra = getIcmp6RaMessage(data, length);
ssize_t raLength;

VerifyOrExit(ret != nullptr);
VerifyOrERxit(otBorderRoutingDhcp6PdGetState(aInstance) == OT_BORDER_ROUTING_DHCP6_PD_STATE_RUNNING);

raLength = length + (ret - data);
otPlatBorderRoutingProcessIcmp6Ra(aInstance, ra, raLength);

#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

exit:
return ra != nullptr;
}
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE

static void processTransmit(otInstance *aInstance)
{
otMessage *message = nullptr;
Expand All @@ -1046,13 +1105,17 @@ static void processTransmit(otInstance *aInstance)
}
#endif

#if OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE
VerifyOrExit(!tryProcessIcmp6RaMessage(aInstance, &packet[offset], rval));
#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(&packet[offset]) == IP_VERSION_IP4);
message = isIp4 ? otIp4NewMessage(aInstance, &settings) : otIp6NewMessage(aInstance, &settings);
#else
message = otIp6NewMessage(aInstance, &settings);
Expand Down

0 comments on commit 202332c

Please sign in to comment.