mirror of
https://github.com/espressif/openthread.git
synced 2026-08-13 06:07:48 +00:00
[ip6] no anycast as source address (#5632)
- Check source address of packets from users - Determine anycast address by MLE API for accuracy - Replace anycast address with a valid unicast address when sending with platform UDP in UDP layer - Replace anycast address with a valid unicast address in IP layer
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 (32)
|
||||
#define OPENTHREAD_API_VERSION (33)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
@@ -486,11 +486,13 @@ void otIp6SetReceiveFilterEnabled(otInstance *aInstance, bool aEnabled);
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aMessage A pointer to the message buffer containing the IPv6 datagram.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully processed the message.
|
||||
* @retval OT_ERROR_DROP Message was well-formed but not fully processed due to packet processing rules.
|
||||
* @retval OT_ERROR_NO_BUFS Could not allocate necessary message buffers when processing the datagram.
|
||||
* @retval OT_ERROR_NO_ROUTE No route to host.
|
||||
* @retval OT_ERROR_PARSE Encountered a malformed header when processing the message.
|
||||
* @retval OT_ERROR_NONE Successfully processed the message.
|
||||
* @retval OT_ERROR_DROP Message was well-formed but not fully processed due to packet processing
|
||||
* rules.
|
||||
* @retval OT_ERROR_NO_BUFS Could not allocate necessary message buffers when processing the datagram.
|
||||
* @retval OT_ERROR_NO_ROUTE No route to host.
|
||||
* @retval OT_ERROR_INVALID_SOURCE_ADDRESS Source addresss is invalid, e.g. an anycast address or a multicast address.
|
||||
* @retval OT_ERROR_PARSE Encountered a malformed header when processing the message.
|
||||
*
|
||||
*/
|
||||
otError otIp6Send(otInstance *aInstance, otMessage *aMessage);
|
||||
|
||||
+11
-7
@@ -457,7 +457,8 @@ otError Ip6::SendDatagram(Message &aMessage, MessageInfo &aMessageInfo, uint8_t
|
||||
header.SetHopLimit(static_cast<uint8_t>(kDefaultHopLimit));
|
||||
}
|
||||
|
||||
if (aMessageInfo.GetSockAddr().IsUnspecified() || aMessageInfo.GetSockAddr().IsMulticast())
|
||||
if (aMessageInfo.GetSockAddr().IsUnspecified() || aMessageInfo.GetSockAddr().IsMulticast() ||
|
||||
Get<Mle::Mle>().IsAnycastLocator(aMessageInfo.GetSockAddr()))
|
||||
{
|
||||
const NetifUnicastAddress *source = SelectSourceAddress(aMessageInfo);
|
||||
|
||||
@@ -1071,6 +1072,8 @@ otError Ip6::SendRaw(Message &aMessage)
|
||||
bool freed = false;
|
||||
|
||||
SuccessOrExit(error = header.Init(aMessage));
|
||||
VerifyOrExit(!header.GetSource().IsMulticast() && !Get<Mle::Mle>().IsAnycastLocator(header.GetSource()),
|
||||
error = OT_ERROR_INVALID_SOURCE_ADDRESS);
|
||||
|
||||
messageInfo.SetPeerAddr(header.GetSource());
|
||||
messageInfo.SetSockAddr(header.GetDestination());
|
||||
@@ -1301,10 +1304,11 @@ exit:
|
||||
|
||||
const NetifUnicastAddress *Ip6::SelectSourceAddress(MessageInfo &aMessageInfo)
|
||||
{
|
||||
Address * destination = &aMessageInfo.GetPeerAddr();
|
||||
uint8_t destinationScope = destination->GetScope();
|
||||
const NetifUnicastAddress *rvalAddr = nullptr;
|
||||
uint8_t rvalPrefixMatched = 0;
|
||||
Address * destination = &aMessageInfo.GetPeerAddr();
|
||||
uint8_t destinationScope = destination->GetScope();
|
||||
const bool destinationIsRoutingLocator = Get<Mle::Mle>().IsRoutingLocator(*destination);
|
||||
const NetifUnicastAddress *rvalAddr = nullptr;
|
||||
uint8_t rvalPrefixMatched = 0;
|
||||
|
||||
for (const NetifUnicastAddress *addr = Get<ThreadNetif>().GetUnicastAddresses(); addr; addr = addr->GetNext())
|
||||
{
|
||||
@@ -1312,7 +1316,7 @@ const NetifUnicastAddress *Ip6::SelectSourceAddress(MessageInfo &aMessageInfo)
|
||||
uint8_t candidatePrefixMatched;
|
||||
uint8_t overrideScope;
|
||||
|
||||
if (candidateAddr->GetIid().IsAnycastLocator())
|
||||
if (Get<Mle::Mle>().IsAnycastLocator(*candidateAddr))
|
||||
{
|
||||
// Don't use anycast address as source address.
|
||||
continue;
|
||||
@@ -1382,7 +1386,7 @@ const NetifUnicastAddress *Ip6::SelectSourceAddress(MessageInfo &aMessageInfo)
|
||||
rvalPrefixMatched = candidatePrefixMatched;
|
||||
}
|
||||
else if ((candidatePrefixMatched == rvalPrefixMatched) &&
|
||||
(destination->GetIid().IsRoutingLocator() == candidateAddr->GetIid().IsRoutingLocator()))
|
||||
(destinationIsRoutingLocator == Get<Mle::Mle>().IsRoutingLocator(*candidateAddr)))
|
||||
{
|
||||
// Additional rule: Prefer RLOC source for RLOC destination, EID source for anything else
|
||||
rvalAddr = addr;
|
||||
|
||||
@@ -327,6 +327,15 @@ otError Udp::SendTo(SocketHandle &aSocket, Message &aMessage, const MessageInfo
|
||||
if (!IsMlePort(aSocket.mSockName.mPort) &&
|
||||
!(aSocket.mSockName.mPort == Tmf::kUdpPort && aMessage.GetSubType() == Message::kSubTypeJoinerEntrust))
|
||||
{
|
||||
// Replace anycast address with a valid unicast address since response messages typically copy the peer address
|
||||
if (Get<Mle::Mle>().IsAnycastLocator(messageInfoLocal.GetSockAddr()))
|
||||
{
|
||||
const NetifUnicastAddress *netifAddr = Get<Ip6>().SelectSourceAddress(messageInfoLocal);
|
||||
|
||||
VerifyOrExit(netifAddr != nullptr, error = OT_ERROR_INVALID_ARGS);
|
||||
messageInfoLocal.SetSockAddr(netifAddr->GetAddress());
|
||||
}
|
||||
|
||||
SuccessOrExit(error = otPlatUdpSend(&aSocket, &aMessage, &messageInfoLocal));
|
||||
}
|
||||
else
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/expect -f
|
||||
#
|
||||
# Copyright (c) 2020, The OpenThread Authors.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# 3. Neither the name of the copyright holder nor the
|
||||
# names of its contributors may be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
source "tests/scripts/expect/_common.exp"
|
||||
|
||||
|
||||
set spawn_id [spawn_node 1]
|
||||
|
||||
send "panid 0xface\n"
|
||||
expect "Done"
|
||||
send "ifconfig up\n"
|
||||
expect "Done"
|
||||
send "thread start\n"
|
||||
expect "Done"
|
||||
|
||||
wait_for "state" "leader"
|
||||
expect "Done"
|
||||
|
||||
send "ping fdde:ad00:beef:0:0:ff:fe00:fc00\n"
|
||||
expect "Done"
|
||||
expect "16 bytes from "
|
||||
expect {
|
||||
"fdde:ad00:beef:0:0:ff:fe00:fc00" abort
|
||||
|
||||
-re {(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4})} {}
|
||||
|
||||
timeout abort
|
||||
}
|
||||
|
||||
dispose
|
||||
@@ -40,7 +40,7 @@ expect "Done"
|
||||
wait_for "state" "leader"
|
||||
expect "Done"
|
||||
|
||||
send "ipaddr\n"
|
||||
send "ipaddr mleid\n"
|
||||
expect -re {(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4})}
|
||||
set addr $expect_out(1,string)
|
||||
expect "Done"
|
||||
|
||||
Reference in New Issue
Block a user