Skip to content

Commit c3823f6

Browse files
authored
[trel] add PeerTable using OwningList and allow heap use (openthread#11484)
This commit introduces `PeerTable` as a separate class to track TREL peers, separating this logic from `Trel::Interface`. The peer table uses `OwningList`, ensuring that `Peer` entries are properly freed upon removal. The logic for allocating a new peer is simplified, including the mechanism to evict a peer to make room for a new one. This commit also adds a new configuration option to allow TREL to use heap-allocated `Peer` entries instead of a `Pool<Peer>` with a fixed size. The `Peer` class now has a `Free()` method to ensure `Peer` instances are properly freed, regardless of whether they are heap or pool allocated. This, combined with the use of `OwningList`, simplifies memory management. To cover all configurations, `toranj` build configurations for the POSIX platform are configured to disallow TREL heap usage, while `toranj` configurations for the simulation platform enable it.
1 parent adf306c commit c3823f6

11 files changed

Lines changed: 320 additions & 171 deletions

src/core/api/trel_api.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,17 +50,17 @@ bool otTrelIsEnabled(otInstance *aInstance) { return AsCoreType(aInstance).Get<T
5050

5151
void otTrelInitPeerIterator(otInstance *aInstance, otTrelPeerIterator *aIterator)
5252
{
53-
AsCoreType(aInstance).Get<Trel::Interface>().InitIterator(*aIterator);
53+
AsCoreType(aInstance).Get<Trel::PeerTable>().InitIterator(*aIterator);
5454
}
5555

5656
const otTrelPeer *otTrelGetNextPeer(otInstance *aInstance, otTrelPeerIterator *aIterator)
5757
{
58-
return AsCoreType(aInstance).Get<Trel::Interface>().GetNextPeer(*aIterator);
58+
return AsCoreType(aInstance).Get<Trel::PeerTable>().GetNextPeer(*aIterator);
5959
}
6060

6161
uint16_t otTrelGetNumberOfPeers(otInstance *aInstance)
6262
{
63-
return AsCoreType(aInstance).Get<Trel::Interface>().GetNumberOfPeers();
63+
return AsCoreType(aInstance).Get<Trel::PeerTable>().GetNumberOfPeers();
6464
}
6565

6666
void otTrelSetFilterEnabled(otInstance *aInstance, bool aEnable)

src/core/config/trel.h

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,23 @@
4343
* @{
4444
*/
4545

46+
/**
47+
* @def OPENTHREAD_CONFIG_TREL_USE_HEAP_ENABLE
48+
*
49+
* Define as 1 to allow TREL modules to use heap allocated objects (e.g. for the TREL peer table).
50+
*/
51+
#ifndef OPENTHREAD_CONFIG_TREL_USE_HEAP_ENABLE
52+
#define OPENTHREAD_CONFIG_TREL_USE_HEAP_ENABLE 0
53+
#endif
54+
4655
/**
4756
* @def OPENTHREAD_CONFIG_TREL_PEER_TABLE_SIZE
4857
*
49-
* Specifies the capacity of TREL peer table. Only non-zero value
50-
* will be directly used for setting the TREL peer table capacity.
51-
* Zero value lets the size to be determined by the OT stack itself
52-
* which is derived based on other configurations such as a child
53-
* table size, neighbor table size, etc.
58+
* Specifies the capacity of TREL peer table. Only non-zero value will be directly used for setting the TREL peer table
59+
* capacity. Zero value lets the size to be determined by the OT stack itself which is derived based on other
60+
* configurations such as a child table size, neighbor table size, etc.
61+
*
62+
* Applicable when `OPENTHREAD_CONFIG_TREL_USE_HEAP_ENABLE` is not used.
5463
*/
5564
#ifndef OPENTHREAD_CONFIG_TREL_PEER_TABLE_SIZE
5665
#define OPENTHREAD_CONFIG_TREL_PEER_TABLE_SIZE (0)

src/core/instance/instance.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,8 @@ template <> inline Mac::SubMac &Instance::Get(void) { return mMac.mLinks.mSubMac
799799
template <> inline Trel::Link &Instance::Get(void) { return mMac.mLinks.mTrel; }
800800

801801
template <> inline Trel::Interface &Instance::Get(void) { return mMac.mLinks.mTrel.mInterface; }
802+
803+
template <> inline Trel::PeerTable &Instance::Get(void) { return mMac.mLinks.mTrel.mPeerTable; }
802804
#endif
803805

804806
#if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE

src/core/radio/trel_interface.cpp

Lines changed: 21 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -102,21 +102,13 @@ void Interface::Disable(void)
102102
VerifyOrExit(mInitialized);
103103

104104
otPlatTrelDisable(&GetInstance());
105-
ClearPeerList();
105+
Get<PeerTable>().Clear();
106106
LogDebg("Disabled interface");
107107

108108
exit:
109109
return;
110110
}
111111

112-
void Interface::ClearPeerList(void)
113-
{
114-
mPeerList.Clear();
115-
mPeerPool.FreeAll();
116-
}
117-
118-
Peer *Interface::FindPeer(const Mac::ExtAddress &aExtAddress) { return mPeerList.FindMatching(aExtAddress); }
119-
120112
void Interface::NotifyPeerSocketAddressDifference(const Ip6::SockAddr &aPeerSockAddr, const Ip6::SockAddr &aRxSockAddr)
121113
{
122114
otPlatTrelNotifyPeerSocketAddressDifference(&GetInstance(), &aPeerSockAddr, &aRxSockAddr);
@@ -183,7 +175,7 @@ extern "C" void otPlatTrelHandleDiscoveredPeerInfo(otInstance *aInstance, const
183175

184176
void Interface::HandleDiscoveredPeerInfo(const PeerInfo &aInfo)
185177
{
186-
Peer *entry;
178+
Peer *peer;
187179
Mac::ExtAddress extAddress;
188180
MeshCoP::ExtendedPanId extPanId;
189181
bool isNew = false;
@@ -196,9 +188,7 @@ void Interface::HandleDiscoveredPeerInfo(const PeerInfo &aInfo)
196188

197189
if (aInfo.IsRemoved())
198190
{
199-
entry = FindPeer(extAddress);
200-
VerifyOrExit(entry != nullptr);
201-
RemovePeerEntry(*entry);
191+
Get<PeerTable>().RemoveAndFreeAllMatching(extAddress);
202192
ExitNow();
203193
}
204194

@@ -208,37 +198,37 @@ void Interface::HandleDiscoveredPeerInfo(const PeerInfo &aInfo)
208198
// different Extended MAC address. This ensures that we do not
209199
// keep stale entries in the peer table.
210200

211-
entry = mPeerList.FindMatching(aInfo.GetSockAddr());
201+
peer = Get<PeerTable>().FindMatching(aInfo.GetSockAddr());
212202

213-
if ((entry != nullptr) && !entry->Matches(extAddress))
203+
if ((peer != nullptr) && !peer->Matches(extAddress))
214204
{
215-
RemovePeerEntry(*entry);
216-
entry = nullptr;
205+
Get<PeerTable>().RemoveMatching(aInfo.GetSockAddr());
206+
peer = nullptr;
217207
}
218208

219-
if (entry == nullptr)
209+
if (peer == nullptr)
220210
{
221-
entry = mPeerList.FindMatching(extAddress);
211+
peer = Get<PeerTable>().FindMatching(extAddress);
222212
}
223213

224-
if (entry == nullptr)
214+
if (peer == nullptr)
225215
{
226-
entry = GetNewPeerEntry();
227-
VerifyOrExit(entry != nullptr);
216+
peer = Get<PeerTable>().AllocateAndAddNewPeer();
217+
VerifyOrExit(peer != nullptr);
228218

229-
entry->SetExtAddress(extAddress);
219+
peer->SetExtAddress(extAddress);
230220
isNew = true;
231221
}
232222

233223
if (!isNew)
234224
{
235-
VerifyOrExit((entry->GetExtPanId() != extPanId) || (entry->GetSockAddr() != aInfo.GetSockAddr()));
225+
VerifyOrExit((peer->GetExtPanId() != extPanId) || (peer->GetSockAddr() != aInfo.GetSockAddr()));
236226
}
237227

238-
entry->SetExtPanId(extPanId);
239-
entry->SetSockAddr(aInfo.GetSockAddr());
228+
peer->SetExtPanId(extPanId);
229+
peer->SetSockAddr(aInfo.GetSockAddr());
240230

241-
entry->Log(isNew ? Peer::kAdded : Peer::kUpdated);
231+
peer->Log(isNew ? Peer::kAdded : Peer::kUpdated);
242232

243233
exit:
244234
return;
@@ -294,60 +284,6 @@ Error Interface::PeerInfo::ParseTxtData(Mac::ExtAddress &aExtAddress, MeshCoP::E
294284
return error;
295285
}
296286

297-
Peer *Interface::GetNewPeerEntry(void)
298-
{
299-
Peer *peerEntry;
300-
301-
peerEntry = mPeerPool.Allocate();
302-
303-
if (peerEntry != nullptr)
304-
{
305-
mPeerList.Push(*peerEntry);
306-
ExitNow();
307-
}
308-
309-
for (Peer &entry : mPeerList)
310-
{
311-
if (entry.GetExtPanId() != Get<MeshCoP::ExtendedPanIdManager>().GetExtPanId())
312-
{
313-
ExitNow(peerEntry = &entry);
314-
}
315-
}
316-
317-
for (Peer &entry : mPeerList)
318-
{
319-
// We skip over any existing entry in neighbor table (even if the
320-
// entry is in invalid state).
321-
322-
if (Get<NeighborTable>().FindNeighbor(entry.GetExtAddress(), Neighbor::kInStateAny) != nullptr)
323-
{
324-
continue;
325-
}
326-
327-
#if OPENTHREAD_FTD
328-
if (Get<NeighborTable>().FindRxOnlyNeighborRouter(entry.GetExtAddress()) != nullptr)
329-
{
330-
continue;
331-
}
332-
#endif
333-
334-
ExitNow(peerEntry = &entry);
335-
}
336-
337-
exit:
338-
return peerEntry;
339-
}
340-
341-
void Interface::RemovePeerEntry(Peer &aEntry)
342-
{
343-
aEntry.Log(Peer::kRemoving);
344-
345-
if (mPeerList.Remove(aEntry) == kErrorNone)
346-
{
347-
mPeerPool.Free(aEntry);
348-
}
349-
}
350-
351287
const Counters *Interface::GetCounters(void) const { return otPlatTrelGetCounters(&GetInstance()); }
352288

353289
void Interface::ResetCounters(void) { otPlatTrelResetCounters(&GetInstance()); }
@@ -363,20 +299,20 @@ Error Interface::Send(const Packet &aPacket, bool aIsDiscovery)
363299
switch (aPacket.GetHeader().GetType())
364300
{
365301
case Header::kTypeBroadcast:
366-
for (Peer &entry : mPeerList)
302+
for (const Peer &peer : Get<PeerTable>())
367303
{
368-
if (!aIsDiscovery && (entry.GetExtPanId() != Get<MeshCoP::ExtendedPanIdManager>().GetExtPanId()))
304+
if (!aIsDiscovery && (peer.GetExtPanId() != Get<MeshCoP::ExtendedPanIdManager>().GetExtPanId()))
369305
{
370306
continue;
371307
}
372308

373-
otPlatTrelSend(&GetInstance(), aPacket.GetBuffer(), aPacket.GetLength(), &entry.mSockAddr);
309+
otPlatTrelSend(&GetInstance(), aPacket.GetBuffer(), aPacket.GetLength(), &peer.mSockAddr);
374310
}
375311
break;
376312

377313
case Header::kTypeUnicast:
378314
case Header::kTypeAck:
379-
peerEntry = mPeerList.FindMatching(aPacket.GetHeader().GetDestination());
315+
peerEntry = Get<PeerTable>().FindMatching(aPacket.GetHeader().GetDestination());
380316
VerifyOrExit(peerEntry != nullptr, error = kErrorAbort);
381317
otPlatTrelSend(&GetInstance(), aPacket.GetBuffer(), aPacket.GetLength(), &peerEntry->mSockAddr);
382318
break;
@@ -413,30 +349,6 @@ void Interface::HandleReceived(uint8_t *aBuffer, uint16_t aLength, const Ip6::So
413349
return;
414350
}
415351

416-
const Peer *Interface::GetNextPeer(PeerIterator &aIterator) const
417-
{
418-
const Peer *entry = static_cast<const Peer *>(aIterator);
419-
420-
VerifyOrExit(entry != nullptr);
421-
aIterator = entry->GetNext();
422-
423-
exit:
424-
return entry;
425-
}
426-
427-
uint16_t Interface::GetNumberOfPeers(void) const
428-
{
429-
uint16_t count = 0;
430-
431-
for (const Peer &peer : mPeerList)
432-
{
433-
OT_UNUSED_VARIABLE(peer);
434-
count++;
435-
}
436-
437-
return count;
438-
}
439-
440352
} // namespace Trel
441353
} // namespace ot
442354

src/core/radio/trel_interface.hpp

Lines changed: 7 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,6 @@ class Interface : public InstanceLocator
7979
friend void otPlatTrelHandleDiscoveredPeerInfo(otInstance *aInstance, const otPlatTrelPeerInfo *aInfo);
8080

8181
public:
82-
/**
83-
* Represents an iterator for iterating over TREL peer table entries.
84-
*/
85-
typedef otTrelPeerIterator PeerIterator;
86-
8782
/**
8883
* Enables or disables the TREL interface.
8984
*
@@ -117,29 +112,6 @@ class Interface : public InstanceLocator
117112
*/
118113
bool IsEnabled(void) const { return mEnabled; }
119114

120-
/**
121-
* Initializes a peer table iterator.
122-
*
123-
* @param[in] aIterator The iterator to initialize.
124-
*/
125-
void InitIterator(PeerIterator &aIterator) const { aIterator = mPeerList.GetHead(); }
126-
127-
/**
128-
* Iterates over the peer table entries.
129-
*
130-
* @param[in] aIterator The iterator. MUST be initialized.
131-
*
132-
* @returns A pointer to the next `Peer` entry or `nullptr` if no more entries in the table.
133-
*/
134-
const Peer *GetNextPeer(PeerIterator &aIterator) const;
135-
136-
/**
137-
* Returns the number of TREL peers.
138-
*
139-
* @returns The number of TREL peers.
140-
*/
141-
uint16_t GetNumberOfPeers(void) const;
142-
143115
/**
144116
* Sets the filter mode (enables/disables filtering).
145117
*
@@ -180,15 +152,6 @@ class Interface : public InstanceLocator
180152
*/
181153
uint16_t GetUdpPort(void) const { return mUdpPort; }
182154

183-
/**
184-
* Finds the TREL peer associated with a given Extended Address.
185-
*
186-
* @param[in] aExtAddress The extended address.
187-
*
188-
* @returns The peer associated with @ aExtAddress, or `nullptr` if not found.
189-
*/
190-
Peer *FindPeer(const Mac::ExtAddress &aExtAddress);
191-
192155
/**
193156
* Notifies platform that a TREL packet is received from a peer using a different socket address than the one
194157
* reported earlier.
@@ -227,21 +190,16 @@ class Interface : public InstanceLocator
227190
void HandleReceived(uint8_t *aBuffer, uint16_t aLength, const Ip6::SockAddr &aSenderAddr);
228191
void HandleDiscoveredPeerInfo(const PeerInfo &aInfo);
229192

230-
void RegisterService(void);
231-
Peer *GetNewPeerEntry(void);
232-
void RemovePeerEntry(Peer &aEntry);
233-
void ClearPeerList(void);
193+
void RegisterService(void);
234194

235195
using RegisterServiceTask = TaskletIn<Interface, &Interface::RegisterService>;
236196

237-
bool mInitialized : 1;
238-
bool mEnabled : 1;
239-
bool mFiltered : 1;
240-
RegisterServiceTask mRegisterServiceTask;
241-
uint16_t mUdpPort;
242-
Packet mRxPacket;
243-
LinkedList<Peer> mPeerList;
244-
Pool<Peer, kPeerPoolSize> mPeerPool;
197+
bool mInitialized : 1;
198+
bool mEnabled : 1;
199+
bool mFiltered : 1;
200+
RegisterServiceTask mRegisterServiceTask;
201+
uint16_t mUdpPort;
202+
Packet mRxPacket;
245203
};
246204

247205
} // namespace Trel

src/core/radio/trel_link.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ Link::Link(Instance &aInstance)
5050
, mTxTasklet(aInstance)
5151
, mTimer(aInstance)
5252
, mInterface(aInstance)
53+
, mPeerTable(aInstance)
5354
{
5455
ClearAllBytes(mTxFrame);
5556
ClearAllBytes(mRxFrame);
@@ -343,7 +344,7 @@ void Link::ProcessReceivedPacket(Packet &aPacket, const Ip6::SockAddr &aSockAddr
343344
VerifyOrExit(aPacket.GetHeader().GetSource() != Get<Mac::Mac>().GetExtAddress());
344345

345346
mRxPacketSenderAddr = aSockAddr;
346-
mRxPacketPeer = Get<Interface>().FindPeer(aPacket.GetHeader().GetSource());
347+
mRxPacketPeer = Get<PeerTable>().FindMatching(aPacket.GetHeader().GetSource());
347348

348349
if (type != Header::kTypeBroadcast)
349350
{

src/core/radio/trel_link.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include "mac/mac_types.hpp"
4848
#include "radio/trel_interface.hpp"
4949
#include "radio/trel_packet.hpp"
50+
#include "radio/trel_peer.hpp"
5051

5152
namespace ot {
5253

@@ -199,6 +200,7 @@ class Link : public InstanceLocator
199200
TxTasklet mTxTasklet;
200201
TimeoutTimer mTimer;
201202
Interface mInterface;
203+
PeerTable mPeerTable;
202204
Ip6::SockAddr mRxPacketSenderAddr;
203205
Peer *mRxPacketPeer;
204206
Mac::RxFrame mRxFrame;

0 commit comments

Comments
 (0)