mirror of
https://github.com/espressif/openthread.git
synced 2026-08-21 18:09:52 +00:00
[ip6] enhance handling of IPv6 fragmentation (#4940)
This commit introduces a few enhancements: - In NCP architecture forward the IPv6 fragments instead of the full reassembled IPv6 packet (which in the default configuration can't be forwarder due to SPINEL limitations). Without this fix the fragmentation does not work if Thread device wants to send more than MTU data through the Border Router (to the IPv6 address of NCP). - Use OPENTHREAD_CONFIG_IP6_MAX_ASSEMBLED_DATAGRAM only for the receiving path. For transmitting path, relay on the message buffers pool. This is especially important for some of the use-cases we have, and also reduce a need for regenerating OpenThread libraries. - In case receiving IPv6 packet is bigger than supported OPENTHREAD_CONFIG_IP6_MAX_ASSEMBLED_DATAGRAM, exit before trying to allocate the next message buffer.
This commit is contained in:
committed by
Jonathan Hui
parent
069afa5a17
commit
2f683e6e76
+14
-11
@@ -646,8 +646,6 @@ otError Ip6::FragmentDatagram(Message &aMessage, uint8_t aIpProto)
|
||||
FragmentHeader::MakeDivisibleByEight(kMinimalMtu - aMessage.GetOffset() - sizeof(fragmentHeader));
|
||||
uint16_t payloadLeft = aMessage.GetLength() - aMessage.GetOffset();
|
||||
|
||||
VerifyOrExit(aMessage.GetLength() <= kMaxAssembledDatagramLength, error = OT_ERROR_NO_BUFS);
|
||||
|
||||
VerifyOrExit(aMessage.Read(0, sizeof(header), &header) == sizeof(header), error = OT_ERROR_PARSE);
|
||||
header.SetNextHeader(kProtoFragment);
|
||||
|
||||
@@ -699,6 +697,7 @@ otError Ip6::FragmentDatagram(Message &aMessage, uint8_t aIpProto)
|
||||
|
||||
otLogInfoIp6("Fragment %d with %d bytes sent", fragmentCnt, payloadFragment);
|
||||
}
|
||||
|
||||
aMessage.Free();
|
||||
|
||||
exit:
|
||||
@@ -757,6 +756,15 @@ otError Ip6::HandleFragment(Message &aMessage, Netif *aNetif, MessageInfo &aMess
|
||||
offset = FragmentHeader::FragmentOffsetToBytes(fragmentHeader.GetOffset());
|
||||
payloadFragment = aMessage.GetLength() - aMessage.GetOffset() - sizeof(fragmentHeader);
|
||||
|
||||
otLogInfoIp6("Fragment with id %d received > %d bytes, offset %d", fragmentHeader.GetIdentification(),
|
||||
payloadFragment, offset);
|
||||
|
||||
if (offset + payloadFragment + aMessage.GetOffset() > kMaxAssembledDatagramLength)
|
||||
{
|
||||
otLogWarnIp6("Packet too large for fragment buffer");
|
||||
ExitNow(error = OT_ERROR_NO_BUFS);
|
||||
}
|
||||
|
||||
if (message == NULL)
|
||||
{
|
||||
VerifyOrExit((message = NewMessage(0)) != NULL, error = OT_ERROR_NO_BUFS);
|
||||
@@ -780,15 +788,6 @@ otError Ip6::HandleFragment(Message &aMessage, Netif *aNetif, MessageInfo &aMess
|
||||
otLogDebgIp6("start reassembly.");
|
||||
}
|
||||
|
||||
otLogInfoIp6("Fragment with id %d received > %d bytes, offset %d", message->GetDatagramTag(), payloadFragment,
|
||||
offset);
|
||||
|
||||
if (offset + payloadFragment + aMessage.GetOffset() > kMaxAssembledDatagramLength)
|
||||
{
|
||||
otLogWarnIp6("Package too large for fragment buffer");
|
||||
ExitNow(error = OT_ERROR_NO_BUFS);
|
||||
}
|
||||
|
||||
// increase message buffer if necessary
|
||||
if (message->GetLength() < offset + payloadFragment + aMessage.GetOffset())
|
||||
{
|
||||
@@ -833,6 +832,7 @@ exit:
|
||||
}
|
||||
otLogWarnIp6("Reassembly failed: %s", otThreadErrorToString(error));
|
||||
}
|
||||
|
||||
if (isFragmented)
|
||||
{
|
||||
// drop all fragments, the payload is stored in the fragment buffer
|
||||
@@ -970,6 +970,9 @@ otError Ip6::HandleExtensionHeaders(Message & aMessage,
|
||||
break;
|
||||
|
||||
case kProtoFragment:
|
||||
// Always forward IPv6 fragments to the Host.
|
||||
IgnoreError(ProcessReceiveCallback(aMessage, aMessageInfo, aNextHeader, aFromNcpHost));
|
||||
|
||||
SuccessOrExit(error = HandleFragment(aMessage, aNetif, aMessageInfo, aFromNcpHost));
|
||||
break;
|
||||
|
||||
|
||||
@@ -77,9 +77,6 @@ class TestIPv6Fragmentation(thread_cert.TestCase):
|
||||
self.simulator.go(5)
|
||||
self.nodes[LEADER].udp_check_rx(1831)
|
||||
|
||||
self.nodes[ROUTER].udp_send(1953, mleid_leader, common.UDP_TEST_PORT,
|
||||
False)
|
||||
|
||||
self.nodes[ROUTER].udp_stop()
|
||||
self.nodes[LEADER].udp_stop()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user